逻辑回归的批量梯度下降
Batch Gradient Descent for Logistic Regression
我一直在学习 Andrew Ng CSC229 机器学习课程,现在正在学习逻辑回归。目标是最大化对数似然函数并找到最佳的 theta 值。讲义的 link 是:[http://cs229.stanford.edu/notes/cs229-notes1.ps][1] - 第 16-19 页。现在下面的代码显示在课程主页上(虽然在 matlab 中——我将它转换为 python)。
我将其应用于包含 100 个训练示例的数据集(Coursera 主页上提供的机器学习入门课程的数据集)。数据有两个特征,即两次考试的两个分数。如果学生被录取,则输出为 1,如果学生未被录取,则输出为 0。显示了下面的所有代码。以下代码使似然函数收敛到约 -62 的最大值。 theta 对应的值为 [-0.05560301 0.01081111 0.00088362]。当我测试像 [1, 30.28671077, 43.89499752] 这样的训练示例时使用这些值,它应该给出 0 作为输出值,我得到 0.576 这对我来说毫无意义。如果我用输入 [1, 10, 10] 测试假设函数,我得到 0.515,这又一次没有意义。这些值应对应于较低的概率。这让我很困惑。
import numpy as np
import sig as s
def batchlogreg(X, y):
max_iterations = 800
alpha = 0.00001
(m,n) = np.shape(X)
X = np.insert(X, 0, 1, 1)
theta = np.array([0] * (n+1), 'float')
ll = np.array([0] * max_iterations, 'float')
for i in range(max_iterations):
hx = s.sigmoid(np.dot(X, theta))
d = y - hx
theta = theta + alpha*np.dot(np.transpose(X),d)
ll[i] = sum(y * np.log(hx) + (1-y) * np.log(1- hx))
return (theta, ll)
听起来你可能会混淆概率和作业。
概率将是一个介于 0.0 和 1.0 之间的实数。标签将是一个整数(0 或 1)。逻辑回归是一种模型,它提供给定输入特征时标签为 1 的概率。要获得标签值,您需要使用该概率做出决定。一个简单的决策规则是,如果概率小于 0.5,则标签为 0,如果概率大于或等于 0.5,则标签为 1。
因此,对于您给出的示例,决策都是 1(这意味着第一个示例的模型错误,应该为 0)。
注意sigmoid函数有:
sig(0) = 0.5
sig(x > 0) > 0.5
sig(x < 0) < 0.5
由于您得到的所有概率都高于 0.5
,这表明您永远不会使 X * theta
为负数,或者您确实如此,但您的学习率太小而无足轻重。
for i in range(max_iterations):
hx = s.sigmoid(np.dot(X, theta)) # this will probably be > 0.5 initially
d = y - hx # then this will be "very" negative when y is 0
theta = theta + alpha*np.dot(np.transpose(X),d) # (1)
ll[i] = sum(y * np.log(hx) + (1-y) * np.log(1- hx))
问题最有可能出现在 (1)
。点积会非常负,但是你的 alpha
非常小,会抵消它的影响。因此 theta
永远不会减少到足以正确处理 0
.
的正确分类标签
出于同样的原因,阳性实例只能勉强正确分类:您的算法在您的迭代次数和学习率下没有发现合理的假设。
可能的解决方案:增加alpha
和/或迭代次数,或者使用momentum.
我遇到了同样的问题,找到了原因。
首先将 X 归一化或设置一个比例可比较的截距,如 50。
否则成本函数的轮廓也是"narrow"。一个大的 alpha 使它超调,一个小的 alpha 无法进步。
我一直在学习 Andrew Ng CSC229 机器学习课程,现在正在学习逻辑回归。目标是最大化对数似然函数并找到最佳的 theta 值。讲义的 link 是:[http://cs229.stanford.edu/notes/cs229-notes1.ps][1] - 第 16-19 页。现在下面的代码显示在课程主页上(虽然在 matlab 中——我将它转换为 python)。
我将其应用于包含 100 个训练示例的数据集(Coursera 主页上提供的机器学习入门课程的数据集)。数据有两个特征,即两次考试的两个分数。如果学生被录取,则输出为 1,如果学生未被录取,则输出为 0。显示了下面的所有代码。以下代码使似然函数收敛到约 -62 的最大值。 theta 对应的值为 [-0.05560301 0.01081111 0.00088362]。当我测试像 [1, 30.28671077, 43.89499752] 这样的训练示例时使用这些值,它应该给出 0 作为输出值,我得到 0.576 这对我来说毫无意义。如果我用输入 [1, 10, 10] 测试假设函数,我得到 0.515,这又一次没有意义。这些值应对应于较低的概率。这让我很困惑。
import numpy as np
import sig as s
def batchlogreg(X, y):
max_iterations = 800
alpha = 0.00001
(m,n) = np.shape(X)
X = np.insert(X, 0, 1, 1)
theta = np.array([0] * (n+1), 'float')
ll = np.array([0] * max_iterations, 'float')
for i in range(max_iterations):
hx = s.sigmoid(np.dot(X, theta))
d = y - hx
theta = theta + alpha*np.dot(np.transpose(X),d)
ll[i] = sum(y * np.log(hx) + (1-y) * np.log(1- hx))
return (theta, ll)
听起来你可能会混淆概率和作业。
概率将是一个介于 0.0 和 1.0 之间的实数。标签将是一个整数(0 或 1)。逻辑回归是一种模型,它提供给定输入特征时标签为 1 的概率。要获得标签值,您需要使用该概率做出决定。一个简单的决策规则是,如果概率小于 0.5,则标签为 0,如果概率大于或等于 0.5,则标签为 1。
因此,对于您给出的示例,决策都是 1(这意味着第一个示例的模型错误,应该为 0)。
注意sigmoid函数有:
sig(0) = 0.5
sig(x > 0) > 0.5
sig(x < 0) < 0.5
由于您得到的所有概率都高于 0.5
,这表明您永远不会使 X * theta
为负数,或者您确实如此,但您的学习率太小而无足轻重。
for i in range(max_iterations):
hx = s.sigmoid(np.dot(X, theta)) # this will probably be > 0.5 initially
d = y - hx # then this will be "very" negative when y is 0
theta = theta + alpha*np.dot(np.transpose(X),d) # (1)
ll[i] = sum(y * np.log(hx) + (1-y) * np.log(1- hx))
问题最有可能出现在 (1)
。点积会非常负,但是你的 alpha
非常小,会抵消它的影响。因此 theta
永远不会减少到足以正确处理 0
.
出于同样的原因,阳性实例只能勉强正确分类:您的算法在您的迭代次数和学习率下没有发现合理的假设。
可能的解决方案:增加alpha
和/或迭代次数,或者使用momentum.
我遇到了同样的问题,找到了原因。
首先将 X 归一化或设置一个比例可比较的截距,如 50。
否则成本函数的轮廓也是"narrow"。一个大的 alpha 使它超调,一个小的 alpha 无法进步。