Coursera ML - 在python中实现正则化逻辑回归成本函数

时间:2017-06-26 04:28:02

标签: python matlab numpy machine-learning logistic-regression

我正在通过在Python中实现所有代码而不是MATLAB来完成Andrew Ng在Coursera上的机器学习。

在编程练习3中,我以矢量化形式实现了我的正则化逻辑回归成本函数:

def compute_cost_regularized(theta, X, y, lda):
    reg =lda/(2*len(y)) * np.sum(theta**2) 
    return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta)) 
                         - (1-y) @ np.log(1-sigmoid(X@theta))) + reg

在以下测试输入上:

theta_test = np.array([-2,-1,1,2])
X_test = np.concatenate((np.ones((5,1)), 
         np.fromiter((x/10 for x in range(1,16)), float).reshape((3,5)).T), axis = 1)
y_test = np.array([1,0,1,0,1])
lambda_test = 3

上述成本函数输出3.734819396109744。但是,根据提供给我们的骨架MATLAB代码,正确的输出应为2.534819。我很困惑,因为我发现我的成本函数没有任何问题,但我相信它有一个错误。事实上,我在二进制分类案例中的编程练习2中也implemented it并且它工作正常,给出result close to the expected value

我认为有一个原因可能是我错误地构建了我的*_test输入数组,这是基于错误解释提供的骨架MATLAB代码:

theta_t = [-2; -1; 1; 2];
X_t = [ones(5,1) reshape(1:15,5,3)/10];
y_t = ([1;0;1;0;1] >= 0.5);
lambda_t = 3;

但是,我通过Octave解释器运行它们以查看它们实际上是什么,并确保我可以在python中完全匹配它们。

此外,使用我自己的矢量化和正则化梯度函数计算基于这些输入的梯度也是正确的。最后,我决定继续计算并检查预测结果。我预测的准确性低于预期的准确性,因此它更有理由怀疑我的成本函数出现问题,导致其他一切都出错。

请帮忙!谢谢。

1 个答案:

答案 0 :(得分:2)

如果您回想一下正则化,那么会使偏差系数正常化。执行梯度下降时,不仅将梯度设置为零,而且还不在成本函数中包含此梯度。如果您将此作为总和的一部分,则会略有错误(请参阅笔记本中您链接的单元格#18 - 总和应从j = 1开始,但您将其作为j = 0)。因此,您需要从theta的第二个元素到末尾求和,而不是第一个元素。您可以在Github存储库中显示的ex2.pdf PDF分配的第9页上验证这一点。这解释了膨胀成本,因为您将偏差单元作为正规化的一部分。

因此,在reg计算正则化时,索引theta,以便从第二个元素开始,然后再开始:

def compute_cost_regularized(theta, X, y, lda):
    reg =lda/(2*len(y)) * np.sum(theta[1:]**2) # Change here
    return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta)) 
                         - (1-y) @ np.log(1-sigmoid(X@theta))) + reg

一旦我这样做,定义你的测试值以及定义你的sigmoid函数,我得到你期望的正确答案:

In [8]: def compute_cost_regularized(theta, X, y, lda):
   ...:     reg =lda/(2*len(y)) * np.sum(theta[1:]**2)
   ...:     return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta))
   ...:                          - (1-y) @ np.log(1-sigmoid(X@theta))) + reg
   ...:

In [9]: def sigmoid(z):
   ...:     return 1 / (1 + np.exp(-z))
   ...:

In [10]: theta_test = np.array([-2,-1,1,2])
    ...: X_test = np.concatenate((np.ones((5,1)),
    ...:          np.fromiter((x/10 for x in range(1,16)), float).reshape((3,5)).T), axis = 1)
    ...: y_test = np.array([1,0,1,0,1])
    ...: lambda_test = 3
    ...:

In [11]: compute_cost_regularized(theta_test, X_test, y_test, lambda_test)
Out[11]: 2.5348193961097438