Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow. Aurélien Géron
ist der Wert von θ, für den die Kostenfunktion minimal wird.
y ist ein Vektor der Zielwerte von y(1) bis y(m).
Erstellen wir einige annähernd lineare Daten, um diese Gleichung auszuprobieren (Abbildung 4-1):
import numpy as np
X = 2 * np.random.rand(100, 1)
y = 4 + 3* X + np.random.randn(100, 1)
Abbildung 4-1: Zufällig generierter linearer Datensatz
Berechnen wir nun
X_b = np.c_[np.ones((100, 1)), X] # füge x0 = 1 zu jedem Datenpunkt hinzu
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
Die eigentliche Funktion zum Generieren der Daten ist y = 4 + 3x1 + normalverteiltes Rauschen. Sehen wir einmal, was die Gleichung herausgefunden hat:
>>> theta_best
array([[4.21509616],
[2.77011339]])
Wir hatten gehofft, θ0 = 4 und θ1 = 3 anstelle von θ0 = 4,215 und θ1 = 2,770 zu erhalten. Das ist nah dran, aber durch das Rauschen wurde es unmöglich, die Parameter der ursprünglichen Funktion exakt zu reproduzieren.
Nun können Sie mithilfe von
>>> X_new = np.array([[0], [2]])
>>> X_new_b = np.c_[np.ones((2, 1)), X_
new] # füge x0 = 1 zu jedem Datenpunkt hinzu
>>> y_predict = X_new_b.dot(theta_best)
>>> y_predict
array([[4.21509616],
[9.75532293]])
Anschließend plotten wir die Vorhersagen dieses Modells (Abbildung 4-2):
plt.plot(X_new, y_predict, "r-")
plt.plot(X, y, "b.")
plt.axis([0, 2, 0, 15])
plt.show()
Abbildung 4-2: Vorhersagen des linearen Regressionsmodells
Das Durchführen der linearen Regression mit Scikit-Learn ist einfach:2
>>> from sklearn.linear_model import LinearRegression
>>> lin_reg = LinearRegression()
>>> lin_reg.fit(X, y)
>>> lin_reg.intercept_, lin_reg.coef_
(array([4.21509616]), array([[2.77011339]]))
>>> lin_reg.predict(X_new)
array([[4.21509616],
[9.75532293]])
Die Klasse LinearRegression basiert auf der Funktion scipy.linalg.lstsq() (der Name steht für »Least Squares«), die Sie auch direkt aufrufen können:
>>> theta_best_svd, residuals, rank,s = np.linalg.lstsq(X_b, y, rcond=1e-6)
>>> theta_best_svd
array([[4.21509616],
[2.77011339]])
Diese Funktion berechnet
>>> np.linalg.pinv(X_b).dot(y)
array([[4.21509616],
[2.77011339]])
Die Pseudoinverse selbst wird mit einer Standard-Matrixfaktorisierungstechnik namens Singulärwertzerlegung (SWZ; Singular Value Decomposition, SVD) berechnet, die die Matrix X mit dem Trainingsdatensatz in die Matrixmultiplikation der drei Matrizen UΣVT zerlegt (siehe numpy.linalg.svd()). Die Pseudoinverse wird so berechnet: X+ = VΣ+UT. Um die Matrix Σ+ zu berechnen, nimmt der Algorithmus Σ und setzt alle Werte auf null, die kleiner als ein kleiner Schwellenwert sind, dann ersetzt er alle Nicht-null-Werte durch ihr Inverses und transponiert schließlich die so entstandene Matrix. Dieses Vorgehen ist effizienter als das Berechnen der Normalengleichung, zudem kommt sie mit Randfällen besser zurecht: Die Normalengleichung funktioniert eventuell nicht, wenn die Matrix XTX nicht invertierbar (also singulär) ist, wenn beispielsweise m < n oder wenn Features redundant sind. Aber die Pseudoinverse ist immer definiert.
Komplexität der Berechnung
Die Normalengleichung berechnet die Inversion von XT · X, eine (n+1) × (n+1)-Matrix (wobei n die Anzahl Merkmale ist). Die Komplexität der Berechnung dieser Matrizeninversion beträgt typischerweise etwa O(n2,4) bis O(n3) (abhängig von der Implementierung). Anders ausgedrückt, wenn Sie die Anzahl Merkmale verdoppeln, erhöht sich die Rechenzeit etwa um den Faktor 22,4 = 5,3 bis 23 = 8.
Der SVD-Ansatz der Klasse LinearRegression von Scikit-Learn liegt bei O(n2). Verdoppeln Sie die Anzahl an Merkmalen, multiplizieren Sie die Rechenzeit ungefähr mit 4.
|
Sowohl die Normalengleichung wie auch der SVD-Ansatz werden sehr langsam, wenn die Anzahl Merkmale groß wird (z.B. 100. 000). Andererseits sind beide in Bezug auf die Anzahl an Instanzen im Trainingsdatensatz linear (O(m)), sodass sie große Trainingsdatensätze effizient verarbeiten können, sofern diese in den Speicher passen. |
Wenn Sie Ihr lineares Regressionsmodell erst einmal trainiert haben (mithilfe der Normalengleichung oder einem anderen Algorithmus), sind die Vorhersagen sehr schnell: Die Komplexität der Berechnung verhält sich sowohl in Bezug auf die Anzahl vorherzusagender Datenpunkte als auch auf die Anzahl Merkmale linear. Anders ausgedrückt, das Treffen einer Vorhersage dauert für doppelt so viele Datenpunkte (oder doppelt so viele Merkmale) nur etwa doppelt so lange.
Wir werden uns nun völlig andere Verfahren zum Trainieren eines linearen Regressionsmodells ansehen, die sich besser für Fälle eignen, in denen es eine große Anzahl Merkmale oder zu viele Trainingsdaten gibt, als dass sie sich im Speicher unterbringen ließen.