我们将从建立理论开始,然后是工作示例,并以一些 cmets 结束。
问题陈述
使用梯度下降法拟合/训练逻辑回归模型(与任何监督机器学习模型一样)的步骤如下
- 使用参数 [
w,b] 识别假设函数 [h(X)]
- 识别损失函数 [
J(w,b)]
- 前向传播:使用假设函数进行预测 [
y_hat = h(X)]
- 使用损失函数计算实际标签 [
y] 和预测标签 [y_hat] 之间的误差。
-
反向传播:根据误差(通过计算梯度)调整假设函数中的参数,使用更新规则
如果梯度较高则进入第 3 步,否则结束
计算梯度
逻辑回归的假设函数:
其中X 是一个向量,X^i 是向量的第 i 个元素。
逻辑回归常用的损失函数是对数损失。 l2正则化的log loss为:
让我们计算梯度
同样
现在我们知道了梯度,让我们编写梯度体面算法以适应我们的逻辑回归模型的参数
玩具示例
# load data
iris = datasets.load_iris()
# Lets take only two classes
y = iris.target
X = iris.data[y != 2]
y = y[y != 2]
# Normalize data to 0 mean and 1 std
X[:, 0] = (X[:, 0] - np.mean(X[:, 0]))/np.std(X[:, 0])
X[:, 1] = (X[:, 1] - np.mean(X[:, 1]))/np.std(X[:, 1])
X[:, 2] = (X[:, 2] - np.mean(X[:, 2]))/np.std(X[:, 2])
X[:, 3] = (X[:, 3] - np.mean(X[:, 3]))/np.std(X[:, 3])
def sigmoid(x):
return 1 / (1+math.exp(-x))
# initialize weights
w0, w1, w2, w3, b = 0.01,0.01,0.01,0.01,0.01
n = len(X)
# Learning rate
alpha = 0.01
# The gardient decent loop
while True:
y_hat = [sigmoid(w0*x[0] + w1*x[1] + w2*x[2] + w3*x[3] + b) for x in X]
delta_w0 = -np.sum([(y[j] - y_hat[j])*X[j,0] for j in range(n)])/n + 2*w0
delta_w1 = -np.sum([(y[j] - y_hat[j])*X[j,1] for j in range(n)])/n + 2*w1
delta_w2 = -np.sum([(y[j] - y_hat[j])*X[j,2] for j in range(n)])/n + 2*w2
delta_w3 = -np.sum([(y[j] - y_hat[j])*X[j,3] for j in range(n)])/n + 2*w3
delta_b = -np.sum([(y[j] - y_hat[j]) for j in range(n)])/n + 2*b
w0 = w0 - alpha*delta_w0
w1 = w1 - alpha*delta_w1
w2 = w2 - alpha*delta_w2
w3 = w3 - alpha*delta_w3
b = b - alpha*delta_b
if np.sum(np.abs([delta_w0, delta_w1, delta_w2, delta_w3, delta_b])) < 1e-5:
break
# Make predictions
pred = [1 if i > 0.5 else 0 for i in y_hat]
# Find no:of correct predictions
correct = np.sum([1 if pred[i] == y[i] else 0 for i in range(n)])
print (correct)
评论
- 上面的玩具示例是以最低效的方式编码的。目的是清楚地显示步骤而不是效率。话虽如此,我们将不得不对操作进行向量化(使用 np 数组和矩阵操作)以提高效率。
- 数据规范化很重要
- 模型在训练数据上进行训练,并根据测试/验证数据测量性能。