Régression linéaire multiple en Python


129

Je n'arrive pas à trouver de bibliothèques python qui effectuent des régressions multiples. Les seules choses que je trouve ne font qu'une simple régression. J'ai besoin de régresser ma variable dépendante (y) par rapport à plusieurs variables indépendantes (x1, x2, x3, etc.).

Par exemple, avec ces données:

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)

(sortie pour ci-dessus :)

      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

Comment pourrais-je les régresser en python, pour obtenir la formule de régression linéaire:

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


pas un expert, mais si les variables sont indépendantes, ne pouvez-vous pas simplement exécuter une régression simple sur chacune et additionner le résultat?
Hugh Bothwell

8
@HughBothwell Vous ne pouvez cependant pas supposer que les variables sont indépendantes. En fait, si vous supposez que les variables sont indépendantes, vous risquez de modéliser vos données de manière incorrecte. En d'autres termes, les réponses Ypeuvent être corrélées les unes aux autres, mais en supposant que l'indépendance ne modélise pas avec précision l'ensemble de données.
hlin117

@HughBothwell désolé si c'est une question idiote, mais pourquoi est-ce important que les variables de caractéristiques brutes x_i soient indépendantes ou non? Comment cela affecte-t-il le prédicteur (= modèle)?
Charlie Parker

Réponses:


100

sklearn.linear_model.LinearRegression le fera:

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

Ensuite clf.coef_aura les coefficients de régression.

sklearn.linear_model a également des interfaces similaires pour effectuer divers types de régularisations sur la régression.


2
Cela renvoie une erreur avec certaines entrées . D'autres solutions sont-elles disponibles?
Zach

@Dougal peut-il également utiliser sklearn.linear_model.LinearRegression pour la régression multivariée pondérée ?
user961627

1
Pour ajuster un terme constant: clf = linear_model.LinearRegression (fit_intercept = True)
Imran

2
Suivi, savez-vous comment obtenir le niveau de confiance en utilisant sklearn.linear_model.LinearRegression? Merci.
Huanian Zhang

1
@HuanianZhang qu'entendez-vous par niveau de confiance? Si vous voulez le coefficient de détermination, la scoreméthode le fera; sklearn.metricsa d'autres critères d'évaluation du modèle. Si vous voulez les choses comme dans la réponse d'Akavall, statsmodels a des diagnostics plus R-like.
Dougal

60

Voici un petit travail autour que j'ai créé. Je l'ai vérifié avec R et cela fonctionne correctement.

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

Résultat:

print reg_m(y, x).summary()

Production:

                            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 fournit un moyen pratique d'exécuter OLS comme indiqué dans cette réponse:

Exécuter une régression OLS avec Pandas Data Frame


18
La reg_mfonction est inutilement compliquée. x = np.array(x).T, x = sm.add_constant(x)et results = sm.OLS(endog=y, exog=x).fit()c'est assez.
cd98

1
C'est un bel outil. Posez simplement une question: dans ce cas, la valeur t est en dehors de l'intervalle de confiance de 95,5%, cela signifie donc que cet ajustement n'est pas du tout précis, ou comment expliquez-vous cela?
Huanian Zhang

2
Vous venez de remarquer que vos x1, x2, x3 sont dans l'ordre inverse dans votre liste de prédicteurs d'origine, c'est-à-dire x = [x3, x2, x1]?
sophiadw

@sophiadw, vous pouvez simplement ajouter x = x[::-1]dans la définition de la fonction pour être dans le bon ordre
Ashrith

@HuanianZhang "valeur t" est juste combien d'écarts types le coefficient est éloigné de zéro, tandis que 95% IC est approximativement coef +- 2 * std err(en fait la distribution Student-t paramétrée par degrés de liberté dans les résidus). c'est-à-dire que des valeurs t absolues plus élevées impliquent des IC plus éloignés de zéro, mais elles ne doivent pas être comparées directement. la clarification est un peu tardive, mais j'espère qu'elle sera utile à quelqu'un
Sam Mason

47

Juste pour clarifier, l'exemple que vous avez donné est une régression linéaire multiple , pas une régression linéaire multivariée . Différence :

Le cas le plus simple d'une variable prédictive scalaire unique x et d'une variable de réponse scalaire unique y est appelé régression linéaire simple. L'extension aux variables prédictives à valeurs multiples et / ou vectorielles (désignées par un X majuscule) est connue sous le nom de régression linéaire multiple, également appelée régression linéaire multivariée. Presque tous les modèles de régression du monde réel impliquent plusieurs prédicteurs, et les descriptions de base de la régression linéaire sont souvent formulées en termes de modèle de régression multiple. Notez cependant que dans ces cas, la variable de réponse y est toujours un scalaire. Un autre terme de régression linéaire multivariée fait référence aux cas où y est un vecteur, c'est-à-dire identique à la régression linéaire générale.

En bref:

  • régression linéaire multiple : la réponse y est un scalaire.
  • régression linéaire multivariée : la réponse y est un vecteur.

(Une autre source .)


5
Cela peut être une information utile, mais je ne vois pas comment cela répond à la question.
Akavall

7
@Akavall en utilisant la terminologie correcte est la première étape pour trouver une réponse.
Franck Dernoncourt

1
@FranckDernoncourt mais la valeur Y de OP EST un vecteur?
alwaysaskingquestions

@FranckDernoncourt: "utiliser la bonne terminologie est la première étape pour trouver une réponse" . Génial, donc nous pouvons tous les deux être d'accord: ce n'est pas en soi une réponse. Les utilisateurs doivent pouvoir résoudre leur problème directement à partir des réponses sans avoir à rechercher d'autres ressources .
Mac

28

Vous pouvez utiliser 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

Résultat:

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

Vous pouvez voir la sortie estimée avec:

print np.dot(X,beta_hat)

Résultat:

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

puis-je savoir quelle est la différence entre print np.dot (X, beta_hat) ... et mod_wls = sm.WLS (y, X, poids = poids) res = mod_wls.fit () predsY = res.predict () ils tous renvoie le résultat Y
jj90p

13

Utilisez scipy.optimize.curve_fit. Et pas seulement pour l'ajustement linéaire.

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

Une fois que vous avez converti vos données en un dataframe pandas ( 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)

Le terme d'interception est inclus par défaut.

Consultez ce cahier pour plus d'exemples.


Ce cahier est génial. il montre comment régresser plusieurs variables indépendantes (x1, x2, x3 ...) sur Y avec seulement 3 lignes de code et en utilisant scikit learn.
jxn

@canary_in_the_data_mine merci pour le cahier. Comment puis-je tracer une régression linéaire comportant plusieurs caractéristiques? Je n'ai pas pu trouver dans le cahier. tous les pointeurs seront grandement appréciés. - Merci
Jai Prakash

Ajoute-t-il l'interception parce que nous devons ajouter l'interception en passant smf.add_intercept () comme paramètre à ols ()
bluedroid

4

Je pense que c'est peut-être le moyen le plus simple de terminer ce travail:

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 régression linéaire multiple peut être gérée à l'aide de la bibliothèque sklearn comme indiqué ci-dessus. J'utilise l'installation Anaconda de Python 3.6.

Créez votre modèle comme suit:

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

# display coefficients
print(regressor.coef_)

3

Vous pouvez utiliser numpy.linalg.lstsq


6
Comment pouvez-vous utiliser cela pour obtenir les coefficients d'une régression multivariée? Je ne vois que comment faire une simple régression ... et je ne vois pas comment obtenir les coefficients ..
Zach

1

Vous pouvez utiliser la fonction ci-dessous et lui passer 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 est une bibliothèque d'apprentissage automatique pour Python qui peut faire ce travail pour vous. Importez simplement le module sklearn.linear_model dans votre script.

Trouvez le modèle de code pour la régression linéaire multiple à l'aide de sklearn en 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)

C'est tout. Vous pouvez utiliser ce code comme modèle pour implémenter la régression linéaire multiple dans n'importe quel ensemble de données. Pour une meilleure compréhension avec un exemple, visitez: Régression linéaire avec un exemple


0

Voici une méthode alternative et basique:

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

Au lieu de sm.OLSvous pouvez également utiliser sm.Logitou sm.Probitet etc.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.