以前的文章已經講述了簡單線性迴歸的概念和代碼實現,如今來繼續看看多元線性迴歸。所謂多元線性迴歸其實就是自變量的個數變多了,以前的簡單線性迴歸方程能夠表示爲:$y=b_0 +bx$,那麼在多元中則是$y=b_0+b_1x_1+b_2x_2+...+b_nx_n$。python
在正式使用多元線性迴歸以前,咱們先談談關於線性迴歸的幾個前置條件,首先,在線性迴歸中有幾個重要的假設以下所示:算法
也就是說咱們在使用線性迴歸時,要考慮到實際狀況是否吻合上述的幾種假設,不然可能會致使擬合的模型不許確。api
除此以外,以前數據預處理的時候也提到過一個叫作虛擬變量的概念,如今對其進行詳細的講解。來看下面的數據集(一樣因爲篇幅問題只提供部分):app
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這列數據能夠拆分紅三列:dom
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的預測頗有幫助因素,咱們須要從其中剔除掉無用的元素來獲得最合適的模型,那麼此時就有一個問題,如何來選擇這些自變量呢?這裏有五種方法來創建模型:編碼
其中的2,3,4三種方式,也是咱們最經常使用的,叫作Step Regression也就是逐步迴歸,它們的算法是相似的,只是應用的順序有點不一樣。接下來一種種的介紹這幾種方法。
所謂All-in,就是把全部咱們認爲的自變量全扔進去,通常有這幾種狀況使用:
All-in這個方法很簡單,但通常都是一些特殊狀況下或者一些外力干涉時纔會使用,這種方法不做推薦。
反向淘汰這個算法的精髓在於對於每個這個模型的自變量來講,他對咱們的模型的預測結果實際上是有影響力的,用統計學上的一個概念叫作P-value來形容它的影響力。在這裏咱們先定義它的這個影響力是否顯著的一個門檻也就是一個significance level(SL),先定義爲0.05。接着第二步使用全部的自變量來擬合出一個模型。第三步,對於這個模型當中的每個自變量都來計算它的P值(P-value),來顯示它對咱們模型有多大的影響力,而後咱們取這個最高的P值,假設這個P>SL,就繼續往第四步,不然就算法結束。那麼第四步,最高的P值對應的那個自變量咱們就要將它從咱們的模型中去除。第五步,去除了一個自變量後,在用剩下的自變量從新對模型進行擬合,所以這裏就是一個第三步到第五步的一個循環,直到全部剩下的P值都比SL要小,這樣就說明模型已經擬合好了。步驟詳情以下:
順向選擇和反向淘汰的算法思想很接近,只是順序有了個顛倒。這裏第一步仍是先定一個顯著性的門檻SL=0.05.第二步,咱們在這邊對每一個自變量$x_n$都進行簡單線性迴歸擬合,分別獲得它們的P值,而後取得它們中最低的。第三步對於這個最低的P值,咱們的結論就是這個自變量它對咱們將要擬合的模型的影響是最大的,因此說,咱們會保留這個自變量。接下來第四步咱們再看剩下的自變量當中加上哪個會給咱們帶來最小的P值,假如說新的P值比咱們以前定義的SL小,那就從新回到第三步,也就是第三步又加入了一個新的變量而後在接下來剩下的變量當中,從新找最大的P值,而後繼續加到模型當中,以此類推,直到剩下來的尚未被加入模型當中的變量它們的P值所有大於SL,也就是說剩下的變量對於模型有可能產生的影響不夠顯著,那對這些就不予採納,這個時候模型就擬合好了。步驟詳情以下:
所謂雙向淘汰,其實就是對以前的兩種算法的結合。在第一步中,咱們須要選擇兩個顯著性門檻:一箇舊的變量是否應該被剔除和一個新的尚未被採納的變量是否應當進入咱們的模型。在第二步中,咱們要進行順向選擇,來決定是否採納一個新的自變量。第三步要進行反向淘汰,也就是咱們可能要剔除舊的變量,而後在第二第三步之間進行循環,因爲已經定義了兩個門檻,但出現新的出不去,舊的進不來時,就說明模型已經擬合好了。步驟詳情以下:
最後一種,信息量比較。所謂信息量,就是對於一個多元線性迴歸模型的一個評價方式。好比說給它進行打分。那麼就有不少種打分方式。好比最多見的一種,叫作Akaike criterion.對於全部可能的模型,咱們對它們進行逐一的打分,對於多元線性迴歸,若是有N個自變量,那麼就有$2^N-1$個不一樣的模型,對這些模型打分後選擇分數最高的模型。那這裏就會有一個問題,若是N很大的時候,模型的數量就會很是龐大。因此說這個方法雖然直覺上很好理解,但自變量數量很大時就不適合使用這種方法。
接下來就要進行代碼編寫了,首先仍是老樣子,先進行數據預處理,將數據導入並對分類數據進行虛擬編碼,而後將數據集劃分紅訓練集和測試集。上面有說起過虛擬編碼的陷阱,實際上咱們使用的包中已經避開了這個陷阱,但爲了強調這個問題,這裏也對其進行處理一下:
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()方法,這個方法能給咱們提供不少迴歸器的信息,執行後獲得結果以下:
這裏能看到全部自變量對用的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()
最終獲得的結果是:
那麼根據這個結果能夠獲得的結論就是一家公司的收益主要跟公司的研發投入有關。固然其實其中也有其餘的自變量對應了很低的P值,若是本身一步步運行這段代碼會發現行政的投入對應的P值也只有0.07不算很高,如何更好的判斷線性迴歸模型的優劣後面還會有其餘的方法來判斷。