从Matlab到Python的线性回归转换

2024-06-25 23:46:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一段代码从Matlab翻译成Python,但遇到了一些错误:

Matlab软件:

function [beta] = linear_regression_train(traindata)
y = traindata(:,1); %output
ind2 = find(y == 2);
ind3 = find(y == 3);
y(ind2) = -1;
y(ind3) = 1;
X = traindata(:,2:257); %X matrix,with size of 1389x256
beta = inv(X'*X)*X'*y;

Python:

^{pr2}$

我收到一个错误:操作数无法与计算beta的行上的形状(257,01389)(1389,0257)一起广播。在

感谢任何帮助!在

谢谢!在


Tags: 代码output软件错误functiontrainfindmatrix
1条回答
网友
1楼 · 发布于 2024-06-25 23:46:56

问题是你使用的是numpy数组,而不是MATLAB中的矩阵。默认情况下,矩阵进行矩阵数学运算。所以X*Y做了X和{}的矩阵乘法。但是,对于数组,默认情况下是使用逐元素操作。因此X*YX和{}的每个对应元素相乘。这相当于MATLAB的.*操作。在

但是就像MATLAB的矩阵可以进行逐元素运算一样,Numpy的数组也可以进行矩阵乘法。所以你需要做的是使用numpy的矩阵乘法,而不是它的逐元素乘法。对于python3.5或更高版本(这是您应该用于这类工作的版本),这只是@运算符。所以你的台词是:

beta = inv(X_T @ X) @ X_T @ y

或者,更好的是,您可以使用更简单的.T转置,它与np.transpose相同,但要简洁得多(可以去掉`np.转置全部线路):

^{pr2}$

对于python3.4或更早版本,您将需要使用np.dot,因为这些版本的Python没有@矩阵乘法运算符:

beta = np.dot(np.dot(inv(np.dot(X.T, X)), X.T), y)

Numpy有一个默认情况下使用矩阵运算的matrix对象,就像MATLAB矩阵一样。不要用它!它速度慢,支持不足,而且几乎永远不是您真正想要的。Python社区已经围绕数组进行了标准化,因此请使用这些数组。在

traindata的维数也可能有一些问题。要使其正常工作,traindata.ndim应该等于3。为了使y和{}是2D,traindata应该是{}。在

如果traindata是二维的,而您希望y是MATLAB风格的“向量”(MATLAB所称的“向量”实际上不是向量),那么这可能是一个问题。在numpy中,使用一个像traindata[:, 0]这样的索引可以减少维度的数量,而像traindata[:, :1]这样的切片不会减少维数。因此,要在traindata是2D时保持{}2D,只需做一个长度为1的切片traindata[:, :1]。这是完全相同的值,但它保持与traindata相同的维数。在

注释:使用逻辑索引可以显著简化代码:

def linear_regression_train(traindata):
    y = traindata[:, 0] # This is the output
    y[labels == 2] = -1
    y[labels == 3] = 1
    X = traindata[:, 1:257]
    return inv(X.T @ X) @ X.T @ y
    return beta

另外,您的切片在定义X时是错误的。Python切片排除了最后一个值,因此要获得256个长的切片,您需要执行1:257,正如我上面所做的那样。在

最后,请记住,对函数内部数组的修改会在函数外部进行,而索引不会产生副本。因此,对y的更改(将一些值设置为1,其他值设置为-1),将影响函数之外的traindata。如果要避免这种情况,则需要在进行更改之前制作一个副本:

y = traindata[:, 0].copy()

相关问题 更多 >