Beim letzten Mal habe ich mich auf mathematische Diskussionen konzentriert und den Überblick verloren, wofür ich geschrieben habe. Dieses Mal werden wir mehrere Regressionen in Python implementieren.
Das Erstellen eigener Dateien ist wichtig, um sich mit Python-Grammatik und Numpy vertraut zu machen. Ich denke, dass Sie Ihr Verständnis vertiefen können, indem Sie sich auf die Implementierung von Teil 1 beziehen.
Die Gewichte werden als $ \ beta = (X ^ TX) ^ {-1} X ^ Ty $ angegeben, was die Lösung der normalen Gleichung $ X ^ Ty = X ^ TX \ beta $ ist. Wir lösen $ y = X \ beta $ nicht, weil $ X $ im Allgemeinen keine quadratische Matrix ist, sodass $ X $ möglicherweise keine inverse Matrix hat. Wenn $ X ^ TX $ nicht regulär ist, tritt ein Fehler auf, aber berechnen wir einfach mit $ \ beta = (X ^ TX) ^ {-1} X ^ Ty $.
model = LinearRegression()
model.fit(X_train, y)
model.predict(X_test)
Machen wir das Skelett. Numpys numpy.dot (A, B) ist sehr einfach, das Matrix-zu-Matrix- oder Matrix-zu-Vektor-Produkt zu berechnen.
import numpy as np
import matplotlib.pyplot as plt
Lassen Sie uns eine Klasse von Regressionsmodellen erstellen, mit denen Sie vertraut sind. Es fiel mir schwer, weil ich nicht an Python-Grammatik gewöhnt war. Der Einfachheit halber wird die Vorspannung zur linken Spalte der Gewichtsmatrix hinzugefügt. Gleichzeitig wird links von der erklärenden Variablen ein neues Element 1 hinzugefügt.
class LinearRegression():
def fit(self, X, y):
X_ = np.concatenate([np.ones(X.shape[0]).reshape(-1, 1), X], axis=1)
# X_ = np.c_[np.ones(X.shape[0]), X]Kann auch geschrieben werden
self.beta = np.linalg.inv(np.dot(X_.T, X_)).dot(X_.T).dot(y)
def predict(self, X):
X_ = np.concatenate([np.ones(X.shape[0]).reshape(-1, 1), X], axis=1)
# X_ = np.c_[np.ones(X.shape[0]), X]Kann auch geschrieben werden
return np.dot(X_, self.beta)
Als Beispiel verwenden wir eine Stichprobe mit einer Verteilung nahe $ y = 2x_1 + 3x_2 + 4 $.
n = 100 #Bereiten Sie 100 Proben vor
np.random.seed(0)
X_train = (np.random.random((n, 2)) - 0.5) * 20 #Generieren Sie eine n * 2-Matrix, sodass die Elemente zufällig sind (Bereich)-Von 10 bis 10)
y = 2*X_train[:, 0] + 3*X_train[:, 1] + 4 + np.random.randn(n) * 0.1
model = LinearRegression()
model.fit(X_train, y)
print("beta={}".format(model.beta))
Wenn du das machst
beta=[3.9916141 1.9978685 3.00014788]
Wird ausgegeben. Beta [0] ist die Verzerrung. Sie können sehen, dass es eine gute Annäherung ist.
Lassen Sie es uns visualisieren. Beginnen wir mit einem Streudiagramm von X_train.
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(X_train[:, 0], X_train[:, 1], y, marker="o", linestyle="None")
Lassen Sie uns vor diesem Hintergrund die vorhergesagte Ebene veranschaulichen.
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(X_train[:, 0], X_train[:, 1], y, marker="o", linestyle="None")
xmesh, ymesh = np.meshgrid(np.linspace(-10, 10, 20), np.linspace(-10, 10, 20))
zmesh = (model.beta[1] * xmesh.ravel() + model.beta[2] * ymesh.ravel() + model.beta[0]).reshape(xmesh.shape)
ax.plot_wireframe(xmesh, ymesh, zmesh, color="r")
Dies ist für den geschäftlichen Gebrauch. Ich werde es sofort umsetzen!
from sklearn.linear_model import LinearRegression
n = 100 #Bereiten Sie 100 Proben vor
np.random.seed(0)
X_train = (np.random.random((n, 2)) - 0.5) * 20 #Generieren Sie eine n * 2-Matrix, sodass die Elemente zufällig sind (Bereich)-Von 10 bis 10)
y = 2*X_train[:, 0] + 3*X_train[:, 1] + 4 + np.random.randn(n) * 0.1
model = LinearRegression()
model.fit(X_train, y)
print("coef_, intercept_ = {}, {}".format(model.coef_, model.intercept_))
X_test = np.c_[np.linspace(-10, 10, 20), np.linspace(-10, 10, 20)]
model.predict(X_test)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(X_train[:, 0], X_train[:, 1], y, marker="o", linestyle="None")
xmesh, ymesh = np.meshgrid(X_test[:, 0], X_test[:, 1])
zmesh = (model.coef_[0] * xmesh.ravel() + model.coef_[1] * ymesh.ravel() + model.intercept_).reshape(xmesh.shape)
ax.plot_wireframe(xmesh, ymesh, zmesh, color="r")
Hast du die gleiche Zahl bekommen?
Zeichnen wir die Residuen.
#Restgrundstück
y_train_pred = model.predict(X_train)
plt.scatter(y_train_pred, y_train_pred - y, marker="o", label="training data")
plt.scatter(y_test_pred, y_test_pred - (2*X_test[:, 0]+3*X_test[:, 1]+4), marker="^", label="test data")
plt.xlabel("predicted values")
plt.ylabel("residuals")
plt.hlines(y=0, xmin=-40, xmax=55, color="k")
plt.xlim([-40, 55])
Es gibt noch viel mehr über multiple Regression zu lernen, aber dies sollte für die praktische Arbeit ausreichen. Nächstes Mal planen wir, nach Ridge und Lasso zurückzukehren.
Recommended Posts