Pandas Data Frame ile bir OLS regresyonu çalıştırın


111

Bir pandasveri çerçevem ​​var ve B ve C sütunlarındaki değerlerden A sütunundaki değerleri tahmin edebilmek istiyorum. İşte bir oyuncak örneği:

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

İdeal olarak, buna benzer bir şeye sahip olurdum, ols(A ~ B + C, data = df)ancak algoritma kitaplıklarından örneklere baktığımda scikit-learn, verileri sütunlar yerine satırlar listesiyle modele besliyor gibi görünüyor. Bu, verileri listelerin içindeki listeler halinde yeniden biçimlendirmemi gerektirecek, bu da ilk başta pandaları kullanma amacını bozuyor gibi görünüyor. Pandalar veri çerçevesindeki veriler üzerinde OLS regresyonunu (veya daha genel olarak herhangi bir makine öğrenimi algoritmasını) çalıştırmanın en pitonik yolu nedir?

Yanıtlar:


152

0.20.0'danpandas önceki pandas' isteğe bağlı bağımlılıklardan' biri olan istatistik modelleri paketini kullanarak ideal olacağını düşündüğünüz şeyi neredeyse tam olarak yapabileceğinizi düşünüyorum (içinde birkaç şey için kullanıldı 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
Doğru anahtar kelimenin yerine formulayanlışlıkla yazdım formulasve tuhaf bir hata TypeError: from_formula() takes at least 3 arguments (2 given)
aldığımı unutmayın

@DSM Python için çok yeni. Aynı kodunuzu çalıştırmayı denedim ve her iki yazdırma iletisinde de hatalar var: yazdırma sonucu.summary () ^ Sözdizimi Hatası: geçersiz sözdizimi >>> yazdırma sonucu.parmas Dosyası "<stdin>", satır 1 yazdırma sonucu.parmas ^ Sözdizimi Hatası: içinde parantezler eksik 'yazdır' çağrısı ... Belki paketleri yanlış yükledim ?? "Yazdır" yazmadığımda işe yarıyor gibi görünüyor. Teşekkürler.
a.powell

2
@ a.powell OP'nin kodu Python 2 içindir. Yapmanız gereken tek değişiklik, yazdırmak için argümanların etrafına parantez koymaktır: print(result.params)veprint(result.summary())
Paul Moore

Şuna bir göz
atıp

bu formula()yaklaşımı kullanmaya çalışmak TypeError: __init __ () eksik 1 konumsal bağımsız değişken: 'endog' tür hatası atıyor, bu yüzden kullanımdan kaldırıldı. ayrıca, olsşimdiOLS
3pitt

68

Not: 0.20.0 ile pandas.stats kaldırılmıştır


Bunu şu şekilde yapmak mümkündür 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---------------------------------

statsmodelsPaketin kurulu olması gerektiğini unutmayın , bu pandas.stats.olsişlev tarafından dahili olarak kullanılır .


13
Pandaların gelecekteki sürümlerinde bunun kullanımdan kaldırılacağını unutmayın!
denfromufa

4
Neden yapıyorsun Umarım bu işlev hayatta kalır! GERÇEKTEN kullanışlı ve hızlı!
FaCoffee

2
The pandas.stats.ols module is deprecated and will be removed in a future version. We refer to external packages like statsmodels, see some examples here: http://www.statsmodels.org/stable/regression.html
javadba

2
@DestaHaileselassieHagos. Bu, ile ilgili bir sorundan kaynaklanıyor olabilir missing intercepts. Eşdeğer Rpaketin tasarımcısı , ortalama için ayarlamayı kaldırarak ayarlama yapar: stats.stackexchange.com/a/36068/64552 . . Diğer öneriler: you can use sm.add_constant to add an intercept to the exog arrayve bir reg = ols("y ~ x", data=dict(y=y,x=x)).fit()
dikte

2
pandas.stats💔
3kstc

31

Bunun sklearnveya içinde yeni olup olmadığını bilmiyorum pandas, ancak sklearnveri çerçevesini bir uyuşmuş diziye veya diğer veri türlerine dönüştürmeden veri çerçevesini doğrudan aktarabiliyorum .

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

2
.values.reshape(-1, 1)OP'den küçük sapma - ancak bu özel yanıtı , veri çerçevesi sütunlarına ekledikten sonra çok yararlı buldum . Örneğin: x_data = df['x_data'].values.reshape(-1, 1)ve x_data(ve benzer şekilde oluşturulmuş y_data) np dizilerini .fit()yönteme geçirmek .
S3DEV

16

Bu, verileri listelerin içindeki listeler halinde yeniden biçimlendirmemi gerektirecek, bu da ilk başta pandaları kullanma amacını bozuyor gibi görünüyor.

Hayır değil, sadece bir NumPy dizisine dönüştürün:

>>> data = np.asarray(df)

Bu sabit zaman alır çünkü verileriniz üzerinde sadece bir görünüm oluşturur . Sonra scikit-learn için besleyin:

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

3
Yapmak zorundaydım np.matrix( np.asarray( df ) ), çünkü sklearn dikey bir vektör beklerken, uyuşuk diziler, onları bir diziden ayırdığınızda, yatay vecotr'lar gibi davranır, ki bu çoğu zaman harikadır.
cjohnson318

bu rota ile katsayıları test etmenin basit bir yolu yok, ancak
MichaelChirico

2
Scikit-Learn'ü Pandas DataFrame ile doğrudan beslemenin bir yolu yok mu?
Femto Trader

diğer sklearn modülleri için (karar ağacı vb.), df ['colname']. değerlerini kullandım, ancak bu işe yaramadı.
szeitlin

1
.valuesÖzniteliği de kullanabilirsiniz . Yani reg.fit(df[['B', 'C']].values, df['A'].values),.
3novak

6

Statsmodels, doğrudan bir pandas veri çerçevesine sütun referanslarıyla bir OLS modeli oluşturabilir.

Kısa ve güzel:

model = sm.OLS(df[y], df[x]).fit()


Kod ayrıntıları ve regresyon özeti:

# imports
import pandas as pd
import statsmodels.api as sm
import numpy as np

# data
np.random.seed(123)
df = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns=list('ABC'))

# assign dependent and independent / explanatory variables
variables = list(df.columns)
y = 'A'
x = [var for var in variables if var not in y ]

# Ordinary least squares regression
model_Simple = sm.OLS(df[y], df[x]).fit()

# Add a constant term like so:
model = sm.OLS(df[y], sm.add_constant(df[x])).fit()

model.summary()

Çıktı:

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      A   R-squared:                       0.019
Model:                            OLS   Adj. R-squared:                 -0.001
Method:                 Least Squares   F-statistic:                    0.9409
Date:                Thu, 14 Feb 2019   Prob (F-statistic):              0.394
Time:                        08:35:04   Log-Likelihood:                -484.49
No. Observations:                 100   AIC:                             975.0
Df Residuals:                      97   BIC:                             982.8
Df Model:                           2                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const         43.4801      8.809      4.936      0.000      25.996      60.964
B              0.1241      0.105      1.188      0.238      -0.083       0.332
C             -0.0752      0.110     -0.681      0.497      -0.294       0.144
==============================================================================
Omnibus:                       50.990   Durbin-Watson:                   2.013
Prob(Omnibus):                  0.000   Jarque-Bera (JB):                6.905
Skew:                           0.032   Prob(JB):                       0.0317
Kurtosis:                       1.714   Cond. No.                         231.
==============================================================================

Doğrudan R kare, Katsayılar ve p değeri nasıl alınır:

# commands:
model.params
model.pvalues
model.rsquared

# demo:
In[1]: 
model.params
Out[1]:
const    43.480106
B         0.124130
C        -0.075156
dtype: float64

In[2]: 
model.pvalues
Out[2]: 
const    0.000003
B        0.237924
C        0.497400
dtype: float64

Out[3]:
model.rsquared
Out[2]:
0.0190
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.