
我剛開始學資料科學的時候,總覺得「欄位越多,資訊量越大,模型應該越準吧?」
後來我才發現,這完全是個誤區。這在業界有個專業術語叫「維度詛咒」(Curse of Dimensionality)。
過多的垃圾欄位不僅會干擾模型判斷,還會讓模型變得極度不穩定。
今天我想跟你聊聊,在我自己的實戰流程中,我是如何透過「過濾法」(Filter Methods)來快速瘦身資料集,只留下那些真正有價值的特徵。
什麼是過濾法?為什麼它是你的第一道防線?
在特徵選擇(Feature Selection)的世界裡,方法有很多種,但「過濾法」絕對是 CP 值最高的一種。
簡單來說,過濾法就像是夜店門口的「保鑣」。
它不看你的內在(模型效能),只看你的基本條件(統計指標)。
它會根據每個特徵與目標變數(Target)之間的相關性,給出一個分數,分數太低的直接踢掉。
為什麼我推薦先用過濾法?
1. 速度極快: 它不需要訓練任何模型,純粹是數學計算。
2. 不挑模型: 無論你最後是用隨機森林還是邏輯斯迴歸,過濾法的篩選結果都具有參考價值。
3. 預處理的 MVP: 它是把 500 個欄位縮減到 50 個最有效率的手段。
下面我拆解了五種我最常用的過濾法,附上實戰程式碼,建議你直接存起來。
皮爾森相關係數 (Pearson Correlation):最直觀的線性指標

這應該是大家最熟悉的統計量。它衡量的是兩個變數之間「線性」關係的強弱,值介於 -1 到 1 之間。
1: 你加一倍,我也加一倍(完全正相關)。
-1: 你加一倍,我減一倍(完全負相關)。
0: 我們兩個各走各的路,沒什麼線性關係。
我自己的經驗:
皮爾森雖然好用,但它有一個很大的「雷點」——它假設資料是常態分佈且具有線性關係。如果你發現你的資料分佈很奇怪,或者兩者關係是曲線(例如:拋物線),皮爾森可能就會失準。
實戰程式碼範例:
import pandas as pd
from sklearn.datasets import load_breast_cancer
# 載入經典的乳癌資料集
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)
#計算特徵與目標的皮爾森相關係數
correlations = X.corrwith(y)
看看誰才是關鍵欄位(取絕對值,因為負相關也很重要)
top_features = correlations.abs().sort_values(ascending=False)
print("與癌症診斷最相關的前 5 個特徵:")
print(top_features.head(5))
斯皮爾曼相關係數 (Spearman’s Rank Correlation):對付「不乖」的資料

如果你的資料裡有很多極端值(Outliers),或者分佈根本不符合常態(例如:收入分佈、流量數據),皮爾森可能會騙了你。
這時候,我會換成「斯皮爾曼相關係數」。
它的原理很有趣:它不看數值大小,而是看「排名」。
這意味著它捕捉的是「單調關係」(Monotonic relationship)。
只要變數 A 增加時,變數 B 也跟著增加(不一定要線性增加),斯皮爾曼就會給高分。
為什麼要用它?
它比皮爾森更「強健」(Robust),不容易被一兩個偏離值帶風向。
實戰程式碼範例:
# 只要改一個參數 method='spearman'
spearman_correlations = X.corrwith(y, method='spearman')
print("斯皮爾曼相關性排序:")
print(spearman_correlations.abs().sort_values(ascending=False).head(5))
肯德爾相關係數 (Kendall’s Tau):小樣本的精準專家

肯德爾係數跟斯皮爾曼很像,也是基於排名。但它更關注「配對的一致性」。
我什麼時候會用?
當我的資料量很小(Small sample size)或者是分類等級資料(Ordinal data)時。
它的統計效力在小樣本下通常比斯皮爾曼更好,算出來的結果也更穩定。
實戰程式碼範例:
# method 換成 'kendall'
kendall_correlations = X.corrwith(y, method='kendall')
print("肯德爾相關性排序:")
print(kendall_correlations.abs().sort_values(ascending=False).head(5))
卡方檢驗 (Chi-Square Test):分類問題的必備良藥

前面三個方法主要針對連續型變數(數字)。
但如果你的特徵是類別型(例如:性別、地區、會員等級),目標也是類別(如:是否購買),那你就得搬出「卡方檢驗」。
卡方檢驗是在看:這兩個類別變數之間是否「獨立」?
如果它們不獨立,說明這個特徵對預測目標很有幫助。
注意: 在 sklearn 中使用 `chi2` 前,數值必須是非負數,所以我通常會先做縮放。
實戰程式碼範例:
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.preprocessing import MinMaxScaler
# 1. 確保數值非負(Min-Max 縮放)
scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X)
# 2. 選出前 5 個最有解釋力的特徵
chi2_selector = SelectKBest(chi2, k=5)
X_kbest = chi2_selector.fit_transform(X_scaled, y)
# 3. 抓出這 5 個欄位的名字
selected_names = X.columns[chi2_selector.get_support()]
print("卡方檢驗選出的關鍵特徵:", list(selected_names))
方差選擇法 (Variance Threshold):剔除那些「沒反應」的欄位

這是我在做特徵工程時的第一步,甚至在看相關性之前就會先做。
邏輯非常簡單:
如果一個欄位在所有樣本中幾乎都長一樣(例如 99% 的人的某個數值都是 0),那這個欄位的「變異度」(Variance)就非常低。
一個幾乎不變動的欄位,是不可能提供任何預測資訊的。
這就像是:
你在調查「影響健康的因素」,結果每個人都回答「我有呼吸」。
那「有呼吸」這個指標對你的研究就毫無價值,因為它沒有區別性。
實戰程式碼範例:
from sklearn.feature_selection import VarianceThreshold
# 設定門檻:如果變異度小於 0.1 就不要了
# 這裡要注意,這會受到資料單位影響,建議先做標準化或針對特性調整
variance_selector = VarianceThreshold(threshold=0.1)
X_high_variance = variance_selector.fit_transform(X)
print("過濾後的剩餘特徵數量:", X_high_variance.shape[1])
麥特的實戰思考框架:我該怎麼選?
看了這麼多,你可能想問:「麥特,那我到底該用哪一個?」
別糾結,這是我整理的「快速決定清單」,你可以直接套用:
1. 先跑方差選擇法 (Variance Threshold): 先把那些幾乎沒變動的垃圾欄位砍掉。
2. 看資料類型:
- 都是數字 (Continuous) + 符合常態: 用 Pearson。
- 有極端值或非線性: 用 Spearman。
- 樣本很少: 用 Kendall。
- 類別型 (Categorical): 用 Chi-Square。
3. 組合技: 實戰中,我通常會同時算 Pearson 和 Spearman。如果兩者選出的特徵差不多,那信心度就很高;如果差很多,我就會去檢查資料是否有嚴重的偏態或異常值。
總結:先求「瘦身」,再求「健美」
很多人在做資料分析時,會直接跳進複雜的算法調整。
但我的經驗告訴我:好的資料(Feature Selection)往往比好的模型更重要。
過濾法就是你的「瘦身」階段。
它雖然簡單,但能幫你過濾掉 80% 的雜訊,讓你剩下的精力能集中在真正有影響力的變數上。
這就是我常說的「槓桿原則」:花 20% 的力氣做統計篩選,能省下後續 80% 調整模型的痛苦。
【讀者專屬小任務】
如果你手邊剛好有一個資料集,不管是在 Kaggle 找的還是公司的資料,試著跑一下這行程式碼:
X.corrwith(y).abs().sort_values(ascending=False)
看看排名前五的欄位,是否跟你直覺想的一樣?
如果發現有某個看起來很廢的欄位相關性竟然很高,那恭喜你,你可能發現了數據裡的寶藏(或者是一個需要清理的 Bug)。
如果你在實作時遇到報錯,或者對哪種統計方法有疑問,歡迎在下方留言跟我討論!
如果你覺得這篇文章有幫你釐清概念,也歡迎分享給那個被「維度詛咒」困擾的朋友。
麥特資料探險 — 帶你用最實戰的方式,把資料變成資產。
