Hike News
Hike News

機器學習-特徵工程-降維

Introduction

降維不是將array的維度減少(3D陣列->2D陣列),而使指將特徵的數量減少
DecreaseDimension

  • 有些特徵與目標值較無關係,會選擇將此特徵剃除,稱之為降維
    • 拋棄掉對模型帶來負面影響的特徵
  • 得到一組"特徵間相互獨立(不相關)"主變量的過程

數據降維通常有兩種方式:

  1. 特徵選擇
  2. 主成分分析

特徵選擇(feature_selection)

從所有的特徵中,選擇出有意義的對模型有幫助的特徵,通常須人為的挑選,同時也必須了解相關業務知識

  • 避免必須將所有特徵都導入模型進行訓練的窘境
  • 重要!!:必須與數據提供者討論

選擇後的特徵維數肯定比選擇前小,特徵在選擇和選擇後可以改變值

  • 冗餘特徵:部份特徵相關度高,容易消耗計算性能
  • 噪聲特徵(不需要的特徵):對預測結果造成影響

主要方法

  • Filter(過濾式):VarianceThreshold
    • 透過特徵本身的方差來篩選特徵
    • 主要探究特徵本身特點、特徵和目標值之間關聯
    • 方差選擇法:低方差特徵過濾
    • 相關係數:得知特徵與特徵之間的相關程度
  • Embedded(嵌入式):算法自動選擇特徵(特徵與目標之間的關聯)
    • 正則化:L1、L2
    • 決策樹:信息熵、信息增益
    • 深度學習:巻積等
  • Wrapper(包裹式) -> 較不常使用

VarianceThreshold(方差門檻)

  • 將方差較小的特徵刪除:樣本間特徵集中(相似),較不易影響最後結果
    • 特徵方差小:某個特徵大多樣本的值比較相近;表示此特徵在此數據集上幾乎沒有差異
      • 此特徵對於區分樣本沒有貢獻(可能須刪除)
      • 優先消除方差為0的特徵
    • 特徵方差大:某個特徵大多樣本的值都有差別
  • 使用sklearn.feature_selection.VarianceThreshold

VarianceThreshold(threshold = 0.0)

刪除所有低方差的特徵

  • threshold:指定方差小於多少則刪除特徵,預設為0

fit_transform(X)

  • X: numpy array格式的數據[n_sample, n_features]
  • 返回值: 訓練集差異低於threshold的特徵將被刪除
    • 預設值是保留所有非零方差的特徵,即刪除所有樣本中具有相同值的特徵

流程

  1. 初始化VarianceThreshold
    • 指定方差的threshold
  2. 調用fit_transform

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.feature_selection import VarianceThreshold

UnFS_data = [[90,2,1000,0.8,1],
[120,5,2500,0.75,1],
[45,10,1800,0.38,1],
[45, 10, 1800, 0.38,1],
[30, 7, 3500, 0.11,1],
[75, 8, 2700, 0.29,1],]

def featureSelect_VT():
VT = VarianceThreshold(threshold=0.0)
FS_data = VT.fit_transform(UnFS_data)
print(FS_data)

if __name__ == '__main__':
featureSelect_VT()
  • 根據自己的需求設置threshold之值,默認為0

特徵篩選後

1
2
3
4
5
6
[[9.0e+01 2.0e+00 1.0e+03 8.0e-01]
[1.2e+02 5.0e+00 2.5e+03 7.5e-01]
[4.5e+01 1.0e+01 1.8e+03 3.8e-01]
[4.5e+01 1.0e+01 1.8e+03 3.8e-01]
[3.0e+01 7.0e+00 3.5e+03 1.1e-01]
[7.5e+01 8.0e+00 2.7e+03 2.9e-01]]

tips

  • 如果一開始已經明確知道要多少特徵,方差(VarianceThreshold)也可以一步到位進行處理
    • 希望留下一半特徵:
      • 找到全部特徵列的方差,將各特徵列的方差其中位數作為threshold參數的值即可
        • .var()可查詢各列特徵的方差
        • 利用np.median()尋找中位數

特徵為二分類

特徵為二分類時,特徵的取值就是伯努利分布(取值非0即1)

  • 其分布的方差可以計算:

  • 假設 $p$ = 0.8 ,表示二分類特徵中某種分類佔到80%以上時就刪除特徵

1
2
x_bvar = VarianceThreshold(.8*(1-.8)).fit_transform(Binary_UnFS_data)
x_bvar.shape #查看刪除結果

結論

  • 方差過濾法適用於需要遍歷特徵或升維的演算法,包括KNN,SVM等等
    • 會大幅度的減少計算成本
    • 對隨機森林較無效果
      • 隨機森林是隨機選取特徵
  • 主要目的:在維持演算法表現的前提下,幫助算法降低計算成本

其他特徵選擇方法

  • 神經網路

相關係數

降維的目的在於得到一組"特徵間相互獨立(不相關)"主變量的過程,因此得知特徵之間的相關性是極重要的

  • 相關係數可以知道特徵之間的相關程度
  • 較常用皮爾遜相關係數(Pearson Correlation Coefficient)
    • 反應變量之間相關關係密切程度的統計指標

特點

相關係數(r)值介於-1 至 1 之間,即-1 ≤ r ≤ 1,其性質如下:

  • 當 r > 0 時,表示兩變量正相關;r < 0 時,兩變量為負相關
  • 當 |r| = 1 時,表示兩變量為完全相關; r = 0 時,表示兩變量間無相關關係
  • 當 0 < |r| < 1 時,表示兩變量存在一定程度相關,且|r|越接近1,兩變量間線性關係越密切;且|r|越接近0,兩變量間線性相關越弱
  • 一般分為三個等級:
    • |r| < 0.4 為低度相關
    • 0.4 ≤ |r| < 0.7 為顯著性相關
    • 0.7 ≤ |r| < 1 為高度線性相關

Example

計算年廣告費投入與月均銷售額之間的關係

  • 有10個樣本數

Imgur

  • 最終計算的結果為0.9942

API

其位於scipy.stats中的pearsonr函數,其有兩個參數

  • x : 特徵x數據,為array_like形式
  • y : 特徵y數據,為array_like形式
  • 返回一元組,第一個值為r值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from scipy.stats import pearsonr

data = [[12.5,21.2],
[15.3,23.9],
[23.2,32.9],
[26.4,34.1],
[33.5,42.5],
[34.4,43.2],
[39.4,49.0],
[45.2,52.8],
[55.4,59.4],
[60.9,63.5]]

X = [x[0] for x in data]
Y = [x[1] for x in data]

r_value = pearsonr(X,Y)
print("Relation Coefficient : %s"%r_value[0])

Result

1
Relation Coefficient : 0.9941983762371883

tips

  • 特徵與特徵相關性很高的情況下,可在進行其處理
    • 選取其中一個特徵作為代表,刪除另一個特徵
    • 按一定權重求和作為新特徵
      • X特徵50% + Y特徵50%
    • 主成分分析

主成分分析(PCA)

定義:高維度數據化為低維度數據的過程,在此過程中可能會捨棄原有數據,創造新的變量;是一種分析、簡化數據集的技術。
雖然主要用於減少維度,但仍希望信息盡可能的表示完整,不會損耗太多
目的:使數據維數壓縮,盡可能降低原數據的維度(複雜度),但損失最少量信息
作用:可以削減回歸分析或者聚類分析中特徵的數量
應用場景:當特徵數量達到上百時,才會考慮用PCA去簡化數據

  • 使用sklearn.decomposition import PCA

高維度數據的問題

  • 特徵之間容易出現一些相關的特徵

重要參數

n_components=None

降維後所需要的維度(即降維後需要保留的特徵數量)

  • 為一超參數
  • 可以有三種形式:
    • 浮點數形式(介於0-1):保留多少百分比的信息(例如0.9為90%),人為可控參數,建議90%-95%
      • 當使用n_components為浮點數形式時,必須要指定svd_solver參數為"full"否則效果會不佳
        • PCA(n_components=0.97,svd_solver="full")
    • 整數形式:減少到多少特徵數量(一般較少使用)
      • 其介於0 - min(X.shape)
      • 可使用這種輸入方式畫出 累計可解釋方差貢獻曲線,以此選擇最好的n_components整數取值
        • 降維後的特徵個數 為 橫坐標;降維後新特徵矩陣捕捉到的累加可解釋方差貢獻率 為 縱座標
        • 可搭配numpy.cumsum()方法一起使用
          • numpy.cumsum(pca_lin_object.explained_variance_ratio_)
    • "mle":使用 最大似然估計(maximum likehood estimation) 自選超參數的方法
      • 計算量非常大,謹慎使用
  • 要是其不填任何值,則為min(X.shape)個特徵

svd_solver

奇異值分解器;共有四種不同的模式

sklearn將降維流程拆分成兩部份:

  • 計算特徵空間$V$ 由奇異值分解完成
    • 利用SVD的性質減少計算量,但是信息量的評估指標仍為PCA所使用的方差
  • 映射數據 及 求解新特徵矩陣 由主成分分析完成
  • 雖是PCA降維方法(使用CPCA本身特徵值分解),但是可以透過使用奇異值分解來減少計算量
  • 預設為"auto":基於X.shapen_components的預設策略來選擇分解器
    • 如果輸入的數據大於$500\times500$;且欲提取的特徵數**小於數據最小維度(min(X.shape))的80%,啟用效率更高的"randomized"方法
    • 否則精確完整的SVD($U{(m,m)},\sum{m,n},V^T_{(n,n)}$) 完整三個矩陣將被計算(同"full"模式)
  • "full":從scipy.linalg.svd中調用標準的LAPACK分解器來生成精確完整的SVD
    • 適合數據量比較適中,計算時間充足的情況使用
  • "arpack":從scipy.sparse.linalg.svds調用標準的ARPACK分解器來運行截斷奇異值分解(SVD truncated)
    • 分解時救將特徵數量降到n_components中輸入的值
      • 分解時同時降維
    • 可以加快運算速度
    • 適合特徵矩陣很大的時候
      • 一般用於特徵矩陣為稀疏矩陣的情況
    • 過程包含一定的隨機性
  • "randomized":生成多個隨機向量,一一檢測隨機向量中是否有符合分解需求的,如果有,則保留此隨機向量
    • 基於保留的隨機向量方向構建向量空間
    • full模式快,且能保證運行效果
    • 適合特徵矩陣巨大,計算量龐大的情況

random_state

此參數只在svd_solver"arpack""randomized"時生效,可控制兩個SVD模式中的隨機模式

方法

fit_transform(X)

X: numpy array格式的數據[n_sample, n_features]
返回值: 轉換後指定維度的array

inverse_transform

  • inverse_transform後並非原圖片信息
    • PCA降維過程中刪除掉的信息無法復原
    • 並不是完全可逆
  • 應用:可在不完全恢復原始數據的情況下,將降維後的數據返回原本的維度,達到降噪效果
    • 保證維度,但去掉方差很小特徵所帶的信息

流程

  1. 初始化PCA轉換器
    • 指定減少後的維度(整數) 或 保留多少%信息(浮點數)
  2. 調用fit_transform

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sklearn.decomposition import PCA

UnDD_data = [[90,2,1000,0.8,1],
[120,5,2500,0.75,1],
[45,10,1800,0.38,1],
[45, 10, 1800, 0.38,1],
[30, 7, 3500, 0.11,1],
[75, 8, 2700, 0.29,1],]

# 主成分分析進行特徵降維
def DecreaseDimension_PCA():
pca = PCA(n_components=0.95)
DD_data = pca.fit_transform(UnDD_data)
print(DD_data)

if __name__ == '__main__':
DecreaseDimension_PCA()

降維結果

1
2
3
4
5
6
[[-1216.836117  ]
[ 282.78600381]
[ -416.41490377]
[ -416.41490377]
[ 1283.6463807 ]
[ 483.23354004]]

重要屬性

explainedvariance

查看降維後每個新特徵所帶的信息量大小(可解釋性方差的大小)

  • pca實例.explained_variance_
  • 第一個特徵的信息量(方差)通常最大(數據會被壓縮在盡量少的特徵上)
    • 因此會盡量壓縮在第一個特徵
    • 後面特徵所帶的信息量會越來越少

explainedvariance_ratio

查看降維後每個新特徵向量所占的信息量占原始數據總信息量的百分比

  • 又稱可解釋方差貢獻率
  • pca實例.explained_variance_ratio_
  • pca實例.explained_variance_ratio_.sum()
    • 其代表矩陣降維後的特徵向量貢獻率加和,為原始數據信息量的百分比

components_

查看降維過後的新特徵空間$V(k,n)$

  • $V(k,n)$:是要將原始數據進行映射的那些 新特徵向量 組成的矩陣
    • 當$V(k,n)$是數字時,無法判斷$V(k,n)$和原有的特徵的聯繫
    • 但是如果原特徵矩陣為圖像;且$V(k,n)$此空間矩陣可以被可視化
      • 可通過原圖及空間矩陣兩張圖比較,知道新特徵空間$V(k,n)$從原始數據中提取什麼信息
      • 運用於人臉識別
  • $k$:n_components 輸入的整數
  • $n$:原特徵矩陣的feature數目
  • pca實例.components_
  • pca實例.somponents_.shape

tips

  • 通常會對擁有高維度的數據進行降維處理
  • 通常在能進行PCA降維的情況下,不會進行特徵選擇
    • 無法使用PCA降維的情況下才會做特徵選擇