Chap 2 Logistic Regression
- 预习
- 决策边界
- 预测函数
- 代价函数
- 模型的求解
- 梯度下降法
- sklearn
预习
- 逻辑回归用于分类问题
- 决策边界
- 逻辑回归的预测函数
关于sigmoid函数
Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的激活函数,将变量映射到0,1之间。
sigmoid函数也叫Logistic函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。
值域
- 逻辑回归的代价函数(求min)
分类模型的性能评估
- 混淆矩阵
- 准确率、正确率、召回率
- F-score
- ROC&AUC
决策边界
当
当
线性可分的
非线性可分的:引入高次项
建模:找出决策边界的系数
模型,样本,真实值
找出一组使得n维向量降维成一维
为一类,为另一类。
预测函数
,其中函数是sigmoid函数
表示分类为的概率
当,归为1类的概率大于0.5
代价函数
代价函数形式的推导:
模型的求解
梯度下降法
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report #用于评估模型的性能
from sklearn import preprocessing #用于数据标准化预处理
scale = False # 数据是否需要标准化
# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1]
print(x_data)
print(y_data)
def plot():
x1_0 = []
x2_0 = []
x1_1 = []
x2_1 = []
# 切分不同类别的数据
for i in range(len(x_data)):
if y_data[i]==0:
x1_0.append(x_data[i,0])
x2_0.append(x_data[i,1])
else:
x1_1.append(x_data[i,0])
x2_1.append(x_data[i,1])
# 画图
scatter0 = plt.scatter(x1_0, x2_0, c='b', marker='o')
scatter1 = plt.scatter(x1_1, x2_1, c='r', marker='x')
#画图例
plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best') #loc表示图例的位置
plot()
plt.show()
# 数据处理,添加偏置项
print(x_data.shape)
print(y_data.shape)
print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data)
print(X_data.shape)
y_data = data[:,-1,np.newaxis]
print(y_data.shape)
def sigmoid(x):
return 1.0/(1+np.exp(-x))
def cost(xMat, yMat, ws): #计算代价
left = np.multiply(yMat, np.log(sigmoid(xMat*ws))) # multiply表示矩阵按对应位置相乘
right = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat*ws)))
return np.sum(left + right) / -(len(xMat))
def gradAscent(xArr, yArr): #梯度下降
if scale == True:
xArr = preprocessing.scale(xArr)
xMat = np.mat(xArr)
yMat = np.mat(yArr)
lr = 0.001
epochs = 10000
costList = []
# 计算数据行列数
# 行代表数据个数,列代表权值个数
m,n = np.shape(xMat)
# 初始化权值
ws = np.mat(np.ones((n,1)))
for i in range(epochs+1): #迭代10001次,最后一次i=10000
# xMat和weights矩阵相乘
h = sigmoid(xMat*ws) #xMat:(100,3); ws:(3,1); h:(100,1)
# 计算误差
ws_grad = xMat.T*(h - yMat)/m # xMat.T: (3,100) ; h - yMat:(100,1); ws_grad:(3,1)
ws = ws - lr*ws_grad
if i % 50 == 0:
costList.append(cost(xMat,yMat,ws))
return ws,costList
# 训练模型,得到权值和cost值的变化
ws,costList = gradAscent(X_data, y_data)
print(ws)
if scale == False:
# 画图决策边界
plot()
x_test = [[-4],[3]]
y_test = (-ws[0] - x_test*ws[1])/ws[2]
plt.plot(x_test, y_test, 'k') #k:black
plt.show()
# 画图 loss值的变化
x = np.linspace(0,10000,201)
print(x)
plt.plot(x, costList, c='r')
plt.title('Train')
plt.xlabel('Epochs')
plt.ylabel('Cost')
plt.show()
# 预测
def predict(x_data, ws):
if scale == True:
x_data = preprocessing.scale(x_data)
xMat = np.mat(x_data)
ws = np.mat(ws)
return [1 if x >= 0.5 else 0 for x in sigmoid(xMat*ws)]
predictions = predict(X_data, ws)
y_data = data[:,-1]
print(y_data)
print(predictions)
print(classification_report(y_data, predictions))
sklearn
import numpy as np
from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn import linear_model
# 数据是否需要标准化
scale = False
# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1]
def plot():
x0 = []
x1 = []
y0 = []
y1 = []
# 切分不同类别的数据
for i in range(len(x_data)):
if y_data[i]==0:
x0.append(x_data[i,0])
y0.append(x_data[i,1])
else:
x1.append(x_data[i,0])
y1.append(x_data[i,1])
# 画图
scatter0 = plt.scatter(x0, y0, c='b', marker='o')
scatter1 = plt.scatter(x1, y1, c='r', marker='x')
#画图例
plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best')
plot()
plt.show()
logistic = linear_model.LogisticRegression()
logistic.fit(x_data, y_data)
if scale == False:
# 画图决策边界
plot()
x_test = np.array([[-4],[3]])
print(logistic.coef_)
y_test = (-logistic.intercept_ - x_test*logistic.coef_[0][0])/logistic.coef_[0][1]
plt.plot(x_test, y_test, 'k')
plt.show()
predictions = logistic.predict(x_data)
print(classification_report(y_data, predictions))