ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

数学建模竞赛实战:基于LightGBM与优化模型的生鲜商品定价补货决策

数学建模竞赛实战:基于LightGBM与优化模型的生鲜商品定价补货决策 1. 项目概述从赛题到实战的跨越每年九月的那个周末对于全国几十万理工科大学生来说都是一场没有硝烟的“战争”——高教社杯全国大学生数学建模竞赛。2023年的C题“蔬菜类商品的自动定价与补货决策”一出来就戳中了很多人的痛点。它不像一些纯理论推导题那样飘在天上而是结结实实地落在了我们每天都能接触到的超市、菜市场里。题目给了一堆某生鲜商超的销售流水要求我们这帮“学生军”去扮演供应链经理和定价分析师的角色用数学模型和算法去回答明天该进多少菜每种菜该卖多少钱这听起来简单做起来全是坑。定价高了卖不掉菜烂在库里定价低了看似热闹但毛利覆盖不了损耗和成本忙活一场白干。补货更是门艺术补多了是浪费补少了错过销售机会还影响顾客体验。这道题的精妙之处在于它完美融合了数据分析、时序预测、优化决策和商业洞察是一个典型的“数据驱动业务”的实战场景。它考察的绝不仅仅是你会不会套几个模型而是看你能否真正理解业务逻辑并用严谨的数学语言将其表达和求解。我自己带学生打过好几届比赛深知这道题的价值。它几乎是一个微缩版的企业运营决策系统原型。搞定它你学到的不是几个孤立的算法而是一套从数据清洗、特征工程、模型构建、到求解验证、策略输出的完整数据分析与决策流水线。这对于未来无论你是想搞算法、做量化、进互联网还是从事供应链管理都是极其宝贵的硬核经验。接下来我就结合这道赛题拆解一下从解题思路到代码实现的完整路径分享一些实战中容易踩的坑和关键技巧。2. 核心问题拆解与建模总览面对“自动定价与补货决策”这个复合问题第一步不是急着找代码而是要把大问题庖丁解牛分解成几个可以逐个击破的子问题。一个清晰的建模框架是成功的一半。2.1 问题一销量与定价关系分析题目要求首先分析蔬菜各品类和单品之间的销售量分布规律以及其与定价策略的关系。这本质上是描述性统计分析和相关性探索。核心思路数据透视与可视化对销售流水数据按品类、单品进行聚合计算日均销量、销售总额、毛利率等指标。使用条形图、饼图展示品类销售占比用箱线图观察不同单品销量的分布与异常值。价格弹性初步探索这是关键。价格弹性衡量销量对价格变化的敏感程度。我们可以计算每个单品在不同日期的“销量-价格”数据对绘制散点图观察趋势。更严谨的做法是对于销售记录足够多的单品尝试拟合简单的需求曲线模型例如线性模型销量 a * 价格 b或幂律模型销量 k * (价格)^e其中e就是价格弹性系数通常为负值。弹性系数绝对值大的单品定价需格外谨慎。品类/单品关联分析利用相关系数矩阵或关联规则挖掘如Apriori算法分析哪些单品经常被同时购买互补品哪些存在此消彼长的关系替代品。这为后续的组合定价和补货联动提供依据。注意题目给出的销售数据是历史结果包含了当时定价策略的影响。直接观察到的“价格-销量”关系可能并非真正的市场需求曲线而是掺杂了库存缺货、促销活动等其他因素的“实现曲线”。在分析时需要保持这一清醒认识结论表述要留有余地。2.2 问题二未来一周日补货总量与定价策略这是题目的核心要求我们基于过去三年多的数据预测未来一周2023年7月1-7日每一天每个单品的销量并据此制定日补货总量和定价策略使得商超收益最大化。核心思路分两步走销量预测模型这是一个典型的时间序列预测问题。对于每个单品我们拥有按天的历史销量序列。需要考虑以下因素季节性蔬菜销售有强烈的年度季节性如夏季瓜果多冬季根茎类多和每周季节性周末销量高。趋势性某些单品可能呈现缓慢增长或下降的长期趋势。节假日效应春节、国庆等节假日会极大影响销量。价格影响需要将历史价格作为特征纳入模型。品类层次结构可以先预测品类总销量再按历史比例分解到单品或使用层次预测模型。模型选型建议传统统计模型SARIMA季节性自回归移动平均模型是处理时间序列的经典方法能很好地捕捉季节性和自相关性。但对于多个单品和外部特征价格的支持稍弱。机器学习模型LightGBM、XGBoost等树模型非常适合表格数据可以方便地加入价格、星期几、是否节假日、月份等特征。需要小心避免未来数据泄露不能用未来的价格预测过去的销量。深度学习模型LSTM、Transformer等序列模型理论上能力更强但对于数学建模竞赛72小时的时间限制和有限的数据量其调参复杂度和训练时间可能是巨大挑战需谨慎选择。定价与补货联合优化模型预测出销量后我们需要决策补货量和定价。这是一个优化问题。目标函数是商超的日均收益或周总收益。决策变量是每个单品每天的补货量和定价。约束条件包括需求约束预测销量是定价的函数。可以假设一个简化的需求模型例如预测销量 基础预测销量 * (1 价格弹性 * (价格变化率))。这里的基础预测销量来自上一步的预测模型假设价格与历史均价相同。库存动力学约束当日库存 前日库存 当日补货 - 当日实际销量。实际销量不能超过当日库存和潜在需求。损耗约束蔬菜有损耗率当日未售出的部分会按一定比例损耗。容量约束总补货量可能受到仓储空间、到货能力等限制。定价范围约束价格通常有上下限例如不能低于成本价不能高于市场承受范围。这通常形成一个非线性规划问题因为目标函数收益销量*价格-成本和需求约束中包含了价格与销量的乘积关系。可以使用SciPy.optimize或专用优化求解器如PuLP调用CBC或GEKKO进行求解。一个实用的简化策略是两阶段法先固定价格如历史均价用预测销量决定补货量再在补货量确定的情况下优化定价。虽然非全局最优但更稳健、易求解。2.3 问题三未来一周日补货总量与定价策略附加损耗率问题三在问题二的基础上增加了对可销售时间如叶菜类1天茄果类2-3天和当日未售出商品损耗比例的考虑。这极大地增加了模型的复杂性。核心思路引入库存状态变量现在库存不能只用一个数字表示了。我们需要区分不同“年龄”的蔬菜。例如需要记录“今天新到的”、“昨天剩的”等。这引入了库存龄的概念。构建多期库存滚动模型决策变得更加动态。今天的补货决策不仅影响今天的销售还影响未来几天的可售库存因为没卖完的会进入第二天但可能产生损耗。这需要建立一个多期例如7天的滚动优化模型。更新目标函数与约束目标函数总收益需要扣除损耗带来的成本。损耗成本 损耗量 * 成本价。销售优先级约束顾客会优先购买新鲜度更高的商品。在模型中可以假设先销售旧库存再销售新库存FIFO先进先出。损耗规则约束根据单品特性设定若商品在库超过其“可销售时间”则全部或按比例损耗。模型求解这通常形成一个更复杂的动态规划或多阶段随机规划问题如果考虑需求不确定性。在竞赛有限时间内一个可行的近似方法是在问题二的单日优化模型基础上在约束中加入“销售量不能超过当前最新鲜批次的库存量”并将多日损耗成本计入目标函数然后进行滚动优化——每天根据最新的库存状态和预测重新求解一次未来一天的决策如此滚动进行一周。3. 数据预处理与特征工程实战“垃圾进垃圾出”在数据建模中永不过时。题目提供的数据通常是原始的销售流水直接丢进模型效果肯定很差。预处理和特征工程往往消耗一半以上的时间也直接决定模型的上限。3.1 数据清洗与整合缺失值与异常值处理缺失日期检查是否有日期中断特别是节假日前后。可能需要根据前后日期进行插补或标记为特殊日期。异常销量/价格销量为0或极高价格为零或负值都可能是数据记录错误。需要用统计方法如3σ原则或业务规则进行识别和处理。对于价格可以参照成本价和市场常识进行修正。单次销售明细合并原始流水可能是每一笔交易一条记录需要按单品编码和销售日期聚合为日度销量和日均价格。数据整合将销售流水、商品分类表品类、单品名称、成本表如果提供通过单品编码关联起来。生成一个以日期和单品编码为行索引的面板数据列包括销量、销售单价、成本单价、是否打折、所属品类等。3.2 关键特征构造这是提升预测模型性能的核心。我们需要为每个单品-日期样本构造有预测力的特征。特征类别具体特征示例构造方法与意义时间特征year,month,day_of_month,day_of_week,week_of_year,is_weekend,quarter直接从日期提取捕捉周期性和趋势。滞后特征lag_1,lag_2,lag_3,lag_7,lag_30(销量/价格)过去1天、2天...的销量/价格反映短期自相关和惯性。滚动统计特征rolling_mean_7,rolling_std_7,rolling_max_7,rolling_min_7(销量)过去7天的均值、标准差等反映近期水平与波动。历史同期特征same_day_last_week,same_day_last_year(销量)捕捉周度和年度的强季节性。价格相关特征current_price,price_change_ratio(相比昨日/上周同期),price_category(高/中/低)直接反映定价策略。价格变化率是重要信号。品类聚合特征category_total_sales_yesterday,category_avg_price_today反映品类整体行情对单品有传导作用。事件特征is_holiday,is_festival,is_promotion_day(如有促销标记)二元特征对销量有显著影响。需要外部日历或从数据中推断。交互特征销量_lag1 / 品类日均销量(相对热度)刻画单品在品类内的相对表现。实操心得对于LightGBM/XGBoost这类模型滞后特征和滚动统计特征非常强大。但要注意避免未来信息泄露在构造lag_1昨日销量特征时必须确保在预测第t天的销量时只使用t-1天及之前的信息。在代码实现中这通常通过pandas的shift操作配合按时间排序的分组操作来实现。一个常见的错误是在全局做shift导致时间序列混乱。3.3 处理销量为零的日期这是一个非常实际的问题。销量为零可能有两种原因1. 真的没卖出去需求为零或定价过高2.缺货库存为零。在建模时必须区分这两种情况因为缺货日的“零销量”不代表需求为零直接用于训练会严重误导模型。处理方法识别缺货日如果数据中有库存信息最好。如果没有一个启发式规则是如果某单品连续多日销量为零且之后恢复销售那么中间的零销量日很可能是缺货日。或者如果某日销量为零但该日前后价格有异常波动也可能暗示缺货。标记或剔除将识别出的缺货日样本标记在训练预测模型时将其剔除或赋予一个极低的权重。因为我们的模型目标是预测潜在需求而不是观测到的受库存限制的销量。目标变量处理对于回归模型目标变量就是销量。对于存在大量零值的销量数据特别是高频低销单品可以考虑使用Tweedie回归或零膨胀模型这些模型能更好地处理零膨胀分布。4. 销量预测模型构建与调优我们以LightGBM模型为例展示一个稳健的销量预测流程。选择LightGBM是因为它速度快、精度高、能自动处理特征交互且对缺失值不敏感非常适合竞赛场景。4.1 模型训练框架import pandas as pd import numpy as np from sklearn.model_selection import TimeSeriesSplit from sklearn.metrics import mean_absolute_error, mean_squared_error import lightgbm as lgb # 假设 df 是已经完成特征工程的面板数据索引为[‘日期’ ‘单品编码’] # 目标变量是 ‘销量’ # 1. 划分训练集和测试集按时间顺序 cutoff_date ‘2023-06-01’ # 假设用此日期之前的数据训练之后的数据验证 train_mask df.index.get_level_values(‘日期’) cutoff_date test_mask df.index.get_level_values(‘日期’) cutoff_date X_train df.loc[train_mask].drop(columns[‘销量’]) y_train df.loc[train_mask, ‘销量’] X_test df.loc[test_mask].drop(columns[‘销量’]) y_test df.loc[test_mask, ‘销量’] # 2. 定义时间序列交叉验证 tscv TimeSeriesSplit(n_splits5) # 使用5折时序交叉验证 # 3. 初始化LightGBM模型 lgb_params { ‘objective’: ‘regression’, # 回归任务 ‘metric’: ‘rmse’, # 评估指标用均方根误差 ‘boosting_type’: ‘gbdt’, ‘num_leaves’: 31, ‘learning_rate’: 0.05, ‘feature_fraction’: 0.9, ‘bagging_fraction’: 0.8, ‘bagging_freq’: 5, ‘verbose’: -1, ‘n_jobs’: -1 # 使用所有CPU核心 } # 4. 使用交叉验证训练并早停 dtrain lgb.Dataset(X_train, labely_train) cv_results lgb.cv( paramslgb_params, train_setdtrain, num_boost_round1000, foldstscv, # 使用时序分割 early_stopping_rounds50, verbose_eval50 ) best_rounds len(cv_results[‘rmse-mean’]) # 5. 用最佳轮数在全量训练集上训练最终模型 final_model lgb.train( paramslgb_params, train_setdtrain, num_boost_roundbest_rounds ) # 6. 预测与评估 y_pred final_model.predict(X_test) mae mean_absolute_error(y_test, y_pred) rmse np.sqrt(mean_squared_error(y_test, y_pred)) print(f”测试集 MAE: {mae:.2f}, RMSE: {rmse:.2f}“) # 7. 特征重要性分析 importance_df pd.DataFrame({ ‘feature’: X_train.columns, ‘importance’: final_model.feature_importance() }).sort_values(‘importance’, ascendingFalse) print(importance_df.head(20))4.2 模型集成与后处理单一模型可能有局限集成学习能提升鲁棒性。多模型集成除了LightGBM可以同时训练XGBoost和CatBoost或者使用SARIMA做线性部分预测。然后将它们的预测结果进行加权平均或堆叠Stacking。品类层次调和先预测品类总销量再预测各单品在品类内的占比。最后将单品预测值按比例调整使其总和等于品类预测值。这可以保证加总逻辑一致减少品类层面的误差。非负约束与整数化销量预测值应为非负整数。可以在模型输出后进行max(0, round(pred))操作。更优雅的方法是在训练时使用适合非负数据的损失函数如Poisson loss或Tweedie loss。踩坑记录最大的坑莫过于“看似美好的验证分数”。如果你随机划分训练验证集可能会得到虚高的分数因为模型看到了未来的信息通过滞后特征泄露。必须使用时序交叉验证TimeSeriesSplit确保验证集的时间始终在训练集之后这样才能模拟真实的预测场景评估结果才可信。5. 定价与补货联合优化模型实现预测出“基础销量”假设价格与历史持平后我们进入优化环节。这里展示一个简化版的单日、单品优化模型忽略库存龄和跨期影响重点展示如何将业务逻辑转化为数学优化问题并用代码求解。5.1 问题定义与数学模型假设我们已经预测出单品i在未来某天的“基础需求量” ( D_i^0 )件。当价格 ( p_i ) 偏离历史平均价格 ( \bar{p_i} ) 时需求量会变化。我们采用一个简单的线性需求模型 [ D_i(p_i) D_i^0 \times [1 e_i \times (\frac{p_i - \bar{p_i}}{\bar{p_i}})] ] 其中( e_i ) 是单品i的价格弹性负数通过历史数据拟合得到。决策变量( x_i )单品i的补货量件( p_i )单品i的销售定价元/件参数( c_i )单品i的成本价元/件( S_{i0} )单品i的期初库存件( \beta_i )单品i的损耗率当日未售出部分的损耗比例( C_{max} )总补货能力上限件可选目标函数最大化当日总利润 [ \max \sum_{i} [ \min(D_i(p_i), S_{i0} x_i) \times p_i - x_i \times c_i - \beta_i \times \max(0, S_{i0}x_i - D_i(p_i)) \times c_i ] ] 解释min(D_i(p_i), S_{i0}x_i)实际销量不能超过需求也不能超过可用库存。min(...) * p_i销售收入。x_i * c_i补货成本。β_i * max(0, S_{i0}x_i - D_i(p_i)) * c_i损耗成本。未售出库存max(0, 库存-需求)按比例β_i损耗损耗物的成本按成本价c_i计算。约束条件( x_i \ge 0 ) 补货量非负( p_i^{min} \le p_i \le p_i^{max} ) 价格在合理范围内( \sum_i x_i \le C_{max} ) 总补货能力约束可选5.2 Python实现使用SciPy进行优化import numpy as np from scipy.optimize import minimize, Bounds, LinearConstraint # 假设我们有N个单品 N 10 # 基础需求预测 (D0) D0 np.array([100, 150, 80, 200, 90, 120, 180, 70, 110, 95]) # 历史均价 (p_bar) p_bar np.array([5.0, 8.0, 12.0, 3.0, 6.0, 10.0, 7.0, 15.0, 4.0, 9.0]) # 价格弹性 (e)假设已通过历史数据拟合得到均为负值 e np.array([-1.2, -0.8, -1.5, -0.9, -1.1, -0.7, -1.3, -0.6, -1.0, -0.5]) # 成本价 (c) c np.array([3.0, 5.0, 8.0, 2.0, 4.0, 6.0, 4.5, 10.0, 2.5, 6.0]) # 期初库存 (S0) S0 np.array([20, 30, 15, 50, 10, 25, 40, 5, 35, 18]) # 损耗率 (beta) beta np.array([0.1, 0.05, 0.2, 0.15, 0.1, 0.05, 0.1, 0.03, 0.08, 0.06]) # 价格下限和上限 (这里简单设定为成本价的0.8倍到1.5倍) p_min c * 0.8 p_max c * 1.5 # 总补货能力上限 (假设为500件) C_max 500 # 定义目标函数求最小化所以加负号 def objective(vars): # vars前N个是补货量x后N个是价格p x vars[:N] p vars[N:] # 计算需求函数 D(p) D D0 * (1 e * (p - p_bar) / p_bar) # 确保需求非负 D np.maximum(D, 0) # 可用库存 available_stock S0 x # 实际销量 actual_sales np.minimum(D, available_stock) # 期末库存未售出部分 leftover_stock np.maximum(available_stock - D, 0) # 总收入 revenue np.sum(actual_sales * p) # 总补货成本 replenishment_cost np.sum(x * c) # 总损耗成本 waste_cost np.sum(beta * leftover_stock * c) # 总利润 收入 - 补货成本 - 损耗成本 total_profit revenue - replenishment_cost - waste_cost # 由于scipy.minimize是求最小值我们返回负利润 return -total_profit # 定义约束和边界 # 决策变量边界x 0, p_min p p_max bounds Bounds(lbnp.concatenate([np.zeros(N), p_min]), ubnp.concatenate([np.full(N, np.inf), p_max])) # 线性约束总补货量 sum(x_i) C_max A np.concatenate([np.ones(N), np.zeros(N)]).reshape(1, -1) # 系数矩阵 linear_constraint LinearConstraint(A, lb-np.inf, ubC_max) # 初始猜测 # 初始补货量设为0初始价格设为历史均价 x0 np.zeros(N) p0 p_bar.copy() initial_guess np.concatenate([x0, p0]) # 求解优化问题 result minimize(objective, initial_guess, method‘SLSQP’, # 序列二次规划法能处理边界和约束 boundsbounds, constraints[linear_constraint], options{‘maxiter’: 1000, ‘ftol’: 1e-9, ‘disp’: True}) # 解析结果 if result.success: optimal_vars result.x optimal_x optimal_vars[:N] optimal_p optimal_vars[N:] optimal_profit -result.fun # 记得取负号变回利润 print(“优化成功”) print(f”预计最大总利润{optimal_profit:.2f}元“) for i in range(N): print(f”单品{i1}: 补货{optimal_x[i]:.1f}件 定价{optimal_p[i]:.2f}元/件“) else: print(“优化失败”, result.message)代码解读与注意事项需求模型简化我们使用了线性需求模型这在数学上易于处理。现实中需求曲线可能更复杂如对数线性、指数形式但线性模型在价格变动不大时是一个很好的近似且能保证优化问题是凸的易于求解。求解器选择SciPy.optimize.minimize的SLSQP或trust-constr方法可以处理带边界和非线性约束的问题。对于更大规模的问题成百上千个单品可能需要更专业的商业求解器如Gurobi, CPLEX或利用问题结构设计启发式算法。多期滚动优化对于问题三需要将上述单日模型嵌入一个循环。每天开始时根据最新的库存状态包含了前日剩余并扣除损耗后的库存和更新的需求预测重新求解当天的优化问题并将决策补货量、定价付诸“实施”然后更新库存状态进入下一天。不确定性处理上述模型是确定性的即假设预测是准确的。更高级的做法是考虑需求的不确定性引入随机规划或鲁棒优化但这在72小时竞赛中实现难度极大。一个折中方案是进行场景分析用预测区间的上下界如乐观、悲观场景分别运行优化模型观察决策的变化为决策者提供风险参考。6. 模型评估、验证与策略分析模型建好了代码跑通了但结果靠谱吗不能只靠一个最终的利润数字就下结论必须进行多维度评估和稳健性检验。6.1 预测模型评估回溯测试将模型应用到历史数据上模拟“过去”的预测和决策。比较模拟利润与实际历史利润如果可获得或至少比较模拟销量与实际销量的吻合程度。关键指标监控预测误差MAE, RMSE, MAPE平均绝对百分比误差。MAPE对业务方更直观。分位数预测对于补货决策我们不仅关心平均预测值更关心高需求分位数如90%分位数以避免缺货。可以训练分位数回归模型LightGBM支持来提供预测区间。品类一致性检查各单品预测销量的加总是否与品类总预测销量相匹配。可视化诊断绘制主要单品的历史销量与预测销量对比曲线。绘制预测误差残差的时间序列图检查是否存在未捕捉到的模式如误差在特定星期几偏大。绘制残差与特征如价格、星期几的散点图检查模型是否存在系统性偏差。6.2 优化策略分析优化模型输出的是一组数字补货量、定价。我们需要解读这些数字背后的策略含义。敏感度分析价格弹性敏感度将价格弹性e上下调整10%重新优化观察最优利润和决策的变化。对于弹性绝对值大的单品定价策略需要更加精细。成本敏感度模拟成本上涨5%或10%对定价和利润的影响。能力约束敏感度改变总补货能力上限C_max观察利润的变化曲线找到能力的“瓶颈点”。策略归类与解读高利润高弹性单品通常应保持相对稳定的价格和充足的库存因为小幅降价可能带来销量大幅增长大幅提价则可能严重损失客流。低利润低弹性单品可能是引流品或必需品。利润空间有限主要目标是保证供应避免缺货影响整体客流定价可接近成本。高损耗率单品补货策略必须非常保守“少食多餐”宁愿少量缺货也不要大量损耗。定价可以稍高以覆盖损耗风险。与简单策略对比基准策略1按历史同期销量均值补货按历史均价销售。基准策略2按上一周销量补货价格固定。将我们优化模型的模拟结果与这些简单策略对比量化模型带来的增量价值利润提升百分比、损耗降低百分比、缺货率降低百分比。这是证明模型价值最有力的方式。6.3 论文写作中的模型展示要点在最终的数学建模论文中不能只贴代码和结果必须清晰地展示思考过程。模型假设清单明确列出所有重要假设如线性需求模型、确定性需求、FIFO销售原则等并讨论其合理性和局限性。参数估计过程详细说明如何从历史数据中估计关键参数如价格弹性e、损耗率β。给出估计结果的统计摘要如均值、置信区间。模型流程图用清晰的框图展示“数据输入 - 预处理 - 预测模型 - 优化模型 - 决策输出”的完整流程。核心公式与算法伪代码将优化问题的数学模型完整呈现。对于复杂的求解算法如滚动优化给出伪代码。结果可视化用表格展示核心单品未来一周的补货与定价建议。用柱状图对比优化策略与基准策略的关键绩效指标KPI。用折线图展示未来一周预测销量与库存水平的动态变化。稳健性与扩展性讨论坦诚说明模型的不足例如未考虑竞争对手定价、天气因素、突发新闻事件等并提出未来可以如何纳入这些因素以扩展模型。7. 参赛实战技巧与避坑指南结合多年指导经验和评审视角分享一些在72小时高压竞赛中至关重要的实战技巧。时间管理是生命线Day 1 (上午)全体队员深入讨论彻底理解题目确定解题技术路线完成数据预处理和探索性分析EDA。必须在这一天形成统一的建模框架共识。Day 1 (下午) - Day 2 (全天)分头行动。一至两人主攻预测模型一人主攻优化模型另一人开始撰写论文的“问题重述”、“模型假设”、“符号说明”部分。晚上集中讨论整合初步结果解决遇到的技术卡点。Day 3 (全天)模型调优、结果分析、敏感度测试。下午必须开始论文核心部分的撰写模型建立、求解、结果分析。所有代码、图表必须在晚上之前整理完毕。最后通宵专注于论文打磨、摘要精炼、格式排版、检查错误。摘要和模型假设部分是评委重点看的务必反复修改。代码与文档的规范性代码注释关键步骤一定要写注释说明这一步在做什么、为什么这么做。这不仅能帮助队友理解在最后检查时也能快速定位问题。模块化编程将数据加载、预处理、特征工程、模型训练、优化求解分别写成函数或类。这样调试起来方便也便于在论文中展示核心代码片段。版本控制哪怕只用最简单的文件夹日期命名如code_v1_day1.py,code_final.py也要做好备份。避免最后时刻误操作覆盖文件。论文写作的“隐藏考点”摘要用一段话概括“针对什么问题、用了什么方法、建立了什么模型、得到了什么结论、有什么特色与创新”。最后写但最重要。要独立成篇即使不读正文也能了解全貌。模型假设不是凑字数而是体现你对问题复杂性的认知和简化能力。合理的假设能让模型可行并界定其适用范围。图表一图胜千言。图表要有编号和标题在正文中要有引用如“如图1所示”。确保图表清晰坐标轴标签、图例完整。结果分析不要只罗列数字。要解释“为什么这个单品补货多”“为什么那个单品定价高”将数学结果翻译成业务语言。常见大坑与应对坑1过度追求复杂模型一上来就想用LSTMAttention强化学习。结果数据量不够调参复杂时间耗尽效果还不如LightGBM。原则先跑通一个基线模型如线性回归、简单移动平均再逐步迭代复杂化。坑2忽略业务逻辑模型预测出未来某天销量为负数或者优化结果建议给易腐烂的叶菜一次性补货一周的量。这明显违背常识。任何模型输出都要用业务逻辑这把尺子量一量。坑3团队沟通不畅三个人各做各的最后模型对不上论文拼不起来。每天至少开两次短会同步进度明确接口比如预测模块输出什么格式的数据给优化模块。坑4不检查数据质量直接拿原始数据建模结果发现大量异常值或缺失值导致模型完全跑偏。拿到数据第一件事就是做描述性统计和可视化了解数据全貌。
返回列表