Запустите регрессию OLS с помощью Pandas Data Frame

У меня есть кадр данных pandas, и я хотел бы предсказать значения столбца A из значений в столбцах B и C. Вот пример игрушки:

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]})

В идеале, у меня было бы что-то вроде ols(A ~ B + C, data = df), но когда я смотрю examples из библиотек алгоритмов, таких как scikit-learn, он появляется для подачи данных в модель со списком строк вместо столбцов. Это потребовало бы, чтобы я переформатировал данные в списки внутри списков, что, по-видимому, преследует цель использования pandas в первую очередь. Какой самый pythonic способ запустить регрессию OLS (или любой алгоритм машинного обучения в целом) по данным в фрейме данных pandas?

Ответ 1

Я думаю, вы можете сделать почти то, что, по вашему мнению, было бы идеальным, используя statsmodels пакет, который является одним из pandas 'дополнительных зависимостей (он использовался для нескольких вещей в 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.

Ответ 2

Примечание: pandas.stats удален с 0.20.0


Это можно сделать с помощью 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---------------------------------

Обратите внимание, что вам нужно установить пакет statsmodels, он используется внутренне с помощью функции pandas.stats.ols.

Ответ 3

Это потребует от меня переформатировать данные в списки внутри списков, что, по-видимому, в первую очередь превзойдет цель использования pandas.

Нет, нет, просто преобразуйте в массив NumPy:

>>> data = np.asarray(df)

Это занимает постоянное время, потому что оно просто создает представление ваших данных. Затем подайте его на 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

Ответ 4

Я не знаю, является ли это новым в sklearn или pandas, но я могу передать кадр данных непосредственно на sklearn без преобразования фрейма данных в массив numpy или любые другие типы данных.

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])