Regressione lineare multipla in Python


129

Non riesco a trovare alcuna libreria Python che faccia regressione multipla. Le uniche cose che trovo fanno solo una semplice regressione. Devo regredire la mia variabile dipendente (y) rispetto a diverse variabili indipendenti (x1, x2, x3, ecc.).

Ad esempio, con questi dati:

print 'y        x1      x2       x3       x4      x5     x6       x7'
for t in texts:
    print "{:>7.1f}{:>10.2f}{:>9.2f}{:>9.2f}{:>10.2f}{:>7.2f}{:>7.2f}{:>9.2f}" /
   .format(t.y,t.x1,t.x2,t.x3,t.x4,t.x5,t.x6,t.x7)

(uscita per sopra :)

      y        x1       x2       x3        x4     x5     x6       x7
   -6.0     -4.95    -5.87    -0.76     14.73   4.02   0.20     0.45
   -5.0     -4.55    -4.52    -0.71     13.74   4.47   0.16     0.50
  -10.0    -10.96   -11.64    -0.98     15.49   4.18   0.19     0.53
   -5.0     -1.08    -3.36     0.75     24.72   4.96   0.16     0.60
   -8.0     -6.52    -7.45    -0.86     16.59   4.29   0.10     0.48
   -3.0     -0.81    -2.36    -0.50     22.44   4.81   0.15     0.53
   -6.0     -7.01    -7.33    -0.33     13.93   4.32   0.21     0.50
   -8.0     -4.46    -7.65    -0.94     11.40   4.43   0.16     0.49
   -8.0    -11.54   -10.03    -1.03     18.18   4.28   0.21     0.55

Come vorrei regredire a questi in Python per ottenere la formula di regressione lineare:

Y = a1x1 + a2x2 + a3x3 + a4x4 + a5x5 + a6x6 + + a7x7 + c


non un esperto, ma se le variabili sono indipendenti, non puoi semplicemente eseguire una regressione semplice contro ciascuna e sommare il risultato?
Hugh Bothwell,

8
@HughBothwell Tuttavia non puoi supporre che le variabili siano indipendenti. In effetti, se stai assumendo che le variabili siano indipendenti, potresti potenzialmente modellare i tuoi dati in modo errato. In altre parole, le risposte Ypossono essere correlate tra loro, ma assumere l'indipendenza non modella in modo accurato il set di dati.
hlin117,

@HughBothwell scusate se questa è una domanda dum, ma perché importa se le variabili di funzione non elaborate x_i sono indipendenti o no? In che modo influisce sul predittore (= modello)?
Charlie Parker,

Risposte:


100

sklearn.linear_model.LinearRegression lo farà:

from sklearn import linear_model
clf = linear_model.LinearRegression()
clf.fit([[getattr(t, 'x%d' % i) for i in range(1, 8)] for t in texts],
        [t.y for t in texts])

Quindi clf.coef_avrà i coefficienti di regressione.

sklearn.linear_model ha anche interfacce simili per fare vari tipi di regolarizzazioni sulla regressione.


2
Ciò restituisce un errore con determinati input . Altre soluzioni disponibili?
Zach

@Dougal può essere utilizzato anche sklearn.linear_model.LinearRegression per la regressione multivariata ponderata ?
user961627,

1
Per adattarsi a un termine costante: clf = linear_model.LinearRegression (fit_intercept = True)
Imran

2
Follow-up, sai come ottenere il livello di confidenza usando sklearn.linear_model.LinearRegression? Grazie.
Huanian Zhang,

1
@HuanianZhang cosa intendi per livello di confidenza? Se vuoi il coefficiente di determinazione, il scoremetodo lo farà; sklearn.metricsha alcuni altri criteri di valutazione del modello. Se vuoi le cose come nella risposta di Akavall, statsmodels ha un po 'più di diagnostica di tipo R.
Dougal,

60

Ecco una piccola soluzione che ho creato. L'ho controllato con R e funziona correttamente.

import numpy as np
import statsmodels.api as sm

y = [1,2,3,4,3,4,5,4,5,5,4,5,4,5,4,5,6,5,4,5,4,3,4]

x = [
     [4,2,3,4,5,4,5,6,7,4,8,9,8,8,6,6,5,5,5,5,5,5,5],
     [4,1,2,3,4,5,6,7,5,8,7,8,7,8,7,8,7,7,7,7,7,6,5],
     [4,1,2,5,6,7,8,9,7,8,7,8,7,7,7,7,7,7,6,6,4,4,4]
     ]

def reg_m(y, x):
    ones = np.ones(len(x[0]))
    X = sm.add_constant(np.column_stack((x[0], ones)))
    for ele in x[1:]:
        X = sm.add_constant(np.column_stack((ele, X)))
    results = sm.OLS(y, X).fit()
    return results

Risultato:

print reg_m(y, x).summary()

Produzione:

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.535
Model:                            OLS   Adj. R-squared:                  0.461
Method:                 Least Squares   F-statistic:                     7.281
Date:                Tue, 19 Feb 2013   Prob (F-statistic):            0.00191
Time:                        21:51:28   Log-Likelihood:                -26.025
No. Observations:                  23   AIC:                             60.05
Df Residuals:                      19   BIC:                             64.59
Df Model:                           3                                         
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
x1             0.2424      0.139      1.739      0.098        -0.049     0.534
x2             0.2360      0.149      1.587      0.129        -0.075     0.547
x3            -0.0618      0.145     -0.427      0.674        -0.365     0.241
const          1.5704      0.633      2.481      0.023         0.245     2.895

==============================================================================
Omnibus:                        6.904   Durbin-Watson:                   1.905
Prob(Omnibus):                  0.032   Jarque-Bera (JB):                4.708
Skew:                          -0.849   Prob(JB):                       0.0950
Kurtosis:                       4.426   Cond. No.                         38.6

pandas fornisce un modo conveniente per eseguire OLS come indicato in questa risposta:

Esegui una regressione OLS con Pandas Data Frame


18
La reg_mfunzione è inutilmente complicata. x = np.array(x).T, x = sm.add_constant(x)Ed results = sm.OLS(endog=y, exog=x).fit()è sufficiente.
cd98,

1
Questo è uno strumento carino. Fai solo una domanda: in questo caso, il valore t è al di fuori dell'intervallo di confidenza del 95,5%, quindi significa che questo adattamento non è affatto accurato o come lo spieghi?
Huanian Zhang,

2
Hai appena notato che x1, x2, x3 sono in ordine inverso nell'elenco dei predittori originali, ovvero x = [x3, x2, x1]?
Sophiadw,

@sophiadw puoi semplicemente aggiungere la x = x[::-1]definizione della funzione per entrare nel giusto ordine
Ashrith

@HuanianZhang "valore t" è solo quante deviazioni standard il coefficiente è lontano da zero, mentre il 95% CI è approssimativamente coef +- 2 * std err(in realtà la distribuzione Student-t parametrizzata dai gradi di libertà nei residui). cioè valori di t assoluti più grandi implicano CI più lontani da zero, ma non dovrebbero essere confrontati direttamente. il chiarimento è un po 'in ritardo, ma spero che sia utile a qualcuno
Sam Mason,

47

Solo per chiarire, l'esempio che hai dato è la regressione lineare multipla, non riferirsi alla regressione lineare multivariata . Differenza :

Il caso più semplice di una singola variabile predittiva scalare xe di una singola variabile di risposta scalare y è noto come semplice regressione lineare. L'estensione a variabili predittive multiple e / o con valori vettoriali (indicate con una X maiuscola) è nota come regressione lineare multipla, nota anche come regressione lineare multivariabile. Quasi tutti i modelli di regressione del mondo reale coinvolgono predittori multipli e le descrizioni di base della regressione lineare sono spesso formulate in termini di modello di regressione multipla. Si noti, tuttavia, che in questi casi la variabile di risposta y è ancora uno scalare. Un altro termine regressione lineare multivariata si riferisce a casi in cui y è un vettore, ovvero lo stesso della regressione lineare generale.

In breve:

  • multipla regressione lineare: la risposta y è uno scalare.
  • regressione lineare multivariata : la risposta y è un vettore.

(Un'altra fonte .)


5
Questa potrebbe essere un'informazione utile, ma non vedo come risponda alla domanda.
Akavall,

7
@Akavall utilizzando la terminologia corretta è il primo passo per trovare una risposta.
Franck Dernoncourt,

1
@FranckDernoncourt ma il valore Y di OP È un vettore?
Domande poste sempre dal

@FranckDernoncourt: "usare la terminologia corretta è il primo passo per trovare una risposta" . Fantastico, quindi siamo entrambi d'accordo: questa, di per sé, non è in realtà una risposta. Gli utenti dovrebbero essere in grado di risolvere il loro problema direttamente dalle risposte senza dover ricorrere alla ricerca di altre risorse .
Mac,

28

Puoi usare numpy.linalg.lstsq :

import numpy as np
y = np.array([-6,-5,-10,-5,-8,-3,-6,-8,-8])
X = np.array([[-4.95,-4.55,-10.96,-1.08,-6.52,-0.81,-7.01,-4.46,-11.54],[-5.87,-4.52,-11.64,-3.36,-7.45,-2.36,-7.33,-7.65,-10.03],[-0.76,-0.71,-0.98,0.75,-0.86,-0.50,-0.33,-0.94,-1.03],[14.73,13.74,15.49,24.72,16.59,22.44,13.93,11.40,18.18],[4.02,4.47,4.18,4.96,4.29,4.81,4.32,4.43,4.28],[0.20,0.16,0.19,0.16,0.10,0.15,0.21,0.16,0.21],[0.45,0.50,0.53,0.60,0.48,0.53,0.50,0.49,0.55]])
X = X.T # transpose so input vectors are along the rows
X = np.c_[X, np.ones(X.shape[0])] # add bias term
beta_hat = np.linalg.lstsq(X,y)[0]
print beta_hat

Risultato:

[ -0.49104607   0.83271938   0.0860167    0.1326091    6.85681762  22.98163883 -41.08437805 -19.08085066]

Puoi vedere l'output stimato con:

print np.dot(X,beta_hat)

Risultato:

[ -5.97751163,  -5.06465759, -10.16873217,  -4.96959788,  -7.96356915,  -3.06176313,  -6.01818435,  -7.90878145,  -7.86720264]

posso sapere qual è la differenza tra print np.dot (X, beta_hat) ... e mod_wls = sm.WLS (y, X, pesi = pesi) res = mod_wls.fit () predsY = res.predict () tutti restituisce il risultato Y
dd90p

13

Usa scipy.optimize.curve_fit. E non solo per l'adattamento lineare.

from scipy.optimize import curve_fit
import scipy

def fn(x, a, b, c):
    return a + b*x[0] + c*x[1]

# y(x0,x1) data:
#    x0=0 1 2
# ___________
# x1=0 |0 1 2
# x1=1 |1 2 3
# x1=2 |2 3 4

x = scipy.array([[0,1,2,0,1,2,0,1,2,],[0,0,0,1,1,1,2,2,2]])
y = scipy.array([0,1,2,1,2,3,2,3,4])
popt, pcov = curve_fit(fn, x, y)
print popt

8

Dopo aver convertito i tuoi dati in un pandas dataframe ( df),

import statsmodels.formula.api as smf
lm = smf.ols(formula='y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7', data=df).fit()
print(lm.params)

Il termine di intercettazione è incluso per impostazione predefinita.

Vedi questo quaderno per ulteriori esempi.


Questo notebook è fantastico. mostra come regredire più variabili indipendenti (x1, x2, x3 ...) su Y con solo 3 righe di codice e usando scikit learn.
jxn,

@canary_in_the_data_mine grazie per il taccuino. come posso tracciare la regressione lineare che ha più funzioni? Non riuscivo a trovare sul taccuino. eventuali suggerimenti saranno molto apprezzati. - Grazie
Jai Prakash

Aggiunge l'intercetta perché dobbiamo aggiungere l'intercettazione passando smf.add_intercept () come parametro a ols ()
bluedroid,

4

Penso che questo sia il modo più semplice per finire questo lavoro:

from random import random
from pandas import DataFrame
from statsmodels.api import OLS
lr = lambda : [random() for i in range(100)]
x = DataFrame({'x1': lr(), 'x2':lr(), 'x3':lr()})
x['b'] = 1
y = x.x1 + x.x2 * 2 + x.x3 * 3 + 4

print x.head()

         x1        x2        x3  b
0  0.433681  0.946723  0.103422  1
1  0.400423  0.527179  0.131674  1
2  0.992441  0.900678  0.360140  1
3  0.413757  0.099319  0.825181  1
4  0.796491  0.862593  0.193554  1

print y.head()

0    6.637392
1    5.849802
2    7.874218
3    7.087938
4    7.102337
dtype: float64

model = OLS(y, x)
result = model.fit()
print result.summary()

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       1.000
Model:                            OLS   Adj. R-squared:                  1.000
Method:                 Least Squares   F-statistic:                 5.859e+30
Date:                Wed, 09 Dec 2015   Prob (F-statistic):               0.00
Time:                        15:17:32   Log-Likelihood:                 3224.9
No. Observations:                 100   AIC:                            -6442.
Df Residuals:                      96   BIC:                            -6431.
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
x1             1.0000   8.98e-16   1.11e+15      0.000         1.000     1.000
x2             2.0000   8.28e-16   2.41e+15      0.000         2.000     2.000
x3             3.0000   8.34e-16    3.6e+15      0.000         3.000     3.000
b              4.0000   8.51e-16    4.7e+15      0.000         4.000     4.000
==============================================================================
Omnibus:                        7.675   Durbin-Watson:                   1.614
Prob(Omnibus):                  0.022   Jarque-Bera (JB):                3.118
Skew:                           0.045   Prob(JB):                        0.210
Kurtosis:                       2.140   Cond. No.                         6.89
==============================================================================

4

La regressione lineare multipla può essere gestita utilizzando la libreria sklearn come indicato sopra. Sto usando l'installazione Anaconda di Python 3.6.

Crea il tuo modello come segue:

from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X, y)

# display coefficients
print(regressor.coef_)

3

Puoi usare numpy.linalg.lstsq


6
Come puoi usarlo per ottenere i coefficienti di una regressione multivariata? Vedo solo come fare una semplice regressione ... e non vedo come ottenere i coefficienti ..
Zach

1

È possibile utilizzare la funzione seguente e passargli un DataFrame:

def linear(x, y=None, show=True):
    """
    @param x: pd.DataFrame
    @param y: pd.DataFrame or pd.Series or None
              if None, then use last column of x as y
    @param show: if show regression summary
    """
    import statsmodels.api as sm

    xy = sm.add_constant(x if y is None else pd.concat([x, y], axis=1))
    res = sm.OLS(xy.ix[:, -1], xy.ix[:, :-1], missing='drop').fit()

    if show: print res.summary()
    return res

1

Scikit-learn è una libreria di apprendimento automatico per Python che può fare questo lavoro per te. Importa semplicemente il modulo sklearn.linear_model nel tuo script.

Trova il modello di codice per la regressione lineare multipla usando sklearn in Python:

import numpy as np
import matplotlib.pyplot as plt #to plot visualizations
import pandas as pd

# Importing the dataset
df = pd.read_csv(<Your-dataset-path>)
# Assigning feature and target variables
X = df.iloc[:,:-1]
y = df.iloc[:,-1]

# Use label encoders, if you have any categorical variable
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
X['<column-name>'] = labelencoder.fit_transform(X['<column-name>'])

from sklearn.preprocessing import OneHotEncoder
onehotencoder = OneHotEncoder(categorical_features = ['<index-value>'])
X = onehotencoder.fit_transform(X).toarray()

# Avoiding the dummy variable trap
X = X[:,1:] # Usually done by the algorithm itself

#Spliting the data into test and train set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y, random_state = 0, test_size = 0.2)

# Fitting the model
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)

# Predicting the test set results
y_pred = regressor.predict(X_test)

Questo è tutto. È possibile utilizzare questo codice come modello per l'implementazione della regressione lineare multipla in qualsiasi set di dati. Per una migliore comprensione con un esempio, visita: regressione lineare con un esempio


0

Ecco un metodo alternativo e di base:

from patsy import dmatrices
import statsmodels.api as sm

y,x = dmatrices("y_data ~ x_1 + x_2 ", data = my_data)
### y_data is the name of the dependent variable in your data ### 
model_fit = sm.OLS(y,x)
results = model_fit.fit()
print(results.summary())

Invece di sm.OLSte puoi anche usare sm.Logitoe sm.Probitecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.