我正在尝试使用Python在Python中实现向量化逻辑回归
NumPy 的。我的成本函数(CF)似乎工作正常。然而有一个
梯度计算的问题。它返回 3x100 数组,而它
应返回 3x1。我认为 (hypo-y)
部分有问题。
def sigmoid(a):
return 1/(1+np.exp(-a))
def CF(theta,X,y):
m=len(y)
hypo=sigmoid(np.matmul(X,theta))
J=(-1./m)*((np.matmul(y.T,np.log(hypo)))+(np.matmul((1-y).T,np.log(1-hypo))))
return(J)
def gr(theta,X,y):
m=len(y)
hypo=sigmoid(np.matmul(X,theta))
grad=(1/m)*(np.matmul(X.T,(hypo-y)))
return(grad)
X
是 100x3 数组,y
是 100x1,theta
是 3x1 数组。看起来这两个函数都是单独工作的,但是这个优化函数给出了一个错误:
optim = minimize(CF, theta, method='BFGS', jac=gr, args=(X,y))
The error: "ValueError: shapes (3,100) and (3,100) not aligned: 100 (dim 1) != 3 (dim 0)"
最佳答案
I think there is a problem with the (hypo-y) part.
准确!
hypo
的形状为 (100,)
,y
的形状为 (100, 1)
。在逐元素 -
操作中,hypo
根据 numpy 的 broadcasting rules 广播为形状 (1, 100)
。这会产生一个 (100, 100)
数组,进而导致矩阵乘法产生一个 (3, 100)
数组。
通过将 hypo
引入与 y
相同的形状来解决此问题:
hypo = sigmoid(np.matmul(X, theta)).reshape(-1, 1) # -1 means automatic size on first dimension
还有一个问题:scipy.optimize.minimize
(我假设您正在使用)期望渐变是形状为(k,)
的数组,但是函数 gr
返回形状为 (k, 1)
的向量。这很容易修复:
return grad.reshape(-1)
最终函数变为
def gr(theta,X,y):
m=len(y)
hypo=sigmoid(np.matmul(X,theta)).reshape(-1, 1)
grad=(1/m)*(np.matmul(X.T,(hypo-y)))
return grad.reshape(-1)
并使用玩具数据运行它(我没有检查数学或结果的合理性):
theta = np.reshape([1, 2, 3], 3, 1)
X = np.random.randn(100, 3)
y = np.round(np.random.rand(100, 1))
optim = minimize(CF, theta, method='BFGS', jac=gr, args=(X,y))
print(optim)
# fun: 0.6830931976615066
# hess_inv: array([[ 4.51307367, -0.13048255, 0.9400538 ],
# [-0.13048255, 3.53320257, 0.32364498],
# [ 0.9400538 , 0.32364498, 5.08740428]])
# jac: array([ -9.20709950e-07, 3.34459058e-08, 2.21354905e-07])
# message: 'Optimization terminated successfully.'
# nfev: 15
# nit: 13
# njev: 15
# status: 0
# success: True
# x: array([-0.07794477, 0.14840167, 0.24572182])
关于Python Numpy 逻辑回归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46588190/