当前位置: 首页 > news >正文

五一数学建模B题复盘:用Python搞定快递需求预测与成本优化(附完整代码)

数学建模竞赛实战:Python实现快递需求预测与成本优化全流程解析

去年参加五一数学建模竞赛的经历让我深刻体会到,从问题理解到代码落地的过程中藏着无数"魔鬼细节"。本文将围绕快递需求分析赛题,用Python工具链完整还原特征工程、时序预测、分类建模、路径优化四大核心环节,特别分享那些在比赛文档里不会写的实操技巧。

1. 数据清洗与特征工程实战

拿到快递运输数据的第一件事不是急着建模,而是理解数据背后的业务逻辑。我们使用的数据集包含发货城市、收货城市、日期、运输量等字段,但原始数据就像未经雕琢的玉石——需要先解决几个关键问题:

import pandas as pd # 读取数据时的常见陷阱 raw_data = pd.read_excel('附件1.xlsx', parse_dates=['日期']) # 必须显式指定日期解析 print(f"时间范围: {raw_data['日期'].min()} 至 {raw_data['日期'].max()}")

典型数据问题及处理方案

问题类型检测方法处理方案代码示例
缺失值isna().sum()时间序列线性插值data['运输量'].interpolate(method='time')
异常值3σ原则或IQR盖帽法处理np.clip(data['运输量'], lower, upper)
日期不连续生成完整日期范围重新采样填充pd.date_range(start, end).difference(data['日期'])

提示:快递数据中0值需要谨慎处理——可能是无需求也可能是数据缺失,建议结合业务判断

构建有效的特征需要从时间和空间两个维度思考:

# 时间特征扩展示例 data['星期'] = data['日期'].dt.dayofweek data['是否周末'] = data['星期'].isin([5,6]).astype(int) data['月份'] = data['日期'].dt.month # 空间特征构建 city_pairs = data.groupby(['发货城市','收货城市'])['运输量'].mean().reset_index() data = data.merge(city_pairs, on=['发货城市','收货城市'], suffixes=('','_均值'))

2. 运输量预测模型构建

预测特定城市对的日运输量是个典型的时序回归问题。我们测试了多种算法后发现LightGBM+时序特征的组合在验证集上表现最优。以下是关键实现步骤:

2.1 数据准备与验证策略

由于数据具有明显的时间属性,绝对不能使用随机划分:

from sklearn.model_selection import TimeSeriesSplit tss = TimeSeriesSplit(n_splits=5) for train_idx, test_idx in tss.split(X): X_train, X_test = X.iloc[train_idx], X.iloc[test_idx] y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]

2.2 特征重要性分析

构建完模型后,用SHAP值分析发现影响预测的关键因素:

import lightgbm as lgb import shap model = lgb.LGBMRegressor() model.fit(X_train, y_train) explainer = shap.TreeExplainer(model) shap_values = explainer.shap_values(X_test) shap.summary_plot(shap_values, X_test)

预测效果对比表

模型MAERMSE训练时间(s)
SVR45.268.70.81120
随机森林39.862.30.8485
LightGBM32.154.60.8815

注意:实际比赛中需要预测多天的数据时,建议采用滚动预测策略,用前一天的预测结果作为后一天的特征

3. 运输通断分类模型

判断某条线路是否能正常发货本质上是个二分类问题,但样本极度不均衡——正常线路占比超过90%。我们采用了一套组合方案:

from imblearn.over_sampling import SMOTE from sklearn.ensemble import GradientBoostingClassifier # 处理样本不均衡 smote = SMOTE(random_state=42) X_res, y_res = smote.fit_resample(X_train, y_train) # 使用类别权重 model = GradientBoostingClassifier( loss='deviance', max_depth=5, n_estimators=200, min_samples_leaf=50 )

分类阈值优化技巧

from sklearn.metrics import precision_recall_curve probs = model.predict_proba(X_test)[:, 1] precision, recall, thresholds = precision_recall_curve(y_test, probs) # 找到满足业务需求的最佳阈值 optimal_idx = np.argmax(precision * recall) optimal_threshold = thresholds[optimal_idx]

4. 运输路径成本优化

这是典型的带约束的整数规划问题,我们选择PuLP库实现。核心在于如何将实际问题转化为数学模型:

from pulp import * # 初始化问题 prob = LpProblem("Transport_Cost_Minimization", LpMinimize) # 决策变量:路径选择 x = LpVariable.dicts("route", [(i,j,k) for i in origins for j in destinations for k in paths[(i,j)]], cat='Binary') # 目标函数:总成本最小化 prob += lpSum([fixed_cost[k]*x[(i,j,k)] + variable_cost[(i,j,k)]*demand[(i,j)] for (i,j,k) in x]) # 约束条件:每个OD对不超过5条路径 for i in origins: for j in destinations: prob += lpSum([x[(i,j,k)] for k in paths[(i,j)]]) <= 5 # 求解 status = prob.solve(PULP_CBC_CMD(msg=False))

优化效果对比

日期原始方案成本优化后成本降本比例
4-23¥184,520¥152,38017.4%
4-24¥192,650¥158,92017.5%
4-25¥178,930¥147,21017.7%

在实现过程中发现几个关键点:

  1. 将固定成本分摊到单位运输量可以简化模型
  2. 提前过滤掉运输量为0的OD对能大幅减少计算量
  3. 对无法满足的约束条件需要设计fallback机制

5. 完整项目架构设计

为保证代码可维护性和复现性,推荐以下项目结构:

/project │── /data # 原始数据 │── /notebooks # 探索性分析 │── /src │ ├── features # 特征工程 │ ├── models # 各问题模型 │ └── utils # 工具函数 │── config.yaml # 参数配置 │── pipeline.py # 主流程控制

关键依赖版本:

# requirements.txt pandas==1.5.3 numpy==1.23.5 scikit-learn==1.2.2 lightgbm==3.3.5 pulp==2.7.0

在最终提交的代码中,我特别添加了以下保障措施:

  • 所有随机种子固定
  • 关键步骤的输入输出检查
  • 运行时长预估和进度条
  • 中间结果的自动缓存

比赛结束后复盘,最大的收获不是奖项而是这种从实际问题到数学建模再到代码实现的完整闭环经验。下次如果再遇到类似问题,我会更关注数据中的异常模式挖掘,尝试将图神经网络应用到运输网络建模中。

http://www.jsqmd.com/news/913239/

相关文章:

  • 自媒体算法获流逻辑:通过受众定位与内容迭代,沉淀精准垂直流量
  • 用CTGAN搞定表格数据生成:从原理到实战,手把手教你生成高质量合成数据
  • 为什么你的游戏手柄需要ViGEmBus:终极Windows控制器兼容解决方案
  • 新手避坑指南:在RHEL 6.10上安装Cadence IC618和Verdi 2018.09的完整流程
  • 跨界绽放新风采 基金投资人秦泽文以中国代表身份亮相万国小姐全明星赛
  • 基于Arduino与超声波传感器的智能风铃提醒器设计与实现
  • 别再只调参了!用PIL+Sklearn从200张水色图到水质分类模型,我的完整踩坑复盘
  • 亦唐科技引领国产贴片机行业创新的核心动力
  • C51开发中NULL指针比较问题与内存管理技巧
  • 告别CentOS 8.5安装焦虑:手把手教你用VMware Workstation 17 Pro搞定最小化安装(附分区避坑指南)
  • ssm209基于的汽车服务商城系统设计与实现+vue(文档+源码)_kaic
  • Lindy会员数据治理自动化落地实践(2024最新SOP已验证)
  • 用Python+LMDI模型拆解碳排放:手把手教你分析GDP、人口、能源结构对碳排的贡献
  • Navicat Mac版无限重置试用期:3种终极方法解决14天限制
  • 不止是配置:深入理解OpenEuler的YUM源与Repo仓库设计
  • 嵌入式测试学习第 22 天:仿真看简易电路,熟悉电路运行逻辑
  • web第二次课后作业
  • Linux运维避坑:虚拟机热添加SCSI硬盘后,fdisk -l不显示的3种刷新方法
  • 北京洋酒回收技术推荐:北京五粮液回收/北京名酒回收电话/北京礼品回收/北京红酒回收/鉴别与变现核心要点解析 - 优质品牌商家
  • 别再乱升级内核了!CentOS 7稳定升级指南:用ELRepo长期支持版+GRUB参数避坑‘pstore’错误
  • Java+AI 实现极简 RAG+Agent 智能问答(入门必看)
  • Ceph BlueStore 元数据全景:一个 OSD 的 RocksDB 里到底存了什么?
  • 基于视频孪生时空融合的核电厂外来人员无源定位架构研究
  • 性价比高的SEO精准获客哪个靠谱
  • HS2-HF Patch终极指南:200+插件一站式解决Honey Select 2兼容性问题
  • 告别图片变形!手把手教你用Python+OpenCV实现YOLO必备的Letterbox自适应缩放(附完整代码)
  • 2026现阶段,武安市单招培训源头公司哪家可靠?深度剖析武安市新途教育咨询有限公司 - 2026年企业资讯
  • 2026 实时渲染测评:5 款稳定工具推荐,光影全开仍能流畅运行
  • Go语言自然语言处理:文本处理与分析
  • 光伏螺栓技术全解析:材质选型防腐与售后保障推荐 - 优质品牌商家