专栏 | 基于 Jupyter 的特征工程手册:特征选择(一)
作者:陳穎祥、楊子晗
編譯:AI有道
數據預處理后,我們生成了大量的新變量(比如獨熱編碼生成了大量僅包含0或1的變量)。但實際上,部分新生成的變量可能是多余:一方面它們本身不一定包含有用的信息,故無法提高模型性能;另一方面過這些多余變量在構建模型時會消耗大量內存和計算能力。因此,我們應該進行特征選擇并選擇特征子集進行建模。
項目地址:
https://github.com/YC-Coder-Chen/feature-engineering-handbook
本文將介紹特征工程第一種算法:Filter Methods 過濾法(上)。
目錄:
1.1?Filter Methods 過濾法
過濾法通過使用一些統計量或假設檢驗結果為每個變量打分。得分較高的功能往往更加重要,因此應被包含在子集中。以下為一個簡單的基于過濾法的機器學習工作流(以最簡單的訓練-驗證-測試這種數據集劃分方法為例)。
1.1.1 Univariate Filter Methods 單變量特征過濾
單變量過濾方法依據單變量統計量或統計檢驗選擇最佳特征。其僅僅考慮單個變量與目標變量的關系(方差選擇法僅基于單個變量)。
1.1.1.1?Variance Threshold 方差選擇法
方差選擇法刪除變量方差低于某個閾值的所有特征。例如,我們應刪除方差為零的特征(所有觀測點中具有相同值的特征),因為該特征無法解釋目標變量的任何變化。
import numpy as np import pandas as pd from sklearn.feature_selection import VarianceThreshold# 合成一些數據集用于演示 train_set = np.array([[1,2,3],[1,4,7],[1,4,9]]) # 可見第一個變量方差為0 # array([[1, 2, 3], # [1, 4, 7], # [1, 4, 9]])test_set = np.array([[3,2,3],[1,2,7]]) # 故意將第二個變量方差設為0 # array([[3, 2, 3], # [1, 2, 7]])selector = VarianceThreshold() selector.fit(train_set) # 在訓練集上訓練 transformed_train = selector.transform(train_set) # 轉換訓練集 # 下面為返回結果,可見第一個變量已被刪除 # array([[2, 3], # [4, 7], # [4, 9]])transformed_test = selector.transform(test_set) # 轉換測試集 # 下面為返回結果,可見第一個變量已被刪除 # array([[2, 3], # [2, 7]]) # 雖然測試集中第二個變量的方差也為0 # 但是我們的選擇是基于訓練集,所以我們依然刪除第一個變量1.1.1.2?Pearson Correlation (regression problem) 皮爾森相關系數 (回歸問題)
皮爾森相關系數一般用于衡量兩個連續變量之間的線性相關性,也可以用于衡量二元變量與目標變量的相關性。故可以將類別變量利用獨熱編碼轉換為多個二元變量之后利用皮爾森相關系數進行篩選。
公式:
import numpy as np from scipy.stats import pearsonr from sklearn.feature_selection import SelectKBest# 直接載入數據集 from sklearn.datasets import fetch_california_housing dataset = fetch_california_housing() X, y = dataset.data, dataset.target # 利用 california_housing 數據集來演示 # 此數據集中,X,y均為連續變量,故此滿足使用皮爾森相關系數的條件# 選擇前15000個觀測點作為訓練集 # 剩下的作為測試集 train_set = X[0:15000,:] test_set = X[15000:,] train_y = y[0:15000]# sklearn 中沒有直接的方程可以使用 # 此處將用 scipy.stats.pearsonr方程來實現基于皮爾森相關系數的特征過濾 # 注意 scipy.stats.pearsonr 計算的是兩個變量之間的相關系數 # 因sklearn SelectKBest需要,我們將基于scipy.stats.pearsonr 重寫允許多特征同時輸入的方程 udf_pearsonrdef udf_pearsonr(X, y):# 將會分別計算每一個變量與目標變量的關系result = np.array([pearsonr(x, y) for x in X.T]) # 包含(皮爾森相關系數, p值) 的列表return np.absolute(result[:,0]), result[:,1]# SelectKBest 將會基于一個判別方程自動選擇得分高的變量 # 這里的判別方程為皮爾森相關系數 selector = SelectKBest(udf_pearsonr, k=2) # k => 我們想要選擇的變量數 selector.fit(train_set, train_y) # 在訓練集上訓練 transformed_train = selector.transform(train_set) # 轉換訓練集 transformed_train.shape #(15000, 2), 其選擇了第一個及第七個變量 assert np.array_equal(transformed_train, train_set[:,[0,6]])transformed_test = selector.transform(test_set) # 轉換測試集 assert np.array_equal(transformed_test, test_set[:,[0,6]]); # 可見對于測試集,其依然選擇了第一個及第七個變量 # 驗算一下我們的結果 for idx in range(train_set.shape[1]):pea_score, p_value = pearsonr(train_set[:,idx], train_y)print(f"第{idx + 1}個變量和目標的皮爾森相關系數的絕對值為{round(np.abs(pea_score),2)}, p-值為{round(p_value,3)}") # 應選擇第一個及第七個變量 第1個變量和目標的皮爾森相關系數的絕對值為0.7, p-值為0.0 第2個變量和目標的皮爾森相關系數的絕對值為0.07, p-值為0.0 第3個變量和目標的皮爾森相關系數的絕對值為0.14, p-值為0.0 第4個變量和目標的皮爾森相關系數的絕對值為0.04, p-值為0.0 第5個變量和目標的皮爾森相關系數的絕對值為0.02, p-值為0.011 第6個變量和目標的皮爾森相關系數的絕對值為0.05, p-值為0.0 第7個變量和目標的皮爾森相關系數的絕對值為0.23, p-值為0.0 第8個變量和目標的皮爾森相關系數的絕對值為0.08, p-值為0.01.1.1.3?Distance Correlation (regression problem) 距離相關系數 (回歸問題)
與皮爾森相關系數類似,距離相關系數也一般被用于衡量兩個連續變量之間的相關性。但與皮爾森相關系數不同的是,距離相關系數還衡量了兩個變量之間的非線性關聯。?
公式:?
首先,計算(n x n)距離矩陣dX。dX中的每一個元素為???????????????? 。類似的,我們也可以計算距離矩陣dY,其中dY中的每個元素為????????????????。????????????????是為觀測點i與觀測點j之間的距離:
其次,我們計算如下雙中心距離并更新距離矩陣。其中, ????????ˉ 為距離矩陣dX的第i行平均值, ????????ˉ 為距離矩陣dX的第j列的平均值, ∑????????∑???????????????????????? 為全局平均值:
隨后,我們便可以算出樣本距離協方差及距離方差:
最后,距離相關系數 ????????????????(????,????) 便為如下:
import numpy as np from dcor import distance_correlation from dcor.independence import distance_covariance_test from sklearn.feature_selection import SelectKBest# 直接載入數據集 from sklearn.datasets import fetch_california_housing dataset = fetch_california_housing() X, y = dataset.data, dataset.target # 利用 california_housing 數據集來演示 # 此數據集中,X,y均為連續變量,故此滿足使用距離相關系數的條件# 選擇前15000個觀測點作為訓練集 # 剩下的作為測試集 train_set = X[0:15000,:] test_set = X[15000:,] train_y = y[0:15000]# sklearn 中沒有直接的方程可以使用 # 此處將用 dcor.distance_correlation方程來實現基于距離相關系數的特征過濾 # 注意 dcor.distance_correlation 計算的是兩個變量之間的相關系數 # 因sklearn SelectKBest需要,我們將基于dcor.distance_correlation 重寫允許多特征同時輸入的方程 udf_dcorrdef udf_dcorr(X, y):# 將會分別計算每一個變量與目標變量的關系result = np.array([[distance_correlation(x, y), distance_covariance_test(x,y)[0]]for x in X.T]) # 包含(距離相關系數, p值) 的列表return result[:,0], result[:,1]# SelectKBest 將會基于一個判別方程自動選擇得分高的變量 # 這里的判別方程為距離相關系數 selector = SelectKBest(udf_dcorr, k=2) # k => 我們想要選擇的變量數 selector.fit(train_set, train_y) # 在訓練集上訓練 transformed_train = selector.transform(train_set) # 轉換訓練集 transformed_train.shape #(15000, 2), 其選擇了第一個及第三個變量 assert np.array_equal(transformed_train, train_set[:,[0,2]])transformed_test = selector.transform(test_set) # 轉換測試集 assert np.array_equal(transformed_test, test_set[:,[0,2]]); # 可見對于測試集,其依然選擇了第一個及第三個變量 # 驗算一下我們的結果 for idx in range(train_set.shape[1]):d_score = distance_correlation(train_set[:,idx], train_y)p_value = distance_covariance_test(train_set[:,idx], train_y)[0]print(f"第{idx + 1}個變量和目標的距離相關系數為{round(d_score,2)}, p-值為{round(p_value,3)}") # 應選擇第一個及第三個變量 第1個變量和目標的距離相關系數為0.66, p-值為1.0 第2個變量和目標的距離相關系數為0.07, p-值為1.0 第3個變量和目標的距離相關系數為0.31, p-值為1.0 第4個變量和目標的距離相關系數為0.12, p-值為1.0 第5個變量和目標的距離相關系數為0.08, p-值為1.0 第6個變量和目標的距離相關系數為0.29, p-值為1.0 第7個變量和目標的距離相關系數為0.25, p-值為1.0 第8個變量和目標的距離相關系數為0.19, p-值為1.01.1.1.4?F-Score (regression problem) F-統計量 (回歸問題)
F統計量(F-Score)用于檢驗線性回歸模型的整體顯著性。在sklearn中,其將對每一個變量分別建立一個一元的線性回歸模型,然后分別報告每一個對應模型的F統計量。F-統計量的零假設是該線性模型系數不顯著,在一元模型中,該統計量能夠反映各變量與目標變量之間的線性關系。因此,我們應該選擇具有較高F統計量的特征(更有可能拒絕原假設)。
公式:
SST為總平方和,SSR為回歸平方和,p為線性回歸自變量數(包括常數項,故在上述的一元線性模型中,p=2), ???? 為自變量與因變量的線性相關系數,n為總觀測數。因上述線性模型為一元線性模型,故可證 ????2=????2 。
import numpy as np from sklearn.feature_selection import f_regression from sklearn.feature_selection import SelectKBest# 直接載入數據集 from sklearn.datasets import fetch_california_housing dataset = fetch_california_housing() X, y = dataset.data, dataset.target # 利用 california_housing 數據集來演示 # 此數據集中,X,y均為連續變量,故此滿足使用F統計量的條件# 選擇前15000個觀測點作為訓練集 # 剩下的作為測試集 train_set = X[0:15000,:] test_set = X[15000:,] train_y = y[0:15000]# sklearn 中直接提供了方程用于計算F統計量 # SelectKBest 將會基于一個判別方程自動選擇得分高的變量 # 這里的判別方程為F統計量 selector = SelectKBest(f_regression, k=2) # k => 我們想要選擇的變量數 selector.fit(train_set, train_y) # 在訓練集上訓練 transformed_train = selector.transform(train_set) # 轉換訓練集 transformed_train.shape #(15000, 2), 其選擇了第一個及第七個變量 assert np.array_equal(transformed_train, train_set[:,[0,6]])transformed_test = selector.transform(test_set) # 轉換測試集 assert np.array_equal(transformed_test, test_set[:,[0,6]]); # 可見對于測試集,其依然選擇了第一個及第七個變量 # 驗算一下我們的結果 for idx in range(train_set.shape[1]):score, p_value = f_regression(train_set[:,idx].reshape(-1,1), train_y)print(f"第{idx + 1}個變量的F統計量為{round(score[0],2)}, p-值為{round(p_value[0],3)}") # 故應選擇第一個及第七個變量 第1個變量的F統計量為14111.79, p-值為0.0 第2個變量的F統計量為71.99, p-值為0.0 第3個變量的F統計量為317.04, p-值為0.0 第4個變量的F統計量為23.93, p-值為0.0 第5個變量的F統計量為6.54, p-值為0.011 第6個變量的F統計量為35.93, p-值為0.0 第7個變量的F統計量為846.61, p-值為0.0 第8個變量的F統計量為98.06, p-值為0.0專欄系列:
專欄 | 基于 Jupyter 的特征工程手冊:數據預處理(一)
專欄 | 基于 Jupyter 的特征工程手冊:數據預處理(二)
專欄 | 基于 Jupyter 的特征工程手冊:數據預處理(三)
專欄 | 基于 Jupyter 的特征工程手冊:數據預處理(四)
目前該項目完整中文版正在制作中,請持續關注哦~
中文版 Jupyter 地址:
https://github.com/YC-Coder-Chen/feature-engineering-handbook/blob/master/中文版/2.%20特征選擇.ipynb
推薦閱讀
(點擊標題可跳轉閱讀)
干貨 | 公眾號歷史文章精選
我的深度學習入門路線
我的機器學習入門路線圖
算法工程師必備!
AI有道年度技術文章電子版PDF來啦!
掃描下方二維碼,添加?AI有道小助手微信,可申請入群,并獲得2020完整技術文章合集PDF(一定要備注:入群?+ 地點 + 學校/公司。例如:入群+上海+復旦。?
長按掃碼,申請入群
(添加人數較多,請耐心等待)
?
最新 AI 干貨,我在看?
總結
以上是生活随笔為你收集整理的专栏 | 基于 Jupyter 的特征工程手册:特征选择(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员应该学的追女孩方法
- 下一篇: 专栏 | 基于 Jupyter 的特征工