Das Problem ist, dass Sie mit numpy Arrays, nicht Matrizen wie in MATLAB arbeiten. Matrizen führen standardmäßig mathematische Matrixoperationen durch. Also X*Y
tut eine Matrix-Multiplikation von X
und Y
. Bei Arrays werden jedoch standardmäßig Element-für-Element-Operationen verwendet. So multipliziert X*Y
jedes entsprechende Element von X
und Y
. Dies entspricht dem .*
von MATLAB.
Aber genauso wie die MATLAB-Matrizen Element-für-Element-Operationen ausführen können, können Numpys Matrizen eine Matrixmultiplikation durchführen. Was Sie also tun müssen, ist die Matrixmultiplikation von numpy anstelle der elementweisen Multiplikation. Für Python 3.5 oder höher (das ist die Version, die Sie für diese Art von Arbeit verwenden sollten), das ist nur der Operator @
. So Ihre Linie wird:
beta = inv(X_T @ X) @ X_T @ y
Oder, noch besser, können Sie die einfachere .T
transponieren verwenden, die die gleiche wie np.transpose
ist aber viel prägnanter (Sie der `np.transpose Linie befreien vollständig erhalten kann):
beta = inv(X.T @ X) @ X.T @ y
für Python 3.4 oder früher, müssen Sie np.dot
da diese Versionen von Python haben nicht den Operator @
Matrixmultiplikation verwenden:
beta = np.dot(np.dot(inv(np.dot(X.T, X)), X.T), y)
Numpy hat ein Matrixobjekt, das standardmäßig Matrixoperationen wie die MATLAB-Matrix verwendet. Nicht benutzen! Es ist langsam, schlecht unterstützt und fast nie, was Sie wirklich wollen. Die Python-Community hat sich um Arrays herum standardisiert, also benutze diese.
Es kann auch einige Probleme mit den Abmessungen von traindata
geben. Damit dies ordnungsgemäß funktioniert, sollte gleich 3
sein. Damit y
und X
2D sind, sollte traindata
3D
sein.
Dies könnte ein Problem sein, wenn traindata
2D ist und Sie möchten, dass y
MATLAB-Stil "Vektor" (was MATLAB nennt "Vektoren" sind nicht wirklich Vektoren). In Numpy reduziert die Verwendung eines einzelnen Index wie traindata[:, 0]
die Anzahl der Dimensionen, während ein Slice wie traindata[:, :1]
dies nicht tut. Um also y
2D zu behalten, wenn traindata
2D ist, mach einfach einen length-1 slice, traindata[:, :1]
. Dies sind genau die gleichen Werte, aber dies hält die gleiche Anzahl von Dimensionen wie traindata
.
Hinweise: Ihr Code wesentlich vereinfacht logische Indizierung werden können:
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
Auch Ihre Scheibe falsch ist, wenn X
definieren. Python-Slicing schließt den letzten Wert aus. Um also eine 256 lange Slice zu erhalten, müssen Sie 1:257
ausführen, wie ich oben getan habe.
Schließlich, bitte beachten Sie, dass Änderungen an Arrays in Funktionen außerhalb der Funktionen übertragen, und Indexierung keine Kopie macht. Ihre Änderungen an y
(setzen Sie einige Werte auf 1
und andere auf -1
), beeinflussen traindata
außerhalb Ihrer Funktion. Wenn Sie dies vermeiden möchten, müssen Sie eine Kopie erstellen, bevor Sie Ihre Änderungen vornehmen:
y = traindata[:, 0].copy()
Bitte senden Sie den Fehler, den Sie erhalten. –
@DineshPundkar Fehler hinzugefügt – Gary