web-dev-qa-db-fra.com

Régression OLS: Scikit vs Statsmodels?

Version courte : J'utilisais le scikit LinearRegression sur certaines données, mais je suis habitué aux valeurs de p, alors mettez les données dans les modèles OLS, et bien que le R ^ 2 soit à peu près le même, les coefficients variables sont tous différents en grande quantité. Cela m'inquiète car le problème le plus probable est que j'ai fait une erreur quelque part et maintenant je ne me sens pas en confiance dans les deux sorties (car j'ai probablement fait un modèle incorrectement mais je ne sais pas lequel).

Version plus longue : Parce que je ne sais pas où est le problème, je ne sais pas exactement quels détails inclure, et tout inclure est probablement trop . Je ne suis pas sûr non plus d'inclure du code ou des données.

J'ai l'impression que le LR de scikit et les modèles de statistiques OLS devraient tous deux faire de l'OLS, et pour autant que je sache, l'OLS est l'OLS, donc les résultats devraient être les mêmes.

Pour le LR de scikit, les résultats sont (statistiquement) les mêmes que je définisse normalize = True ou = False, ce que je trouve quelque peu étrange.

Pour les modèles de statistiques OLS, je normalise les données en utilisant StandardScaler de sklearn. J'ajoute une colonne de ceux-ci afin qu'elle comprenne une interception (puisque la sortie de scikit comprend une interception). Plus d'informations à ce sujet ici: http://statsmodels.sourceforge.net/devel/examples/generated/example_ols.html (L'ajout de cette colonne n'a pas modifié les coefficients variables à un degré notable et l'interception était très proche de zéro.) StandardScaler n'aimait pas que mes encres ne soient pas des flotteurs, j'ai donc essayé ceci: https://github.com/scikit-learn/scikit-learn/issues/1709 That fait disparaître l'avertissement mais les résultats sont exactement les mêmes.

Certes, j'utilise un cv 5 fois pour l'approche sklearn (R ^ 2 sont cohérents pour les données de test et d'entraînement à chaque fois), et pour les modèles de statistiques, je jette simplement toutes les données.

R ^ 2 est d'environ 0,41 pour sklearn et les modèles de statistiques (c'est bon pour les sciences sociales). Cela pourrait être un bon signe ou juste une coïncidence.

Les données sont des observations d'avatars dans WoW (de http://mmnet.iis.sinica.edu.tw/dl/wowah/ ) que j'ai fait sur le point de le faire chaque semaine avec quelques fonctionnalités différentes. À l'origine, il s'agissait d'un projet de classe pour une classe de science des données.

Les variables indépendantes comprennent le nombre d'observations dans une semaine (int), le niveau de caractère (int), si dans une guilde (booléen), lorsqu'il est vu (booléens le jour de la semaine, veille du jour de la semaine, fin de semaine et les mêmes trois pour le week-end), a factice pour la classe de caractères (au moment de la collecte de données, il n'y avait que 8 classes dans WoW, il y a donc 7 variables factices et la variable catégorielle de chaîne d'origine est supprimée), et d'autres.

La variable dépendante est le nombre de niveaux gagnés par chaque personnage au cours de cette semaine (int).

Fait intéressant, une partie de l'ordre relatif au sein de variables similaires est maintenue dans les modèles de statistiques et l'apprentissage par le biais de sklearn. Ainsi, l'ordre de classement de "lorsqu'il est vu" est le même bien que les chargements soient très différents, et l'ordre de classement pour les mannequins de classe de personnage est le même bien que les chargements soient encore très différents.

Je pense que cette question est similaire à celle-ci: Différence dans Python statsmodels OLS et R's lm

Je suis assez bon pour Python et les statistiques pour y aller, mais pas assez pour comprendre quelque chose comme ça. J'ai essayé de lire les documents sklearn et les documents statsmodels, mais si le la réponse était là me regardant en face je ne le comprenais pas.

J'aimerais bien savoir:

  1. Quelle sortie peut être précise? (Certes, ils pourraient l'être tous les deux si je manquais un kwarg.)
  2. Si j'ai fait une erreur, qu'est-ce que c'est et comment y remédier?
  3. Aurais-je pu comprendre cela sans demander ici, et si oui, comment?

Je sais que cette question a des bits plutôt vagues (pas de code, pas de données, pas de sortie), mais je pense qu'il s'agit davantage des processus généraux des deux packages. Bien sûr, l'un semble être plus de statistiques et l'autre semble être plus d'apprentissage automatique, mais ils sont tous les deux OLS, donc je ne comprends pas pourquoi les sorties ne sont pas les mêmes.

(J'ai même essayé d'autres appels OLS pour trianguler, l'un a donné un R ^ 2 beaucoup plus faible, un en boucle pendant cinq minutes et je l'ai tué, et un s'est écrasé.)

Merci!

24
Nat Poor

Il semble que vous n'alimentiez pas la même matrice de régresseurs X aux deux procédures (mais voir ci-dessous). Voici un exemple pour vous montrer quelles options vous devez utiliser pour sklearn et statsmodels pour produire des résultats identiques.

import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression

# Generate artificial data (2 regressors + constant)
nobs = 100 
X = np.random.random((nobs, 2)) 
X = sm.add_constant(X)
beta = [1, .1, .5] 
e = np.random.random(nobs)
y = np.dot(X, beta) + e 

# Fit regression model
sm.OLS(y, X).fit().params
>> array([ 1.4507724 ,  0.08612654,  0.60129898])

LinearRegression(fit_intercept=False).fit(X, y).coef_
>> array([ 1.4507724 ,  0.08612654,  0.60129898])

Comme un commentateur l'a suggéré, même si vous donnez aux deux programmes le même X, X peut ne pas avoir le rang de colonne complet, et sm/sk pourrait prendre des actions (différentes) sous le capot pour faire passer le calcul OLS (c.-à-d. suppression de différentes colonnes).

Je vous recommande d'utiliser pandas et patsy pour vous en occuper:

import pandas as pd
from patsy import dmatrices

dat = pd.read_csv('wow.csv')
y, X = dmatrices('levels ~ week + character + guild', data=dat)

Ou, alternativement, l'interface de formule statsmodels:

import statsmodels.formula.api as smf
dat = pd.read_csv('wow.csv')
mod = smf.ols('levels ~ week + character + guild', data=dat).fit()

Modifier: cet exemple peut être utile: http://statsmodels.sourceforge.net/devel/example_formulas.html

35
Vincent

je voulais juste ajouter ici, qu'en termes de sklearn, il n'utilise pas la méthode OLS pour la régression linéaire sous le capot. Étant donné que sklearn provient du domaine de l'exploration de données/apprentissage machine, ils aiment utiliser l'algorithme Steepest Descent Gradient. Il s'agit d'une méthode numérique sensible aux conditions initiales, etc., tandis que l'OLS est une approche analytique sous forme fermée, il faut donc s'attendre à des différences. Les modèles de statistiques proviennent donc du domaine des statistiques classiques, ils utiliseraient donc la technique OLS. Il y a donc des différences entre les deux régressions linéaires des 2 bibliothèques différentes

1
Palu

Si vous utilisez des modèles de statistiques, je vous recommande fortement d'utiliser plutôt l'interface de formule des modèles de statistiques. Vous obtiendrez le même ancien résultat d'OLS en utilisant l'interface de formule statsmodels que vous le feriez de sklearn.linear_model.LinearRegression, ou R, ou SAS, ou Excel.

smod = smf.ols(formula ='y~ x', data=df)
result = smod.fit()
print(result.summary())

En cas de doute, veuillez

  1. essayez de lire le code source
  2. essayez une autre langue pour le benchmark, ou
  3. essayez OLS à partir de zéro, qui est l'algèbre linéaire de base.
1
Sarah