逻辑回归梯度下降
Logistic Regression Gradient Descent
我必须使用批量梯度下降法进行逻辑回归。
import numpy as np
X = np.asarray([
[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75],
[2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50],
[4.00],[4.25],[4.50],[4.75],[5.00],[5.50]])
y = np.asarray([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1])
m = len(X)
def sigmoid(a):
return 1.0 / (1 + np.exp(-a))
def gradient_Descent(theta, alpha, X , y):
for i in range(0,m):
cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i])))
grad = theta - alpha * (1.0/m) * (np.dot(cost,X[i]))
theta = theta - alpha * grad
return
gradient_Descent(0.1,0.005,X,y)
我必须这样做的方式是这样的,但我似乎无法理解如何让它工作。
看起来你在这里混了一些东西。执行此操作时,务必要跟踪矢量的形状并确保获得合理的结果。例如,您正在计算费用:
cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i])))
在您的例子中,y
是包含 20 个项目的向量,X[i] 是单个值。这使您的成本计算成为一个没有意义的 20 项向量。你的成本应该是一个单一的价值。 (你也在你的梯度下降函数中无缘无故地计算了很多次这个成本)。
此外,如果您希望它能够拟合您的数据,您需要向 X
添加偏差项。那么让我们从这里开始吧。
X = np.asarray([
[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75],
[2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50],
[4.00],[4.25],[4.50],[4.75],[5.00],[5.50]])
ones = np.ones(X.shape)
X = np.hstack([ones, X])
# X.shape is now (20, 2)
Theta 现在需要每个 X 的 2 个值。所以初始化它和 Y:
Y = np.array([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]).reshape([-1, 1])
# reshape Y so it's column vector so matrix multiplication is easier
Theta = np.array([[0], [0]])
你的 sigmoid 函数很好。让我们也做一个矢量化成本函数:
def sigmoid(a):
return 1.0 / (1 + np.exp(-a))
def cost(x, y, theta):
m = x.shape[0]
h = sigmoid(np.matmul(x, theta))
cost = (np.matmul(-y.T, np.log(h)) - np.matmul((1 -y.T), np.log(1 - h)))/m
return cost
成本函数起作用是因为 Theta
的形状为 (2, 1) 而 X
的形状为 (20, 2) 所以 matmul(X, Theta)
的形状为 (20 , 1).然后矩阵乘以 Y 的转置(y.T
形状为 (1, 20)),结果为单个值,我们的成本给定了特定的 Theta 值。
然后我们可以编写一个函数来执行单步批量梯度下降:
def gradient_Descent(theta, alpha, x , y):
m = x.shape[0]
h = sigmoid(np.matmul(x, theta))
grad = np.matmul(X.T, (h - y)) / m;
theta = theta - alpha * grad
return theta
注意 np.matmul(X.T, (h - y))
将形状 (2, 20) 和 (20, 1) 相乘,得到形状 (2, 1) — 与 Theta
相同的形状你想从你的梯度。这允许您将 is 乘以您的学习率并从初始 Theta 中减去它,这就是梯度下降应该做的。
所以现在你只需编写一个循环进行多次迭代并更新 Theta 直到它看起来收敛:
n_iterations = 500
learning_rate = 0.5
for i in range(n_iterations):
Theta = gradient_Descent(Theta, learning_rate, X, Y)
if i % 50 == 0:
print(cost(X, Y, Theta))
这将每 50 次迭代打印一次成本,从而导致成本稳步下降,这正是您所希望的:
[[ 0.6410409]]
[[ 0.44766253]]
[[ 0.41593581]]
[[ 0.40697167]]
[[ 0.40377785]]
[[ 0.4024982]]
[[ 0.40195]]
[[ 0.40170533]]
[[ 0.40159325]]
[[ 0.40154101]]
您可以尝试 Theta
的不同初始值,您会发现它总是收敛到相同的东西。
现在您可以使用新发现的 Theta
值进行预测:
h = sigmoid(np.matmul(X, Theta))
print((h > .5).astype(int) )
这会打印出您对数据线性拟合的期望:
[[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]]
我必须使用批量梯度下降法进行逻辑回归。
import numpy as np
X = np.asarray([
[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75],
[2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50],
[4.00],[4.25],[4.50],[4.75],[5.00],[5.50]])
y = np.asarray([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1])
m = len(X)
def sigmoid(a):
return 1.0 / (1 + np.exp(-a))
def gradient_Descent(theta, alpha, X , y):
for i in range(0,m):
cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i])))
grad = theta - alpha * (1.0/m) * (np.dot(cost,X[i]))
theta = theta - alpha * grad
return
gradient_Descent(0.1,0.005,X,y)
我必须这样做的方式是这样的,但我似乎无法理解如何让它工作。
看起来你在这里混了一些东西。执行此操作时,务必要跟踪矢量的形状并确保获得合理的结果。例如,您正在计算费用:
cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i])))
在您的例子中,y
是包含 20 个项目的向量,X[i] 是单个值。这使您的成本计算成为一个没有意义的 20 项向量。你的成本应该是一个单一的价值。 (你也在你的梯度下降函数中无缘无故地计算了很多次这个成本)。
此外,如果您希望它能够拟合您的数据,您需要向 X
添加偏差项。那么让我们从这里开始吧。
X = np.asarray([
[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75],
[2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50],
[4.00],[4.25],[4.50],[4.75],[5.00],[5.50]])
ones = np.ones(X.shape)
X = np.hstack([ones, X])
# X.shape is now (20, 2)
Theta 现在需要每个 X 的 2 个值。所以初始化它和 Y:
Y = np.array([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]).reshape([-1, 1])
# reshape Y so it's column vector so matrix multiplication is easier
Theta = np.array([[0], [0]])
你的 sigmoid 函数很好。让我们也做一个矢量化成本函数:
def sigmoid(a):
return 1.0 / (1 + np.exp(-a))
def cost(x, y, theta):
m = x.shape[0]
h = sigmoid(np.matmul(x, theta))
cost = (np.matmul(-y.T, np.log(h)) - np.matmul((1 -y.T), np.log(1 - h)))/m
return cost
成本函数起作用是因为 Theta
的形状为 (2, 1) 而 X
的形状为 (20, 2) 所以 matmul(X, Theta)
的形状为 (20 , 1).然后矩阵乘以 Y 的转置(y.T
形状为 (1, 20)),结果为单个值,我们的成本给定了特定的 Theta 值。
然后我们可以编写一个函数来执行单步批量梯度下降:
def gradient_Descent(theta, alpha, x , y):
m = x.shape[0]
h = sigmoid(np.matmul(x, theta))
grad = np.matmul(X.T, (h - y)) / m;
theta = theta - alpha * grad
return theta
注意 np.matmul(X.T, (h - y))
将形状 (2, 20) 和 (20, 1) 相乘,得到形状 (2, 1) — 与 Theta
相同的形状你想从你的梯度。这允许您将 is 乘以您的学习率并从初始 Theta 中减去它,这就是梯度下降应该做的。
所以现在你只需编写一个循环进行多次迭代并更新 Theta 直到它看起来收敛:
n_iterations = 500
learning_rate = 0.5
for i in range(n_iterations):
Theta = gradient_Descent(Theta, learning_rate, X, Y)
if i % 50 == 0:
print(cost(X, Y, Theta))
这将每 50 次迭代打印一次成本,从而导致成本稳步下降,这正是您所希望的:
[[ 0.6410409]]
[[ 0.44766253]]
[[ 0.41593581]]
[[ 0.40697167]]
[[ 0.40377785]]
[[ 0.4024982]]
[[ 0.40195]]
[[ 0.40170533]]
[[ 0.40159325]]
[[ 0.40154101]]
您可以尝试 Theta
的不同初始值,您会发现它总是收敛到相同的东西。
现在您可以使用新发现的 Theta
值进行预测:
h = sigmoid(np.matmul(X, Theta))
print((h > .5).astype(int) )
这会打印出您对数据线性拟合的期望:
[[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]]