Le guide ultime de la régression linéaire
Dans cet article, nous allons discuter du modèle de régression linéaire utilisé dans l’apprentissage automatique. Modéliser pour ce poste signifie utiliser une technique d’apprentissage automatique pour apprendre – à partir des données – la relation entre un ensemble de fonctionnalités et ce que nous espérons prédire. Apportons quelques données pour concrétiser cette idée.
from sklearn.datasets import load_boston
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np from sklearn.model_selection
import learning_curve from sklearn.metrics
import make_scorer
%matplotlib inlinenp.random.seed(42)boston_data = load_boston() boston_df = pd.DataFrame(boston_data.data, columns=boston_data.feature_names)
target = boston_data.target
Voici une description de nos données:
- CRIM – taux de criminalité par habitant par ville
- ZN – proportion de terrains résidentiels zonés pour des lots de plus de 25 000 pi.ca.
- INDUS – proportion d’acres commerciales non commerciales par ville.
- CHAS – Variable fictive Charles River (1 si le tronçon délimite la rivière; 0 sinon)
- NOX – concentration en oxydes nitriques (parties pour 10 millions)
- RM – nombre moyen de pièces par logement
- AGE – proportion de logements occupés par le propriétaire construits avant 1940
- DIS – distances pondérées vers cinq centres d’emploi de Boston
- RAD – indice d’accessibilité aux autoroutes radiales
- TAXE – taux d’imposition foncière de pleine valeur pour 10 000 dollars
- PTRATIO – ratio élèves / enseignant par ville
- B – 1000 (Bk – 0,63) ² où Bk est la proportion de noirs par ville
- LSTAT – pourcentage de statut inférieur de la population
- CIBLE – Valeur médiane des logements occupés par le propriétaire en milliers de dollars
L’objectif de cet ensemble de données est d’utiliser les entités (tout sauf la cible) pour prédire la cible (valeur médiane d’origine).
Comment pourrions-nous faire cela?
Pour notre premier passage, simplifions le problème. Supposons que nous voulions simplement utiliser LSAT pour prédire TARGET.
plt.scatter(boston_df['LSTAT'], target)
Sur l’axe x, nous avons LSTAT et l’axe Y TARGET. À y regarder, il semble y avoir une relation négative: lorsque LSTAT monte, TARGET baisse.
Comment pouvons-nous résoudre le problème de la prévision de TARGET à partir de LSTAT? Un bon endroit pour commencer à réfléchir est: disons que nous développons de nombreux modèles pour prédire notre cible, comment choisirions-nous le meilleur? Une fois que nous avons déterminé cela, notre objectif est alors de minimiser / maximiser cette valeur.
Il est extrêmement utile de réduire votre problème à un métrique d’évaluation unique car alors il est très facile de répéter le développement du modèle. Dans l’industrie, cependant, cela peut être délicat. Parfois, il n’est pas très clair ce que vous voulez que votre modèle maximise / minimise. Mais c’est un défi pour un autre poste.
Donc, pour ce problème, je proposerais la mesure d’évaluation suivante: erreur quadratique moyenne (MSE). Pour comprendre MSE, définissons une terminologie:
- Ceci est notre valeur prédite pour le ième point de données
- Il s’agit de la valeur réelle du ième point de données
- n – le nombre de points de données
Ainsi, MSE est:
En anglais, pour chaque point, nous soustrayons notre valeur prédite de la valeur réelle. Puis, comme nous ne nous soucions pas de la direction de l’erreur, nous ajustons la différence. Enfin, nous prenons la moyenne de toutes ces valeurs. Fondamentalement, nous disons que nous voulons que la distance moyenne entre nos prévisions et nos chiffres réels soit petite.
Vous vous demandez peut-être pourquoi nous avons quadrillé la valeur au lieu de prendre la valeur absolue. Il s’avère que pour certains des calculs suivants, la mise au carré de la valeur fonctionne bien. C’est aussi l’estimation du maximum de vraisemblance. Cela a cependant pour effet de pondérer davantage les erreurs importantes dans notre moyenne, car nous mettons toutes les différences au carré.
Maintenant que nous avons notre fonction de coût, comment trouver un moyen de la minimiser? Dans cet article, nous passerons en revue le modèle de régression linéaire. Le modèle est le suivant:
Où j est le nombre de prédicteurs que nous avons et la bêta les valeurs sont nos coefficients avec beta 0 étant l’interception. Fondamentalement, notre modèle est une combinaison linéaire de nos prédicteurs avec une interception.
Maintenant que nous avons un modèle et une fonction de coût, notre défi consiste à trouver le bêta valeurs de notre modèle qui minimisent le MSE pour nos données. Pour la régression linéaire, il existe en fait une solution de forme fermée appelée équation normale. Dans ce post, cependant, nous allons utiliser une technique différente qui est plus courante dans l’apprentissage automatique – la descente de gradient.
La descente en gradient est une technique que nous empruntons à l’optimisation. Il s’agit d’un algorithme très simple mais puissant qui peut être utilisé pour trouver le minimum d’une fonction.
- Choisissez une valeur de départ aléatoire
- Faites des pas proportionnels au négatif du gradient au point courant
- Répétez jusqu’à ce que vous convergiez
Cette technique trouvera le minimum global si une fonction est convexe, sinon, nous ne pouvons que prouver qu’elle trouvera un minimum local.
La première question à laquelle nous devons répondre est: notre fonction de coût est-elle convexe? Nous allons jeter un coup d’oeil:
Ce que nous avons fait ci-dessus est pris une gamme de valeurs de coefficient pour LSTAT et pour chacun calculé le MSE sur nos données. Si nous traçons ensuite ceux-ci, nous obtenons la courbe ci-dessus – semble assez convexe! Et en fait, il s’avère que notre fonction MSE avec notre modèle de régression linéaire sera toujours convexe! Cela signifie que nous pouvons utiliser la descente de gradient pour trouver les coefficients optimaux pour notre modèle!
L’une des raisons pour lesquelles la descente de gradient est plus courante que l’équation normale pour l’apprentissage automatique est qu’elle évolue beaucoup mieux lorsque nous augmentons le nombre de fonctionnalités. Il s’agit également d’une technique d’optimisation générale qui apparaît tout au long de l’apprentissage automatique, il est donc extrêmement utile de comprendre comment cela fonctionne.
Si vous regardez à nouveau notre pseudocode pour la descente de gradient, vous verrez que tout ce que nous devons faire est de calculer les gradients. Alors – quels sont les gradients? Ce ne sont que des dérivées partielles par rapport aux coefficients. Pour chaque coefficient que nous avons, nous devrons calculer la dérivée de notre MSE par rapport à ce coefficient. Commençons!
Développons nos coûts pour notre exemple simple avec une interception et une seule variable, LSTAT:
Maintenant, pour la dérivée de cela par rapport à beta 0, on obtient (multiplié par -1):
Et pour bêta 1:
Maintenant, exécutons notre algorithme de descente de gradient et confirmons que le MSE est en train de diminuer:
beta_0: 34.553840879456807beta_1: -0.95004935376241229
Le premier graphique imprimé ci-dessus montre la valeur de MSE lors de la descente en gradient. Comme nous nous y attendons, le MSE diminue avec le temps au fur et à mesure que l’algorithme s’exécute, ce qui signifie que nous nous rapprochons continuellement de la solution optimale.
Vous pouvez également voir sur le graphique que nous aurions pu arrêter plus tôt parce que le MSE se stabilise essentiellement à environ 4 000 itérations.
La descente en gradient en cours a trouvé l’interception optimale à 34,55 et la pente optimale à -0,95.
Le graphique ci-dessus montre cette ligne au-dessus de nos données et elle semble en fait être la ligne la mieux adaptée.
Un paramètre dont nous n’avons pas encore discuté est le taux d’apprentissage. Ce taux est un hyper-paramètre utilisé pour déterminer à quelle distance nous nous éloignons de la direction du gradient. Comment savez-vous quelle valeur choisir? En règle générale, de nombreuses valeurs peuvent être essayées et voici quelques-unes qui, selon moi, sont suggérées par Andrew Ng: .001, .003, .01, .03, .1, .3, 1, 3
Le choix d’une valeur trop petite entraîne un ralentissement de la convergence. Choisir une valeur trop grande peut entraîner un dépassement du minimum et une divergence.
Il existe également d’autres optimiseurs de descente de gradient qui sont plus sophistiqués et adaptent le taux d’apprentissage des heures supplémentaires pour vous. C’est aussi quelque chose que vous pouvez faire par vous-même où vous diminuez lentement le taux d’apprentissage au fil du temps.
Dans mon code, je choisis simplement d’exécuter notre boucle 10 000 fois. Pourquoi 10 000? Il n’y avait pas de vraie raison autre que j’étais à peu près sûr que c’était assez long pour converger. Ce n’est généralement pas la meilleure pratique. Quelques meilleures idées sont:
- Surveillez votre coût après chaque boucle et quand il diminue de moins d’une certaine tolérance – disons 0,001 – arrêtez.
- Utilisez un ensemble de validation et suivez la perte – par exemple, MSE – à ce sujet. Quand il cesse de diminuer, arrêtez.
Lorsque vous travaillez avec une descente de gradient, vous voulez que toutes vos données soient normalisées. Soustrayez la moyenne et divisez par l’écart-type pour toutes vos fonctions d’entraînement. Cela rend généralement la formation plus rapide et réduit les chances de rester coincé dans l’optimum local si votre fonction de coût n’est pas convexe.
La descente de gradient que nous avons montrée ici est une forme vanille, ce qui signifie que chaque mise à jour de coefficient utilise toutes les données pour calculer les gradients. Il y a aussi descente de gradient stochastique qui utilise seulement 1 ligne de données pour mettre à jour les coefficients dans chaque boucle. Ceci est beaucoup plus évolutif car vous n’avez qu’à regarder une ligne de données à la fois avant la mise à jour, mais est également beaucoup plus aléatoire car vous essayez de naviguer en utilisant un gradient calculé sur un seul point de données.
Un autre type de descente en pente est descente en gradient mini-batch. Ce formulaire est un compromis entre les deux où vous choisissez une taille de lot de disons 32 (ou mieux encore un calendrier de lots qui commence par de petits lots et augmente au fil des époques) et chaque itération de votre descente de gradient utilise 32 lignes aléatoires de données avec lesquelles calculer le gradient (il utilise toutes les lignes avant de rééchantillonner à nouveau les mêmes lignes). Cela offre une certaine évolutivité et un certain caractère aléatoire. Ce caractère aléatoire s’avère en fait utile pour les fonctions de coût qui ne sont pas convexes (apprentissage profond) car il peut aider le modèle à échapper au minimum local. Il s’agit de la méthode la plus courante pour les fonctions de coût non convexes.
Chaque fois que vous traitez avec un modèle, il est bon d’être conscient des hypothèses qu’il fait. J’allais écrire une section à ce sujet ici, mais Duke a déjà fait un excellent travail: http://people.duke.edu/~rnau/testing.htm.
Maintenant que nous comprenons un peu la théorie et l’implémentation, tournons-nous vers une bibliothèque de logiciels pour exécuter une régression linéaire sur nos données. Il est très utile pour apprendre à écrire des modèles à partir de zéro, mais dans la pratique, il est généralement préférable d’utiliser une bibliothèque testée et largement utilisée.
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
N’oubliez pas de faire évoluer vos données – très important!
scaler = StandardScaler()
scaler.fit(boston_df)
scaled_df = scaler.transform(boston_df)
Scikit-learn a une très belle API. Il fournit de nombreux modèles et tous ont une fonction d’ajustement et de prévision. Tu appelles en forme sur les données X et y pour former le modèle, puis prédire sur de nouvelles fonctionnalités pour obtenir une valeur prédite. Scikit-learn fournit également de nombreuses mesures que vous pouvez utiliser pour l’évaluation, telles que MSE. Ici, je produis MSE racine (RMSE) parce que cela nous ramène à l’échelle d’origine de notre cible, que je trouve plus facile à comprendre.
Avec notre SGDRegressor (qui exécute une régression linéaire en utilisant la descente de gradient), tol indique au modèle quand arrêter l’itération et eta0 est notre taux d’apprentissage initial.
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01) linear_regression_model.fit(scaled_df, target)
predictions = linear_regression_model.predict(scaled_df)
mse = mean_squared_error(target, predictions)
print("RMSE: {}".format(np.sqrt(mse)))RMSE: 4.721352143256387
Notre RMSE s’est retrouvé à 4,72 pour notre ensemble de formation utilisant scikit-learn.
Si vous vous souvenez de notre complot de LSTAT contre notre cible, il semblait y avoir une relation polynomiale. La régression linéaire s’adapte aux relations linéaires, mais si vous ajoutez des entités polynomiales, telles que LSTAT², vous pouvez ajuster des relations plus complexes. SKLearn vous facilite la tâche:
from sklearn.preprocessing import PolynomialFeaturespoly = PolynomialFeatures(2, include_bias=False)
poly_df = poly.fit_transform(boston_df)
scaled_poly_df = scaler.fit_transform(poly_df) print(scaled_poly_df.shape)(506, 104)linear_regression_model.fit(scaled_poly_df, target)
predictions = linear_regression_model.predict(scaled_poly_df)
mse = mean_squared_error(target, predictions)
print("RMSE: {}".format(np.sqrt(mse)))RMSE: 3.77419484950651
La commande d’entités polynomiales a généré une nouvelle matrice d’entités composée de toutes les combinaisons polynomiales des entités d’un degré inférieur ou égal au degré spécifié (dans notre exemple 2). Nous avons ensuite mis à l’échelle ces données et les avons introduites dans notre modèle. Et nous avons obtenu une meilleure formation RMSE – 3,77. Notez cependant que ces résultats ne figurent à nouveau que dans nos données d’entraînement à des fins d’illustration.
La régression linéaire est l’un des modèles avec lesquels vous devez faire attention lorsque vous disposez de données catégoriques. Si vous avez une fonctionnalité avec les valeurs 1, 2 et 3 qui signifie en fait Homme, Femme, Aucune réponse, vous ne voulez pas la donner au modèle de cette façon, même si ce sont des nombres. Si vous le faisiez, le modèle attribuerait à cette caractéristique un coefficient – peut-être 0,1. Cela signifierait qu’être une femme augmente la prédiction de 0,1 et aucune réponse de 0,2. Mais peut-être que les femmes devraient augmenter le score de 1,2 et Aucune réponse de seulement 0,001. Pour tenir compte de cela, vous devez convertir ces valeurs en variables factices afin que chaque valeur puisse avoir son propre poids. Vous pouvez voir comment procéder avec scikit-learn ici.
La régression linéaire est un excellent modèle statistique qui existe depuis longtemps. Il existe de nombreuses techniques statistiques que l’on peut utiliser pour l’évaluer et l’interpréter. Nous ne les couvrirons pas tous et, en fait, nous nous concentrerons principalement sur des méthodes très simples qui sont peut-être plus courantes dans l’apprentissage automatique que les statistiques. Pour mieux comprendre les techniques statistiques, veuillez lire le chapitre 3 de Introduction à l’apprentissage statistique et jetez un oeil à la modèles de statistiques paquet.
Voyons d’abord les coefficients que notre modèle a appris (à partir de toutes les fonctionnalités):
linear_regression_model.fit(scaled_df, target) sorted(list(zip(boston_df.columns, linear_regression_model.coef_)), key=lambda x: abs(x[1]))[('AGE', -0.15579031087838216), ('INDUS', -0.36890070005440012), ('ZN', 0.61249837977769284), ('TAX', -0.6639660631363058), ('CRIM', -0.7135059713991182), ('CHAS', 0.73578321065548924), ('B', 0.87494012630072004), ('RAD', 1.1142142863056546), ('NOX', -1.2452942744431366), ('PTRATIO', -1.9425283730193659), ('DIS', -2.2549312823672696), ('RM', 3.0623224309690911), ('LSTAT', -3.4699728921831285)]
Quels sont ces coefficients? Ils représentent la variation moyenne du prix du logement pour une unité de variation de l’élément tout en maintenant les autres éléments du modèle constants. Par exemple, tout en maintenant le reste, une augmentation unitaire de LSTAT diminue notre objectif (prix du logement) de 3,469 et une augmentation unitaire de RM augmente notre objectif de 3,062.
C’est vraiment sympa! Nous pouvons peut-être dire que si vous voulez augmenter la valeur des maisons, l’augmentation du RM et la diminution du LSTAT pourraient être un point de départ. Je dis peut-être parce que la régression linéaire examine les corrélations. Dans nos données, cela semble certainement être le cas, mais cela ne signifie pas en soi que ces caractéristiques ont une relation causale. Cela pourrait être un bon endroit pour rechercher une relation causale, cependant, et représente des relations qui ont été vues dans les données.
Souvent en apprentissage automatique, il est très utile d’avoir un intervalle de confiance autour de vos estimations. Il existe différentes façons de le faire, mais une méthode assez générale utilise amorcer.
Un bootstrap est un échantillon aléatoire avec remplacement de nos données et cet échantillon est de la même taille que les données d’origine. Il s’agit d’un moyen de générer plusieurs vues des mêmes données. Créons 1 000 bootstrap de nos données.
from sklearn.utils import resample
n_bootstraps = 1000
bootstrap_X = []
bootstrap_y = []
for _ in range(n_bootstraps):
sample_X, sample_y = resample(scaled_df, target)
bootstrap_X.append(sample_X) bootstrap_y.append(sample_y)
Ensuite, sur chacun de ces ensembles de données, nous pouvons adapter notre modèle et obtenir nos coefficients:
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01)
coeffs = []
for i, data in enumerate(bootstrap_X):
linear_regression_model.fit(data, bootstrap_y[i])
coeffs.append(linear_regression_model.coef_)coef_df = pd.DataFrame(coeffs, columns=boston_df.columns) coef_df.plot(kind='box') plt.xticks(rotation=90)
Ce graphique montre la plage de valeurs de coefficient que nous avons obtenues pour chaque entité pour tous les modèles que nous avons formés. L’ÂGE est une caractéristique particulièrement intéressante, car les valeurs des coefficients étaient à la fois positives et négatives, ce qui est un bon signe qu’il n’y a probablement pas de relation entre l’AGE et notre cible.
De plus, nous pouvons voir que LSTAT a une grande variance dans les valeurs des coefficients tandis que PTRATIO a une variance relativement petite, ce qui augmente notre confiance dans notre estimation du coefficient.
Nous pouvons même approfondir un peu plus nos coefficients LSTAT:
coef_df['LSTAT'].plot(kind='hist')
coef_df['LSTAT'].describe()count 1000.000000 mean -3.599465 std 0.687444 min -5.825069 25% -4.058086 50% -3.592409 75% -3.120958 max -1.575822 Name: LSTAT, dtype: float64
C’est plutôt sympa! Maintenant, nous pouvons dire avec une forte confiance que le coefficient réel sur LSTAT est négatif et presque certainement entre -1,2 et -5,5.
Jusqu’à présent, nous nous sommes entraînés sur toutes les données dont nous disposons. Cela pourrait avoir un sens car nous voulons maximiser l’utilité de nos données en utilisant autant que possible pour la formation. D’un autre côté, cependant, il est difficile d’évaluer la performance de notre modèle. La raison en est que si nous calculons simplement notre score MSE en utilisant des données sur lesquelles le modèle a été formé, nous pourrions constater que lorsque nous introduisons des données sur lesquelles il n’a pas été formé, il fonctionne assez mal.
Cette idée s’appelle surajustement. Fondamentalement, lorsqu’un modèle fonctionne beaucoup mieux sur les données sur lesquelles il a été formé que sur de nouvelles données, il a un caractère unique pour les données de formation qui ne se généralise pas.
L’autre côté de cela s’appelle biais. Un modèle présente un biais élevé alors qu’il ne fait vraiment pas un bon travail d’adaptation aux données. Dans ce cas, le MSE sera élevé pour les données d’entraînement et les données non vues pendant l’entraînement.
Dans l’apprentissage automatique, il y a toujours un compromis entre le biais et la variance. Au fur et à mesure que vos modèles deviennent plus complexes, le risque de surajustement de vos données d’entraînement augmente.
Maintenant que nous savons qu’il est difficile de ne regarder que le MSE dans nos données de formation, que pouvons-nous faire pour mieux juger de la généralisation? En plus de diagnostiquer le sur-ajustement et les biais? En règle générale, nous divisons nos données en deux ensembles: un ensemble de formation et un ensemble de tests.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(scaled_df, target, test_size=0.33, random_state=42)
Maintenant que nous avons deux ensembles de données distincts, nous pouvons nous entraîner sur nos données de formation et calculer des mesures pour nos données de formation et de test (il est préférable de n’utiliser vos données de test qu’après avoir réglé votre modèle):
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01) linear_regression_model.fit(X_train, y_train)
train_predictions = linear_regression_model.predict(X_train) test_predictions = linear_regression_model.predict(X_test)
train_mse = mean_squared_error(y_train, train_predictions)
test_mse = mean_squared_error(y_test, test_predictions)
print("Train MSE: {}".format(train_mse))
print("Test MSE: {}".format(test_mse))Train MSE: 23.33856804462054 Test MSE: 21.820947809040835
Excellent! Maintenant, nous avons RMSE sur nos données de formation et de test. Et les deux sont assez proches, ce qui suggère que nous n’avons pas de problème de sur-ajustement. Sont-ils tous les deux faibles? Ce qui suggère un biais élevé.
Une façon d’examiner cela est de tracer la courbe d’apprentissage. Une courbe d’apprentissage trace notre fonction d’erreur (MSE) avec différentes quantités de données utilisées pour la formation. Voici notre intrigue:
Vous pouvez voir qu’avec moins de 50 exemples de formation, la formation MSE est assez bonne et la validation croisée est assez mauvaise (nous n’avons pas encore parlé de validation croisée, alors pensez-y comme test pour l’instant). Si nous n’avions alors que tant de données, cela ressemblerait à un problème de forte variance.
Au fur et à mesure que nous augmentons nos données, nous commençons à améliorer nos deux scores et ils deviennent très proches, ce qui suggère que nous n’avons pas de problème de grande variance. En règle générale, avec une variance élevée, ce graphique aurait les deux lignes assez éloignées et, si nous continuions à ajouter plus de données, elles pourraient converger.
Ce graphique ressemble plus à un problème de biais élevé car nos deux courbes sont très proches et s’aplatissent. Il est difficile de dire avec certitude, cependant, car nous venons peut-être d’atteindre le meilleur MSE possible. Dans ce cas, ce ne serait pas un problème de biais élevé. Ce ne serait un problème que si nos courbes s’aplatissaient avec un MSE supérieur à l’optimal. Dans la vraie vie, vous ne savez pas quel est le MSE optimal, vous devez donc théoriser un peu pour savoir si vous pensez que la diminution du biais améliorerait votre score – ou tout simplement l’essayer!
Alors, maintenant que vous avez diagnostiqué votre problème de biais ou de variance, comment pouvez-vous les résoudre?
Pour variance élevée:
- Obtenez plus de données d’entraînement
- Essayez un plus petit ensemble de fonctionnalités
- Essayez un modèle moins complexe
- Ajouter une régularisation
Pour biais élevé:
- Essayez d’ajouter des fonctionnalités
- Essayez un modèle plus complexe
Plus tôt, nous avons mentionné cette phrase: validation croisée. Parlons-en maintenant. Jusqu’à présent, nous avons appris que c’est une bonne idée de diviser vos données en ensembles de formation et de test pour mieux comprendre la performance réelle du modèle. C’est très bien, mais imaginez que nous voulons tester plusieurs modèles différents ou tester différents paramètres pour notre modèle – par exemple, un taux d’apprentissage ou une tolérance différente. Comment pourrions-nous décider quel modèle ou quel paramètre est le meilleur? Allions-nous tout former sur les données de formation et tout tester sur nos données de test? Avec un peu de chance, vous voyez que cela n’a pas de sens, car nous serions alors essentiellement au même endroit que nous l’étions avant sans moyen de tester notre efficacité avec des données jamais vues auparavant. Donc – nous voulons garder notre ensemble de tests intact dans le sens où, dans un monde parfait, nous ne ferions nos tests qu’après avoir fait toutes nos expérimentations et penser que nous avons trouvé le meilleur modèle.
Il semble que nous ayons besoin d’un troisième ensemble de données – un ensemble de validation. Fondamentalement, ce que nous pouvons faire est de décomposer nos données de formation en deux ensembles: un ensemble de formation et un ensemble de validation. Tous les modèles seront formés sur l’ensemble de formation, puis testés sur notre ensemble de validation. Nous prenons ensuite le modèle qui fait le mieux lors de la validation et voyons à quel point il fonctionne lors des tests. Nos résultats de test représentent à quel point nous pensons que notre modèle ferait avec des données invisibles – et alors nous avons terminé.
Remarque: l’hypothèse ici est que nos tests et validation définissent notre échantillon représentatif de notre population. Par exemple, si le prix moyen des maisons dans votre ensemble de validation est de 1 million, mais dans la population de 300 000, vous avez un mauvais échantillon. Souvent, nous échantillonnons au hasard nos données disponibles dans nos trois ensembles, mais il est toujours bon de confirmer que ces ensembles sont de bonnes représentations. Sinon, vous constaterez que votre modèle qui a bien fonctionné lors de la validation et des tests fonctionne mal en pratique.
En pratique, au lieu de créer un seul ensemble de validation, nous utilisons souvent la validation croisée k-fold. Ce que cela fait, c’est que nous choisissons une valeur de k, disons 3. Nous prenons ensuite nos données d’entraînement et les divisons en 3 plis. Nous sélectionnons au hasard 2 plis pour nous entraîner, puis utilisons le reste pour les tests. Nous répétons ensuite ceci 2 fois de plus, pour un total de 3 fois de sorte que toutes les observations sont utilisées à la fois pour la formation et la validation, et chaque observation est utilisée pour la validation exactement une fois. Nous ferions ensuite la moyenne des trois scores (dans notre cas MSE) pour obtenir un score pour un modèle particulier. Nous pouvons ensuite répéter ce processus pour plusieurs modèles afin de trouver le meilleur.
Voici une vidéo qui décrit ce processus plus visuellement: https://www.youtube.com/watch?v=TIgfjmp-4BA
Ce processus est très simple avec sklearn:
from sklearn.model_selection import RandomizedSearchCV
param_dist = {"eta0": [ .001, .003, .01, .03, .1, .3, 1, 3]} linear_regression_model = SGDRegressor(tol=.0001)
n_iter_search = 8
random_search = RandomizedSearchCV(linear_regression_model, param_distributions=param_dist, n_iter=n_iter_search, cv=3, scoring='neg_mean_squared_error')
random_search.fit(X_train, y_train)
print("Best Parameters: {}".format(random_search.best_params_)) print("Best Negative MSE: {}".format(random_search.best_score_))Best Parameters: {'eta0': 0.01} Best Negative MSE: -25.322156767075665
Ici, nous avons en fait utilisé la recherche aléatoire qui est généralement meilleure que la recherche sur toutes les valeurs possibles. Souvent, vous voulez essayer de nombreux paramètres différents pour de nombreux boutons différents et la recherche de grille (essayer toutes les combinaisons possibles) sur tout n’est pas efficace. Habituellement, vous souhaitez utiliser une recherche aléatoire comme nous l’avons fait ci-dessus (sélection aléatoire des combinaisons). Cependant, comme nous n’avions qu’un petit nombre de valeurs, nous l’avons forcé à être une recherche dans la grille en définissant n_iter_search sur le nombre de valeurs que nous voulions essayer.
Nous avons également défini cv = 3 pour avoir 3 plis et utilisé un MSE négatif car les fonctions CV de scikit-learn tentent de maximiser une valeur.
Vous pouvez en savoir plus sur la recherche aléatoire et la recherche dans la grille ici: http://scikit-learn.org/stable/modules/grid_search.html
En outre, scikit-learn possède de nombreuses autres fonctions CV qui sont utiles, surtout si vous souhaitez tester différents modèles avec les mêmes plis. Voici une documentation: http://scikit-learn.org/stable/modules/cross_validation.html
Pour expliquer les modèles à forte variance, j’ai mentionné la régularisation. Vous pouvez considérer la régularisation comme une méthode utilisée pour pénaliser un modèle en apprenant des relations complexes. Pour la régression linéaire, cela prend la forme de trois méthodes populaires. Toutes ces méthodes sont centrées sur l’idée de limiter la taille des coefficients sur nos caractéristiques. L’idée étant que si nous surestimons l’impact d’un prédicteur (un coefficient élevé), il est probable que nous sur-adaptons. Remarque: nous pouvons toujours avoir des coefficients importants. La régularisation dit simplement que la diminution de l’ESM doit justifier l’augmentation des amplitudes des coefficients.
- Régularisation L1 (Lasso): vous ajoutez la somme des valeurs absolues des coefficients à la fonction de coût. Cette méthode peut forcer les coefficients à zéro, ce qui peut alors être un moyen de sélection des caractéristiques.
- Régularisation L2 (Ridge): vous ajoutez la somme des valeurs au carré des coefficients à la fonction de coût.
- Elastic-net: vous ajoutez les deux et choisissez comment les pondérer.
Chacune de ces méthodes prend un facteur de pondération qui vous indique combien vous devez pondérer le terme de régularisation dans la fonction de coût. Dans scikit-learn, il est appelé alpha. Un alpha de zéro n’ajouterait aucune pénalité, tandis qu’un alpha élevé pénaliserait beaucoup le modèle pour avoir de grands coefficients. Vous pouvez utiliser la validation croisée pour découvrir une bonne valeur pour alpha.
Sklearn vous facilite la tâche:
from sklearn.linear_model import ElasticNetCV
# l1 ratio of zero is l2 and visa-versa
# alphas are how much to weight regularization
clf = ElasticNetCV(l1_ratio=[.1, .5, .7, .9, .95, .99, 1], alphas=[.1, 1, 10])
clf.fit(X_train, y_train)
train_predictions = clf.predict(X_train)
test_predictions = clf.predict(X_test)
print("Train MSE: {}".format(mean_squared_error(y_train, train_predictions)))
print("Test MSE: {}".format(mean_squared_error(y_test, test_predictions)))Train MSE: 23.500345265727802 Test MSE: 21.60819303537859
Ici, nous avons utilisé la fonction ElasticNetCV qui a une validation croisée intégrée afin de choisir la meilleure valeur pour alpha. Le l1_ratio, c’est combien de poids à donner à la régularisation L1. Le poids restant est appliqué à L2.
Si vous êtes arrivé jusqu’ici, félicitations! C’était un tonne d’informations, mais je vous promets que si vous prenez le temps de les absorber, vous aurez une très bonne compréhension de la régression linéaire et de beaucoup de choses qu’elle peut faire!
En outre, vous pouvez trouver des versions mieux rendues du code ici.
I have read so many posts about the blogger lovers however this post is really a good piece of writing, keep it up
I just got to this amazing site not long ago. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page!
I am overwhelmed by your post with such a nice topic. Usually I visit your blogs and get updated through the information you include but today’s blog would be the most appreciable. Well done!
This is very educational content and written well for a change. It’s nice to see that some people still understand how to write a quality post!
I adore your websites way of raising the awareness on your readers.
The blog and data is excellent and informative as well
I feel really happy to have seen your webpage and look forward to so many more entertaining times reading here. Thanks once more for all the details.
I am always searching online for articles that can help me. There is obviously a lot to know about this. I think you made some good points in Features also. Keep working, great job !
Your blog provided us with valuable information to work with. Each & every tips of your post are awesome. Thanks a lot for sharing. Keep blogging,
Glad to chat your blog, I seem to be forward to more reliable articles and I think we all wish to thank so many good articles, blog to share with us.
I like viewing web sites which comprehend the price of delivering the excellent useful resource free of charge. I truly adored reading your posting. Thank you!
What a really awesome post this is. Truly, one of the best posts I’ve ever witnessed to see in my whole life. Wow, just keep it up.
With so many books and articles coming up to give gateway to make-money-online field and confusing reader even more on the actual way of earning money,