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?

87
demandé sur denfromufa 2013-11-15 04:47:00

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.
115
répondu DSM 2013-11-16 14:19:42

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 .

61
répondu Roman Pekar 2017-06-30 18:04:07

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])
19
répondu 3novak 2017-01-07 02:51:14

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
15
répondu Fred Foo 2013-11-17 13:16:02