Python - ValueError: operands could not be broadcast together with shapes (17,90) (17,)
Python - ValueError: operands could not be broadcast together with shapes (17,90) (17,)
我正在尝试使用 SciPy 库中的 optimize.minimize
在 Python 中通过正则化实现逻辑回归。这是我的代码:
import pandas as pd
import numpy as np
from scipy import optimize
l = 0.1 # lambda
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def cost_function_logit(theta, X, y, l):
h = sigmoid(X @ theta)
# cost
J = -1 / m * (y.T @ np.log(h)
+ (1 - y).T @ np.log(1 - h)) \
+ l / (2 * m) * sum(theta[1:] ** 2)
# gradient
a = 1 / m * X.T @ (h - y)
b = l / m * theta
grad = a + b
grad[0] = 1 / m * sum(h - y)
return J, grad
data = pd.read_excel('Data.xlsx')
X = data.drop(columns = ['healthy'])
m, n = X.shape
X = X.to_numpy()
X = np.hstack([np.ones([m, 1]), X])
y = pd.DataFrame(data, columns = ['healthy'])
y = y.to_numpy()
initial_theta = np.zeros([n + 1, 1])
options = {'maxiter': 400}
res = optimize.minimize(cost_function_logit,
initial_theta,
(X, y, l),
jac = True,
method = 'TNC',
options = options)
我使用optimize.minimize
的那一行出现错误。最后两行报错如下:
grad = a + b
ValueError: operands could not be broadcast together with shapes (17,90) (17,)
我检查了 X、y 和 theta 的类型和维度,它们对我来说似乎是正确的。
>>> type(X)
<class 'numpy.ndarray'>
>>> type(y)
<class 'numpy.ndarray'>
>>> type(theta)
<class 'numpy.ndarray'>
>>> X.shape
(90, 17)
>>> y.shape
(90, 1)
>>> theta.shape
(17, 1)
错误说 a 是 (17,90) 矩阵,但根据我的计算,它应该是 (17,1) 向量。有谁知道我错在哪里?
a
的元素是90维向量,而b
的元素是数字。我不完全确定你想做什么,但如果你想添加矢量,它们需要具有相同的形状。如果你想将 b
中的东西添加到 a
row-wise 中的每个元素,你可以做
grad = a + np.stack((b,) * a.shape[1], axis=-1)
但我假设你只是在搞砸构建 a
。
我找到了解决办法。显然,optimize.minimize
不喜欢 y 和 theta 分别具有 (90,1) 和 (17,1) 的形状。我将它们的形状转换为 (90,) 和 (17,),错误消息消失了。
代码方面,我改了
initial_theta = np.zeros([n + 1, 1])
仅此而已:
initial_theta = np.zeros([n + 1])
我添加了以下行:
y = np.reshape(y, [m])
感谢那些试图帮助我的人。
我正在尝试使用 SciPy 库中的 optimize.minimize
在 Python 中通过正则化实现逻辑回归。这是我的代码:
import pandas as pd
import numpy as np
from scipy import optimize
l = 0.1 # lambda
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def cost_function_logit(theta, X, y, l):
h = sigmoid(X @ theta)
# cost
J = -1 / m * (y.T @ np.log(h)
+ (1 - y).T @ np.log(1 - h)) \
+ l / (2 * m) * sum(theta[1:] ** 2)
# gradient
a = 1 / m * X.T @ (h - y)
b = l / m * theta
grad = a + b
grad[0] = 1 / m * sum(h - y)
return J, grad
data = pd.read_excel('Data.xlsx')
X = data.drop(columns = ['healthy'])
m, n = X.shape
X = X.to_numpy()
X = np.hstack([np.ones([m, 1]), X])
y = pd.DataFrame(data, columns = ['healthy'])
y = y.to_numpy()
initial_theta = np.zeros([n + 1, 1])
options = {'maxiter': 400}
res = optimize.minimize(cost_function_logit,
initial_theta,
(X, y, l),
jac = True,
method = 'TNC',
options = options)
我使用optimize.minimize
的那一行出现错误。最后两行报错如下:
grad = a + b
ValueError: operands could not be broadcast together with shapes (17,90) (17,)
我检查了 X、y 和 theta 的类型和维度,它们对我来说似乎是正确的。
>>> type(X)
<class 'numpy.ndarray'>
>>> type(y)
<class 'numpy.ndarray'>
>>> type(theta)
<class 'numpy.ndarray'>
>>> X.shape
(90, 17)
>>> y.shape
(90, 1)
>>> theta.shape
(17, 1)
错误说 a 是 (17,90) 矩阵,但根据我的计算,它应该是 (17,1) 向量。有谁知道我错在哪里?
a
的元素是90维向量,而b
的元素是数字。我不完全确定你想做什么,但如果你想添加矢量,它们需要具有相同的形状。如果你想将 b
中的东西添加到 a
row-wise 中的每个元素,你可以做
grad = a + np.stack((b,) * a.shape[1], axis=-1)
但我假设你只是在搞砸构建 a
。
我找到了解决办法。显然,optimize.minimize
不喜欢 y 和 theta 分别具有 (90,1) 和 (17,1) 的形状。我将它们的形状转换为 (90,) 和 (17,),错误消息消失了。
代码方面,我改了
initial_theta = np.zeros([n + 1, 1])
仅此而已:
initial_theta = np.zeros([n + 1])
我添加了以下行:
y = np.reshape(y, [m])
感谢那些试图帮助我的人。