2. 基于互信息的近红外光谱特征选择与SVR建模
任务说明
本案例针对近红外光谱数据维度高、冗余大的问题,使用互信息(Mutual Information, MI)方法筛选与目标性质最相关的特征波段,并基于筛选后的特征建立支持向量回归(SVR)模型。输入为光谱矩阵X(样本×波长点)与目标值y(如某化学成分浓度),输出为特征选择结果与模型预测性能评估。
数据准备
为便于独立复现,本案例使用公开数据集Corn(玉米)近红外光谱数据中的m5光谱(1100~2498nm,间隔2nm,共700个波长点),预测目标为水分含量。数据集共80个样本,按7:3划分训练集(56个)与测试集(24个)。
实现代码
import numpy as np
import pandas as pd
from sklearn.feature_selection import mutual_info_regression
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import r2_score, mean_squared_error
from sklearn.model_selection import train_test_split
import scipy.io
# 1. 加载Corn数据集(需提前下载corn.mat放入同目录)
data = scipy.io.loadmat('corn.mat')
X = data['m5spec'] # 形状 (80, 700)
y = data['m5refprops'][:, 0] # 水分含量,形状 (80,)
# 2. 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 3. 互信息特征选择
mi_scores = mutual_info_regression(X_train, y_train, random_state=42)
n_select = 50 # 选择前50个波长点
selected_idx = np.argsort(mi_scores)[-n_select:][::-1]
selected_idx = np.sort(selected_idx) # 按波长顺序排列
X_train_mi = X_train[:, selected_idx]
X_test_mi = X_test[:, selected_idx]
# 4. 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train_mi)
X_test_scaled = scaler.transform(X_test_mi)
# 5. SVR建模(RBF核)
svr = SVR(kernel='rbf', C=10.0, epsilon=0.1, gamma='scale')
svr.fit(X_train_scaled, y_train)
# 6. 预测与评估
y_pred_train = svr.predict(X_train_scaled)
y_pred_test = svr.predict(X_test_scaled)
train_r2 = r2_score(y_train, y_pred_train)
test_r2 = r2_score(y_test, y_pred_test)
test_rmse = np.sqrt(mean_squared_error(y_test, y_pred_test))
# 7. 输出结果
print(f"选择特征数: {n_select}")
print(f"训练集 R²: {train_r2:.4f}")
print(f"测试集 R²: {test_r2:.4f}")
print(f"测试集 RMSE: {test_rmse:.4f}")
print("选中的波长索引(前10个):", selected_idx[:10])
运行方式与依赖
需要安装Python 3.8+及以下库:numpy, pandas, scikit-learn, scipy。从https://www.eigenvector.com/data/Corn/下载corn.mat文件,与脚本置于同一目录后运行即可。
验证方法与判定标准
运行脚本后观察终端输出。判定标准:
- 程序无报错,正常输出特征数、R²与RMSE值;
- 测试集R²大于0.85,RMSE小于0.5(水分含量单位%),表明筛选后的50个特征保留了足够的预测信息;
- 选中的波长索引在0~699范围内且数量为50。
若测试集R²低于0.8,可尝试调整n_select(如改为100)或SVR参数C、epsilon。
特征选择效果对比
为验证互信息筛选的有效性,可将上述结果与使用全部700个波长点直接建立SVR模型进行对比。预期筛选后模型性能接近或优于全谱模型,但输入维度降低93%,显著减少计算开销。
结果解读
运行脚本后,终端会输出选中的波长索引及模型性能指标。若测试集R²达到0.85以上,说明互信息筛选出的50个波长点能够有效代表原始光谱中的关键信息。实际应用中,可进一步结合化学知识分析选中波长对应的官能团吸收带,验证特征选择的合理性。