遥感机器学习入门实战教程|Sklearn案例⑥:网格搜索与超参数优化
在前几篇案例中,有同学在后台留言:
“模型的参数到底怎么调?比如 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
,在参数空间很大时更高效。 - 在实际科研和工程中,参数调优往往比更换模型更能带来提升。
👉 下一篇,我们将进入 特征选择与重要性分析,看看如何找到对分类最关键的波段或特征(当然,也可能应要求更新其他内容)。
欢迎大家关注下方我的公众获取更多内容!