在機器學習流程中,特徵降維和變數選擇是兩種關鍵的資料預處理技術。特徵降維旨在降低資料的維度,同時保留重要的資訊,而變數選擇則旨在識別和選擇與目標變數最相關的特徵。本文將探討如何在 PySpark 中應用這些技術,並介紹一些進階的變數處理方法。高維資料通常會增加計算複雜度,並可能導致模型過擬合。PCA 和 SVD 是兩種常用的降維技術,它們透過線性變換將資料投影到低維空間。PySpark 提供了方便的工具來實作這些技術,可以有效地處理大規模資料集。對於變數選擇,卡方檢定和根據模型的特徵重要性是兩種常用的方法。卡方檢定適用於類別變數,而根據模型的特徵重要性則可以應用於各種型別的變數。此外,WOE 和 IV 可以用於評估變數的預測能力,而斯皮爾曼相關係數則可以幫助我們進行單調分箱,從而提高模型的效能。
主成分分析(PCA)在特徵降維中的應用
在機器學習和資料分析中,主成分分析(PCA)是一種常見的降維技術,用於減少資料集的特徵數量同時保留大部分的資訊。本文將探討PCA的工作原理、PySpark中的實作方法,以及在實際應用中的注意事項。
PCA的工作原理
PCA透過找出資料的主要成分,將原始資料投影到新的座標系中,使得資料在新的座標系中具有最大的變異數。第一主成分(PC1)是資料變異數最大的方向,第二主成分(PC2)是與PC1正交且變異數次大的方向,依此類別推。
圖解PCA
圖表翻譯: 此圖示展示了PCA如何將原始資料轉換到主成分空間,並選取主要成分進行降維。
PySpark中的PCA實作
在PySpark中,可以使用PCA類別來實作主成分分析。以下是一個範例程式碼:
from pyspark.ml.feature import PCA
from pyspark.ml.linalg import Vectors
# 設定主成分數量
no_of_components = 3
# 初始化PCA模型
pca = PCA(k=no_of_components, inputCol="features", outputCol="pcaFeatures")
# 擬合模型並轉換資料
model = pca.fit(df)
result = model.transform(df).select("pcaFeatures")
result.show(truncate=False)
內容解密:
PCA類別用於建立PCA模型,其中k引數指定了要保留的主成分數量。inputCol引數指定了輸入的特徵欄位名稱。outputCol引數指定了輸出的主成分特徵欄位名稱。fit方法用於擬合PCA模型,transform方法用於將原始資料轉換到主成分空間。
載入分數與變異數解釋
載入分數代表了原始特徵在主成分上的權重,可以用來解釋主成分的意義。變異數解釋則代表了每個主成分能夠解釋的資料變異數比例。
# 取得載入分數
loading_scores = model.pc.toArray()
print(loading_scores)
# 取得變異數解釋
explained_variance = model.explainedVariance
print(explained_variance)
內容解密:
model.pc.toArray()用於取得載入分數矩陣,每一列代表一個主成分,每一行代表一個原始特徵。model.explainedVariance用於取得每個主成分的變異數解釋比例。
資料標準化對PCA的影響
在進行PCA之前對資料進行標準化可以避免因為特徵尺度不同而導致的主成分偏差。
from pyspark.ml.feature import StandardScaler
# 資料標準化
scaler = StandardScaler(inputCol="assembled_features", outputCol="features2")
stages = [assembler, scaler]
pipeline = Pipeline(stages=stages)
scaleAssembleModel = pipeline.fit(df)
df = scaleAssembleModel.transform(df).select(selectedCols)
內容解密:
StandardScaler用於對資料進行標準化,將特徵縮放到相同的尺度上。- 將標準化後的資料用於PCA,可以獲得更穩健的主成分。
奇異值分解(SVD)與變數選擇
奇異值分解(Singular Value Decomposition, SVD)是一種矩陣分解技術,幾乎可以應用於任何矩陣,使其成為一種穩定的演算法。SVD 將一個矩陣分解為三個矩陣:U、Σ 和 V,使得 A = UΣV^T。
SVD 的組成部分
- A 是原始矩陣,維度為 r x c,其中 r 是行數,c 是列數。
- U 是一個 r x r 的矩陣,被稱為 A 的左奇異向量。
- Σ 是一個 r x c 的對角矩陣,其對角線上的值是原始矩陣 A 的奇異值。
- V^T 是一個 c x c 的矩陣,被稱為 A 的右奇異向量。
SVD 與變數選擇的關係在於 Σ 矩陣。假設有一個影像具有 1,000 個特徵,使用 SVD 可以從 Σ 矩陣中選取前 k 個奇異值,根據要在低維度中表示的資訊量來選擇 k。在 PCA 中,可以將其視為解釋的變異數。假設前 100 個特徵(k=100)解釋了資料中 80% 的資訊,並且可以接受這樣的結果,那麼就可以選取前 100 個奇異值,並將 Σ 矩陣中的其他值替換為 0。由此產生的低秩矩陣可以用於建立原始資料的表示。
SVD 在 PySpark 中的實作
from pyspark.mllib.linalg import Vectors
from pyspark.mllib.linalg.distributed import RowMatrix
# 將 DataFrame 轉換為 RDD,並提取特徵作為陣列
df_svd_vector = df.rdd.map(lambda x: x['features'].toArray())
# 從向量 RDD 建立 RowMatrix
mat = RowMatrix(df_svd_vector)
# 計算前 5 個奇異值和對應的奇異向量
svd = mat.computeSVD(5, computeU=True)
U = svd.U # U 因子是一個 RowMatrix
s = svd.s # 奇異值儲存在本地密集向量中
V = svd.V # V 因子是一個本地密集矩陣
內容解密:
- 匯入必要的函式庫:首先,需要從
pyspark.mllib.linalg和pyspark.mllib.linalg.distributed中匯入Vectors和RowMatrix,以便進行矩陣運算。 - 將 DataFrame 轉換為 RDD:使用
rdd.map將 DataFrame 中的特徵欄位轉換為陣列形式,以便建立 RowMatrix。 - 建立 RowMatrix:透過
RowMatrix函式,將向量 RDD 轉換為分散式矩陣,以便進行 SVD 分解。 - 計算 SVD:使用
computeSVD方法計算矩陣的 SVD 分解,並指定要保留的奇異值數量(此例中為 5)。 - 提取分解結果:SVD 分解後,分別提取 U、Σ(以 s 表示)和 V 三個矩陣。其中,U 是左奇異向量組成的 RowMatrix,s 是奇異值組成的向量,V 是右奇異向量組成的矩陣。
卡方選擇器(ChiSq Selector)
卡方選擇器使用卡方檢定來選擇最佳特徵,適用於處理類別變數。如果要使用連續變數,需要先將其分組。
卡方檢定的步驟
- 建立列聯表:根據變數之間的關係建立列聯表,例如在 Titanic 資料集中分析性別與存活率之間的關係。
- 提出虛無假設和替代假設:
- 虛無假設:兩個變數之間沒有關係。
- 替代假設:兩個變數之間存在關係。
- 計算卡方值:使用公式 χ² = Σ [(觀察值 - 期望值)^2 / 期望值] 計算卡方值。
- 計算自由度:使用公式 df = (r-1) * (c-1) 計算自由度,其中 r 是列數,c 是行數。
- 查詢 p 值:根據卡方值和自由度查詢 p 值,如果 p 值小於指定的顯著性水平(通常為 0.05),則拒絕虛無假設,認為兩個變數之間存在關係。
圖表翻譯:
此圖示呈現了 Titanic 資料集中性別與存活率之間的關係,從中可以看出女性存活率遠高於男性。
變數選擇技術在機器學習中的重要性
在機器學習領域,變數選擇(Variable Selection)是一個至關重要的步驟。它的主要目標是從原始資料集中選出最相關的特徵,以提高模型的預測準確性和降低計算成本。在本章中,我們將探討兩種主要的變數選擇技術:根據卡方檢驗(Chi-square)和根據模型的特徵重要性(Model-based Feature Importance)。
根據卡方檢驗的變數選擇
卡方檢驗是一種統計方法,用於評估兩個類別變數之間的相關性。在變數選擇的背景下,卡方檢驗可以幫助我們識別出與目標變數最相關的特徵。
程式碼範例:
from pyspark.ml.feature import ChiSqSelector
from pyspark.ml.linalg import Vectors
# 選擇類別特徵
features_list = char_vars
# 初始化 ChiSqSelector
selector = ChiSqSelector(numTopFeatures=6, featuresCol="features",
outputCol="selectedFeatures", labelCol="y")
# 擬合資料
chi_selector = selector.fit(df)
# 轉換資料
result = chi_selector.transform(df)
# 輸出結果
print("ChiSqSelector output with top %d features selected" % selector.getNumTopFeatures())
print("Selected Indices: ", chi_selector.selectedFeatures)
features_df['chisq_importance'] = features_df['idx'].apply(lambda x: 1 if x in chi_selector.selectedFeatures else 0)
print(features_df)
內容解密:
- 匯入必要的函式庫:我們匯入了
ChiSqSelector和Vectors,它們分別用於執行卡方檢驗和處理特徵向量。 - 選擇類別特徵:透過
char_vars選擇了類別特徵,這些特徵將被用於卡方檢驗。 - 初始化 ChiSqSelector:建立了一個
ChiSqSelector物件,指定了要選擇的特徵數量 (numTopFeatures=6)、特徵列 (featuresCol="features")、輸出列 (outputCol="selectedFeatures") 和標籤列 (labelCol="y")。 - 擬合和轉換資料:使用
fit方法擬合資料,然後使用transform方法轉換資料,以獲得選定的特徵。 - 評估結果:輸出了選定的特徵索引,並在
features_df中標記了被選中的特徵。
根據模型的特徵重要性
根據模型的特徵重要性是一種透過訓練機器學習模型來評估特徵重要性的方法。在本例中,我們使用了隨機森林(Random Forest)模型。
程式碼範例:
from pyspark.ml.classification import RandomForestClassifier
# 初始化隨機森林分類別器
rf = RandomForestClassifier(featuresCol='features', labelCol=target_variable_name)
# 擬合模型
rf_model = rf.fit(df)
# 取得特徵重要性
rf_model.featureImportances
# 處理特徵重要性輸出
import pandas as pd
features_df = pd.DataFrame()
for k, v in df.schema["features"].metadata["ml_attr"]["attrs"].items():
final = pd.DataFrame(v)
features_df = features_df.append(final, ignore_index=True)
rf_output = rf_model.featureImportances
features_df['Importance'] = features_df['idx'].apply(lambda x: rf_output[x] if x in rf_output.indices else 0)
features_df.sort_values("Importance", ascending=False, inplace=True)
內容解密:
- 匯入隨機森林分類別器:匯入了
RandomForestClassifier,用於建立隨機森林模型。 - 初始化和擬合模型:建立了一個隨機森林分類別器,並使用資料擬合了模型。
- 取得特徵重要性:透過
featureImportances取得了特徵重要性評分。 - 處理輸出:將特徵重要性評分與特徵名稱對應起來,並按重要性排序。
圖表翻譯:
此圖示展示了不同特徵的重要性評分,可以用於直觀地理解哪些特徵對模型的預測貢獻最大。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title PySpark特徵降維與變數選擇技術
package "機器學習流程" {
package "資料處理" {
component [資料收集] as collect
component [資料清洗] as clean
component [特徵工程] as feature
}
package "模型訓練" {
component [模型選擇] as select
component [超參數調優] as tune
component [交叉驗證] as cv
}
package "評估部署" {
component [模型評估] as eval
component [模型部署] as deploy
component [監控維護] as monitor
}
}
collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型
note right of feature
特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理
end note
note right of eval
評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC
end note
@enduml
圖表翻譯: 此圖表展示了不同特徵對應的重要性評分,數值越大表示該特徵越重要。
連續與多項式目標變數的處理
在處理目標變數時,我們需要根據其型別選擇適當的模型。對於連續型目標變數,可以使用迴歸樹(如 RandomForestRegressor)進行建模,這些模型可以在 pyspark.ml.regression 模組中找到。與此同時,需要使用 LinearRegression 模組取代 LogisticRegression 來建立連續型模型。其餘的程式碼可以用於計算特徵重要性。
對於多項式目標變數,仍然可以使用根據樹的模型,如前文所述,但不適用於線性模型 LogisticRegression。當處理多項式目標變數時,使用邏輯迴歸計算特徵重要性會比較棘手。因此,建議使用根據樹的模型來處理這類別目標變數。
自定義變數選擇流程
本文將介紹一些自定義的變數選擇技術。
使用證據權重(WOE)和資訊價值(IV)
證據權重(WOE)和資訊價值(IV)是簡單而強大的技術,用於進行變數轉換和選擇。這些概念與邏輯迴歸建模技術密切相關,廣泛應用於信用評分領域,用於衡量好客戶與壞客戶之間的區隔。
計算 WOE 和 IV 的公式如下:
WOE = ln(%Event/%NonEvent)
IV = ∑(%Event - %NonEvent) * ln(%Event/%NonEvent)
或者簡化為:
IV = ∑(%Event - %NonEvent) * WOE
WOE 轉換的優點包括:
- 能夠處理缺失值。
- 能夠處理異常值。
- 轉換根據分佈的對數值,與邏輯迴歸輸出函式一致。
- 無需使用虛擬變數。
- 使用適當的分箱技術可以建立獨立變數與依賴變數之間的單調關係。
IV 值可以用於根據預測能力表(如圖 4-15 所示)選擇變數。
使用斯皮爾曼相關係數進行單調分箱
首先,我們來瞭解什麼是單調關係。如圖 4-16 所示,當 x 軸變數增加時,y 軸值具有單一趨勢(增加或減少),這就是單調關係。
斯皮爾曼相關係數用於衡量兩個變數之間的單調關聯強度和方向。它與皮爾森相關係數不同,後者用於測試兩個變數之間的線性關係。
斯皮爾曼相關係數的計算公式如下:
ρ = 1 - (6*∑d_i^2)/(n*(n^2 - 1))
其中,ρ 是斯皮爾曼相關係數,d_i 是成對排名的差異,n 是案例數量。
當斯皮爾曼相關係數的值接近 1 或 -1 時,表示兩個變數之間的單調關係較強;當值接近 0 時,表示沒有單調關係。
在單調分箱的程式碼中,mono_bin() 函式使用 max_bin 選項,該選項由使用者指定。對於連續型變數,我們從使用者提供的 max_bin 開始,然後在每個步驟中減少分箱數量,以建立分位數。
程式碼範例與實作練習
練習 4-2:根據模型的特徵選擇
- 實作決策樹特徵重要性,並與隨機森林輸出進行比較。
- 實作梯度提升樹特徵重要性,並與隨機森林輸出進行比較。
- 實作邏輯迴歸特徵重要性,並與隨機森林輸出進行比較。(提示:使用邏輯迴歸的係數,注意邏輯迴歸產生的是密集向量而非稀疏向量。)
自定義變數選擇技術實作
使用 WOE 和 IV 進行變數選擇,並利用斯皮爾曼相關係數進行單調分箱,以最佳化連續型變數的處理。
#### 內容解密:
上述內容主要講解了如何根據目標變數的型別選擇適當的模型,以及如何使用自定義變數選擇技術來最佳化模型的表現。其中,WOE 和 IV 是用於衡量變數預測能力的指標,而斯皮爾曼相關係數則用於評估變數之間的單調關係,從而實作單調分箱。這些技術在信用評分和金融風險評估等領域具有廣泛的應用價值。
圖表翻譯:
圖 4-14 展示了 WOE 和 IV 的計算過程。圖 4-15 說明瞭 IV 值與預測能力之間的關係。圖 4-16 對比了單調關係和非單調關係。圖 4-17 和圖 4-18 分別展示了餘額與目標變數之間的單調關係,以及斯皮爾曼相關係數的計算過程。圖 4-19 提供了一個,用於判斷斯皮爾曼相關係數值的強度。