跳到正文
余翰林 · 产品作品集
返回

数据分析

蔬菜定价优化:2023 CUMCM C 题的三轮建模迭代

历史赛题重做的完整建模练习:常数弹性模型的负利润暴露、线性需求的校准突破、报童模型的官方对标,以及真实批发价交叉校准。

业务问题与数据口径

2023 年全国大学生数学建模竞赛 C 题的历史赛题重做(个人练习,非参赛):生鲜商超 6 大蔬菜品类的自动定价与补货决策,目标最大化 7 天总期望利润。选题动机是给竞赛方法做一次全流程演练——从数据审计到模型迭代再到官方解法对标。

第一个决策点在数据审计:题目附件是逐单品逐日明细,但能稳定提取的只有汇总级数据。这个差距直接决定方法空间——汇总数据做不了逐品类 ARIMA 时序预测,竞赛获奖论文的标准管线(ARIMA + Newsvendor + 动态博弈)在这份数据上不可复制。数据粒度审计必须在建模之前完成,这是本题最大的教训,也是最值钱的一条。

三轮模型迭代

第一轮:常数弹性需求模型。 需求函数 D(P) = exp(a)·P^b,SLSQP 非线性规划求解,品类优化利润 1007 元/天。问题在参数校准时暴露:代入学术文献的真实弹性值(|b| ≈ 0.68 至 0.93)后,模型出现负利润——这不是代码 bug,是 log-log 结构在低弹性区间数学上不可行。需求函数的数学形式本身就是一个隐性假设,而我在第一轮没有检查它的边界行为。

第二轮:线性需求模型。 需求函数改 D(P) = a - b·P,校准方法是在参考价格点令线性需求的弹性等于文献目标值。结果全部 6 个情景转为正利润,推荐情景(ε=-0.93 + 真实市场价)总利润 672 元/天,最优价格比参考价高 40% 至 60%——符合"缺乏弹性 → 适度提价"的经济学直觉。

第三轮:报童模型官方对标。 做完自己的两轮后查阅出题人解析与获奖论文,标准框架是 ARIMA + Newsvendor 补货 + 动态博弈定价。报童临界分位点 CR = (p·(1-ℓ) - W) / (p·(1-ℓ)) 的验证结论:经济学优化框架与报童框架互补而非互斥——前者管定价、后者管补货。对标不是照抄,而是定位自己的方法在光谱中的位置,并诚实标注"数据粒度不够、不能做 ARIMA"的缺口。

真实数据交叉校准

用农业农村部真实批发价格校准题目数据,发现 PPT 给的批发价在 5/6 品类中低于真实市场价 26% 至 102%。竞赛题给的数据不一定符合现实——主动引入外部真实数据做交叉验证,既发现了题目数据的问题,也让"提价 40% 至 60%"的结论有了现实锚点。

工程结构与可复现性

10 个模块通过 outputs/tables/*.csv 契约通信,每模块独立 run.py 与测试,全流程 3.3 秒端到端一行命令跑通。新增报童验证模块(M10)与重校准模块(M09)时未改动任何已有代码——模块化结构让"补一轮验证"变成加法而不是重构。

结论与教训

  • 数据粒度决定方法空间:审计先于建模,粒度不够时选择与数据匹配的方法(NLP/线性需求),并如实标注不能做什么。
  • 需求函数形式是隐性假设:选型前先跑参数扫描(弹性 0→2 全区间看利润曲线是否合理),检查边界行为。
  • 知名赛题做完必须对标官方解法:不是为了抄答案,是为了知道自己的方法处在什么位置、缺什么。
  • 诚实交代:全部利润数字是模型输出,依赖弹性假设与汇总数据的近似,口径为建模练习——不构成真实经营决策依据。