2016-08-28 9 views
1

に線形回帰を翻訳:私はMATLABからの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:

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 

エラーが発生しました:オペランドをベータ計算された行の図形(257,0,1389)(1389,0,257)とともにブロードキャストできませんでした。

ご協力いただきましてありがとうございます。

ありがとうございます!

+1

取得したエラーを投稿してください。 –

+0

@DineshPundkarエラーが追加されました – Gary

答えて

2

問題は、MATLABのように行列ではなくnumpy配列で作業していることです。行列は、デフォルトで行列演算を実行します。したがって、X*Yは、XYの行列乗算を行います。ただし、配列の場合、デフォルトでは要素ごとの操作が使用されます。したがって、X*Yは、対応する各要素にXYを乗算します。これは、MATLABの.*操作と同じです。

しかし、MATLABの行列が要素ごとの演算を行う方法と同様に、Numpyの配列は行列の乗算を行うことができます。ですから、要素ごとの乗算の代わりにnumpyの行列乗算を使用する必要があります。 Python 3.5以降(この種の作業に使用するバージョン)では、これはちょうど@の演算子です。だからあなたの行は次のようになります。

いっそ
beta = inv(X_T @ X) @ X_T @ y 

または、あなたは(あなたが完全に `np.transposeラインを取り除くことができます)np.transposeと同じですが、はるかに簡潔でシンプルな.T転置を、使用することができます。 Pythonの3.4またはそれ以前のバージョンについては

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

のpythonのこれらのバージョンは@行列乗算演算子がないため、あなたはnp.dotを使用する必要があります:

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

Numpyには、MATLAB行列のように行列操作を使用する行列オブジェクトがあります。 使用しないでください!これは遅く、貧弱にサポートされており、あなたが本当に望むものはほとんどありません。 Pythonコミュニティは配列の周りで標準化しているので、それらを使用してください。

traindataの寸法には問題がある場合もあります。これが正しく機能するためには、traindata.ndim3と等しくなければなりません。 yXを2Dとするには、traindata3Dである必要があります。

traindataが2Dで、yをMATLABスタイルの「ベクトル」(MATLABが「ベクトル」と呼ぶものは実際にベクトルではありません)にしたい場合、この問題が発生する可能性があります。 numpyでは、traindata[:, 0]のような単一のインデックスを使用すると、次元数が少なくなりますが、traindata[:, :1]のようなスライスは使用されません。したがって、traindataが2Dのときにy 2Dを維持するには、長さ1のスライスtraindata[:, :1]を実行します。これはまったく同じ値ですが、これは同じ数のディメンションをtraindataとして保持します。

ノート:あなたのコードはかなり論理インデックスを使用して単純化することができます。Xを定義するとき

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 

はまた、あなたのスライスは間違っています。 Pythonのスライスは最後の値を除外しているので、上記のように、256の長いスライスを得るには1:257を実行する必要があります。

最後に、関数内の配列の変更は関数の外部に持ち越され、インデックスはコピーを作成しないことに注意してください。したがって、y(一部の値を1に設定し、その他の値を-1に設定した場合)は、機能の外部にあるtraindataに影響します。それを避けたい場合は、変更を加える前にコピーを作成する必要があります。

y = traindata[:, 0].copy() 
関連する問題