【问题标题】:Translating a Linear Regression from Matlab to Python将线性回归从 Matlab 转换为 Python
【发布时间】:2016-08-29 11:01:00
【问题描述】:

我试图将一段代码从 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:

def linear_regression_train(traindata):
        y = traindata[:,0] # This is the output
        ind2 = (labels==2).nonzero()
        ind3 = (labels==3).nonzero()
        y[ind2] = -1
        y[ind3] = 1
        X = traindata[ : , 1:256]
        X_T = numpy.transpose(X)
        beta = inv(X_T*X)*X_T*y
        return beta

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

感谢任何帮助!

谢谢!

【问题讨论】:

  • 请发布您遇到的错误。
  • @DineshPundkar 添加了错误

标签: python matlab


【解决方案1】:

问题在于您使用的是 numpy 数组,而不是 MATLAB 中的矩阵。默认情况下,矩阵进行矩阵数学运算。所以X*YXY 进行矩阵乘法。然而,对于数组,默认是使用逐个元素的操作。所以X*YXY 的每个对应元素相乘。这相当于 MATLAB 的 .* 操作。

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

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

或者,更好的是,您可以使用更简单的.T 转置,它与np.transpose 相同,但更简洁(您可以完全摆脱`np.transpose 行):

beta = inv(X.T @ X) @ X.T @ y

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

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

Numpy 有一个矩阵对象,它默认使用矩阵运算,如 MATLAB 矩阵。 不要使用它!它很慢,支持很差,而且几乎不是你真正想要的。 Python 社区已经围绕数组进行了标准化,因此请使用它们。

traindata 的尺寸也可能存在一些问题。为了使其正常工作,traindata.ndim 应该等于3。为了使yX 成为2D,traindata 应该是3D

如果 traindata 是 2D 并且您希望 y 是 MATLAB 风格的“向量”(MATLAB 所谓的“向量”并不是真正的向量),这可能是一个问题。在 numpy 中,使用像 traindata[:, 0] 这样的单个索引会减少维数,而像 traindata[:, :1] 这样的切片不会。所以当traindata 是2D 时要保持y 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()

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    相关资源
    最近更新 更多