La dernière fois, je me suis concentré sur des discussions mathématiques et j'ai perdu la trace de ce pour quoi j'écrivais. Cette fois, nous allons implémenter la régression multiple en Python.
Créer le vôtre est essentiel pour vous familiariser avec la grammaire Python et Numpy. Je pense que vous pouvez approfondir votre compréhension en vous référant à la mise en œuvre de la partie 1.
Les poids sont donnés comme $ \ beta = (X ^ TX) ^ {-1} X ^ Ty $, qui est la solution de l'équation normale $ X ^ Ty = X ^ TX \ beta $. Nous ne résolvons pas $ y = X \ beta $ car $ X $ n'est pas une matrice carrée en général, donc $ X $ peut ne pas avoir de matrice inverse. Si $ X ^ TX $ n'est pas régulier, une erreur se produira, mais calculons simplement avec $ \ beta = (X ^ TX) ^ {-1} X ^ Ty $.
model = LinearRegression()
model.fit(X_train, y)
model.predict(X_test)
Faisons le squelette. Numpy.dot (A, B) de Numpy est très facile à calculer le produit matrice à matrice ou matrice à vecteur.
import numpy as np
import matplotlib.pyplot as plt
Créons une classe de modèles de régression que vous connaissez bien. J'ai eu du mal car je n'étais pas habitué à la grammaire Python. Par souci de simplicité, le biais est ajouté à la colonne de gauche de la matrice de pondération. Parallèlement à cela, un nouvel élément 1 est ajouté à gauche de la variable explicative.
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]Peut aussi être écrit
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]Peut aussi être écrit
return np.dot(X_, self.beta)
A titre d'exemple, nous utilisons un échantillon avec une distribution proche de $ y = 2x_1 + 3x_2 + 4 $.
n = 100 #Préparez 100 échantillons
np.random.seed(0)
X_train = (np.random.random((n, 2)) - 0.5) * 20 #Générer une matrice n * 2 pour que les éléments soient aléatoires (intervalle)-De 10 à 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))
Quand tu fais ça
beta=[3.9916141 1.9978685 3.00014788]
Est sortie. beta [0] est le biais. Vous pouvez voir que c'est une bonne approximation.
Visualisons-le. Commençons par un diagramme de dispersion de 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")
Dans cet esprit, illustrons le plan prédit.
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")
Ceci est à usage professionnel. Je vais l'implémenter tout de suite!
from sklearn.linear_model import LinearRegression
n = 100 #Préparez 100 échantillons
np.random.seed(0)
X_train = (np.random.random((n, 2)) - 0.5) * 20 #Générer une matrice n * 2 pour que les éléments soient aléatoires (intervalle)-De 10 à 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")
Avez-vous obtenu le même chiffre?
Tracons les résidus.
#Graphique résiduel
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])
Il y a beaucoup plus à apprendre sur la régression multiple, mais cela devrait suffire pour des travaux pratiques. La prochaine fois, nous prévoyons de retourner à Ridge et Lasso.
--Koichi Kato "Essence of Machine Learning" SB Creative, 2019 --S. Raschka, V. Mirjalili «Programmation d'apprentissage automatique Python [2e édition]» Impress, 2020