Exécuter une régression OLS avec la base de données Pandas
j'ai un cadre de données pandas
et je voudrais pouvoir prédire les valeurs de la colonne A à partir des valeurs des colonnes B et C. Voici un exemple de jouet:
import pandas as pd
df = pd.DataFrame({"A": [10,20,30,40,50],
"B": [20, 30, 10, 40, 50],
"C": [32, 234, 23, 23, 42523]})
idéalement, j'aurais quelque chose comme ols(A ~ B + C, data = df)
mais quand je regarde les exemples des bibliothèques d'algorithmes comme scikit-learn
il semble alimenter les données au modèle avec une liste de lignes au lieu de colonnes. Cela me demanderait de reformater les données en listes des listes internes, ce qui semble aller à l'encontre de l'objectif de l'utilisation de pandas en premier lieu. Quelle est la manière la plus pythonique d'exécuter une régression OLS (ou n'importe quel algorithme d'apprentissage machine plus généralement) sur des données dans un cadre de données pandas?
4 réponses
je pense que vous pouvez presque faire exactement ce que vous pensiez être idéal, en utilisant le paquet statsmodels qui est l'une des dépendances optionnelles de pandas
(il est utilisé pour quelques choses dans pandas.stats
.)
>>> import pandas as pd
>>> import statsmodels.formula.api as sm
>>> df = pd.DataFrame({"A": [10,20,30,40,50], "B": [20, 30, 10, 40, 50], "C": [32, 234, 23, 23, 42523]})
>>> result = sm.ols(formula="A ~ B + C", data=df).fit()
>>> print result.params
Intercept 14.952480
B 0.401182
C 0.000352
dtype: float64
>>> print result.summary()
OLS Regression Results
==============================================================================
Dep. Variable: A R-squared: 0.579
Model: OLS Adj. R-squared: 0.158
Method: Least Squares F-statistic: 1.375
Date: Thu, 14 Nov 2013 Prob (F-statistic): 0.421
Time: 20:04:30 Log-Likelihood: -18.178
No. Observations: 5 AIC: 42.36
Df Residuals: 2 BIC: 41.19
Df Model: 2
==============================================================================
coef std err t P>|t| [95.0% Conf. Int.]
------------------------------------------------------------------------------
Intercept 14.9525 17.764 0.842 0.489 -61.481 91.386
B 0.4012 0.650 0.617 0.600 -2.394 3.197
C 0.0004 0.001 0.650 0.583 -0.002 0.003
==============================================================================
Omnibus: nan Durbin-Watson: 1.061
Prob(Omnibus): nan Jarque-Bera (JB): 0.498
Skew: -0.123 Prob(JB): 0.780
Kurtosis: 1.474 Cond. No. 5.21e+04
==============================================================================
Warnings:
[1] The condition number is large, 5.21e+04. This might indicate that there are
strong multicollinearity or other numerical problems.
Note: pandas.stats
a été supprimé avec 0.20.0
il est possible de le faire avec pandas.stats.ols
:
>>> from pandas.stats.api import ols
>>> df = pd.DataFrame({"A": [10,20,30,40,50], "B": [20, 30, 10, 40, 50], "C": [32, 234, 23, 23, 42523]})
>>> res = ols(y=df['A'], x=df[['B','C']])
>>> res
-------------------------Summary of Regression Analysis-------------------------
Formula: Y ~ <B> + <C> + <intercept>
Number of Observations: 5
Number of Degrees of Freedom: 3
R-squared: 0.5789
Adj R-squared: 0.1577
Rmse: 14.5108
F-stat (2, 2): 1.3746, p-value: 0.4211
Degrees of Freedom: model 2, resid 2
-----------------------Summary of Estimated Coefficients------------------------
Variable Coef Std Err t-stat p-value CI 2.5% CI 97.5%
--------------------------------------------------------------------------------
B 0.4012 0.6497 0.62 0.5999 -0.8723 1.6746
C 0.0004 0.0005 0.65 0.5826 -0.0007 0.0014
intercept 14.9525 17.7643 0.84 0.4886 -19.8655 49.7705
---------------------------------End of Summary---------------------------------
notez que vous devez avoir le paquet statsmodels
installé, il est utilisé en interne par la fonction pandas.stats.ols
.
Je ne sais pas si c'est nouveau dans sklearn
ou pandas
, mais je suis capable de passer la base de données directement à sklearn
sans convertir la base de données à un tableau numpy ou tout autre type de données.
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(df[['B', 'C']], df['A'])
>>> reg.coef_
array([ 4.01182386e-01, 3.51587361e-04])
cela me demanderait de reformater les données en listes à l'intérieur des listes, ce qui semble aller à l'encontre de l'objectif de l'utilisation de pandas en premier lieu.
Non, ce n'est pas le cas, il suffit de convertir un tableau NumPy:
>>> data = np.asarray(df)
cela prend du temps constant parce qu'il crée juste un vue sur vos données. Ensuite, donnez-le à scikit-learn:
>>> from sklearn.linear_model import LinearRegression
>>> lr = LinearRegression()
>>> X, y = data[:, 1:], data[:, 0]
>>> lr.fit(X, y)
LinearRegression(copy_X=True, fit_intercept=True, normalize=False)
>>> lr.coef_
array([ 4.01182386e-01, 3.51587361e-04])
>>> lr.intercept_
14.952479503953672