基于CNN-SVR的多输入单输出组合回归预测模型 python代码 特征提取与非线性建模: CNN-SVR的核心思想是使用卷积神经网络来提取数据中的重要特征。 CNN具有强大的特征提取能力,能够自动学习数据中的非线性特征。 支持向量回归(SVR): 特征被提取,CNN-SVR将这些特征提供给支持向量回归模型。 SVR是一种非线性回归方法,它可以捕捉特征与目标之间的复杂非线性关系。 性能评估: 计算均方误差(MSE)、平均绝对误差(MAE)、R2(R-squared)和平均绝对百分比误差(MAPE)等性能指标。 可视化: 提供了各种图表,包括真实值与预测值的折线图、散点图、拟合线图、残差分布直方图,以及模型收敛速度曲线。
from tensorflow.keras.layers import Conv1D, GlobalAvgPool1D, Dense from sklearn.svm import SVR # 特征提取器 cnn_feature_extractor = Sequential([ Conv1D(64, 3, activation='relu', input_shape=(100, 8)), Conv1D(128, 5, activation='relu'), GlobalAvgPool1D(), Dense(32, activation='relu') ]) # 组合模型 svr_regressor = SVR(kernel='rbf', C=1.0, epsilon=0.1) # 这里偷个懒,实际使用记得分开训练集测试集 features = cnn_feature_extractor.predict(X_train) svr_regressor.fit(features, y_train)搞过图像处理的兄弟可能发现了,这CNN用的1D卷积。没错,时间序列或者表格数据就该这么玩。第一层卷积核尺寸3,抓局部特征;第二层加大到5,捕捉更长距离的关系。全局平均池化这个老六直接把三维输出拍成一维,比Flatten省参数多了。
特征提取完扔给SVR的时候有个坑要注意:CNN输出的特征维度别太高,否则SVR算到地老天荒。所以最后接了个32维的全连接层,算是特征压缩。这里要是换成降维算法也行,不过让模型自己学更省事。
评估指标咱们得整点实在的,别光看损失曲线自嗨:
from sklearn.metrics import mean_squared_error, r2_score preds = svr_regressor.predict(cnn_feature_extractor.predict(X_test)) print(f'MSE: {mean_squared_error(y_test, preds):.3f}') print(f'R²: {r2_score(y_test, preds):.3f}') # 画图大法 plt.figure(figsize=(12,6)) plt.plot(y_test[:200], label='Ground Truth', alpha=0.7) plt.plot(preds[:200], label='Predictions', linestyle='--') plt.legend() plt.title('CNN-SVR预测效果对比')这个对比图一出来,甲方爸爸立马看懂。重点区域建议用方框标出来,比如某些预测突变点,方便解释模型哪里表现好哪里拉胯。散点图也别忘了加,顺便画条y=x的参考线:
sns.jointplot(x=y_test, y=preds, kind='reg', height=8) plt.plot([y_min, y_max], [y_min, y_max], 'r--')残差分析是检验模型健康的X光片。正常应该接近正态分布,要是出现双峰或者偏得离谱,赶紧回去检查数据泄露或者特征工程:
residuals = y_test - preds sns.histplot(residuals, kde=True, bins=30) plt.xlabel('预测残差')最后说个实战技巧:CNN部分先用Adam快速收敛,等loss降不动了换SGD微调。SVR的超参数调优可以用网格搜索,但更骚的操作是用贝叶斯优化,迭代次数能省一半。代码别写死超参数,搞个配置文件或者命令行参数,方便不同数据集切换。
这路子适合中小规模数据(万级样本),数据量太大还是直接上全连接DNN吧。毕竟SVR的时间复杂度摆在那儿,别跟自个儿的CPU过不去。模型融合的玄学在于,CNN抽的特征可能比人工设计的更有区分度,但解释性确实差点意思——鱼和熊掌不可兼得啊。