很多同學問:波段/特征一多就“維度災難”,訓練慢、過擬合,且很難解釋“哪些特征最關鍵”。本篇用 sklearn 給出一套能跑、可視化、可比較的最小工作流,并配上方法論速記,幫助你在高光譜/多特征任務里做出穩健篩選。
🎯 你將學到
- 三大范式的特征選擇:Filter / Wrapper / Embedded
- 為什么有效:統計相關性 vs. 子集搜索 vs. 模型內置重要性
- 如何落地:一段精簡代碼完成選擇→訓練→可視化→對比
🧠 方法論速記
-
Filter(過濾法):先驗統計量直接篩特征,不依賴具體模型,速度快。
- 例:Chi2/卡方檢驗,衡量特征與標簽的獨立性(需要非負特征)。
- 適用:快速粗篩,移除無信息/弱相關特征。
-
Wrapper(包裹法):把“選特征”當搜索問題,用模型性能做打分,通常更準但更慢。
- 例:RFE(遞歸特征消除):訓練模型→按重要性剔除最差→重復,直到剩 K 個。
- 適用:樣本量中小、追求更優子集、可接受計算成本。
-
Embedded(嵌入法):使用帶稀疏/重要性機制的模型,邊訓練邊選擇。
- 例:隨機森林特征重要性(基于分裂增益/不純度減少)。
- 適用:想要可解釋、穩健的一次性重要性排序。
實戰建議:Filter 粗篩 → Embedded 排序 → Wrapper 精修。多法交叉,關注一致入選的“關鍵波段”。
💻 一鍵可跑代碼(簡潔版)
僅需把
DATA_DIR = "your_path"
改成你的數據目錄(包含KSC.mat
與KSC_gt.mat
)。
# -*- coding: utf-8 -*-
"""
Sklearn案例⑦:特征選擇與重要性分析(簡潔可跑)
方法:Chi2 / RFE(Logistic) / RF-Importance
可視化:重要性曲線、入選熱圖、精度對比
"""import os, numpy as np, scipy.io as sio, matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import SelectKBest, chi2, RFE
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score# ===== 路徑與參數 =====
DATA_DIR = "your_path" # ← 修改為你的數據文件夾
TRAIN_RATIO= 0.3
SEED = 42
K_SELECT = 30 # 目標特征數# ===== 1) 載入有標注像素 =====
X_cube = sio.loadmat(os.path.join(DATA_DIR, "KSC.mat"))["KSC"].astype(np.float32)
Y_map = sio.loadmat(os.path.join(DATA_DIR, "KSC_gt.mat"))["KSC_gt"].astype(int)
coords = np.argwhere(Y_map != 0)
X_all = X_cube[coords[:,0], coords[:,1]] # (N, B)
y_all = Y_map[coords[:,0], coords[:,1]] - 1 # 0-basedX_train, X_test, y_train, y_test = train_test_split(X_all, y_all, train_size=TRAIN_RATIO, stratify=y_all, random_state=SEED
)# ===== 2) 預處理:MinMax 到 [0,1](Chi2 需非負;其余方法也可用)=====
scaler = MinMaxScaler().fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
B = X_train.shape[1]# ===== 3) 三種選擇法 =====
# 3.1 Filter: Chi2(統計相關性,快)
chi2_sel = SelectKBest(chi2, k=K_SELECT).fit(X_train, y_train)
mask_chi2 = chi2_sel.get_support()# 3.2 Wrapper: RFE(Logistic)(用性能做打分,精細但慢)
# 收斂穩健:用 saga + 充分迭代,避免 lbfgs 收斂告警
lr = LogisticRegression(solver="saga", penalty="l2", C=1.0,max_iter=5000, n_jobs=-1, random_state=SEED)
rfe = RFE(estimator=lr, n_features_to_select=K_SELECT).fit(X_train, y_train)
mask_rfe = rfe.support_# 3.3 Embedded: RF-Importance(模型內置重要性,一次性排序)
rf = RandomForestClassifier(n_estimators=200, random_state=SEED, n_jobs=-1).fit(X_train, y_train)
importances = rf.feature_importances_
topk_idx = np.argsort(importances)[::-1][:K_SELECT]
mask_rf = np.zeros(B, dtype=bool); mask_rf[topk_idx] = True# ===== 4) 評估:統一用RF在子集上測OA =====
def eval_mask(mask, name):clf = RandomForestClassifier(n_estimators=200, random_state=SEED, n_jobs=-1)clf.fit(X_train[:,mask], y_train)acc = accuracy_score(y_test, clf.predict(X_test[:,mask]))return name, acc*100results = [eval_mask(np.ones(B, dtype=bool), "All"),eval_mask(mask_chi2, "Chi2"),eval_mask(mask_rfe, "RFE"),eval_mask(mask_rf, "RF-TopK")
]# ===== 5) 可視化 A:隨機森林重要性曲線 =====
plt.figure(figsize=(8,3))
plt.plot(importances, marker='o', linewidth=1.2)
plt.title("A) 隨機森林特征重要性")
plt.xlabel("波段索引"); plt.ylabel("重要性")
plt.grid(alpha=0.3); plt.tight_layout(); plt.show()# ===== 6) 可視化 B:三法入選熱圖(方法 × 波段)=====
select_mat = np.vstack([mask_chi2, mask_rfe, mask_rf]).astype(int)
plt.figure(figsize=(8,2.5))
plt.imshow(select_mat, aspect='auto', cmap='Greens')
plt.yticks([0,1,2], ["Chi2","RFE","RF-TopK"])
plt.xlabel("波段索引"); plt.title("B) 三法選中特征對比(1=入選)")
plt.colorbar(label="是否入選", fraction=0.05, pad=0.04)
plt.tight_layout(); plt.show()# ===== 7) 可視化 C:特征子集精度對比 =====
names, accs = zip(*results)
plt.figure(figsize=(6,3))
plt.bar(names, accs)
for i,a in enumerate(accs): plt.text(i, a+0.6, f"{a:.1f}%", ha='center')
plt.ylabel("OA(%)"); plt.title("C) 子集精度對比(統一RF評估)")
plt.ylim(min(accs)-5, min(100, max(accs)+6))
plt.grid(axis='y', alpha=0.25, linestyle='--')
plt.tight_layout(); plt.show()print("\n=== 精度匯總 ===")
for n,a in results: print(f"{n:8s}: {a:.2f}%")
🔍 如何讀圖與用圖
-
重要性曲線(A):波段層面的“貢獻度”直觀譜型;峰值對應的波段往往很關鍵。
-
入選熱圖(B):對比不同方法的“共識帶”,交集/高頻入選波段通常是穩健特征。
-
精度對比(C):用統一評估器(RF)衡量不同子集的有效性;若精選子集與全特征接近或更好,說明篩選成功。
? 實戰建議
- 先快后準:用 Chi2 快速減容,再用 RF 排序抓關鍵,再用 RFE 小范圍“打磨”。
- 關注共識特征:多法一致入選的波段,優先保留。
- 結合業務知識:把選出的關鍵波段與地物機理對照(吸收峰、紅邊等),提升解釋力。
- 穩定性檢查:換劃分/種子,觀察被選特征的一致性。
歡迎大家關注下方我的公眾獲取更多內容!