0

目前我正在研究逻辑回归的实现。没什么复杂的,只需使用一个简单的数据集(Andrew Ng 的购房预测)。这是我正在做的事情:

我的成本函数:

def Cost(theta, X, Y):
  m = Y.size 
  h = Sigmoid(X.dot(theta.T))
  J = (1.0/m) * ((-Y.T.dot(log(h))) - ((1.0 - Y.T).dot(log(1.0-h))))
  return J.sum()

调用 fmin:

initial_theta = zeros(shape = (X.shape[1],1))
theta = fmin(Cost2,initial_theta, args = (X,Y))

使用 fmin 时,我得到的最终 theta 太大而无法预测。预测时,我总是得到 0,62 和 0,71 左右的值,这将始终预测为真。也许通过更多的迭代,我可以获得更好的结果,但我不确定。

使用 fmin_bfgs 时,如果收敛到 NaN 的成本,则使其无法使用。

还有一些其他数据:

最终θ:

[ 0.00126059  0.01033406]

最终成本:

[ 0.62079972]

预测:

[ 0.63422573  0.6727308   0.62957501  0.66757524  0.64503653  0.62245727
0.67765315  0.68966732  0.72525886  0.73487524  0.67716454  0.70974059
0.7142225   0.70415933  0.62892863  0.69232142  0.70645758  0.64152605
0.62052863  0.69538731]

真实评分(如果为 1,则预测应 >=.5 如果为 0,则预测应<0.5)。这是我应该收到的:

[0 0 0 1 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1]

关于如何使它变得更好的任何想法?

4

1 回答 1

0

因此,经过一些研究和测试,我找到了我的代码无法正常工作的原因。

由于 fmin_bfgs 正在转换为 NaN,我决定看看为什么,以及我能做些什么来解决这个问题。我所做的不是最好的方法,但解决了这个问题,现在我的代码可以工作了。

因此,基本上,fmin_bfgs 生成的数字太小,导致溢出,导致 NaN。我所做的是(再一次,不是解决问题的理想方法,但它成功了):

首先:将成本函数拆分为三部分:

def Cost(theta, X, Y): 
  m = Y.size
  Y = Y.flatten()
  for i in range(X.shape[0]):
  X[i]=X[i].flatten()

  h = Sigmoid(X.dot(theta.T))
  a = (-Y.T.dot(log(h)))
  b = ((1.0 - Y.T).dot(log(1.0-h)))

因此,如您所见,代码

J = (1.0/m) * ((-Y.T.dot(log(h))) - ((1.0 - Y.T).dot(log(1.0-h))))

被因子 a、b 和 h 替换,其中 h 是应用于向量的 sigmoid 函数。经过一些测试,我发现问题出在 b 术语上。对数计算生成 -infinity,因为 h 被计算为每个术语的 1,生成一个 log(0.0),对于那些知道一些基本数学的人来说,什么是 -infinity。所以,这就是我为解决问题所做的:

if math.isnan(b):
  #case of overflow
  b = -999999

J =  (a-b)/m

return J/m 

基本上,我的想法是:“好吧,我在这里收到一个 -infinity。这是一个非常小的数字,但会导致溢出。所以,让我们用一个不会导致溢出的非常小的数字替换它!”

再一次,可能不是最好的方法,但它对我有用。

在此之后,我的代码运行顺利,实际上效果非常好。

于 2012-12-12T11:06:36.883 回答