การถดถอยเชิงเส้นพหุคูณใน Python


130

ฉันไม่พบไลบรารี 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


ไม่ใช่ผู้เชี่ยวชาญ แต่ถ้าตัวแปรเป็นอิสระคุณไม่สามารถเรียกใช้การถดถอยอย่างง่ายกับแต่ละตัวแปรและสรุปผลลัพธ์ได้หรือไม่?
Hugh Bothwell

8
@HughBothwell คุณไม่สามารถสันนิษฐานได้ว่าตัวแปรเป็นอิสระ ในความเป็นจริงหากคุณสมมติว่าตัวแปรเป็นอิสระคุณอาจจำลองข้อมูลของคุณไม่ถูกต้อง กล่าวอีกนัยหนึ่งคำตอบYอาจมีความสัมพันธ์กัน แต่การพิจารณาความเป็นอิสระไม่ได้จำลองชุดข้อมูลอย่างถูกต้อง
hlin117

@HughBothwell ขออภัยหากนี่เป็นคำถามหลอกลวง แต่ทำไมจึงมีความสำคัญว่าตัวแปรคุณลักษณะดิบ x_i เป็นอิสระหรือไม่? สิ่งนั้นมีผลต่อตัวทำนาย (= model) อย่างไร?
Charlie Parker

คำตอบ:


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 นอกจากนี้ยังมีอินเทอร์เฟซที่คล้ายกันในการทำ normalization ต่างๆเกี่ยวกับการถดถอย


2
นี้จะส่งกลับข้อผิดพลาดกับบางปัจจัยการผลิต มีโซลูชันอื่น ๆ อีกไหม
Zach

@Dougal สามารถใช้ sklearn.linear_model.LinearRegression สำหรับการถดถอยหลายตัวแปรแบบถ่วงน้ำหนักได้ด้วยหรือไม่
user961627

1
เพื่อให้พอดีกับระยะคงที่: clf = linear_model.LinearRegression (fit_intercept = True)
Imran

2
ติดตามผลคุณรู้วิธีรับระดับความมั่นใจโดยใช้ sklearn.linear_model.LinearRegression หรือไม่? ขอบคุณ
Huanian Zhang

1
@HuanianZhang ระดับความมั่นใจหมายความว่ายังไง? หากคุณต้องการค่าสัมประสิทธิ์การกำหนดscoreวิธีการจะทำ sklearn.metricsมีเกณฑ์การประเมินรูปแบบอื่น ๆ หากคุณต้องการสิ่งต่างๆเช่นในคำตอบของ Akavall statsmodels จะมีการวินิจฉัยแบบ R เพิ่มเติม
Dougal

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 Data Frame


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% ดังนั้นจึงหมายความว่าการติดตั้งนี้ไม่แม่นยำเลยหรือคุณจะอธิบายสิ่งนี้อย่างไร
Huanian Zhang

2
เพิ่งสังเกตว่า x1, x2, x3 ของคุณอยู่ในลำดับย้อนกลับในรายการทำนายเดิมของคุณเช่น x = [x3, x2, x1]?
sophiadw

@sophiadw คุณสามารถเพิ่มx = x[::-1]ภายในนิยามฟังก์ชันเพื่อให้ได้ลำดับที่ถูกต้อง
Ashrith

@HuanianZhang "ค่า t" คือจำนวนค่าเบี่ยงเบนมาตรฐานที่ค่าสัมประสิทธิ์อยู่ห่างจากศูนย์ในขณะที่ 95% CI มีค่าประมาณcoef +- 2 * std err(ที่จริงแล้วการแจกแจง Student-t กำหนดพารามิเตอร์โดยองศาอิสระในส่วนที่เหลือ) นั่นคือค่า t สัมบูรณ์ที่ใหญ่กว่าหมายถึง CI ที่ห่างจากศูนย์ แต่ไม่ควรเปรียบเทียบโดยตรง การชี้แจงช้าไปหน่อย แต่หวังว่าจะมีประโยชน์กับใครบางคน
Sam Mason

47

เพียงชี้แจงตัวอย่างที่คุณให้เป็นหลายถดถอยเชิงเส้นไม่หลายตัวแปรการถดถอยเชิงเส้นดู ความแตกต่าง :

กรณีที่ง่ายที่สุดของตัวแปรทำนายสเกลาร์ตัวเดียว x และตัวแปรตอบสนองสเกลาร์เดียว y เรียกว่าการถดถอยเชิงเส้นอย่างง่าย ส่วนขยายไปยังตัวแปรทำนายค่าพหุคูณและ / หรือเวกเตอร์ (แสดงด้วยตัวพิมพ์ใหญ่ X) เรียกว่าการถดถอยเชิงเส้นพหุคูณหรือที่เรียกว่าการถดถอยเชิงเส้นหลายตัวแปร แบบจำลองการถดถอยในโลกแห่งความเป็นจริงเกือบทั้งหมดเกี่ยวข้องกับตัวทำนายหลายตัวและคำอธิบายพื้นฐานของการถดถอยเชิงเส้นมักใช้ในรูปแบบการถดถอยพหุคูณ อย่างไรก็ตามโปรดทราบว่าในกรณีเหล่านี้ตัวแปรตอบกลับ y ยังคงเป็นสเกลาร์ อีกคำว่าการถดถอยเชิงเส้นหลายตัวแปรหมายถึงกรณีที่ y เป็นเวกเตอร์กล่าวคือเหมือนกับการถดถอยเชิงเส้นทั่วไป

ในระยะสั้น:

  • หลายถดถอยเชิงเส้น: Y ตอบเป็นสเกลา
  • การถดถอยเชิงเส้นหลายตัวแปร : การตอบสนอง y เป็นเวกเตอร์

( แหล่งข้อมูลอื่น)


5
นี่อาจเป็นข้อมูลที่มีประโยชน์ แต่ฉันไม่เห็นว่ามันตอบคำถามอย่างไร
Akavall

7
@Akavall ใช้คำศัพท์ที่ถูกต้องเป็นขั้นตอนแรกในการหาคำตอบ
Franck Dernoncourt

1
@FranckDernoncourt แต่ค่า Y ของ OP เป็นเวกเตอร์?
alwaysaskingquestions

@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, weights = weights) 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 ขอบคุณสำหรับสมุดบันทึก ฉันจะพล็อตการถดถอยเชิงเส้นซึ่งมีคุณสมบัติหลายอย่างได้อย่างไร ฉันไม่พบในสมุดบันทึก คำแนะนำใด ๆ จะได้รับการชื่นชมอย่างมาก - Thanks
Jai Prakash

มันเพิ่มการสกัดกั้นหรือไม่เพราะเราต้องเพิ่มการสกัดกั้นโดยส่ง 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
คุณจะใช้สิ่งนี้เพื่อหาค่าสัมประสิทธิ์ของการถดถอยหลายตัวแปรได้อย่างไร? ฉันเห็นเพียงวิธีการถดถอยอย่างง่าย ... และไม่เห็นวิธีรับสัมประสิทธิ์ ..
Zach

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 ลงในสคริปต์ของคุณ

ค้นหาเทมเพลตโค้ดสำหรับ Multiple Linear Regression โดยใช้ 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)

แค่นั้นแหละ. คุณสามารถใช้รหัสนี้เป็นเทมเพลตสำหรับการใช้งาน Multiple Linear Regression ในชุดข้อมูลใด ๆ เพื่อความเข้าใจที่ดีขึ้นด้วยตัวอย่าง Visit: Linear Regression พร้อมตัวอย่าง


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และอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.