在前幾篇案例中,有同學在后臺留言:
“模型的參數到底怎么調?比如 SVM 的 C 和 γ,隨機森林的樹數和深度,要怎么選才能得到最優結果呢?”
這是一個非常經典的問題:參數選不好,模型效果差一截;參數調優,性能能上一個臺階。
本篇我們就來介紹 sklearn 中的 網格搜索(Grid Search),看看如何系統地找到最優參數組合。
🧩 1. 什么是超參數搜索?
- 模型參數:訓練過程中自動學習到的(如邏輯回歸的權重)。
- 超參數:需要人為設定的(如 SVM 的核函數、C 值;隨機森林的樹數)。
超參數對模型表現影響巨大。手工調參既耗時又容易遺漏最佳組合,因此 sklearn 提供了 GridSearchCV
,幫我們自動嘗試多組參數,并通過交叉驗證挑選最優解。
?? 2. 完整代碼示例
我們仍然基于 KSC 高光譜數據集,用 PCA 壓縮后特征作為輸入,演示 SVM 與隨機森林 的參數搜索。
# -*- coding: utf-8 -*-
"""
Sklearn案例⑥:網格搜索與超參數優化
"""
import os, numpy as np, scipy.io as sio, matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import seaborn as sns# ===== 參數設置 =====
DATA_DIR = "你的數據路徑"
PCA_DIM, TRAIN_RATIO, SEED = 30, 0.3, 42# ===== 1. 加載數據 =====
X = sio.loadmat(os.path.join(DATA_DIR, "KSC.mat"))["KSC"].astype(np.float32)
Y = sio.loadmat(os.path.join(DATA_DIR, "KSC_gt.mat"))["KSC_gt"].astype(int)
coords = np.argwhere(Y != 0)
labels = Y[coords[:,0], coords[:,1]] - 1
train_ids, test_ids = train_test_split(np.arange(len(coords)), train_size=TRAIN_RATIO,stratify=labels, random_state=SEED
)
train_pixels = X[coords[train_ids,0], coords[train_ids,1]]
test_pixels = X[coords[test_ids,0], coords[test_ids,1]]# ===== 2. 標準化 + PCA =====
scaler = StandardScaler().fit(train_pixels)
pca = PCA(n_components=PCA_DIM, random_state=SEED).fit(scaler.transform(train_pixels))
X_train = pca.transform(scaler.transform(train_pixels))
X_test = pca.transform(scaler.transform(test_pixels))
y_train, y_test = labels[train_ids], labels[test_ids]# ===== 3. SVM 參數搜索 =====
param_grid_svm = {"C": [0.1, 1, 10],"gamma": [0.01, 0.1, 1],"kernel": ["rbf"]
}
grid_svm = GridSearchCV(SVC(), param_grid_svm, cv=3, n_jobs=-1, verbose=1)
grid_svm.fit(X_train, y_train)print("最佳參數(SVM):", grid_svm.best_params_)
print("測試集準確率:", accuracy_score(y_test, grid_svm.best_estimator_.predict(X_test)))# 可視化搜索結果 (C vs gamma 熱力圖)
scores = grid_svm.cv_results_["mean_test_score"].reshape(len(param_grid_svm["C"]), len(param_grid_svm["gamma"]))
plt.figure(figsize=(6,5))
sns.heatmap(scores, annot=True, xticklabels=param_grid_svm["gamma"], yticklabels=param_grid_svm["C"], cmap="YlGnBu")
plt.xlabel("gamma"); plt.ylabel("C"); plt.title("SVM 網格搜索結果")
plt.show()# ===== 4. 隨機森林 參數搜索 =====
param_grid_rf = {"n_estimators": [10, 30, 50],"max_depth": [5, 10, None]
}
grid_rf = GridSearchCV(RandomForestClassifier(random_state=SEED),param_grid_rf, cv=3, n_jobs=-1, verbose=1)
grid_rf.fit(X_train, y_train)print("最佳參數(RF):", grid_rf.best_params_)
print("測試集準確率:", accuracy_score(y_test, grid_rf.best_estimator_.predict(X_test)))
📊 3. 結果與分析
運行后我們會得到:
- SVM:輸出最佳
C
和gamma
,并繪制了一個參數搜索熱力圖,可以直觀看出不同參數下的準確率差異。 - 隨機森林:自動選擇最佳樹數和深度。
在實驗中,SVM 的性能對參數敏感,而隨機森林更穩健。通過 GridSearchCV
,我們不再需要手工試探,而是能系統化地找到較優解。
💡 4. 總結
這一節我們解決了同學們常見的疑問:如何找到最優參數?
- sklearn 提供的
GridSearchCV
可以自動化調參,支持交叉驗證,避免“拍腦袋調參”。 - 除了網格搜索,還有
RandomizedSearchCV
,在參數空間很大時更高效。 - 在實際科研和工程中,參數調優往往比更換模型更能帶來提升。
👉 下一篇,我們將進入 特征選擇與重要性分析,看看如何找到對分類最關鍵的波段或特征(當然,也可能應要求更新其他內容)。
歡迎大家關注下方我的公眾獲取更多內容!