機器學習特征相關性及多重共線性

一、相關性分析有6種方法

參考與學習
做數據分析時,為了提煉觀點,相關性分析是必不可少,而且尤為重要的一個環節。但是,對于不同類型的數據,相關性分析的方法都各不相同。本文,主要按照不同的數據類型,來對各種相關性分析方法進行梳理總結。

相關性分析是指對兩個或多個具備相關性的變量元素進行分析,相關性不等于因果性。

  • 離散與離散變量之間的相關性

卡方檢驗
首先這里說的卡方檢驗是特指卡方獨立性檢驗,因為卡方檢驗除了可以分析兩個變量的相關性之外更常用的是做卡方擬合優度檢驗(單變量檢驗),這里需要特別注意。

卡方檢驗是一種用途很廣的計數資料的假設檢驗方法。它屬于非參數檢驗的范疇,主要是比較兩個及兩個以上樣本率( 構成比)以及兩個分類變量的關聯性分析。其根本思想就是在于比較理論頻數和實際頻數的吻合程度或擬合優度問題。

它在分類資料統計推斷中的應用,包括:兩個率或兩個構成比比較的卡方檢驗;多個率或多個構成比比較的卡方檢驗以及分類資料的相關分析等。

(1)假設,多個變量之間不相關

(2)根據假設計算得出每種情況的理論值,根據理論值與實際值的差別,計算得到卡方值 及 自由度

df=(C-1)(R-1)

(3)查卡方表,求p值

卡方值越大,P值越小,變量相關的可能性越大,當P<=0.05,否定原假設,認為變量相關。

信息增益和信息增益率

在介紹信息增益之前,先來介紹兩個基礎概念,信息熵和條件熵。

信息熵,就是一個隨機變量的不確定性程度。

條件熵,就是在一個條件下,隨機變量的不確定性。
(1)信息增益:熵 - 條件熵

在一個條件下,信息不確定性減少的程度。

Gain(Y,X)=H(Y)-H(Y|X)

信息增益越大,表示引入條件X之后,不純度減少得越多。信息增益越大,則兩個變量之間的相關性越大。

(2)信息增益率

假設,某個變量存在大量的不同值,例如ID,引入ID后,每個子節點的不純度都為0,則信息增益減少程度達到最大。所以,當不同變量的取值數量差別很大時,引入取值多的變量,信息增益更大。因此,使用信息增益率,考慮到分支個數的影響。
Gain_ratio=(H(Y)-H(Y|X))/H(Y|X)

  • 連續與連續變量之間的相關性
    協方差

協方差,表達了兩個隨機變量的協同變化關系。如果兩個變量不相關,則協方差為0。

Cov(X,Y)=E{[X-E(X)],[Y-E(Y)]}

當 cov(X, Y)>0時,表明 X與Y 正相關;

當 cov(X, Y)<0時,表明X與Y負相關;

當 cov(X, Y)=0時,表明X與Y不相關。

協方差只能對兩組數據進行相關性分析,當有兩組以上數據時就需要使用協方差矩陣。

協方差通過數字衡量變量間的相關性,正值表示正相關,負值表示負相關。但無法對相關的密切程度進行度量。當我們面對多個變量時,無法通過協方差來說明那兩組數據的相關性最高。要衡量和對比相關性的密切程度,就需要使用下一個方法:相關系數。

線性相關系數

也叫Pearson相關系數, 主要衡量兩個變量線性相關的程度。

r=cov(X,Y)/(D(X)D(Y))

相關系數是用協方差除以兩個隨機變量的標準差。相關系數的大小在-1和1之間變化。再也不會出現因為計量單位變化,而數值暴漲的情況了。

線性相關系數必須建立在因變量與自變量是線性的關系基礎上,否則線性相關系數是無意義的。

  • 連續與離散變量之間的相關性

(方差分析計算關系強度R2,判別離散變量是否對連續變量有顯著影響)
連續變量離散化

將連續變量離散化,然后,使用離散與離散變量相關性分析的方法來分析相關性。

箱形圖

使用畫箱形圖的方法,看離散變量取不同值,連續變量的均值與方差及取值分布情況。

如果,離散變量取不同值,對應的連續變量的箱形圖差別不大,則說明,離散變量取不同值對連續變量的影響不大,相關性不高;反之,相關性高。
代碼參考了kaggle的一個優秀答案

def categorical_factor_with_independ_factor(train, independ_factor, var):
    data = pd.concat([train[independ_factor], train[var]], axis=1)
    f, ax = plt.subplots(figsize=(8, 6))
    fig = sns.boxplot(x=var, y=independ_factor, data=data)
    fig.axis(ymin=0, ymax=800000)
    plt.xticks(rotation=60);
    return
  • 特殊的相關性分析

kendall相關系數

kendall相關系數也稱為和諧系數,是一種等級相關的相關性分析方法。之所以放在特殊類型,是因為不僅要求變量是兩個離散變量而且還要求這兩個變量為有序的。所以我選擇把他單獨放在一類。

此相關系數適用于兩個隨機變量都為等級性質的變量,例如,評分等級,質量等級等符合一定線性邏輯,并且是等級性質的(并且其中的等級劃分區域最好不要相差太大)。

二、多重共線性的檢測和解決辦法

數據預處理系列:多重共線性_檢測和解決辦法-CSDN博客

多重共線性簡介(Collinearity and Multicollinearity)
多重共線性(Collinearity)指的是預測變量,也稱為自變量,彼此之間并不是完全獨立的。
共線性是指兩個特征之間存在線性關系(高度相關),并且它們被用作目標的預測變量。通常使用皮爾遜相關系數來衡量。多于兩個預測變量之間也可能存在共線性(并且通常是這種情況)。

多重共線性這個術語最初是由Ragnar Frisch提出的。多重共線性是共線性的一種特殊情況,其中一個特征與兩個或更多特征呈線性關系。我們也可能出現這樣的情況:多于兩個特征之間存在相關性,但同時它們之間沒有高度相關性。

在多元回歸中,部分多重共線性是普遍存在的。兩個隨機變量在樣本中幾乎總是會在某種程度上相關,即使它們在更大的總體中沒有任何基本關系。換句話說,多重共線性是一個程度問題。

1. 多重共線性的后果
多重共線性可能在模型擬合過程中導致重大問題。它會降低回歸和分類模型的整體性能:

  • 不會增加偏差,但可能會增加方差(過擬合);
  • 使估計值對模型中的微小變化非常敏感;
  • 不會影響預測能力,但可能會錯誤地計算出各個預測變量對響應變量的影響。

結果是,系數估計值不穩定且難以解釋。多重共線性削弱了分析的統計功效,可能導致系數改變符號,并且使得正確指定模型更加困難。

2. 處理多重共線性問題的方法

  • 增加樣本量。增加樣本量會引入更多的數據序列變化,從而減少抽樣誤差的影響,并在估計數據的各種屬性時提高精確度。增加樣本量可以減少多重共線性的存在或影響,或者兩者都可以減少。
  • 刪除一些高度相關的特征。
  1. 手動方法 - 方差膨脹因子(VIF)
  2. 自動方法 - 遞歸特征消除(RFE)
  3. 使用PCA分解進行特征消除(在本研究中將跳過此方法)
  • 用它們的線性組合替換高度相關的回歸變量。
  • 在特征工程中保持常識 - 理解自己在做什么。
  • 使用正則化方法,如嶺回歸(RIDGE)和套索回歸(LASSO)或貝葉斯回歸。

數據和python庫設置

# 導入必要的庫
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from statsmodels.stats.outliers_influence import variance_inflation_factor
from sklearn.model_selection import cross_val_score
from sklearn import metrics
from collections import Counter

# 在jupyter notebook中顯示圖形
%matplotlib inline

1. 數據集特征
波士頓房價
https://www.kaggle.com/datasets/vikrishnan/boston-house-prices
這是UCI ML房屋數據集的副本。
https://archive.ics.uci.edu/ml/machine-learning-databases/housing/

BMI 數據集
https://www.kaggle.com/datasets/yasserh/bmidataset

2. 導入數據

# 定義列名
column_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']

# 讀取波士頓房價數據集
raw_boston = pd.read_csv('../input/boston-house-prices/housing.csv', header=None, delimiter=r"\s+", names=column_names)

# 讀取BMI數據集
raw_bmi = pd.read_csv('../input/bmidataset/bmi.csv')

# 創建一個名為"Gender"的新列,用于存儲性別的虛擬變量
# 將"Gender"列中的"Male"替換為0,"Female"替換為1,以創建性別的虛擬變量
raw_bmi['Gender'] = raw_bmi['Gender'].map({'Male':0, 'Female':1})

相關矩陣
相關矩陣給出了兩個獨立變量之間的成對相關性或雙變量關系 - 共線性。它是一個顯示不同變量之間相關系數的表格。它接受具有數值列的輸入關系,并計算其輸入列之間的皮爾遜相關系數。

該矩陣顯示了表格中所有可能值對之間的相關性。它是總結大型數據集并識別和可視化給定數據中的模式的強大工具。如果相關矩陣顯示出具有高絕對值的元素,我們可以談論共線性。在極端情況下,解釋變量完全重疊。

### 繪制各列之間的相關性熱力圖
plt.figure(figsize = (6, 6))  # 創建一個6x6的圖像窗口
# 使用sns.heatmap函數繪制熱力圖,傳入數據為raw_bmi的相關性矩陣,vmin和vmax參數指定顏色映射的范圍為-1到1,
# annot參數為True表示在熱力圖上顯示相關系數的數值
heatmap = sns.heatmap(raw_bmi.corr(), vmin = -1, vmax = 1, annot = True) 
# 設置熱力圖的標題為'BMI Correlation Heatmap',字體大小為18,標題與圖像之間的間距為12像素
heatmap.set_title('BMI Correlation Heatmap', fontdict = {'fontsize' : 18}, pad = 12)  
Text(0.5, 1.0, 'BMI Correlation Heatmap')

我們可以看到“指數”和“身高”/“體重”之間存在很強的相關性(如預期所示)。
我們還可以注意到,“體重”對“指數”的影響要比“身高”大得多。這也是直觀和預期的。

### 繪制各列之間的相關性熱力圖
plt.figure(figsize = (13, 13))  # 創建一個大小為13x13的圖像畫布
 # 使用seaborn庫的heatmap函數繪制熱力圖,傳入數據為raw_boston的相關性矩陣,設置顏色映射范圍為-1到1,同時在圖中顯示相關系數的數值
heatmap = sns.heatmap(raw_boston.corr(), vmin = -1, vmax = 1, annot = True) 
# 設置熱力圖的標題為'Boston Correlation Heatmap',設置標題的字體大小為18,設置標題與圖像之間的距離為12像素
heatmap.set_title('Boston Correlation Heatmap', fontdict = {'fontsize' : 18}, pad = 12)  
Text(0.5, 1.0, 'Boston Correlation Heatmap')

1. 聚類圖
聚類圖表不僅顯示了變量之間的所有相關性,還顯示了它們之間的分組(聚類)關系。

# 設置繪圖大小
plt.figure(figsize = (4, 4))

# 使用Seaborn庫的clustermap函數繪制聚類熱力圖
# raw_boston.corr()計算Boston房價數據集中各變量之間的相關系數矩陣
# vmin和vmax分別設置熱力圖顏色條的最小值和最大值
# annot=True表示在熱力圖上顯示相關系數數值
clustermap = sns.clustermap(raw_boston.corr(), vmin = -1, vmax = 1, annot = True)

方差膨脹因子
方差膨脹因子(VIF)是回歸分析中多重共線性程度的衡量指標。VIF用于確定一個自變量與一組其他變量之間的相關性。

在回歸分析中,當兩個或更多的變量之間存在線性關系時,存在多重共線性。VIF通過衡量給定回歸變量與其他回歸變量的線性相關性,增加了其系數估計的方差,相對于沒有相關性的基準情況。

VIF告訴我們預測變量之間的相關性如何膨脹方差。例如,VIF為10表示現有的多重共線性使系數的方差相對于沒有多重共線性模型增加了10倍。

VIF沒有任何上限。數值越低越好。大于4或5的值有時被認為是中度到高度的,而大于10的值被認為是非常高的。

因此,通常將VIF = 5作為閾值。這意味著任何大于5的自變量都必須被移除。盡管理想的閾值取決于具體情況,在許多計量經濟學教科書中,只有當VIF > 10時才被認為是嚴重的多重共線性。
1. 兩種多重共線性
基于數據的多重共線性:這種類型的多重共線性存在于數據本身中。觀察性實驗更有可能展現這種類型的多重共線性。

例如:兩個相同(或幾乎相同)的變量。磅重和公斤重,或者投資收入和儲蓄/債券收入。

結構性多重共線性:由研究人員創建新的預測變量引起。當我們使用其他術語創建模型術語時,就會出現這種類型。換句話說,它是我們指定的模型的副產品。

在回歸中包括一個實際上是兩個其他變量的組合的變量。例如,在回歸中包括“總投資收入”,而總投資收入=股票和債券收入+儲蓄利息收入。

2. 基于數據的多重共線性
讓我們使用3個特征:‘性別’、‘身高’和’體重’,來檢查一個BMI數據庫的VIF。

# 導入必要的庫已經完成,不再贅述

# 定義自變量集合
X = raw_bmi[['Gender', 'Height', 'Weight']]

# 創建一個空的VIF數據框
vif_data = pd.DataFrame()

# 將自變量的名稱添加到VIF數據框中
vif_data["Feature"] = X.columns

# 計算每個自變量的VIF值
vif_data["VIF"] = [variance_inflation_factor(X.values, i)
                          for i in range(len(X.columns))]

# 打印VIF數據框
print(vif_data)

‘Height’ 和 ‘Weight’ 的VIF值很高,表明這兩個變量高度相關。這是可以預期的,因為一個人的身高確實會影響他們的體重。因此,考慮這兩個特征仍然會導致一個具有高多重共線性的模型。

3. 結構性多重共線性
現在讓我們使用4個特征:‘Gender’、‘Height’、‘Weight’和’Index’,來檢查BMI數據庫的VIF。

# 定義語料
# 獨立變量集
X = raw_bmi[['Gender', 'Height', 'Weight', 'Index']]

# 創建一個空的VIF數據框
vif_data = pd.DataFrame()

# 在VIF數據框中添加特征列
vif_data["Feature"] = X.columns

# 計算每個特征的VIF
vif_data["VIF"] = [variance_inflation_factor(X.values, i)
                          for i in range(len(X.columns))]

# 打印VIF數據框
print(vif_data)

有一個顯著的差異!'Weight’的VIF值大于40,'Index’的VIF值大于25!

我知道在數據集中有’Index’,但請思考一下’Index’實際代表什么。我們可以將其視為其他特征的派生特征。在特征工程中創建這樣的新特征非常常見。

無論如何,我們可以將其視為研究人員創造的多重共線性的一個很好的例子。

基于VIF的特征降維
讓我們使用VIF檢查波士頓數據框中的多重共線性。

# 導入所需的庫

# 從raw_boston數據集中選擇獨立變量集合,存儲在X2中
X2 = raw_boston[['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']]

# 創建一個空的DataFrame,用于存儲VIF值
vif2_data = pd.DataFrame()

# 在vif2_data中創建一個名為"Feature"的列,用于存儲特征名稱
vif2_data["Feature"] = X2.columns

# 計算每個特征的VIF值,并將結果存儲在vif2_data的"VIF"列中
vif2_data["VIF"] = [variance_inflation_factor(X2.values, i)
                          for i in range(len(X2.columns))]

# 打印vif2_data,顯示每個特征的VIF值
print(vif2_data)

我們這里有一些很大的VIF值!讓我們在接下來的步驟中刪除一些高度相關的特征。

重要提示:我們應該逐步進行,一次刪除一個特征并檢查結果。

# 定義自變量集合
X2 = raw_boston[['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'B', 'LSTAT']]

# 創建一個空的DataFrame用于存儲VIF值
vif2_data = pd.DataFrame()

# 將特征列添加到DataFrame中
vif2_data["Feature"] = X2.columns

# 計算每個特征的VIF值
vif2_data["VIF"] = [variance_inflation_factor(X2.values, i)
                          for i in range(len(X2.columns))]

# 打印VIF值的DataFrame
print(vif2_data)

在僅刪除PTRATIO之后,VIF值發生了顯著變化!但是其他特征仍然具有較高的VIF值。

讓我們進一步刪除更多的特征,直到所有特征的VIF值都低于10。
我不會在這里展示所有的步驟 - 你可以自己查看。

最后一步需要7個特征。

# 定義自變量集合
X2 = raw_boston[['CRIM', 'ZN', 'INDUS', 'CHAS', 'DIS', 'RAD', 'LSTAT']]

# 創建一個空的DataFrame用于存儲VIF值
vif2_data = pd.DataFrame()

# 將自變量的名稱存儲在DataFrame的"Feature"列中
vif2_data["Feature"] = X2.columns

# 計算每個自變量的VIF值
vif2_data["VIF"] = [variance_inflation_factor(X2.values, i)
                          for i in range(len(X2.columns))]

# 打印VIF值的DataFrame
print(vif2_data)

現在我們已經擁有所有VIF值小于10的特征。

在接下來的步驟中,我們將比較包含所有特征的線性回歸模型與使用VIF刪除特征后的模型。

回歸模型性能比較
1. 數據預處理

# 將原始波士頓數據集復制到新的變量scaled_boston中,以便進行縮放處理。
scaled_boston = raw_boston.copy()

# 導入StandardScaler類
from sklearn.preprocessing import StandardScaler

# 定義特征列名
col_names = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']

# 從scaled_boston中提取特征數據
features = scaled_boston[col_names]

# 創建StandardScaler對象,并使用特征數據進行擬合
scaler = StandardScaler().fit(features.values)

# 使用擬合后的scaler對特征數據進行標準化處理
features = scaler.transform(features.values)

# 將標準化后的特征數據更新到scaled_boston中
scaled_boston[col_names] = features

# 提取特征變量X和目標變量y
X = scaled_boston.iloc[:, :-1].values
y = scaled_boston.iloc[:, -1].values

# X是特征變量,包含所有行和除最后一列之外的所有列
# y是目標變量,包含所有行和最后一列的值

2. 回歸評估指標

  • 平均絕對誤差(MAE)是誤差絕對值的平均值:
    平均絕對誤差表示數據集中實際值和預測值之間絕對差異的平均值。它衡量數據集中殘差的平均值。
  • 均方誤差(MSE)是誤差平方的平均值
    均方誤差表示數據集中原始值和預測值之間平方差的平均值。它衡量殘差的方差。MSE 由于MSE“懲罰”較大的誤差,在現實世界中往往很有用。
  • 均方根誤差(RMSE)是均方誤差的平方根
    均方根誤差是均方誤差的平方根。它衡量殘差的標準差。RMSE 在“y”單位中是可解釋的。

R平方 決定系數或R平方表示因變量方差中由線性回歸模型解釋的比例。當R2較高時,表示回歸可以捕捉觀察到的因變量的大部分變異。因此,當R2較高時,我們可以說回歸模型的性能較好。

調整R平方 是R平方的修改版本,它根據模型中的獨立變量數量進行了調整,并且始終小于或等于R2。在下面的公式中,n是數據中的觀測數,k是數據中的獨立變量數。

調整R平方

RMSE和R平方都量化了線性回歸模型擬合數據集的程度。在評估模型擬合數據集的程度時,計算RMSE和R2值是有用的,因為每個指標都告訴我們不同的信息。

  • RMSE告訴我們回歸模型預測值與實際值之間的典型距離。

  • R2告訴我們預測變量能夠解釋響應變量的變異程度。

向回歸模型添加更多的獨立變量或預測變量往往會增加R2值,這會引誘模型制作者添加更多的變量。調整R2用于確定相關性的可靠性以及它受獨立變量添加的影響程度。它始終低于R2。

我們將使用的最后一個指標是交叉驗證的R2。
交叉驗證是一種用于評估機器學習模型的重采樣過程,用于有限的數據樣本。

交叉驗證是一種流行的方法,因為它簡單易懂,并且通常會得出比其他方法(如簡單的訓練/測試拆分)更少偏差或樂觀估計的模型技能。

線性回歸

# 使用train_test_split函數將數據集劃分為訓練集和測試集
# 參數X表示特征數據集,y表示目標數據集
# 參數test_size表示測試集所占比例,這里設置為0.3,即測試集占總數據集的30%
# 參數random_state表示隨機種子,這里設置為42,保證每次劃分的結果一致
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

# 導入LinearRegression線性回歸模型

# 創建并訓練模型
lm = LinearRegression()  # 創建一個線性回歸模型對象
lm.fit(X_train, y_train)  # 使用訓練數據對模型進行訓練

# 模型對測試數據進行預測
y_pred = lm.predict(X_test)  # 使用訓練好的模型對測試數據進行預測,得到預測結果y_pred

# 預測交叉驗證分數
cv_lm = cross_val_score(estimator=lm, X=X_train, y=y_train, cv=10)

# 計算調整后的R-squared
r2 = lm.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R-squared公式
lm_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
lm_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
lm_R2 = lm.score(X_test, y_test)
lmCV_R2 = cv_lm.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(lm.score(X_test, y_test), 4))
print('Adjusted R2:', round(lm_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_lm.mean(), 4))

# 設置圖形的大小
plt.figure(figsize=(10, 5))

# 繪制回歸圖
sns.regplot(x=y_test, y=y_pred)

# 設置圖形的標題和字體大小
plt.title('Linear regression with all features', fontsize=20)

Text(0.5, 1.0, 'Linear regression with all features')

隨機森林

# 導入RandomForestRegressor類
from sklearn.ensemble import RandomForestRegressor
# 創建和訓練模型
# 創建一個隨機森林回歸模型,包含10個決策樹,隨機種子為0
RandomForest_reg = RandomForestRegressor(n_estimators = 10, random_state = 0)  
RandomForest_reg.fit(X_train, y_train)  # 使用訓練數據集X_train和y_train來訓練模型

# 模型對測試數據進行預測
y_pred = RandomForest_reg.predict(X_test)  # 使用訓練好的模型對測試數據集X_test進行預測,預測結果存儲在y_pred中

# 預測交叉驗證分數
cv_rf = cross_val_score(estimator=RandomForest_reg, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = RandomForest_reg.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
rf_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
rf_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
rf_R2 = RandomForest_reg.score(X_test, y_test)
rfCV_R2 = cv_rf.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(RandomForest_reg.score(X_test, y_test), 4))
print('Adjusted R2:', round(rf_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_rf.mean(), 4))

使用VIF刪除特征后的線性回歸

# 復制scaled_boston數據集并將其命名為scaled_boston2
scaled_boston2 = scaled_boston.copy()

# 從scaled_boston2數據集中刪除'NOX', 'RM', 'AGE', 'TAX', 'PTRATIO', 'B'這些列
scaled_boston2 = scaled_boston2.drop(['NOX', 'RM', 'AGE', 'TAX', 'PTRATIO', 'B'], axis=1)

# 提取特征變量X
X = scaled_boston2.iloc[:, :-1].values

# 提取目標變量y
y = scaled_boston2.iloc[:, -1].values

# 使用train_test_split函數將數據集分割為訓練集和測試集
# 參數X為特征數據,y為目標數據
# test_size表示測試集占總數據集的比例,這里設置為0.3,即測試集占總數據集的30%
# random_state用于設置隨機種子,保證每次運行代碼得到的結果一致
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

# 創建一個線性回歸模型對象
lm2 = LinearRegression()

# 使用訓練數據來訓練線性回歸模型
lm2.fit(X_train, y_train)

# 使用訓練好的模型對測試數據進行預測
y_pred = lm2.predict(X_test)

# 設置圖形的大小為10x5
plt.figure(figsize=(10, 5))

# 繪制回歸圖,x軸為y_test,y軸為y_pred
sns.regplot(x=y_test, y=y_pred)

# 設置圖形的標題為'Linear regression after dropping features',字體大小為20
plt.title('Linear regression after dropping features', fontsize=20)
Text(0.5, 1.0, 'Linear regression after dropping features')

# 預測交叉驗證分數
cv_lm2 = cross_val_score(estimator=lm2, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = lm2.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
lm2_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
lm2_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
lm2_R2 = lm2.score(X_test, y_test)
lm2CV_R2 = cv_lm2.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(lm2.score(X_test, y_test), 4))
print('Adjusted R2:', round(lm2_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_lm2.mean(), 4))

如我們所見 - 結果看起來并不好!我們稍后會討論這個問題。

使用VIF方法刪除特征后的隨機森林模型

# 創建和訓練模型
RandomForest2_reg = RandomForestRegressor(n_estimators = 10, random_state = 0)
# 使用隨機森林回歸器模型,設置10個決策樹,隨機種子為0
RandomForest2_reg.fit(X_train, y_train)
# 使用訓練好的模型對測試數據進行預測
y_pred = RandomForest2_reg.predict(X_test)

# 預測交叉驗證分數
cv_rf2 = cross_val_score(estimator=RandomForest2_reg, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = RandomForest2_reg.score(X_test, y_test)
# 觀測值數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
rf2_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
rf2_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
rf2_R2 = RandomForest2_reg.score(X_test, y_test)
rf2CV_R2 = cv_rf2.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(RandomForest2_reg.score(X_test, y_test), 4))
print('Adjusted R2:', round(rf2_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_rf2.mean(), 4))

再一次。在刪除特征之后,我們的結果比之前更差。

遞歸特征消除(RFE)
遞歸特征消除(RFE)是一種通過遞歸地考慮特征子集來選擇特征的方法。它通過反復構建模型并選擇最佳或最差的特征(根據模型的性能)來實現。在每次迭代中,它會將最佳或最差的特征從特征集中移除,然后繼續迭代,直到達到預設的特征數量。

RFE的主要思想是通過遞歸地消除特征,來選擇最佳的特征子集。它可以用于特征選擇和特征排名。在每次迭代中,它會根據模型的性能選擇最佳或最差的特征,并將其從特征集中移除。然后,它會繼續迭代,直到達到預設的特征數量。

RFE的步驟如下:

  1. 選擇一個機器學習模型作為基礎模型。
  2. 根據模型的性能選擇最佳或最差的特征。
  3. 將選擇的特征從特征集中移除。
  4. 重復步驟2和3,直到達到預設的特征數量。

RFE的優點包括:

  • 可以自動選擇特征子集,無需手動選擇。
  • 可以通過遞歸地消除特征來選擇最佳的特征子集。

然而,RFE也有一些限制:

  • 如果特征之間存在高度相關性,RFE可能會選擇其中一個特征,而忽略其他相關特征。
  • RFE的計算成本較高,特別是在特征數量較多的情況下。

總之,遞歸特征消除(RFE)是一種通過遞歸地考慮特征子集來選擇特征的方法。它可以用于特征選擇和特征排名,但也有一些限制。

遞歸特征消除(RFE)是一種向后特征選擇算法。

該算法通過多次擬合模型并在每一步中根據擬合模型的coef_或feature_importances_屬性刪除最弱的特征,從而從模型中消除n個特征。

RFE通過從訓練數據集中的所有特征開始,成功刪除特征直到剩下所需數量的特征來搜索特征子集。

RFE是一種包裝型特征選擇算法。這意味著在方法的核心中給定并使用了不同的機器學習算法,由RFE包裝,并用于幫助選擇特征。

并非所有模型都可以與RFE方法配對,有些模型比其他模型更受益于RFE。因為RFE要求初始模型使用完整的預測變量集,所以當預測變量的數量超過樣本數量時,某些模型無法使用。這些模型包括多元線性回歸、邏輯回歸和線性判別分析。如果我們希望將其中一種技術與RFE一起使用,則必須首先縮小預測變量的范圍。此外,某些模型比其他模型更受益于使用RFE。隨機森林就是這樣一個模型(Svetnik等人,2003)。

向后選擇經常與隨機森林模型一起使用,原因有兩個:

  • 隨機森林傾向于不排除預測方程中的變量;
  • 它有一種內部方法來衡量特征重要性。
# 提取特征變量X和目標變量y
X = scaled_boston.iloc[:, :-1].values
y = scaled_boston.iloc[:, -1].values

# X為特征變量,去除最后一列
# y為目標變量,只包含最后一列的值

# 使用train_test_split函數將數據集分為訓練集和測試集
# 參數X為特征數據,y為目標數據
# test_size表示測試集所占的比例,這里設置為0.3,即測試集占總數據集的30%
# random_state表示隨機種子,這里設置為42,保證每次運行代碼得到的結果一致
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

# 導入所需的庫
from sklearn.feature_selection import RFE
from sklearn.pipeline import Pipeline

# 創建一個Pipeline對象
# 使用RFE進行特征選擇,選擇8個特征
rfe = RFE(estimator=RandomForestRegressor(), n_features_to_select=8)

# 創建一個隨機森林回歸模型
model = RandomForestRegressor()

# 創建一個Pipeline對象,將特征選擇和回歸模型組合在一起
rf_pipeline = Pipeline(steps=[('s',rfe),('m',model)])

# 使用訓練數據進行模型訓練
rf_pipeline.fit(X_train, y_train)

# 使用訓練好的模型對測試數據進行預測
y_pred = rf_pipeline.predict(X_test)

# 預測交叉驗證分數
cv_rf_pipeline = cross_val_score(estimator=rf_pipeline, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = rf_pipeline.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
rf_pipeline_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
rf_pipeline_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
rf_pipeline_R2 = rf_pipeline.score(X_test, y_test)
rf_pipelineCV_R2 = cv_rf_pipeline.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(rf_pipeline.score(X_test, y_test), 4))
print('Adjusted R2:', round(rf_pipeline_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_rf_pipeline.mean(), 4))

看起來使用RFE的隨機森林模型更好!

正則化線性模型
1. 正則化
正則化是一種用于減少模型過擬合的技術。當模型過擬合時,它在訓練數據上表現得很好,但在新數據上的表現卻很差。正則化通過在損失函數中添加一個正則項來懲罰模型的復雜度,從而減少過擬合的風險。

常見的正則化方法有L1正則化和L2正則化。L1正則化通過在損失函數中添加模型參數的絕對值之和來懲罰模型的復雜度。L2正則化則通過在損失函數中添加模型參數的平方和來懲罰模型的復雜度。這兩種方法都可以有效地減少模型的復雜度,從而降低過擬合的風險。

在實際應用中,我們可以通過調整正則化參數來控制正則化的強度。較大的正則化參數會導致模型更加簡單,但可能會增加欠擬合的風險。較小的正則化參數則會使模型更加復雜,但可能會增加過擬合的風險。因此,選擇合適的正則化參數非常重要。

正則化是機器學習中常用的技術之一,它可以幫助我們構建更加穩健和泛化能力強的模型。在實際應用中,我們經常需要使用正則化來提高模型的性能和魯棒性。

模型訓練中的兩個主要問題

在訓練模型時,可能會遇到兩個主要問題:過擬合和欠擬合。

  • 過擬合:當模型在訓練集上表現良好,但在測試數據上表現不佳時。
  • 欠擬合:當模型在訓練集和測試集上都表現不佳時。

特別是在訓練集和測試集性能之間存在較大差異時,會實施正則化以避免數據過擬合。通過正則化,訓練中使用的特征數量保持不變,但是方程1.1中的系數(w)的大小會減小。

2. 嶺回歸
嶺回歸是線性回歸的擴展,它在訓練期間向損失函數添加正則化L2懲罰。當存在多個高度相關的變量時,可以使用嶺回歸。它通過對變量的系數進行懲罰來防止過擬合。嶺回歸通過向誤差函數添加懲罰項來縮小系數的大小,從而減少過擬合。

嶺回歸的優點:

  • 比最小二乘/線性回歸更具有抗共線性的魯棒性;
  • 比線性回歸對異常值不那么敏感(但仍然敏感);
  • 不需要數據完全歸一化;
  • 即使變量的數量大于觀測值的數量,也可以應用。

嶺回歸的缺點:

  • 可能需要更多的數據才能獲得準確的結果;
  • 可能需要更多的計算資源;
  • 結果可能難以解釋,因為嶺項或L2范數修改了系數;
  • 如果數據包含異常值,則對異常值敏感,可能產生不穩定的結果。
# 提取特征和目標變量
X = scaled_boston.iloc[:, :-1].values  # 提取所有行的除最后一列外的所有列作為特征
y = scaled_boston.iloc[:, -1].values  # 提取所有行的最后一列作為目標變量

# 將數據集X和標簽y按照30%的比例分割成訓練集和測試集
# random_state = 42表示隨機種子為42,保證每次運行程序分割的數據集一致
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

# 導入Ridge模型類
from sklearn.linear_model import Ridge

# 創建并訓練模型
ridge_reg = Ridge(alpha=1, solver="cholesky")  # 創建一個Ridge回歸模型,設置alpha為1,使用cholesky求解器
ridge_reg.fit(X_train, y_train)  # 使用訓練數據X_train和對應的目標值y_train來訓練模型

# 模型對測試數據進行預測
y_pred = ridge_reg.predict(X_test)  # 使用訓練好的模型對測試數據X_test進行預測,得到預測結果y_pred

# 預測交叉驗證分數
cv_ridge = cross_val_score(estimator=ridge_reg, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = ridge_reg.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
ridge_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
ridge_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
ridge_R2 = ridge_reg.score(X_test, y_test)
ridgeCV_R2 = cv_ridge.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(ridge_reg.score(X_test, y_test), 4))
print('Adjusted R2:', round(ridge_adjusted_r2, 4))
print("Cross Validated R2: ", round(cv_ridge.mean(), 4))

# 設置圖形的大小
plt.figure(figsize=(10, 5))

# 繪制回歸圖
sns.regplot(x=y_test, y=y_pred)

# 設置圖形的標題和字體大小
plt.title('Ridge Regression model', fontsize=20)
Text(0.5, 1.0, 'Ridge Regression model')

3. Lasso回歸
Lasso回歸是一種常見的正則化線性回歸方法,其中包含L1懲罰項。Lasso是Least Absolute Shrinkage and Selection Operator的縮寫。這種方法的效果是縮小那些對預測任務沒有太大貢獻的輸入變量的系數。

L1懲罰最小化了所有系數的大小,并允許任何系數變為零,從而有效地將輸入特征從模型中移除。

LASSO不是一種回歸類型,而是一種可以應用于許多回歸類型的模型構建和變量選擇方法,包括普通最小二乘法、邏輯回歸等等。

LASSO的優點:

  • 自動特征選擇
  • 減少過擬合

幸運的是,由于LASSO內置的變量選擇功能,它可以處理一些多重共線性問題,而不會損失可解釋性。然而,如果共線性過高,LASSO的變量選擇性能將開始下降。在這種情況下,Ridge回歸更適合。

LASSO的缺點:

  • LASSO模型產生的系數是有偏的。添加到模型中的L1懲罰人為地將系數縮小到接近零,或者在某些情況下,完全變為零。這意味著LASSO模型的系數并不代表特征與結果之間真實關系的大小,而是其縮小版本。
  • 難以估計標準誤差。由于LASSO模型中的系數估計是有偏的,很難對它們進行準確的標準誤差估計。這使得難以對它們進行統計檢驗和建立置信區間等操作。
  • 在相關特征方面存在困難。通常情況下,一個特征會被相對任意地選擇,而與該特征高度相關的所有其他特征將被有效地從模型中刪除。這可能導致錯誤地得出只有被選擇保留在模型中的特征是重要的結論,而實際上其他一些特征可能同樣重要甚至更重要。
  • 估計不穩定。LASSO模型產生的估計值被認為相對不穩定,這意味著當在稍微不同的數據集上進行訓練時,它們可能會發生很大變化。
  • 引入超參數。
# 導入Lasso模型類
from sklearn.linear_model import Lasso

# 創建并訓練模型
lasso_reg = Lasso(alpha=0.2)  # 創建一個Lasso回歸模型對象,設置alpha參數為0.2
lasso_reg.fit(X_train, y_train)  # 使用訓練數據X_train和y_train來訓練模型

# 模型對測試數據進行預測
y_pred = lasso_reg.predict(X_test)  # 使用訓練好的模型對測試數據X_test進行預測,得到預測結果y_pred

# 預測交叉驗證分數
cv_lasso = cross_val_score(estimator=lasso_reg, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = lasso_reg.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測變量,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
lasso_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
lasso_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
lasso_R2 = lasso_reg.score(X_test, y_test)
lassoCV_R2 = cv_lasso.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 4))
print('R2:', round(lasso_reg.score(X_test, y_test), 4))
print('Adjusted R2:', round(lasso_adjusted_r2, 4))
print("Cross Validated R2:", round(cv_lasso.mean(), 4))

# 設置圖形的大小
plt.figure(figsize=(10, 5))

# 繪制回歸圖
sns.regplot(x=y_test, y=y_pred)

# 設置圖形的標題和字體大小
plt.title('Lasso回歸模型', fontsize=20)
Text(0.5, 1.0, 'Lasso Regression model')

4. 貝葉斯嶺回歸
貝葉斯回歸是一種定義和估計統計模型的方法。它可以與任何回歸技術一起使用,如線性回歸、套索回歸等。貝葉斯回歸通過使用概率分布而不是點估計來制定線性回歸,從而允許自然機制來處理數據不足或分布不良的數據。輸出或響應變量’y’被假設為來自概率分布而不是估計為單個值。

當數據集中數據不足或數據分布不良時,貝葉斯回歸非常有用。

貝葉斯回歸的優點:

  • 當數據集的大小較小時非常有效。
  • 適用于基于在線學習的場景(實時接收數據),與基于批處理學習相比,在開始訓練模型之前,我們手頭上有整個數據集。這是因為貝葉斯回歸不需要存儲數據。
  • 貝葉斯嘗試和測試的方法在數學上非常穩健。

貝葉斯回歸的缺點:

  • 模型的推斷可能耗時。
  • 如果數據集中有大量可用的數據,貝葉斯方法不值得,常規的頻率主義方法能更高效地完成任務。
# 導入BayesianRidge模型類
from sklearn.linear_model import BayesianRidge

# 創建并訓練模型
BayesianRidge_reg = BayesianRidge()
BayesianRidge_reg.fit(X_train, y_train)

# 模型對測試數據進行預測
y_pred = BayesianRidge_reg.predict(X_test)

# 預測交叉驗證分數
cv_BayesianRidge = cross_val_score(estimator=BayesianRidge_reg, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = BayesianRidge_reg.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測器,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
BayesianRidge_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
BayesianRidge_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
BayesianRidge_R2 = BayesianRidge_reg.score(X_test, y_test)
BayesianRidgeCV_R2 = cv_BayesianRidge.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 6))
print('R2:', round(BayesianRidge_reg.score(X_test, y_test), 6))
print('Adjusted R2:', round(BayesianRidge_adjusted_r2, 6))
print("Cross Validated R2:", round(cv_BayesianRidge.mean(), 6))

# 導入必要的庫
import matplotlib.pyplot as plt
import seaborn as sns

# 設置圖形大小
plt.figure(figsize=(10, 5))

# 繪制回歸圖
sns.regplot(x=y_test, y=y_pred)

# 設置圖形標題和字體大小
plt.title('Bayesian Ridge Regression model', fontsize=20)
Text(0.5, 1.0, 'Bayesian Ridge Regression model')

模型評估
1. 創建新的數據框架

# 定義一個列表models,其中包含了多個元組,每個元組代表一個模型的名稱和相關指標
models = [('線性回歸', lm_RMSE, lm_R2, lm_adjusted_r2, lmCV_R2),
          ('隨機森林回歸', rf_RMSE, rf_R2, rf_adjusted_r2, rfCV_R2),
          ('線性回歸(VIF)', lm2_RMSE, lm2_R2, lm2_adjusted_r2, lm2CV_R2),
          ('隨機森林回歸(VIF)', rf2_RMSE, rf2_R2, rf2_adjusted_r2, rf2CV_R2),
          ('隨機森林回歸(RFE)', rf_pipeline_RMSE, rf_pipeline_R2, rf_pipeline_adjusted_r2, rf_pipelineCV_R2),
          ('嶺回歸', lasso_RMSE, lasso_R2, lasso_adjusted_r2, lassoCV_R2),
          ('Lasso回歸', ridge_RMSE, ridge_R2, ridge_adjusted_r2, ridgeCV_R2),
          ('貝葉斯嶺回歸', BayesianRidge_RMSE, BayesianRidge_R2, BayesianRidge_adjusted_r2, BayesianRidgeCV_R2),   
         ]

# 創建一個名為predictions的數據框,用于存儲模型的預測結果
# 數據框包含以下列:Model(模型名稱)、RMSE(均方根誤差)、R2 Score(R2得分)、Adjusted R2 Score(調整后的R2得分)、Cross Validated R2 Score(交叉驗證的R2得分)
predictions = pd.DataFrame(data = models, columns=['Model', 'RMSE', 'R2 Score', 'Adjusted R2 Score', 'Cross Validated R2 Score'])
predictions

結果可能會有些令人驚訝。

  • 看起來使用VIF方法進行簡單特征刪除導致了更糟糕的結果!
  • 即使一些更健壯的模型也沒有比最簡單的線性回歸表現更好。

結論是什么?

  • VIF并不像我們預期的那樣簡單。
  • “更好”的模型并不總是更好。
  • 可能我們應該更加努力以獲得更好的結果(例如通過參數調整)。

2. 可視化模型性能

# 導入必要的庫已經完成,不需要再添加import語句
# 創建一個畫布和一個子圖
f, axe = plt.subplots(1,1, figsize=(18,6))

# 按照交叉驗證R2得分進行排序
predictions.sort_values(by=['Cross Validated R2 Score'], ascending=False, inplace=True)

# 使用sns庫中的barplot函數繪制條形圖,x軸為交叉驗證R2得分,y軸為模型名稱,數據來源為predictions,子圖為axe
sns.barplot(x='Cross Validated R2 Score', y='Model', data = predictions, ax = axe)

# 設置x軸標簽為"Cross Validated R2 Score",字體大小為16
axe.set_xlabel('Cross Validated R2 Score', size=16)

# 設置y軸標簽為"Model"
axe.set_ylabel('Model')

# 設置x軸范圍為0到1.0
axe.set_xlim(0,1.0)

# 顯示圖形
plt.show()

使用GridSearchCV進行超參數調優
超參數調整是在構建機器學習模型時調整參數元組的過程。這些參數是由我們定義的。機器學習算法不會學習這些參數。這些參數可以在不同的步驟中進行調整。

GridSearchCV是一種從給定的參數網格中找到最佳超參數值的技術。它本質上是一種交叉驗證技術。必須輸入模型以及參數。在提取最佳參數值后,進行預測。

GridSearchCV識別的“最佳”參數實際上是在您的參數網格中包含的參數的最佳值。

1. 調整后的嶺回歸

# 導入PolynomialFeatures類
from sklearn.preprocessing import PolynomialFeatures

# PolynomialFeatures是通過將現有特征提升到指數來創建的特征。
# 例如,如果一個數據集有一個輸入特征X,
# 那么多項式特征將是添加一個新的特征(列),其中的值是通過對X的值進行平方計算得到的,例如X^2。

# 定義步驟列表,其中包含兩個步驟:'poly'和'model'
steps = [
    ('poly', PolynomialFeatures(degree=2)),  # 使用degree=2創建二次多項式特征
    ('model', Ridge(alpha=3.8, fit_intercept=True))  # 使用Ridge回歸模型,設置alpha=3.8和fit_intercept=True
]

# 創建Pipeline對象,將步驟列表作為參數傳遞給Pipeline構造函數
ridge_pipe = Pipeline(steps)

# 使用訓練數據X_train和y_train來訓練Pipeline對象
ridge_pipe.fit(X_train, y_train)

# 使用訓練好的模型對測試數據X_test進行預測
y_pred = ridge_pipe.predict(X_test)


# 導入GridSearchCV類
from sklearn.model_selection import GridSearchCV

# 定義alpha參數的取值范圍
alpha_params = [{'model__alpha': list(range(1, 15))}]

# 創建GridSearchCV對象,使用ridge_pipe作為模型,alpha_params作為參數范圍,cv=10表示使用10折交叉驗證
clf = GridSearchCV(ridge_pipe, alpha_params, cv=10)

# 使用訓練數據擬合和調優模型
clf.fit(X_train, y_train)

# 模型對測試數據進行預測
y_pred = BayesianRidge_reg.predict(X_test)

# 輸出最佳參數組合及其對應的性能表現
print(clf.best_params_)

{'model__alpha': 12}

# 預測交叉驗證分數
cv_Ridge3 = cross_val_score(estimator=clf, X=X_train, y=y_train, cv=10)

# 計算調整后的R平方
r2 = clf.score(X_test, y_test)
# 觀測值的數量是沿著軸0的形狀
n = X_test.shape[0]
# 特征的數量(預測器,p)是沿著軸1的形狀
p = X_test.shape[1]

# 調整后的R平方公式
Ridge3_adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
Ridge3_RMSE = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
Ridge3_R2 = clf.score(X_test, y_test)
Ridge3CV_R2 = cv_Ridge3.mean()

print('RMSE:', round(np.sqrt(metrics.mean_squared_error(y_test, y_pred)), 6))
print('R2:', round(clf.score(X_test, y_test), 6))
print('Adjusted R2:', round(Ridge3_adjusted_r2, 6))
print("Cross Validated R2:", round(cv_Ridge3.mean(), 6))

2. 可視化模型性能

# 定義了一個列表models2,其中包含了多個元組
# 每個元組包含了一個模型的名稱和相關的評估指標
# 評估指標包括 Ridge3_RMSE(均方根誤差)、Ridge3_R2(R平方值)、Ridge3_adjusted_r2(調整后的R平方值)和Ridge3CV_R2(交叉驗證的R平方值)
models2 = [('Tuned Ridge Regression', Ridge3_RMSE, Ridge3_R2, Ridge3_adjusted_r2, Ridge3CV_R2)]

# 創建一個DataFrame對象predictions2,包含多個列
# 列名分別為'Model', 'RMSE', 'R2 Score', 'Adjusted R2 Score', 'Cross Validated R2 Score'
# data參數為models2,即數據來源為models2
predictions2 = pd.DataFrame(data = models2, columns=['Model', 'RMSE', 'R2 Score', 'Adjusted R2 Score', 'Cross Validated R2 Score'])
predictions2

# 使用pd.concat()函數將predictions和predictions2兩個數據合并為一個數據
# 參數ignore_index=True表示忽略原始數據的索引,重新生成新的索引
# 參數sort=False表示不對合并后的數據進行排序
result = pd.concat([predictions, predictions2], ignore_index=True, sort=False)
result.head()

# 創建一個圖形對象和一個坐標軸對象
f, axe = plt.subplots(1,1, figsize=(18,6))

# 按照'Cross Validated R2 Score'列的值進行降序排序
result.sort_values(by=['Cross Validated R2 Score'], ascending=False, inplace=True)

# 使用條形圖顯示數據,x軸為'Cross Validated R2 Score',y軸為'Model'
sns.barplot(x='Cross Validated R2 Score', y='Model', data = result, ax = axe)

# 設置x軸標簽為'Cross Validated R2 Score',字體大小為16
axe.set_xlabel('Cross Validated R2 Score', size=16)

# 設置y軸標簽為'Model'
axe.set_ylabel('Model')

# 設置x軸的范圍為0到1.0
axe.set_xlim(0,1.0)

# 顯示圖形
plt.show()

我們可以看到,調整后的嶺回歸甚至在考慮交叉驗證的R2得分時也優于隨機森林回歸器RFE!
但是 - 這顯然不是結束。我們可以調整其他模型 ?? 這是機器學習中永無止境的故事,這顯然是令人興奮的部分 ??

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容

  • 1.多重共線性 多重共線性是解釋變量存在線性關系或者近似的線性關系,多重共線性影響的模型一般為底層是線性的模型,例...
    enhengz閱讀 41,970評論 0 17
  • 多重共線性產生的背景和原因 在研究實際問題時,考慮的解釋變量往往有很多個,解釋變量之間完全不相關的情形是非常少見的...
    忠教閱讀 5,684評論 0 1
  • 多元回歸分析中的共線性問題 原創 2015-11-13 ccccfys spss統計分析 多重共線性:回歸模型中,...
    fun游樂場閱讀 2,568評論 0 1
  • 一、多重共線性說明 多重共線性一般是指:如果有兩個或者多個自變量高度相關(相關系數大于0.8),難以區分一個自變量...
    spssau閱讀 837評論 0 2
  • 回歸分析需要考慮多重共線性問題。多重共線性是指自變量之間存在高度相關性,導致回歸模型的系數估計不穩定和假設檢驗不可...
    spssau閱讀 10,551評論 0 1