機器學習A-Z~多元線性迴歸

之前的文章已經講述了簡單線性迴歸的概念和代碼實現,現在來繼續看看多元線性迴歸。所謂多元線性迴歸其實就是自變量的個數變多了,之前的簡單線性迴歸方程可以表示爲:$y=b_0 +bx$,那麼在多元中則是$y=b_0+b_1x_1+b_2x_2+...+b_nx_n$。

線性迴歸的幾個前置條件

在正式使用多元線性迴歸之前,我們先談談關於線性迴歸的幾個前置條件,首先,在線性迴歸中有幾個重要的假設如下所示:

  1. Linearity 線性 (數據呈線性關係)
  2. Homoscedasticity 同方差性(數據要有相同的方差)
  3. Multivariate normality 多元正態分佈 (數據要呈現多元正態分佈)
  4. Independence of errors 誤差獨立 (各個維度上的誤差相互獨立)
  5. Lack of multicollinearity 無多重共線性 (沒有一個自變量和另外的自變量存在線性關係)

也就是說我們在使用線性迴歸時,要考慮到實際情況是否吻合上述的幾種假設,否則可能會導致擬合的模型不準確。

除此之外,之前數據預處理的時候也提到過一個叫做虛擬變量的概念,現在對其進行詳細的講解。來看下面的數據集(同樣由於篇幅問題只提供部分):

R&D Spend Administration Marketing Spend State Profit
165349.2 136897.8 471784.1 New York 192261.83
162597.7 151377.59 443898.53 California 191792.06
153441.51 101145.55 407934.54 Florida 191050.39
144372.41 118671.85 383199.62 New York 182901.99

這組數據集反映的是公司的研發投入,行政支出,市場支出以及所在地點對於公司的收益的影響。其中所在地點這個變量是個分類變量,沒有數值的概念,因此無法對其進行排序或者帶入方程。數據預處理中,我們使用了虛擬變量對其進行重新編碼,那麼對於這組數據我們也可以做同樣的操作,也就是說State這列數據可以拆分成三列:

New York California Florida
1 0 0
0 1 0
0 0 1
1 0 0

假設R&D Spend對應的自變量爲$x_1$,Administration對應的是$x_2$,Marketing Spend對應的是$x_3$,虛擬編碼對應的是$D_1$,$D_2$,$D_3$。但是對於虛擬編碼,任意一個編碼都能用另外兩個來表示,比如是否是Florida,那麼如果New York和California如果存在1,則肯定不是Florida,否則就是Florida。那麼可以定義其多元線性迴歸方程爲:

$$ y = b_0 + b_1*x_1 + b_2*x_2 + b_3*x_3 + b_4*D_1 + b_5*D_2 $$

這裏順便一提,我們這裏給予虛擬變量的值是0和1,那麼如果是(100,0)或者(-1,1)可以嗎?答案是肯定的,比如說(100,0),那我們在方程中將前面的參數D縮小一百倍,達到的效果其實是一樣的。

接下來想想,如果把我們刪掉的$b_6*D_3$加上那麼這個方程對不對呢?其實這裏就是虛擬變量的一個陷阱。回過頭看看上面所說的關於迴歸問題的幾個假設,第五條,無多重共線性這個性質我們是否滿足了?任意一個變量實際上都可以用其他的變量來表示,比如$D_3=1-D_1-D_2$,那麼就不符合無多重共線性這個要求了。因此,在使用虛擬變量的時候一定要注意實際上使用的虛擬變量的數量應該是始終都要忽略掉一個的。

如何構建一個多元線性迴歸模型

接下來我們再談談如何一步一步地去構建一個多元線性迴歸模型。在實際應用中,往往會遇到對於一個因變量y,有很多的自變量x1,x2等等,但這些自變量不是所有的都是對這個y的預測很有幫助因素,我們需要從其中剔除掉無用的元素來得到最合適的模型,那麼此時就有一個問題,如何來選擇這些自變量呢?這裏有五種方法來建立模型:

  1. All-in
  2. Backward Elimination 反向淘汰
  3. Forward Selection 順向選擇
  4. Bidirectional Elimination 雙向淘汰
  5. Score Comparison 信息量比較

其中的2,3,4三種方式,也是我們最常用的,叫做Step Regression也就是逐步迴歸,它們的算法是類似的,只是應用的順序有點不同。接下來一種種的介紹這幾種方法。

All-in

所謂All-in,就是把所有我們認爲的自變量全扔進去,一般有這幾種情況使用:

  • Prior Knowledge 我們已經提前知道了所有的信息,知道這些所有自變量都會對模型結果有影響
  • You have to 上級需要你必須使用這些自變量
  • Preparing for Backward Elimination 爲反向淘汰做準備

All-in這個方法很簡單,但一般都是一些特殊情況下或者一些外力干涉時纔會使用,這種方法不作推薦。

Backward Elimination

反向淘汰這個算法的精髓在於對於每一個這個模型的自變量來說,他對我們的模型的預測結果其實是有影響力的,用統計學上的一個概念叫做P-value來形容它的影響力。在這裏我們先定義它的這個影響力是否顯著的一個門檻也就是一個significance level(SL),先定義爲0.05。接着第二步使用所有的自變量來擬合出一個模型。第三步,對於這個模型當中的每一個自變量都來計算它的P值(P-value),來顯示它對我們模型有多大的影響力,然後我們取這個最高的P值,假設這個P>SL,就繼續往第四步,否則就算法結束。那麼第四步,最高的P值對應的那個自變量我們就要將它從我們的模型中去除。第五步,去除了一個自變量後,在用剩下的自變量重新對模型進行擬合,因此這裏就是一個第三步到第五步的一個循環,直到所有剩下的P值都比SL要小,這樣就說明模型已經擬合好了。步驟詳情如下:

Backward Elimination

Forward Selection

順向選擇和反向淘汰的算法思想很接近,只是順序有了個顛倒。這裏第一步還是先定一個顯著性的門檻SL=0.05.第二步,我們在這邊對每個自變量$x_n$都進行簡單線性迴歸擬合,分別得到它們的P值,然後取得它們中最低的。第三步對於這個最低的P值,我們的結論就是這個自變量它對我們將要擬合的模型的影響是最大的,所以說,我們會保留這個自變量。接下來第四步我們再看剩下的自變量當中加上哪一個會給我們帶來最小的P值,假如說新的P值比我們之前定義的SL小,那就重新回到第三步,也就是第三步又加入了一個新的變量然後在接下來剩下的變量當中,重新找最大的P值,然後繼續加到模型當中,以此類推,直到剩下來的還沒有被加入模型當中的變量它們的P值全部大於SL,也就是說剩下的變量對於模型有可能產生的影響不夠顯著,那對這些就不予採納,這個時候模型就擬合好了。步驟詳情如下:

Forward Selection

Bidirectional Elimination

所謂雙向淘汰,其實就是對之前的兩種算法的結合。在第一步中,我們需要選擇兩個顯著性門檻:一箇舊的變量是否應該被剔除和一個新的還沒有被採納的變量是否應當進入我們的模型。在第二步中,我們要進行順向選擇,來決定是否採納一個新的自變量。第三步要進行反向淘汰,也就是我們可能要剔除舊的變量,然後在第二第三步之間進行循環,由於已經定義了兩個門檻,但出現新的出不去,舊的進不來時,就說明模型已經擬合好了。步驟詳情如下:

Bidirectional Elimination

Score Comparison

最後一種,信息量比較。所謂信息量,就是對於一個多元線性迴歸模型的一個評價方式。比如說給它進行打分。那麼就有很多種打分方式。比如最常見的一種,叫做Akaike criterion.對於所有可能的模型,我們對它們進行逐一的打分,對於多元線性迴歸,如果有N個自變量,那麼就有$2^N-1$個不同的模型,對這些模型打分後選擇分數最高的模型。那這裏就會有一個問題,如果N很大的時候,模型的數量就會非常龐大。所以說這個方法雖然直覺上很好理解,但自變量數量很大時就不適合使用這種方法。

Score Comparison

Coding

接下來就要進行代碼編寫了,首先還是老樣子,先進行數據預處理,將數據導入並對分類數據進行虛擬編碼,然後將數據集劃分成訓練集和測試集。上面有提及過虛擬編碼的陷阱,實際上我們使用的包中已經避開了這個陷阱,但爲了強調這個問題,這裏也對其進行處理一下:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.linear_model import LinearRegression
import statsmodels.formula.api as sm
import numpy as np

data_path = '../data/50_Startups.csv'

dataset = pd.read_csv(data_path)
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 4].values

labelencoder_X = LabelEncoder()
X[:, 3] = labelencoder_X.fit_transform(X[:, 3])
onehotencoder = OneHotEncoder(categorical_features=[3])
X = onehotencoder.fit_transform(X).toarray()

# Avoiding the Dummy Variable Trap
X = X[:, 1:]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

預處理結束後,就來進行擬合線性迴歸模型,這裏第一步擬合線性迴歸模型的方式和之前的簡單線性迴歸是一樣的。

# Fitting Multiple Linear Regression to the Training set
regressor = LinearRegression()
regressor.fit(X_train, y_train)

# Predicting the Test set results
y_pred = regressor.predict(X_test)

目前我們擬合的模型使用的方法是上述提到的All-in方法,但這個方法並不是最好的,這裏我們使用Backward Elimination來對迴歸器進行優化,使用的工具是statsmodels.formula.api。再然後我們還要做一件事情,在多元線性迴歸時,很多時候模型裏面都會有一個常數$b_0$,相當於$b_0*1$。但在用到的標準庫的函數裏面是不包含這個常數項的,因此我們需要在包含自變量的矩陣中加上一列,這一列全部都是1,$b_0$就是它的係數。代碼如下:

X_train = np.append(arr=np.ones((40, 1)), values=X_train, axis=1)

接下來要真正開始反向淘汰了,首先創建一個矩陣X_opt,包含了最佳的自變量選擇,第一步實際上是所有的自變量,之後的不斷循環後會漸漸淘汰其中的自變量。

X_opt = X_train[:, [0, 1, 2, 3, 4, 5]]

這裏爲什麼用X_train[:, [0, 1, 2, 3, 4, 5]]而不是直接X_train呢?這是因爲後面會進行不斷的淘汰,會不斷刪除其中的列,後續的代碼就能看出來了。

創建完X_opt後,接下來就要用它來擬合新的迴歸器regressor_OLS。這裏用的sm.OLS方法的參數解釋一下:endog對應的是因變量,這裏就是y_train,exog指的是自變量,因此這裏就是X_opt。

regressor_OLS = sm.OLS(endog=y_train, exog=X_opt).fit()
regressor_OLS.summary()

然後使用summary()方法,這個方法能給我們提供很多回歸器的信息,執行後得到結果如下:

image

這裏能看到所有自變量對用的P值,其中最大的是$x_2$,就是這個公司是否在加利福利亞洲,然後我們剔除$x_2$,再繼續擬合,得到summary,根據結果不斷剔除自變量直到最終的P值都小於我們定義的SL=0.05.代碼如下:

X_opt = X_train[:, [0, 1, 3, 4, 5]]
regressor_OLS = sm.OLS(endog=y_train, exog=X_opt).fit()
regressor_OLS.summary()

X_opt = X_train[:, [0, 3, 4, 5]]
regressor_OLS = sm.OLS(endog=y_train, exog=X_opt).fit()
regressor_OLS.summary()

X_opt = X_train[:, [0, 3, 5]]
regressor_OLS = sm.OLS(endog=y_train, exog=X_opt).fit()
regressor_OLS.summary()

X_opt = X_train[:, [0, 3]]
regressor_OLS = sm.OLS(endog=y_train, exog=X_opt).fit()
regressor_OLS.summary()

最終得到的結果是:

image

那麼根據這個結果可以得到的結論就是一家公司的收益主要跟公司的研發投入有關。當然其實其中也有其他的自變量對應了很低的P值,如果自己一步步運行這段代碼會發現行政的投入對應的P值也只有0.07不算很高,如何更好的判斷線性迴歸模型的優劣後面還會有其他的方法來判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章