天天看點

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

資料預處理後,我們生成了大量的新變量(比如獨熱編碼生成了大量僅包含0或1的變量)。但實際上,部分新生成的變量可能是多餘:一方面它們本身不一定包含有用的資訊,故無法提高模型性能;另一方面過這些多餘變量在構模組化型時會消耗大量記憶體和計算能力。是以,我們應該進行特征選擇并選擇特征子集進行模組化。

項目位址:

https://github.com/YC-Coder-Chen/feature-engineering-handbook

本文将介紹特征工程中的 Multivariate Filter Methods 多元特征過濾。

目錄:

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

1.1.2 Multivariate Filter Methods 多元特征過濾

單變量特征過濾僅考慮了每一變量與目标變量之間的關系,而忽視了變量間的相關性。多元變量過濾則解決了這一問題,其考慮了變量之間的互相關系,基于整個特征空間選擇最佳特征。是以多元特征過濾在删除備援變量方面表現更好。這裡利用亞利桑那州立大學開發的skfeature子產品來進行多元特征過濾。

1.1.2.1 Max-Relevance Min-Redundancy (mRMR) 最大相關最小備援

最大相關最小備援試圖尋找一個與目标變量有較高相關性(例如:MI)的變量子集,同時這個子集中的變量還應具有較低的互相關聯性。通過解析源代碼,我們發現,skfeature中最大相關最小備援方法僅适用于分類問題中的離散特征,因為它計算過程中使用的是計算離散情形下的互資訊 (MI)的公式。 

公式: 

假設資料集共包含m個特征,則基于mRMR公式,其中第n個特征的重要性可被表示為:

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

𝐼(𝑌,𝑋𝑖) 為變量𝑋𝑖與目标變量Y的互資訊。1/|𝑆|∑𝑋𝑠∈𝑆𝐼(𝑋𝑠,𝑋𝑖)為變量𝑋𝑖與現有變量子集中所有變量的互資訊的平均值。 

mRMR其實是一個逐漸(step-wise)的方法,在mRMR特征選擇過程的每一步中,具有最高特征重要性𝑓𝑚𝑅𝑀𝑅(𝑋𝑖)的變量𝑋𝑖,(𝑋𝑖∉𝑆)将會被加入子集中,直至子集中的變量數達到使用者要求。

import numpy as np
from skfeature.function.information_theoretical_based import MRMR
from sklearn.datasets import load_iris  # 利用iris資料作為示範資料集

# 載入資料集
iris = load_iris()
X, y = iris.data, iris.target

# 選擇前100個觀測點作為訓練集
# 剩下的50個觀測點作為測試集
# 由于skfeature中的mRMR僅适用于離散變量
# 是以我們通過将float轉換為int而把所有連續變量轉換為離散變量
# 此轉換僅用于示範目的

train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)

feature_index,_,_ = MRMR.mrmr(train_set, train_y, n_selected_features=2) # 在訓練集上訓練
transformed_train = train_set[:,feature_index] # 轉換訓練集
assert np.array_equal(transformed_train, train_set[:,[2,3]])  # 其選擇了第三個及第四個變量

transformed_test = test_set[:,feature_index] # 轉換測試集
assert np.array_equal(transformed_test, test_set[:,[2,3]]) # 其選擇了第三個及第四個變量      

1.1.2.2 Correlation-based Feature Selection (CFS) 基于相關性的特征選擇

與mRMR類似,基于相關性的特征選擇(CFS)也基于一個類似的假設:一個好的特征子集應包含與目标高度相關且彼此不相關的特征。通過解析源代碼,我們發現,skfeature中CFS的實作也僅适用于分類問題中的離散特征。因為其使用的是離散情形下的對稱不确定性(symmetrical uncertainty)作為變量間相關性的衡量标準。 

公式:

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

𝑆 為特征子集. 我們需要尋找最大化𝑀𝑒𝑟𝑖𝑡𝑆的最優子集𝑆∗。 

𝑆𝑈(𝑋𝑖,𝑦)為離散變量𝑋𝑖與目标變量𝑦間的對稱不确定性(SU)。 

𝑆𝑈(𝑋𝑖,𝑋𝑗)為離散變量𝑋𝑖與離散變量𝑋𝑗間的對稱不确定性(SU)。

import numpy as np
from skfeature.function.statistical_based import CFS
from sklearn.datasets import load_iris  # 利用iris資料作為示範資料集

# 載入資料集
iris = load_iris()
X, y = iris.data, iris.target

# 選擇前100個觀測點作為訓練集
# 剩下的50個觀測點作為測試集
# 由于skfeature中的CFS僅适用于離散變量
# 是以我們通過将float轉換為int而把所有連續變量轉換為離散變量
# 此轉換僅用于示範目的

train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)

num_feature = 2 # 從原資料集中選擇兩個變量

feature_index = CFS.cfs(train_set, train_y) # 在訓練集上訓練
transformed_train = train_set[:,feature_index[0:num_feature]] # 轉換訓練集
assert np.array_equal(transformed_train, train_set[:,[3,2]])  # 其選擇了第三個及第四個變量

transformed_test = test_set[:,feature_index[0:num_feature]] # 轉換測試集
assert np.array_equal(transformed_test, test_set[:,[3,2]]) # 其選擇了第三個及第四個變量
      

1.1.2.3 Fast Correlation-based Filter (FCBF) 基于相關性的快速特征選擇

相比于CFS,FCBS能夠更加高效的篩選變量。其同樣為逐漸(step-wise)的方法,具體步驟與mRMR非常類似,但FCBS使用對稱不确定性(SU)衡量變量間的關聯性。FCBF首先剔除與目标變量具有較低SU值的變量,并對剩下的變量按與目标變量的SU值從最高到最低排序,然後逐一删除備援特征。與mRMR,CFS相似,在skfeature中實作的FCBF僅适用于具有離散變量的分類問題。

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

步驟: 

1)計算每個特征變量 𝑋𝑖 與目标變量 𝑦 之間的相關性 𝑆𝑈(𝑋𝑖,𝑦) 

2)僅保留 𝑆𝑈(𝑋𝑖,𝑦) 大于一定門檻值 𝜎 的特征變量,組成候選清單 𝑆𝑙𝑖𝑠𝑡 

3)按照 𝑆𝑈(𝑋𝑖,𝑦) 值的大小對 𝑆𝑙𝑖𝑠𝑡 中的變量從大到小排序 

4)按順序依次計算每一個特征 𝑋𝑖 與候選清單 𝑆𝑙𝑖𝑠𝑡 中順序靠後的每一個特征 𝑋𝑗 的相關SU值 𝑆𝑈(𝑋𝑖,𝑋𝑗) 

5)若 𝑆𝑈(𝑋𝑖,𝑋𝑗) 大于 𝑆𝑈(𝑋𝑗,𝑦) ,則從候選清單 𝑆𝑙𝑖𝑠𝑡 中删除 𝑋𝑗

import numpy as np
from skfeature.function.information_theoretical_based import FCBF
from sklearn.datasets import load_iris  # 利用iris資料作為示範資料集

# 載入資料集
iris = load_iris()
X, y = iris.data, iris.target

# 選擇前100個觀測點作為訓練集
# 剩下的50個觀測點作為測試集
# 由于skfeature中的FCFS僅适用于離散變量
# 是以我們通過将float轉換為int而把所有連續變量轉換為離散變量
# 此轉換僅用于示範目的

train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)

num_feature = 2 # 從原資料集中選擇兩個變量

feature_index = FCBF.fcbf(train_set, train_y, n_selected_features = num_feature)[0] # 在訓練集上訓練
transformed_train = train_set[:,feature_index[0:num_feature]] # 轉換訓練集
assert np.array_equal(transformed_train, train_set[:,[3]])  # 其僅選擇了第四個變量 
# 這是由于其他變量目标變量𝑦之間的相關性過低造成的

transformed_test = test_set[:,feature_index[0:num_feature]] # 轉換測試集
assert np.array_equal(transformed_test, test_set[:,[3]]) # 其僅選擇了第四個變量      

1.1.2.4 ReliefF

ReliefF方法是一種基于Relief方法的特征權重算法。在Relief方法中,其根據特征與目标變量的相關性強弱(二分類)給變量配置設定權重,并删除權重低于特定門檻值的特征。其将相關性定義為變量區分鄰近觀測點的能力。

具體來說,在每一步中,Relief方法都會從訓練集中随機選擇一個觀測點S,然後找到具有相同目标标簽的S的最近鄰觀測點,稱為NearHit。它還将找到具有不同目标标簽的S的最近鄰觀測點,稱為NearMiss。然後根據以下規則更新每個功能的權重:

1)若觀測點S在某變量上與NearHit的距離大于與NearMiss的距離,則該變量的權重将增加,因為變量有助于區分最鄰近情形下的目标标簽。2)相反,若觀測點S在某變量上與NearHit的距離小于與NearMiss的距離,則該變量的權重會降低。

将上述過程重複m次,最後我們會獲得每個特征變量的平均權重。特征變量的權重越大,則特征的分類能力越強,越應該被留在最終的特征子集中。

在ReliefF中,其修改了權重更新的方式,是以ReliefF方法可以被應用于多類分類問題。另外,它随機采樣K個最近的觀測點而不是一個。

在skfeature中實作的ReliefF可用于分類問題中的連續特征或二進制類别特征,因其使用的是L1範數來衡量差異。針對非二進制特征,我們可以先将其獨熱編碼,再使用ReliefF方法。

專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(三)

𝑅1 and 𝑅2 為任意兩個觀測點。𝑋𝑖為某一特征變量. S為我們選擇的觀測點. 𝐻𝑗為第j個NearHit,𝑀𝑗為第j個NearMiss. C為與我們所選的觀測點不同的其他目标類别标簽。

import numpy as np
from skfeature.function.similarity_based import reliefF
from sklearn.datasets import load_iris  # 利用iris資料作為示範資料集

# 載入資料集
iris = load_iris()
X, y = iris.data, iris.target

# 選擇前100個觀測點作為訓練集
# 剩下的50個觀測點作為測試集
# skfeature中的reliefF直接适用于連續變量

train_set = X[0:100,:]
test_set = X[100:,]
train_y = y[0:100]

num_feature = 2 # 從原資料集中選擇兩個變量

score = reliefF.reliefF(train_set, train_y) # 計算每一個變量的權重
feature_index = reliefF.feature_ranking(score) # 依據權重選擇變量
transformed_train = train_set[:,feature_index[0:num_feature]] # 轉換訓練集
assert np.array_equal(transformed_train, train_set[:,[2, 3]])  # 其選擇了第三個及第四個變量

transformed_test = test_set[:,feature_index[0:num_feature]] # 轉換測試集
assert np.array_equal(transformed_test, test_set[:,[2, 3]]) # 其選擇了第三個及第四個變量      

1.1.2.5 Spectral Feature Selection (SPEC) 基于譜圖的特征選擇

基于譜圖的特征選擇(SPEC)方法是基于譜圖理論的無監督方法。其首先建立變量相似度集合S,并建立其圖表示。然後,其根據構造圖的頻譜評估特征。由于在skfeature中實作的SPEC方基于RBF(高斯)核心建立相似集,是以其可用于分類問題中的連續特征或二進制類别特征。針對非二進制特征,我們可以先将其獨熱編碼,再使用ReliefF方法。

import numpy as np
from skfeature.function.similarity_based import SPEC
from sklearn.datasets import load_iris  # 利用iris資料作為示範資料集

# 載入資料集
iris = load_iris()
X, y = iris.data, iris.target

# 選擇前100個觀測點作為訓練集
# 剩下的50個觀測點作為測試集
# skfeature中的SEPC方法直接适用于連續變量

train_set = X[0:100,:]
test_set = X[100:,]
train_y = y[0:100]

num_feature = 2 # 從原資料集中選擇兩個變量

score = SPEC.spec(train_set) # 計算每一個變量的得分
feature_index = SPEC.feature_ranking(score) #依據變量得分選擇變量
transformed_train = train_set[:,feature_index[0:num_feature]] # 轉換訓練集
assert np.array_equal(transformed_train, train_set[:,[1, 0]])  # 其選擇了第一個及第二個變量

transformed_test = test_set[:,feature_index[0:num_feature]] # 轉換測試集
assert np.array_equal(transformed_test, test_set[:,[1, 0]]) # 其選擇了第一個及第二個變量      

專欄系列:

專欄 | 基于 Jupyter 的特征工程手冊:資料預處理(一) 專欄 | 基于 Jupyter 的特征工程手冊: 資料預處理(二) 專欄 | 基于 Jupyter 的特征工程手冊:資料預處理(三) 專欄 | 基于 Jupyter 的特征工程手冊:資料預處理(四) 專欄 | 基于 Jupyter 的特征工程手冊:特征選擇(一)

專欄 | 基于Jupyter 的特征工程手冊:特征選擇(二)

目前該項目完整中文版正在制作中,請持續關注哦~

中文版 Jupyter 位址:

https://github.com/YC-Coder-Chen/feature-engineering-handbook/blob/master/

中文版/2.%20特征選擇.ipynb

繼續閱讀