目前我正在开发Logistic回归的实现。没有什么比这更复杂,只需使用简单的数据集(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,则成本无法使用。
还有一些其他数据:
最终theta:
[ 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]
关于如何改善它的任何想法?
答案 0 :(得分: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是应用于向量的S形函数。 经过一些测试,我发现问题出在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。这是一个非常小的数字,但是导致溢出。所以,让我们用一个非常小的数字代替它,不会导致溢出!“
再一次,可能不是最好的方法,但它为我做了诀窍。
在此之后,我的代码运行顺利,实际上效果非常好。