1. 程式人生 > >python資料預處理 :資料共線性處理

python資料預處理 :資料共線性處理

何為共線性:

共線性問題指的是輸入的自變數之間存在較高的線性相關度。共線性問題會導致迴歸模型的穩定性和準確性大大降低,另外,過多無關的維度計算也很浪費時間

共線性產生原因:

變量出現共線性的原因:

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

如何檢驗共線性:

檢驗共線性:

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

如何處理共線性:

處理共線性:

  • 增大樣本量:增大樣本量可以消除猶豫資料量不足而出現的偶然的共線性現象,在可行的前提下這種方法是需要優先考慮的
  • 嶺迴歸法(Ridge Regression):實際上是一種改良最小二乘估計法。通過放棄最小二乘法的無偏性,以損失部分資訊、降低精度為代價來獲得更實際和可靠性更強的迴歸係數。因此嶺迴歸在存在較強共線性的迴歸應用中較為常用。
  • 逐步迴歸法(Stepwise Regression):每次引入一個自變數進行統計檢驗,然後逐步引入其他變數,同時對所有變數的迴歸係數進行檢驗,如果原來引入的變數由於後面變數的引入而變得不再顯著,那麼久將其剔除,逐步得到最有迴歸方程。
  • 主成分迴歸(Principal Components Regression):通過主成分分析,將原始參與建模的變數轉換為少數幾個主成分,麼個主成分是原變數的線性組合,然後基於主成分做迴歸分析,這樣也可以在不丟失重要資料特徵的前提下避開共線性問題。
  • 人工去除:結合人工經驗,對自變數進行刪減,但是對操作者的業務能力、經驗有很高的要求。

部分方法python程式碼實現

import numpy as np
import pandas as pd
from sklearn.linear_model import Ridge
from sklearn.decomposition import PCA
from sklearn.linear_model import LinearRegression

# 匯入資料
df = pd.read_csv('https://raw.githubusercontent.com/ffzs/dataset/master/boston/train.csv')

# 切分自變數
X = df.iloc[:, 1:-1].values

# 切分預測變數
y = df.iloc[:, [-1]].values

# 使用嶺迴歸處理
import matplotlib.pyplot as plt
plt.figure(figsize=(8,6))
n_alphas = 20
alphas = np.logspace(-1,4,num=n_alphas)
coefs = []
for a in alphas:
    ridge = Ridge(alpha=a, fit_intercept=False)
    ridge.fit(X, y)
    coefs.append(ridge.coef_[0])
ax = plt.gca()
ax.plot(alphas, coefs)
ax.set_xscale('log')
handles, labels = ax.get_legend_handles_labels()
plt.legend(labels=df.columns[1:-1])
plt.xlabel('alpha')
plt.ylabel('weights')
plt.axis('tight')
plt.show()

在這裡插入圖片描述

只有nox有些許波動。

# 主成分迴歸進行迴歸分析
pca_model = PCA()
data_pca = pca_model.fit_transform(X)

# 得到所有主成分方差
ratio_cumsum = np.cumsum(pca_model.explained_variance_ratio_)
# 獲取方差佔比超過0.8的索引值
rule_index = np.where(ratio_cumsum > 0.9)
# 獲取最小的索引值
min_index = rule_index[0][0]
# 根據最小索引值提取主成分
data_pca_result = data_pca[:, :min_index+1]
# 建立迴歸模型
model_liner = LinearRegression()
# 訓練模型
model_liner.fit(data_pca_result, y)
print(model_liner.coef_)
#[[-0.02430516 -0.01404814]]

參考:
https://www.jianshu.com/p/ef1b27b8aee0?from=timeline