問題は、MATLABのように行列ではなくnumpy配列で作業していることです。行列は、デフォルトで行列演算を実行します。したがって、X*Y
は、X
とY
の行列乗算を行います。ただし、配列の場合、デフォルトでは要素ごとの操作が使用されます。したがって、X*Y
は、対応する各要素にX
とY
を乗算します。これは、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.ndim
は3
と等しくなければなりません。 y
とX
を2Dとするには、traindata
は3D
である必要があります。
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()
取得したエラーを投稿してください。 –
@DineshPundkarエラーが追加されました – Gary