Багаторазова лінійна регресія в Python


129

Я, здається, не можу знайти жодної бібліотеки python, яка б робила множинні регресії. Єдине, що я знаходжу, - це лише проста регресія. Мені потрібно регресувати залежну змінну (y) проти кількох незалежних змінних (x1, x2, x3 тощо).

Наприклад, з цими даними:

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)

(вихід вище :)

      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

Як би я регресував у python, щоб отримати формулу лінійної регресії:

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


не експерт, але якщо змінні є незалежними, чи не можна просто провести регресію проти кожної і підбити підсумок?
Х'ю Ботвелл

8
@HughBothwell Не можна вважати, що змінні незалежні. Насправді, якщо ви припускаєте, що змінні незалежні, можливо, ви можете неправильно моделювати свої дані. Іншими словами, відповіді Yможуть бути співвіднесені між собою, але якщо припустити незалежність не точно моделює набір даних.
hlin117

@HughBothwell вибачте, якщо це сумнівне запитання, але чому це важливо, якщо невід'ємні змінні функції x_i незалежні чи ні? Як це впливає на предиктора (= модель)?
Чарлі Паркер

Відповіді:


100

sklearn.linear_model.LinearRegression зробимо це:

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

Тоді clf.coef_будуть коефіцієнти регресії.

sklearn.linear_model також має подібні інтерфейси для виконання різного роду регуляризацій на регресії.


2
Це повертає помилку з певними входами . Будь-які інші рішення доступні?
Зак

@Dougal може sklearn.linear_model.LinearRegression використовуватись і для зваженої багатоваріантної регресії?
користувач961627

1
Щоб відповідати постійному терміну: clf = linear_model.LinearRegression (fit_intercept = True)
Імран

2
Слідкуйте, чи знаєте ви, як отримати рівень довіри за допомогою sklearn.linear_model.LinearRegression? Дякую.
Хуаніан Чжан

1
@HuanianZhang, що ти маєш на увазі під рівнем довіри? Якщо ви хочете коефіцієнт визначення, scoreметод зробить це; sklearn.metricsє деякі інші критерії оцінювання моделі. Якщо ви хочете, щоб такі речі, як у відповіді Akavall, statsmodels має ще одну R-подібну діагностику.
Дугал

60

Ось невеличка робота навколо того, що я створив. Я перевірив це за допомогою R, і він працює правильно.

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

Результат:

print reg_m(y, x).summary()

Вихід:

                            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 надає зручний спосіб запуску OLS, як зазначено у цій відповіді:

Запустіть регресію OLS з фреймом даних Pandas


18
reg_mФункція надмірно складна. x = np.array(x).T, x = sm.add_constant(x)і results = sm.OLS(endog=y, exog=x).fit()досить.
cd98

1
Це приємний інструмент. Просто задайте одне запитання: у цьому випадку значення t знаходиться за межами довірчого інтервалу 95,5%, тож це означає, що ця суміш зовсім не точна, або як ви це поясните?
Хуаніан Чжан

2
Щойно помітили, що ваші x1, x2, x3 у зворотному порядку у вашому первісному списку прогнозів, тобто x = [x3, x2, x1]?
sophiadw

@sophiadw ви можете просто додати x = x[::-1]до визначення функції, щоб
навести

@HuanianZhang "t значення" - це лише те, скільки стандартних відхилень коефіцієнт відходить до нуля, тоді як 95% CI - це приблизно coef +- 2 * std err(фактично розподіл Стьюдента-t, параметризований за ступенем свободи в залишках). тобто великі абсолютні величини t означають, що ІС далі від нуля, але їх не слід безпосередньо порівнювати. уточнення трохи пізно, але сподіваюся, що комусь це стане в нагоді
Сем Мейсон

47

Просто для уточнення, приклад, який ви подали, - це множинна лінійна регресія, а не багатовимірна лінійна регресія. Різниця :

Найпростіший випадок одиночної скалярної змінної предиктора x та однієї змінної скалярної відповіді y відомий як проста лінійна регресія. Розширення на множинні та / або векторні значення предиктора прогнозу (позначається з великої літери X) відоме як множинна лінійна регресія, також відома як багатовимірна лінійна регресія. Майже всі регресійні моделі реального рекреації включають багато предикторів, а основні описи лінійної регресії часто формулюються в рамках моделі множинної регресії. Зауважте, що в цих випадках змінна відповіді y все ще є скалярною. Інший термін багатоваріантна лінійна регресія відноситься до випадків, коли y - вектор, тобто такий же, як загальна лінійна регресія.

Коротко:

  • множинна лінійна регресія: відповідь y - скалярна.
  • багатоваріантна лінійна регресія: відповідь y - вектор.

(Інше джерело .)


5
Це може бути корисною інформацією, але я не бачу, як вона відповідає на питання.
Акавал

7
@Akavall з використанням правильної термінології є першим кроком для пошуку відповіді.
Franck Dernoncourt

1
@FranckDernoncourt, але значення Y ОП - це вектор?
завждизапитання

@FranckDernoncourt: "використання правильної термінології є першим кроком для пошуку відповіді" . Чудово, тому ми обидва можемо погодитися: саме по собі це насправді не відповідь. Користувачі повинні мати можливість вирішувати свою проблему безпосередньо з відповідей, не вдаючись до пошуку інших ресурсів .
Мак

28

Ви можете використовувати 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

Результат:

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

Розрахунковий результат можна побачити за допомогою:

print np.dot(X,beta_hat)

Результат:

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

чи можу я знати, в чому різниця між print np.dot (X, beta_hat) ... та mod_wls = sm.WLS (y, X, ваги = ваги) res = mod_wls.fit () predsY = res.predict () вони всі повернути результат Y
dd90p

13

Використовуйте scipy.optimize.curve_fit. І не тільки для лінійної підгонки.

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

Після перетворення даних у рамки даних панди ( 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)

Термін перехоплення включається за замовчуванням.

Дивіться цей зошит для додаткових прикладів.


Цей зошит є приголомшливим. він показує, як регресувати декілька незалежних змінних (x1, x2, x3 ...) на Y, використовуючи лише 3 рядки коду та використовуючи scikit learn.
jxn

@canary_in_the_data_mine дякую за ноутбук. Як я можу побудувати лінійну регресію, яка має кілька функцій? Я не зміг знайти в зошиті. будь-які вказівники будуть дуже вдячні. - Спасибі
Джай Пракаш

Чи додає це перехоплення, тому що ми повинні додати перехоплення, передаючи smf.add_intercept () як параметр ols ()
bluedroid

4

Я думаю, що це може бути найпростішим способом закінчити цю роботу:

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

Кілька лінійних регресій можна обробляти за допомогою бібліотеки sklearn, як зазначено вище. Я використовую встановлення Anaconda Python 3.6.

Створіть свою модель наступним чином:

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

# display coefficients
print(regressor.coef_)

3

Ви можете використовувати numpy.linalg.lstsq


6
Як ви можете використовувати це для отримання коефіцієнтів багатоваріантної регресії? Я бачу лише, як зробити просту регресію ... і не бачу, як отримати коефіцієнти ..
Зак

1

Ви можете скористатися функцією нижче та передати їй 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 - це бібліотека машинного навчання для Python, яка може зробити цю роботу за вас. Просто імпортуйте модуль sklearn.linear_model у свій сценарій.

Знайдіть шаблон коду для множинної лінійної регресії за допомогою sklearn в 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)

Це воно. Ви можете використовувати цей код як шаблон для реалізації декількох лінійних регресій у будь-якому наборі даних. Для кращого розуміння на прикладі, відвідайте: Лінійна регресія з прикладом


0

Ось альтернативний та основний метод:

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

Замість sm.OLSвас також можна використовувати sm.Logitабо sm.Probitі і т.д.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.