逻辑回归实现
逻辑回归定义:
logistic回归是一种广义线性回归(generalized linear model),因此与多重线性回归分析有很多相同之处。它们的模型形式基本上相同,都具有 w‘x+b,其中w和b是待求参数,其区别在于他们的因变量不同,多重线性回归直接将w‘x+b作为因变量,即y =w‘x+b,而logistic回归则通过函数L将w‘x+b对应一个隐状态p,p =L(w‘x+b),然后根据p 与1-p的大小决定因变量的值。如果L是logistic函数,就是logistic回归,如果L是多项式函数就是多项式回归(百度百科)
其他概念详情参见:逻辑回归简介
根据Scikit_Learn中的数据集实现
数据准备阶段
1.导入相应的库函数
import sklearn.datasets
import numpy as np
import matplotlib.pyplot as plt
2.为使得后期图标中的中文显示
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
3.导入make_moons数据集
np.random.seed(1)
X,Y = sklearn.datasets.make_moons(n_samples=200,noise=.2)
X,Y = X.T, Y.reshape(1, Y.shape[0])
plt.scatter(X[0,Y[0 , : ]==0], X[1, Y[0 , :]==0], c = 'r', marker='s')
plt.scatter(X[0,Y[0 , : ]==1], X[1, Y[0 , :]==1], c = 'b', marker='o')
plt.show()
函数定义
1.激活函数sigmoid()
ef sigmoid(x):
"""
函数输入:
-x: sigmoid 函数输入
函数输出:
-y: sigmoid 函数输出
:param x:
:return:
"""
y = 1/(1+np.exp(x))
return y
2梯度下降函数
def optimizer(X, Y, num_iterations = 200, learning_rate = 0.01):
"""
函数输入:
:param X: 输入数据特征 维度= (dim, m)
:param Y: 输出数据标签 维度=(1, m)
:param num_iterations: 迭代训练次数
:param learning_rata: 学习速率
:return:
—W : 训练后的权重参数
-b : 训练后的偏置参数
-cost : 每次训练计算的损失函数存放在cost列表中
"""
cost = []
m = X.shape[1]
dim = X.shape[0]
W = np.zeros((dim, 1))
b = 0
for i in range(num_iterations):
Z = np.dot(W.T, X) + b #线性部分
Y_hat = sigmoid(Z) #非线性部分
J = -1.0 / m * np.sum(Y * np.log(Y_hat) + (1 - Y) * np.log(1 - Y_hat))
cost.append(J)
# 梯度下降
dW = 1.0/m*np.dot(X, (Y_hat -Y).T)
db = 1.0/m*np.sum(Y_hat - Y)
W = W - learning_rate*dW
b = b - learning_rate*db
if(i+1) % 20 == 0:
print('Iteration: %d,J=%f' % (i+1,J))
return W, b, cost
训练
W, b, cost = optimizer(X, Y, num_iterations=1000, learning_rate=0.1)
plt.plot(cost)
plt.xlabel("迭代次数")
plt.ylabel('损失函数')
plt.show()
预测实现
def predict(X, W, b):
"""
函数输入
:param X: 输入数据特征,维度 = (dim, m)
:param W: 训练后的权重参数
:param b: 训练后的偏置参数
:return:
Y_pred: 预测输出标签, 维度 = (1, m)
"""
Y_pred = np.zeros((1, X.shape[1]))
Z = np.dot(W.T, X) + b
Y_hat = sigmoid(Z)
Y_pred[Y_hat > 0.5] = 1
return Y_pred
#预测实现
Y_pred = predict(X, W, b)
accuracy = np.mean(Y_pred == Y)
#编辑彩色可视化决策边界
X_min, X_max = X[0, :].min() - 1, X[0, :].max() + 1
y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
step = 0.001
xx, yy = np.meshgrid(np.arange(X_min, X_max,step), np.arange(y_min, y_max, step))
Z = predict(np.c_[xx.ravel(), yy.ravel()].T, W, b)
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap = plt.cm.Spectral)
plt.scatter(X[0, Y[0, :]==0], X[1, Y[0, :]==0], c ='g', marker='s', label='负类')
plt.scatter(X[0, Y[0, :]==1], X[1, Y[0, :]==1], c ='y', marker='o', label='正类')
plt.legend()
plt.show()
效果显示
由于数据集本身就是非线性可分的,所以使用逻辑回归进行线性划分得到的分类无法将所有样本进行完全百分百的正确划分。逻辑回归是最简单的二分类线性分类器,缺点只能进行线性划分。
下一讲:
神经网络预测实现