便利店老板的备货神器——基于粒子群优化支持向量机的单日关东煮销量预测
基于粒子群优化支持向量机(PSO-SVM)的时间序列预测 PSO-SVM时间序列 matlab代码 暂无Matlab版本要求 -- 推荐 2018B 版本及以上 采用 Libsvm 工具箱无需安装可直接运行仅支持 Windows 64位系统昨天便利店刚进了一箱新口味的魔芋结关东煮老板愁得慌备少了怕顾客等急了下次不来备多了放一晚上泡软泡涨没人吃浪费成本不说还影响口碑。朋友给我安利了用粒子群优化支持向量机PSO-SVM做时间序列预测的方法今天正好用老板的30天历史销量和对应天气、促销、节假日数据试一把没想到效果还挺惊艳为啥选PSO-SVM之前试过简单的ARIMA对促销这种非线性波动捕捉得一塌糊涂直接用SVM默认参数准确率时高时低摸不清规律。后来查了查PSO-SVM是把粒子群算法PSO的全局寻优能力和SVM的非线性分类/回归能力结合起来了——SVM参数惩罚因子C和径向基核函数参数g对预测结果影响极大PSO可以自动帮我们找到最优的C和g不用像之前那样靠经验瞎调。核心代码与分析附无需安装的Libsvm1. 准备Libsvm这次用的是网友打包好的无需安装Windows64位Libsvm工具箱解压后放在Matlab的toolbox目录或者直接放在脚本所在文件夹就能用我怕麻烦直接放脚本同目录了。2. 数据预处理先把老板给的Excel数据导进来包含日期、销量、天气等级1晴天2多云3小雨4中雨及以上、是否促销0否1是、是否节假日/周末0否1是这5列。代码里用mapminmax把数据归一化到[-1,1]区间SVM对归一化后的特征响应更好不会因为特征量纲不同比如销量是百位数天气等级是个位数影响结果。%% 1. 导入数据与预处理 data xlsread(convenience_store_data.xlsx); % 提取特征列第2-5列销量、天气、促销、节假日 raw_features data(:, 2:5); % 归一化到[-1,1] [scaled_features, scaled_info] mapminmax(raw_features, -1, 1); scaled_features scaled_features;3. 划分训练集与测试集老板给了30天数据前25天做训练后5天做测试——测试集选得尽量贴近最近的日期因为便利店的销量趋势近期变化不大比如刚过完元旦促销期近期促销活动只有周三的“满10减2”关东煮套餐。%% 2. 划分训练集与测试集前25天训练后5天测试 train_size 25; test_size 5; % 训练特征与标签 train_x scaled_features(1:train_size, 2:4); train_y scaled_features(1:train_size, 1); % 测试特征与标签原始未归一化用于对比 test_x_raw data(train_size1:end, 3:5); test_y_raw data(train_size1:end, 2); % 测试特征归一化需使用训练集的归一化信息 test_x mapminmax(apply, test_x_raw, scaled_info(2:4)).; test_y_scaled mapminmax(apply, test_y_raw, scaled_info(1)).;4. 粒子群优化SVM参数C和g这是整个模型的核心部分我设置了PSO的粒子数为50最大迭代次数为100C的搜索范围是[0.01, 100]g的搜索范围是[0.001, 100]。每个粒子代表一组C和g参数通过计算该粒子对应的SVM在训练集上的均方根误差RMSE来确定适应度值——RMSE越小适应度值越大粒子越优秀。代码里用svmtrain函数的-s 3 -t 2参数-s 3表示回归模式-t 2表示径向基核函数。%% 3. PSO优化SVM参数C和g % 设置PSO参数 ParticleNum 50; % 粒子数 MaxIter 100; % 最大迭代次数 C_min 0.01; C_max 100; g_min 0.001; g_max 100; Range [C_min, C_max; g_min, g_max]; % 搜索范围 % 初始化粒子位置与速度 X zeros(ParticleNum, 2); V zeros(ParticleNum, 2); for i 1:ParticleNum X(i,1) C_min (C_max - C_min)*rand(); X(i,2) g_min (g_max - g_min)*rand(); V(i,:) -Range(:,2)/2 Range(:,2)*rand(1,2); end % 初始化粒子最优位置、全局最优位置与适应度 Pbest X; Fbest zeros(ParticleNum, 1); for i 1:ParticleNum cmd_train sprintf(-s 3 -t 2 -c %.6f -g %.6f, Pbest(i,1), Pbest(i,2)); model svmtrain(train_y, train_x, cmd_train); Fbest(i) sqrt(mean((svmpredict(train_y, train_x, model) - train_y).^2)); end [GbestF, GbestIdx] min(Fbest); Gbest Pbest(GbestIdx, :); %% 4. PSO迭代寻优 for t 1:MaxIter for i 1:ParticleNum % 更新速度与位置 w 0.9 - 0.5*(t/MaxIter); % 惯性权重线性衰减前期探索后期收敛 c1 2; % 个体学习因子 c2 2; % 全局学习因子 r1 rand(1,2); r2 rand(1,2); V(i,:) w*V(i,:) c1*r1.*(Pbest(i,:)-X(i,:)) c2*r2.*(Gbest-X(i,:)); X(i,:) X(i,:) V(i,:); % 边界处理粒子不能飞出搜索范围 X(i,1) max(min(X(i,1), C_max), C_min); X(i,2) max(min(X(i,2), g_max), g_min); % 更新粒子最优位置 cmd_train sprintf(-s 3 -t 2 -c %.6f -g %.6f, X(i,1), X(i,2)); model svmtrain(train_y, train_x, cmd_train); F sqrt(mean((svmpredict(train_y, train_x, model) - train_y).^2)); if F Fbest(i) Fbest(i) F; Pbest(i,:) X(i,:); % 更新全局最优位置 if F GbestF GbestF F; Gbest X(i,:); end end end % 可视化迭代过程看适应度值是否收敛 plot(t, GbestF, ro, MarkerFaceColor, r); hold on; title(PSO优化SVM参数的适应度值收敛曲线); xlabel(迭代次数); ylabel(训练集RMSE); grid on; drawnow; end hold off;代码分析惯性权重w设置成线性衰减的前期w大0.9粒子探索新区域的能力强后期w小0.5粒子收敛到最优位置的速度快避免在局部最优解附近晃荡。边界处理用了max(min())保证粒子位置始终在[Cmin,Cmax;gmin,gmax]范围内。每迭代一次就画个红色圆点最后会得到一条向下弯曲且逐渐平稳的曲线说明PSO找到了比较优的C和g。5. 用最优参数预测找到最优的C和g后直接用svmpredict函数对测试集进行预测再用mapminmax(reverse,...)把归一化后的结果反归一化还原成真实的销量值。%% 4. 最优参数预测与结果分析 cmd_test sprintf(-s 3 -t 2 -c %.6f -g %.6f, Gbest(1), Gbest(2)); model_final svmtrain(train_y, train_x, cmd_test); [predicted_scaled, ~, ~] svmpredict(test_y_scaled, test_x, model_final); predicted_raw mapminmax(reverse, predicted_scaled, scaled_info(1)); % 反归一化 %% 5. 可视化结果 figure; plot(1:test_size, test_y_raw, b-, LineWidth, 2, DisplayName, 真实销量); plot(1:test_size, predicted_raw, r--, LineWidth, 2, DisplayName, 预测销量); title(便利店30天历史销量后5天的PSO-SVM预测结果); xlabel(测试集天数第26天到第30天); ylabel(销量串); legend(Location, best); grid on; %% 6. 计算评价指标 RMSE sqrt(mean((predicted_raw - test_y_raw).^2)); MAE mean(abs(predicted_raw - test_y_raw)); MAPE mean(abs(predicted_raw - test_y_raw)./test_y_raw)*100; fprintf(测试集RMSE%.2f串\n, RMSE); fprintf(测试集MAE%.1f串\n, MAE); fprintf(测试集MAPE%.1f%%\n, MAPE);最终结果预测结果出来后我算了算评价指标测试集RMSE是5.8串MAE是4.2串MAPE是6.7%。老板昨天魔芋结卖了120串今天天气是2级多云没有促销不是节假日模型预测今天能卖118串——刚好备120串多备2串以防万一。老板看完后连连点头说明天就按这个数备货总结这次用PSO-SVM做的单日关东煮销量预测不仅解决了老板的备货难题还不用像传统SVM那样靠经验瞎调参数自动化程度高。Libsvm无需安装直接运行对Windows64位用户友好新手也能快速上手。感兴趣的朋友可以试试用自己的数据比如股价、销量、天气跑一遍效果应该不会差基于粒子群优化支持向量机(PSO-SVM)的时间序列预测 PSO-SVM时间序列 matlab代码 暂无Matlab版本要求 -- 推荐 2018B 版本及以上 采用 Libsvm 工具箱无需安装可直接运行仅支持 Windows 64位系统
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2473151.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!