Regresión lineal múltiple en Python

129

Parece que no puedo encontrar ninguna biblioteca de Python que haga regresión múltiple. Las únicas cosas que encuentro solo hacen una regresión simple. Necesito retroceder mi variable dependiente (y) contra varias variables independientes (x1, x2, x3, etc.).

Por ejemplo, con estos datos:

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)

(salida para arriba :)

      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

¿Cómo haría retroceder estos en python, para obtener la fórmula de regresión lineal:

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

Zach
fuente
no es un experto, pero si las variables son independientes, ¿no puede simplemente ejecutar una regresión simple contra cada una y sumar el resultado?
Hugh Bothwell
8
@HughBothwell Sin embargo, no puede asumir que las variables son independientes. De hecho, si está asumiendo que las variables son independientes, es posible que esté modelando sus datos incorrectamente. En otras palabras, las respuestas Ypueden estar correlacionadas entre sí, pero asumir que la independencia no modela con precisión el conjunto de datos.
hlin117
@HughBothwell lo siento si es una pregunta tonta, pero ¿por qué importa si las variables de función sin procesar x_i son independientes o no? ¿Cómo afecta eso al predictor (= modelo)?
Charlie Parker

Respuestas:

100

sklearn.linear_model.LinearRegression lo haré:

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

Entonces clf.coef_tendrá los coeficientes de regresión.

sklearn.linear_model También tiene interfaces similares para hacer varios tipos de regularizaciones en la regresión.

Dougal
fuente
2
Esto devuelve un error con ciertas entradas . ¿Alguna otra solución disponible?
Zach
@Dougal ¿se puede utilizar sklearn.linear_model.LinearRegression para la regresión multivariada ponderada también?
user961627
1
Para ajustar un término constante: clf = linear_model.LinearRegression (fit_intercept = True)
Imran
2
Seguimiento, ¿sabes cómo obtener el nivel de confianza usando sklearn.linear_model.LinearRegression? Gracias.
Huanian Zhang
1
@HuanianZhang, ¿qué quieres decir con nivel de confianza? Si desea el coeficiente de determinación, el scoremétodo lo hará; sklearn.metricstiene algunos otros criterios de evaluación del modelo. Si quieres cosas como en la respuesta de Akavall, statsmodels tiene más diagnósticos similares a R.
Dougal
60

Aquí hay un poco de trabajo que creé. Lo revisé con R y funciona correctamente.

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

Resultado:

print reg_m(y, x).summary()

Salida:

                            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 proporciona una forma conveniente de ejecutar OLS como se indica en esta respuesta:

Ejecute una regresión de OLS con el marco de datos de Pandas

Akavall
fuente
18
La reg_mfunción es innecesariamente complicada. x = np.array(x).T, x = sm.add_constant(x)Y results = sm.OLS(endog=y, exog=x).fit()es suficiente.
cd98
1
Esta es una buena herramienta. Solo haga una pregunta: en este caso, el valor t está fuera del intervalo de confianza del 95.5%, por lo que significa que este ajuste no es exacto en absoluto, o ¿cómo explica esto?
Huanian Zhang
2
¿Acabas de notar que tus x1, x2, x3 están en orden inverso en tu lista de predictores original, es decir, x = [x3, x2, x1]?
sophiadw
@sophiadw simplemente puede agregar x = x[::-1]dentro de la definición de función para obtener el orden correcto
Ashrith
El "valor t" de @HuanianZhang es la cantidad de desviaciones estándar que el coeficiente está lejos de cero, mientras que el IC del 95% es aproximadamente coef +- 2 * std err(en realidad, la distribución de Student-t parametrizada por los grados de libertad en los residuos). es decir, los valores de t absolutos más grandes implican CI más lejos de cero, pero no deben compararse directamente. la aclaración es un poco tarde, pero espero que sea útil para alguien
Sam Mason
47

Solo para aclarar, el ejemplo que dio es la regresión lineal múltiple , no la referencia de regresión lineal multivariante . Diferencia :

El caso más simple de una variable de predicción escalar simple xy una variable de respuesta escalar única y se conoce como regresión lineal simple. La extensión a variables predictoras múltiples y / o de valor vectorial (denotadas con una X mayúscula) se conoce como regresión lineal múltiple, también conocida como regresión lineal multivariable. Casi todos los modelos de regresión del mundo real involucran múltiples predictores, y las descripciones básicas de la regresión lineal a menudo se expresan en términos del modelo de regresión múltiple. Sin embargo, tenga en cuenta que en estos casos la variable de respuesta y sigue siendo escalar. Otro término de regresión lineal multivariante se refiere a casos en los que y es un vector, es decir, lo mismo que la regresión lineal general.

En breve:

  • regresión lineal múltiple : la respuesta y es escalar.
  • regresión lineal multivariante : la respuesta y es un vector.

(Otra fuente ).

Franck Dernoncourt
fuente
55
Esta podría ser información útil, pero no veo cómo responde la pregunta.
Akavall
77
@Akavall utilizando la terminología correcta es el primer paso para encontrar una respuesta.
Franck Dernoncourt
1
@FranckDernoncourt pero el valor Y de OP ¿ES un vector?
alwaysaskingquestions
@FranckDernoncourt: "usar la terminología correcta es el primer paso para encontrar una respuesta" . Genial, por lo que ambos podemos estar de acuerdo: esto, en sí mismo, no es en realidad una respuesta. Los usuarios deberían poder resolver su problema directamente de las respuestas sin tener que recurrir a buscar otros recursos .
Mac
28

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

Resultado:

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

Puede ver la salida estimada con:

print np.dot(X,beta_hat)

Resultado:

[ -5.97751163,  -5.06465759, -10.16873217,  -4.96959788,  -7.96356915,  -3.06176313,  -6.01818435,  -7.90878145,  -7.86720264]
Imran
fuente
¿puedo saber cuál es la diferencia entre print np.dot (X, beta_hat) ... y mod_wls = sm.WLS (y, X, weights = weights) res = mod_wls.fit () predsY = res.predict () todos devolver el resultado Y
dd90p
13

Uso scipy.optimize.curve_fit. Y no solo para ajuste lineal.

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
Volodimir Kopey
fuente
8

Una vez que convierta sus datos en un marco de datos de 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)

El término de intercepción se incluye por defecto.

Vea este cuaderno para más ejemplos.

canary_in_the_data_mine
fuente
Este cuaderno es asombroso. muestra cómo hacer retroceder múltiples variables independientes (x1, x2, x3 ...) en Y con solo 3 líneas de código y usando scikit learn.
jxn
@canary_in_the_data_mine gracias por el cuaderno. ¿Cómo puedo trazar la regresión lineal que tiene múltiples características? No pude encontrar en el cuaderno. Cualquier puntero será muy apreciado. - Gracias
Jai Prakash
¿Agrega la intersección porque tenemos que agregar la intersección pasando smf.add_intercept () como parámetro a ols ()
Bluedroid
4

Creo que esta puede ser la forma más fácil de terminar este trabajo:

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
==============================================================================
xmduhan
fuente
4

La regresión lineal múltiple se puede manejar utilizando la biblioteca sklearn como se mencionó anteriormente. Estoy usando la instalación Anaconda de Python 3.6.

Crea tu modelo de la siguiente manera:

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

# display coefficients
print(regressor.coef_)
Eric C. Bohn
fuente
3

Puedes usar numpy.linalg.lstsq

Moukden
fuente
66
¿Cómo puedes usar esto para obtener los coeficientes de una regresión multivariada? Solo veo cómo hacer una regresión simple ... y no veo cómo obtener los coeficientes ..
Zach
1

Puede usar la siguiente función y pasarle 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
Alfa
fuente
1

Scikit-learn es una biblioteca de aprendizaje automático para Python que puede hacer este trabajo por usted. Simplemente importe el módulo sklearn.linear_model a su script.

Encuentre la plantilla de código para Regresión lineal múltiple usando 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)

Eso es. Puede usar este código como plantilla para implementar Regresión lineal múltiple en cualquier conjunto de datos. Para una mejor comprensión con un ejemplo, visite: Regresión lineal con un ejemplo

kowsalya_ckar
fuente
0

Aquí hay un método alternativo y básico:

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

En lugar de sm.OLSusted también puede usar sm.Logito sm.Probity etc.

novato
fuente