3.7 解決運營數據的共線性問題

說明:本文是《Python數據分析與數據化運營》中的「3.7 解決運營數據的共線性問題」。

-----------------------------下面是正文內容--------------------------

所謂共線性(也稱為多重共線性)問題指的是輸入的自變數之間存在較高的線性相關度。共線性問題會導致回歸模型的穩定性和準確性大大降低,另外,過多無關的維度參與計算也會浪費計算資源和時間。

共線性問題是否常見取決於具體業務場景,常見的具有明顯的共線性的維度或變數包括:

  • 訪問量和頁面瀏覽量
  • 頁面瀏覽量和訪問時間
  • 訂單量和銷售額
  • 訂單量和轉化率
  • 促銷費用和銷售額
  • 網路展示廣告費用和訪客數

導致出現變數間共線性的原因可能包括:

  • 數據樣本不夠,導致共線性存在偶然性,這其實反映了缺少數據對於數據建模的影響,共線性僅僅是影響的一部分。
  • 多個變數都基於時間有共同或相反的演變趨勢,例如春節期間的網路銷售量和銷售額都相對於正常時間有下降趨勢。
  • 多個變數間存在一定的推移關係,但總體上變數間的趨勢一致,只是發生的時間點不一致,例如品牌廣告費用和銷售額之間,通常是品牌廣告先進行大範圍的曝光和信息推送,經過一定時間傳播之後,銷售額才能爆發出來。
  • 多個變數間存在近似線性的關係。例如網路展示廣告費用與訪客數之間,如果用y代表訪客數,用x代表展示廣告費用,那麼二者的關係很可能是y = 2*x + b,即每投放一元錢,可以帶來大概2~3個訪客。

3.7.1 如何檢驗共線性

共線性一般通過容忍度、方差膨脹因子、條件指數、特徵根這幾個數據特徵來做判斷:

  • 容忍度(Tolerance),容忍度是每個自變數作為因變數對其他自變數進行回歸建模時得到的殘差比例,大小用1減得到的決定係數來表示。容忍度的值介於0和1之間,如果值越小,說明這個自變數與其它自變數間越可能存在共線性問題。
  • 方差膨脹因(Variance Inflation Factor,VIF):VIF是容忍度的倒數,值越大則共線性問題越明顯,通常以10作為判斷邊界。當VIF<10,不存在多重共線性;當10≤VIF<100,存在較強的多重共線性;當VIF≥100,存在嚴重多重共線性。
  • 特徵值(Eigenvalue),該方法實際上就是對自變數進行主成分分析,如果多個維度的特徵值等於0,則可能有比較嚴重的共線性。

除此以外,還可以使用相關係數輔助判斷,當相關係數R>0.8時就表示可能存在較強的相關性,有關相關性的更多話題,會在「3.8有關相關性分析的混沌」中探討。通常這些方法得到的結果都是相關的,即滿足其中某個特徵後,其他特徵也基本滿足。因此可以通過多種方法共同驗證。

3.7.2 解決共線性的5種常用方法

增大樣本量

通過增加樣本量,來消除由於數據量不足而出現的偶然共線性現象,在可行的前提下這種方法是需要優先考慮的;但即使增加了樣本量,也可能無法解決共線性問題,原因是很可能變數間確實存在這個問題。

嶺回歸法(Ridge Regression)

嶺回歸分析是一種專用於共線性問題的有偏估計回歸方法,實質上是一種改良的最小二乘估計法。它通過放棄最小二乘法的無偏性,以損失部分信息、降低精度為代價來獲得更實際和可靠性更強的回歸係數。因此嶺回歸在存在較強共線性的回歸應用中較為常用。

逐步回歸法(Stepwise Regression)

逐步回歸法是每次引入一個自變數並進行統計檢驗,然後逐步引入其他變數同時對所有變數的回歸係數進行檢驗。如果原來引入的變數由於後面變數的引入而變得不再顯著,那麼就將其剔除,逐步得到最優回歸方程。

主成分回歸(Principal Components Regression)

通過主成分分析,將原始參與建模的變數轉換為少數幾個主成分,每個主成分是原變數的線性組合,然後基於主成分做回歸分析,這樣也可以在不丟失重要數據特徵的前提下避開共線性問題。

人工去除

直接結合人工經驗,對參與回歸模型計算的自變數進行刪減,也是一個較為常用的方法,但這種方法需要操作者對於業務、模型和數據都有相對深入的理解,這樣才有可能做出正確的操作。從專業角度分析,如果缺少上述三個方面的任何一點,那麼人工去除的方式都有可能產生偏差,導致結果不準確。

提示 要完全解決共線性的問題是不可能的,因為任何事物之間都存在一定的聯繫,在解決共線性問題的相關話題中,我們只是解決其中嚴重的共線性問題,而非全部共線性問題。

3.7.3 代碼實操:Python處理共線性問題

本示例中,將通過sklearn進行共線性處理。源文件data5.txt位於「附件-chapter3」中,默認工作目錄為「附件-chapter3」(如果不是,請cd切換到該目錄下,否則會報「IOError:

File data5.txt does not exist」)。

在自動化工作中(尤其是以Python為代表的智能化數據工作),通常不會人多的通過人工的方法參與演算法結果觀察、調優、選擇等內容。同樣,在解決共線性的方法中,通過程序的方式自動選擇或規避是解決共線性的最佳方法。在本示例中,將主要使用嶺回歸和主成分回歸實現。

完整代碼如下:

# 導入相關庫import numpy as npfrom sklearn.linear_model import Ridgefrom sklearn.decomposition import PCAfrom sklearn.linear_model import LinearRegression# 讀取數據data = np.loadtxt(data5.txt,delimiter= ) # 讀取數據文件x = data[:, :-1] # 切分自變數y = data[:, -1] # 切分預測變數# 使用嶺回歸演算法進行回歸分析model_ridge = Ridge(alpha=1.0) # 建立嶺回歸模型對象model_ridge.fit(x, y) # 輸入x/y訓練模型print (model_ridge.coef_) # 列印輸出自變數的係數print (model_ridge.intercept_) # 列印輸出截距# 使用主成分回歸進行回歸分析model_pca = PCA() # 建立PCA模型對象data_pca = model_pca.fit_transform(x) # 將x進行主成分分析ratio_cumsm = np.cumsum(model_pca.explained_variance_ratio_) # 得到所有主成分方差佔比的累積數據print (ratio_cumsm) # 列印輸出所有主成分方差佔比累積rule_index = np.where(ratio_cumsm > 0.8) # 獲取方差佔比超過0.8的所有索引值min_index = rule_index[0][0] # 獲取最小索引值data_pca_result = data_pca[:, :min_index + 1] # 根據最小索引值提取主成分model_liner = LinearRegression() # 建立回歸模型對象model_liner.fit(data_pca_result, y) # 輸入主成分數據和預測變數y並訓練模型print (model_liner.coef_) # 列印輸出自變數的係數print (model_liner.intercept_) # 列印輸出截距

上述示例代碼以空行分為4部分。

第一部分導入相關庫。示例中用到了Numpy、sklearn中的Ridge(嶺回歸)、PCA(主成分分析)和LinearRegression(普通線性回歸)。由於本書用到的Python庫中沒有直接集成主成分回歸方法,因此這裡將通過PCA+LinearRegression的形式組合實現。

第二部分導入數據。使用numpy的loadtxt方法讀取數據文件,數據文件以tab分隔,共1000條數據,有9個自變數和1個因變數。因變數處於最後一列,使用Numpy矩陣進行數據切分。

第三部分使用嶺回歸演算法進行回歸分析。該過程中,先建立嶺回歸模型對象,指定alpha值為0.1,接著通過fit方法將x和y分別輸入模型做訓練,然後列印輸出回歸方程中自變數的係數和截距。結果如下:

[ 8.50164360e+01 -1.18330186e-03 9.80792921e-04 -8.54201056e-042.10489064e-05 2.20180449e-04 -3.00990875e-06 -9.30084240e-06-2.84498824e-08]-7443.98652868

上述結果中包含了各個輸入變數的係數以及截距,假設因變數為y,自變數為x1/x2/...x9,那麼該方程可以寫成:

y = 85.016436*x1+(-0.00118330186)*x2+0.000980792921*x3+(-0.000854201056)*x4+0.0000210489064*x5+0.000220180449*x6+(-0.00000300990875)*x7+(-0.0000093008424)*x9+(-0.0000000284498824)*x9-7443.98652868

提示 由於其中後面幾個變數的係數實在太小,為了清晰的展示方程式,因此保留的小數點位數比較多。

第四部分使用主成分回歸進行回歸分析。該過程主要分為以下步驟:

  • 先建立PCA模型對象,然後使用fit_transform方法直接進行主成分轉換。這裡沒有指定具體主成分的數量,原因是在主成分的方差貢獻率之前,無法知曉到底選擇多少個合適,後續會通過指定閥值的方式自動實現成分選擇。
  • 通過PCA模型對象的explained_variance_ratio_得到各個主成分的方差貢獻率(方差佔比),然後使用Numpy的cumsum方法計算累積佔比,得到如下輸出結果:

[ 0.9028 0.98570494 0.99957412 0.99995908 0.99999562 0.999999390.99999999 1. 1. ]

直觀上分析,前2個主成分基本已經完全代表所有成分參與模型計算。但是如果自動化實現,我們不可能每次先中斷程序並列印出結果,再使用人工判斷。因此我們需要一個閥值,當方差貢獻達到閥值時,就自動選擇前n個主成分作為最終轉換維度。

  • 通過使用Numpy的where方法找到主成分方差佔比累積>0.8的值索引,通常0.8就已經能代表大部分的數據特徵,本示例較為特徵,第一個主成分就已經非常明顯,該方法返回的是一個元組,從元組中得到最小的索引值(越往後累積佔比越大,索引值也越大,因此第一個符合條件的索引就是我們要取出的最後一個主成分)
  • 在獲得最小索引值之後,根據最小索引值提取主成分。切片時在索引列值上加1是由於默認索引值的右側是不包含的,例如[0:1]只取出第0列,而不是我們需要的0和1兩列。
  • 接著進入到線性回歸的環節。跟嶺回歸的步驟類似,建立回歸模型對象並輸入x和y做模型訓練,最後列印輸出回歸方程中自變數的係數和截距。結果如下:

[ 1.26262171e-05]1058.52726

上述結果中包含了輸入變數的係數以及截距,假設因變數為y,滿足自變數方差佔比大於0.9的主成分為第一個主成分,假設其為x1,那麼該方程可以寫成:

y = 0.0000126262171*x1+1058.52726

注意 此時的x1跟嶺回歸中的x1含義不同:嶺回歸的x1是原始數據文件中第一個變數,而這裡的x1是第一個主成分——原始數據文件中自變數的一個線性組合。

推薦閱讀:

TAG:Python數據分析書籍 | 數據分析 | 數據化運營 |