1. 这个项目的真正起点:被天气"坑"出来的备货焦虑
做数据分析的人,大概都有过这么一段经历:模型还没跑起来,自己先被业务逼疯了。这个关东煮销量预测项目,起因其实特别朴素——我楼下便利店的老板,一个特别能聊的大哥,某天突然拉住我,说他被一个东西折磨得不行:关东煮的备货量。
他这么跟我算过一笔账:关东煮的丸子、萝卜、魔芋丝,每天下午5点到晚上9点之间能占整个熟食柜台销售额的四成。备少了,晚高峰断货,一晚上少赚两三百不说,老顾客会跑去隔壁的全家;备多了更麻烦,关东煮的食材过了夜,口感和卖相都不对,报损率直线上升。他每个晚上都在赌,赌第二天冷不冷、下不下雨、是不是周末。
他给我看了手机备忘录,里面记了一堆他自己总结的规律:"下雨天关东煮卖得好""气温跌破15度翻倍""周五晚上比周四多卖30%"……听着头头是道,但这些判断都是模糊的、拍脑袋的,而且互相打架——比如又冷又下雨的周二工作日,该备多少?他的经验完全给不出精确答案。
所以我当时就跟他说,别拍脑袋了,做一个基于历史销售数据的预测模型,让数据告诉你明天该备多少货。于是就有了这个项目:基于粒子群优化支持向量机(PSO-SVM)的单日关东煮销量预测。
这篇文章我会把整个项目的完整链路拆开讲——从数据清洗、特征工程,到为什么选SVM、为什么又要用粒子群算法去优化它,再到最终的模型评估和实际上线后的效果。适合正在学机器学习但不知道怎么做真实项目的同学,也适合那些有数据分析基础、想了解"算法怎么落到便利店这种小场景"的从业者。
有一点先说清楚:这项目听起来有门槛,但代码量并不大,核心用的就是 Python 的 scikit-learn 和 pyswarm,一套流程跑下来,从数据到预测结果,大约两百行代码。难的不是代码,是特征设计和调参逻辑。而这一块,恰恰是书本上很少讲、踩坑才能悟出来的东西。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 为什么单日销量预测这么难?先拆清楚关东煮的业务逻辑
在动手建模之前,我花了整整两天泡在店里,一边吃关东煮一边观察,然后给老板列了一个问题清单。这步看起来不产生任何代码,但我强烈建议所有做预测项目的人认真做——业务逻辑都理不清,模型再花哨也是白搭。
2.1 关东煮的销售节奏和普通商品完全不同
关东煮不是酱油、纸巾那种"稳定消耗品",它有自己非常鲜明的销售节奏。我梳理下来,影响它的因素基本有这么几类:
| 特征类别 | 具体变量 | 为什么影响销量 |
|---|---|---|
| 天气因素 | 日平均气温、天气状况(晴/雨/阴) | 气温低时热食需求上升,雨天顾客更倾向店内即食 |
| 时间因素 | 星期几、是否节假日、是否工作日 | 周五晚高峰与周末下午茶场景差异显著 |
| 门店因素 | 附近是否有学校/写字楼、商圈类型 | 直接影响客流的构成和峰值时段 |
| 经营因素 | 当日是否有促销活动、新品上架 | 促销能带来20%-30%的增量 |
| 惯性因素 | 前一日销量、前7日平均销量 | 消费者习惯有连续性,是强特征 |
老板自己那些"经验之谈",其实句句都指向这些变量,只是他没办法量化。
2.2 单日粒度的数据预测,比小时粒度更"温顺",但依然有陷阱
当初也纠结过到底做小时级预测还是单日预测。做小时级精度更高,但有两个硬伤:第一,便利店收银系统里关东煮的销售数据是当日汇总结账的,按小时拆需要额外上数字化设备,成本高;第二,小时级预测的波动太大,对备货指导意义反而不如单日来的直接——老板只需要知道"明天给我准备多少包丸子"就够了。
不过单日预测有个绕不开的问题:样本量少。一年365天,就算收集一年半的数据,也只有540条样本。这种体量下,深度学习基本别想了,树模型能做,但容易过拟合。而支持向量机(SVM)恰恰是擅长小样本、非线性回归的经典算法,这也是我选择SVM作为基础模型的核心原因。
2.3 数据从哪来?怎么攒出一份能用的训练集
跟老板确认了收银系统的导出功能后,我拉到了过去14个月的销售明细。数据长什么样,这里贴个脱敏后的示例:
text复制日期 天气 最高气温 最低气温 是否节假日 促销活动 关东煮销量
2024-10-15 晴 24 15 0 0 86
2024-10-16 小雨 19 14 0 0 132
2024-11-02 多云 16 9 1 1 178
...
累计约420条有效记录。这里有个很重要的数据工程细节:日期列不能直接扔给模型,需要拆解和转化。我把日期拆成了"星期几""当月第几天""是否月初/月末",把天气转成了分类编码(晴=0、多云=1、阴=2、小雨=3、大雨=4),气温直接用数值。
第一版我还加了一个"前后两天温差"特征。原理很简单:气温骤降的那天,人会明显感觉到冷,关东煮的销量刺激比单纯低温更强烈。后来在特征重要性分析里,这个变量排进了前五,说明这个拍脑袋加的特征是有效的。
数据清洗阶段还有个坑要专门说一下:关东煮销量为0的日子不代表没卖,很可能是设备检修或者断货。如果把这些0值当真实样本放进去,模型会被严重误导。我的处理方式是:连续出现两个以上0值,视为异常点,直接剔除;单日0值,用前后7天的平均销量填充。
3. 算法选型:SVM的看家本领和它的两个"命门"
3.1 支持向量机做回归,核心思想是什么
通常大家接触比较多的是支持向量分类(SVC),用来做分类。但关东煮销量预测是一个回归问题,所以用的是 支持向量回归(Support Vector Regression, SVR)。
SVR的核心思想用大白话讲就是:在样本空间里找一个"管子"(医学上叫ε-不敏感带),让尽可能多的样本落进管子里,同时让管子尽量平缓。落在管子外面的样本,才计算损失。这个特性带来一个巨大的优势:它对离群点不敏感,不会像线性回归那样,被一个异常的旺销日硬生生拉偏整条拟合线。
关东煮的数据正好就有这种离群点:比如去年圣诞节前夜,卖出过320份,平时也就100出头,这种异常值对普通回归模型是灾难,但SVR扛得住。
3.2 RBF核函数里的C、gamma和epsilon,分别管什么
SVR最常用的是RBF(径向基)核函数,它负责把低维不可分的数据映射到高维空间去拟合。而用它的时候,有三个参数直接决定模型表现:
- 惩罚系数C:表示对超出"管子"样本的容忍度。C越大,模型越不能容忍误差,越容易过拟合;C越小,模型越平滑,但可能欠拟合。
- gamma(γ):RBF核的宽度参数。γ越大,每一个样本的影响范围越小,决策边界越复杂,容易过拟合;γ越小,模型越"迟钝",边界越平滑。
- epsilon(ε):管子的粗细。ε越大,允许的误差越大,预测精度越低,但泛化能力通常更好;ε越小,对训练数据拟合得越精确,但可能捡了芝麻丢了西瓜。
既然三个参数都这么敏感,那"怎么定参数"就成了整个项目的成败关键。这也是后面粒
