4.2.5 Python实现逻辑回归
结合之前所讲的理论,本节开始动手实现一个逻辑回归算法。
首先,我们定义一个类,类名为LogisticRegression,并初始化一些变量:维度、截距、theta值,示例代码如下:
class LogisticRegression:
def __init__(self):
"""初始化Logistic regression模型"""
self.coef_ = None #维度self.intercept_ = None #截距
self._theta = None
接着,我们来实现损失函数中的sigmoid(·θT)这个函数,我们之前在4.2.1节已经实现过了Sigmoid函数,
对于sigmoid(·θT)函数,我们输入的值为多元线性回归中的θ0x0+θ1x1+θ2x2+…+θnxn(其中x0恒等于1),为了提高执行效率,我们建议使用向量化来进行处理,而尽量避免使用for循环,所以对于θ0x0+θ1x1+θ2x2+…+θnxn我们使用·θT来代替,具体代码如下:
def _sigmoid(x):
y = 1.0 / (1.0 + np.exp(-x))
return y
接着我们来实现损失函数: 实现代码具体如下: #计算损失函数
def J(theta,X_b,y):
p_predcit = self._sigmoid(X_b.dot(theta))try:
return -np.sum(y*np.log(p_predcit) + (1-y)*np.log(1-p_predcit)) / len(y)
except:
return float('inf')
然后,我们需要实现损失函数的导数。
具体求导过程读者可以自行搜索,我们这里直接给出结论,对于损失函数cost,得到的导数值为: 之前提到过,为考虑计算性能应尽量避免使用for循环实现累加,所以在这里我们使用向量化计算。
完整实现代码具体如下:
import numpy as np
class LogisticRegression:
def __init__(self):
"""初始化Logistic regression模型"""
self.coef_ = None #维度
self.intercept_ = None #截距
self._theta = None
#sigmoid函数,私有化函数
def _sigmoid(self,x):
y = 1.0 / (1.0 + np.exp(-x))
return y
def fit(self,X_train,y_train,eta=0.01,n_iters=1e4):
assert X_train.shape[0] == y_train.shape[0], '训练数据集的长度需要与标签长度保持一致'
#计算损失函数
def J(theta,X_b,y):
p_predcit = self._sigmoid(X_b.dot(theta))
try:
return -np.sum(y*np.log(p_predcit) + (1-y)*np.log(1-p_predcit)) / len(y)
except:
return float('inf')
#求sigmoid梯度的导数
def dJ(theta,X_b,y):
x = self._sigmoid(X_b.dot(theta))
return X_b.T.dot(x-y)/len(X_b)
#模拟梯度下降
def gradient_descent(X_b,y,initial_theta,eta,n_iters=1e4,epsilon=1e-8):
theta = initial_theta
i_iter = 0
while i_iter < n_iters:
gradient = dJ(theta,X_b,y)
last_theta = theta
theta = theta - eta * gradient
i_iter += 1
if (abs(J(theta,X_b,y) - J(last_theta,X_b,y)) < epsilon):
break
return theta
X_b = np.hstack([np.ones((len(X_train),1)),X_train])
initial_theta = np.zeros(X_b.shape[1]) #列向量
self._theta = gradient_descent(X_b,y_train,initial_theta,eta,n_iters)
self.intercept_ = self._theta[0] #截距
self.coef_ = self._theta[1:] #维度
return self
def predict_proba(self,X_predict):
X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
return
self._sigmoid(X_b.dot(self._theta))
def predict(self,X_predict):
proba = self.predict_proba(X_predict)
return np.array(proba > 0.5,dtype='int')
本章小结
本章主要讲述了线性回归模型和逻辑回归模型,并做了相应的实现。
其中,线性回归是逻辑回归的基础,而逻辑回归经常被当作神经网络的神经元,因此逻辑回归又是神经网络的基础。
本章我们借逻辑回归模型介绍了机器学习中必不可少的最优化方法,以及最常见的最优化方法——梯度下降。
了解本章内容会对接下来第5章神经网络的学习有很大的帮助。
网友评论