Regressão linear múltipla em Python

129

Não consigo encontrar nenhuma biblioteca python que faça regressão múltipla. As únicas coisas que acho apenas fazem uma regressão simples. Eu preciso regredir minha variável dependente (y) contra várias variáveis ​​independentes (x1, x2, x3, etc.).

Por exemplo, com esses dados:

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)

(saída para acima :)

      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

Como eu os regrediria em python, para obter a fórmula de regressão linear:

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

Zach
fonte
não é um especialista, mas se as variáveis ​​são independentes, você não pode simplesmente executar uma regressão simples em cada uma delas e somar o resultado?
21412 Hugh Bothwell
8
@HughBothwell Você não pode assumir que as variáveis ​​são independentes. De fato, se você estiver assumindo que as variáveis ​​são independentes, é possível que esteja modelando seus dados incorretamente. Em outras palavras, as respostas Ypodem ser correlacionadas entre si, mas supondo que a independência não modele com precisão o conjunto de dados.
hlin117
@HughBothwell desculpe se isso é uma pergunta dum, mas por que importa se as variáveis ​​brutas do recurso x_i são independentes ou não? Como isso afeta o preditor (= modelo)?
Charlie Parker

Respostas:

100

sklearn.linear_model.LinearRegression vai fazer isso:

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

Então clf.coef_terá os coeficientes de regressão.

sklearn.linear_model também possui interfaces semelhantes para fazer vários tipos de regularizações na regressão.

Dougal
fonte
2
Isso retorna um erro com determinadas entradas . Alguma outra solução disponível?
Zach
@Dougal sklearn.linear_model.LinearRegression também pode ser usado para regressão multivariada ponderada ?
User961627
1
Para ajustar um termo constante: clf = linear_model.LinearRegression (fit_intercept = true)
Imran
2
Acompanhamento, você sabe como obter o nível de confiança usando sklearn.linear_model.LinearRegression? Obrigado.
Huanian Zhang 17/03/16
1
@HuanianZhang, o que você quer dizer com nível de confiança? Se você deseja o coeficiente de determinação, o scoremétodo o fará; sklearn.metricspossui alguns outros critérios de avaliação de modelo. Se você deseja coisas como as da resposta de Akavall, o statsmodels tem mais diagnósticos do tipo R.
Dougal
60

Aqui está um pequeno trabalho que eu criei. Eu verifiquei com R e funciona corretamente.

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

Resultado:

                            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 fornece uma maneira conveniente de executar o OLS, conforme fornecido nesta resposta:

Execute uma regressão OLS com o Pandas Data Frame

Akavall
fonte
18
A reg_mfunção é desnecessariamente complicada. x = np.array(x).T, x = sm.add_constant(x)E results = sm.OLS(endog=y, exog=x).fit()é suficiente.
Cd98
1
Esta é uma boa ferramenta. Basta fazer uma pergunta: nesse caso, o valor t está fora do intervalo de confiança de 95,5%, portanto, significa que esse ajuste não é preciso, ou como você explica isso?
Huanian Zhang 17/03/16
2
Acabei de notar que seus x1, x2, x3 estão na ordem inversa na sua lista de preditores original, ou seja, x = [x3, x2, x1]?
Sophiadw
@sophiadw você pode apenas adicionar x = x[::-1]dentro de definição de função para entrar em ordem certa
Ashrith
@HuanianZhang "valor t" é quantos desvios padrão o coeficiente está longe de zero, enquanto o IC 95% é aproximadamente coef +- 2 * std err(na verdade, a distribuição Student-t parametrizada por graus de liberdade nos resíduos). isto é, valores absolutos maiores de t implicam ICs além de zero, mas eles não devem ser comparados diretamente. esclarecimento é um pouco tarde, mas espero que seja útil para alguém
Sam Mason
47

Só para esclarecer, o exemplo que você deu é múltipla regressão linear, não multivariada de regressão linear referem. Diferença :

O caso mais simples de uma única variável preditora escalar x e uma única variável de resposta escalar y é conhecido como regressão linear simples. A extensão para variáveis ​​preditivas múltiplas e / ou com valor vetorial (denotadas com X maiúsculo) é conhecida como regressão linear múltipla, também conhecida como regressão linear multivariável. Quase todos os modelos de regressão do mundo real envolvem múltiplos preditores, e as descrições básicas da regressão linear são frequentemente formuladas em termos do modelo de regressão múltipla. Observe, no entanto, que nesses casos a variável de resposta y ainda é um escalar. Outro termo regressão linear multivariada refere-se a casos em que y é um vetor, ou seja, o mesmo que regressão linear geral.

Em resumo:

  • múltiplo de regressão linear: a resposta y é um escalar.
  • multivariada de regressão linear: a resposta y é um vector.

(Outra fonte .)

Franck Dernoncourt
fonte
5
Pode ser uma informação útil, mas não vejo como ela responde à pergunta.
Akavall
7
@ Akavall usando a terminologia correta é o primeiro passo para encontrar uma resposta.
Franck Dernoncourt
1
@FranckDernoncourt, mas o valor Y do OP É um vetor?
alwaysaskingquestions
@FranckDernoncourt: "usar a terminologia correta é o primeiro passo para encontrar uma resposta" . Ótimo, então nós dois podemos concordar: isso, por si só, não é realmente uma resposta. Os usuários devem poder resolver seu problema diretamente a partir de respostas sem precisar recorrer a outros recursos .
Mac
28

Você pode 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]

Você pode ver a produção estimada com:

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
fonte
posso saber qual é a diferença entre print np.dot (X, beta_hat) ... e mod_wls = sm.WLS (y, X, pesos = pesos) res = mod_wls.fit () predsY = res.predict () todos retornar o resultado Y
dd90p 14/12/16
13

Use scipy.optimize.curve_fit. E não apenas para ajuste linear.

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

Depois de converter seus dados em um dataframe do 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)

O termo de interceptação é incluído por padrão.

Veja este caderno para mais exemplos.

canary_in_the_data_mine
fonte
Este caderno é incrível. mostra como regredir várias variáveis ​​independentes (x1, x2, x3 ...) em Y com apenas 3 linhas de código e usando o scikit learn.
Jxn 28/08/16
@canary_in_the_data_mine obrigado pelo notebook. Como posso traçar regressão linear com vários recursos? Não consegui encontrar no caderno. quaisquer ponteiros serão muito apreciados. Obrigado
Jai Prakash
Ela acrescenta a interceptação porque temos de acrescentar a interceptação passando smf.add_intercept () como um parâmetro para ols ()
bluedroid
4

Eu acho que essa pode ser a maneira mais fácil de concluir este trabalho:

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

A regressão linear múltipla pode ser manipulada usando a biblioteca sklearn, conforme mencionado acima. Estou usando a instalação Anaconda do Python 3.6.

Crie seu modelo da seguinte maneira:

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

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

Você pode usar numpy.linalg.lstsq

Moukden
fonte
6
Como você pode usar isso para obter os coeficientes de uma regressão multivariada? Eu só ver como fazer uma regressão simples ... e não vê como obter os coefficents ..
Zach
1

Você pode usar a função abaixo e transmitir um 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
fonte
1

O Scikit-learn é uma biblioteca de aprendizado de máquina para Python que pode fazer esse trabalho para você. Apenas importe o módulo sklearn.linear_model para o seu script.

Encontre o modelo de código para regressão linear múltipla usando o sklearn no 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)

É isso aí. Você pode usar esse código como um modelo para implementar a regressão linear múltipla em qualquer conjunto de dados. Para uma melhor compreensão de um exemplo, visite: Regressão linear com um exemplo

kowsalya_ckar
fonte
0

Aqui está um método alternativo e 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())

Em vez de sm.OLSvocê também pode usar sm.Logitor sm.Probite etc.

novato
fonte