线性回归实战电商女装销售预测:从数据清洗到开题报告全流程

发布时间:2026/9/11 10:35:01
线性回归实战电商女装销售预测:从数据清洗到开题报告全流程 去年带学弟做毕设他抱着这个题目来找我时第一句话就是“师兄线性回归谁不会sklearn 三行代码就 fit 完了这能毕业吗”我当时没有说话等他把数据拿到手三天没睡好——不是模型跑不通是数据根本没法直接喂给模型。后来我们花了两周洗数据、做特征工程又把模型诊断和开题报告的论证逻辑来回捋了几遍才让这个“看着简单”的题目真正站稳脚跟。如果你也在做类似的课题——以唯品会女装或任意电商品类的销售数据为对象用线性回归做分析与预测——这篇文章值得你花十五分钟读完。我会按真实项目推进的顺序把业务问题定位、数据清洗与特征工程、建模实操、模型评估与调参、开题报告写作和答辩准备完整拆开讲。这里不会只贴一段跑完就交差的代码而是把每个环节“为什么这么做”的逻辑讲透顺便把新手最容易踩的坑提前标出来。1. 女装销售预测里线性回归到底解决什么问题1.1 女装这一品类为什么“难预测”很多学生选“销售预测”课题时脑子里想的还是教科书里波士顿房价那套逻辑——特征给进去数值吐出来一切水到渠成。但电商女装的数据远比房价数据复杂原因也很具体SKU 极其分散。一个女装店铺可能有几千个款号每个款号的颜色、尺码又切成更多 SKU。线上一件商品的自然流量、转化率、库存深度互相影响直接建模很容易被长尾商品带偏。款式生命周期短。标品比如手机壳可以连续卖一年销售序列有稳定的周规律。女装一条碎花连衣裙可能只卖四周第二周就到了清仓阶段销量曲线完全是另一个故事。季节性叠加促销节奏。春装、夏装、秋装、冬装的切换本身就制造大波动平台的大促节点比如周年庆、品牌特卖日又会把销量短期拉高数倍。如果把这些波动全部丢给模型自行理解线性回归显然吃不消。这不是线性回归的问题而是你在开题阶段就得清醒认识到的业务现实。它决定了后面所有技术决策。1.2 开题定位预测不是目的解释才是刚拿到这个题目时学弟写的第一版研究目标很常见“建立模型对销售量进行预测提高预测准确率。”这句话听起来没问题但放在开题答辩现场很容易被追问“准确率提高到什么程度算好整个行业都在用深度学习和复杂时序模型你凭什么用线性回归”后来我们把目标改成了两条识别影响女装销量的关键因素并量化各自的作用方向与大小建立基于线性回归的销售预测基线模型为后续引入更复杂模型提供对照基准。改动之后课题的价值立刻清晰了。“预测”退居第二位“解释”成为核心卖点。线性回归的系数天然可解释这恰恰是神经网络和树模型难以做到的。开题答辩时导师更关心你的模型能不能帮助业务理解“为什么卖得好”而不是单纯报一个 RMSE。1.3 线性回归与其他候选模型的分工我也被问过“为什么不用 ARIMA、Prophet 或者 LSTM”答案是不一样的题设。ARIMA 和 Prophet 更适合单变量时间序列也就是只有销量这一个变量随历史变化的情况。但我们手上明显有大量解释变量折扣、上架天数、促销标记、评论数、收藏数。多变量回归能回答“折扣降到多少销量大概能涨多少”ARIMA 回答不了这种问题。LSTM 这类深度模型对数据量和调参能力要求高本科或硕士课题的样本量往往不足以支撑而且黑盒模型在开题报告中很难讲清楚内在逻辑。线性回归作为第一个模型性价比最高——跑得快、结论直观、就算性能不够也能为后续用 XGBoost 或 Prophet 提供基线对比。2. 数据清洗与特征工程决定模型上限的前置环节2.1 字段设计先想清楚收集什么拿到脱敏后的电商销售数据第一件事不是急于 dropna而是把字段清单摊开逐个判断它对建模有没有价值。以唯品会女装场景为例我一般会保留和构造这么一批原始字段字段名类型含义说明建模用途order_date日期销售日期时间排序、衍生时间特征listing_date日期首次上架日期计算上架天数category_id分类女装细分类目类别编码price数值实际成交单价价格带分箱discount_rate数值折扣率促销力度量化sales_volume数值当日销量目标变量inventory数值当日可售库存库存对销量的约束comment_count数值累计评价数商品人气积累collect_count数值收藏数用户兴趣程度is_promotion0/1是否参与平台大促突发事件冲击这里要特别留意唯品会“品牌特卖”的业务特征商品以限时抢购形式出现库存深度和售卖窗口是强约束。有些款上线第一天就被抢空后续销量变成零这并不代表商品没人要而是“无货可卖”。如果不加处理模型会把这种“零销量”误判为需求冷淡。2.2 缺失值和异常值处理的具体策略电商数据的缺失值很有套路。常见情况是某件商品因为断码、下架、区域限制某几天没有销量记录。这时候不要直接填零而要分情况连续缺失不超过 3 天且不在大促区间用前后 7 天销量均值填充。大促前后的缺失优先用去年同期或最近一次大促的增幅进行比例估算。特征层面的缺失比如折扣率为空多数情况是该商品未参与折扣直接填 1 表示原价即可。异常值处理也不能拍脑袋。我习惯先用 IQR四分位距法把销量和折扣率的极端值标出来再逐个结合业务判断。比如某款商品单日销量是平时的 20 倍恰巧当天是平台主推位那就不能删这是真实业务信号反之如果一条记录显示折扣率为负数或大于 1基本可以判定是数据录入异常直接剔除。2.3 把日期、文本、价格转换成数值特征原始数据你没法直接丢给线性回归必须做特征工程。这一节是线性回归项目里投入产出比最高的地方也是最容易拉开档次的环节。我按重要程度逐个说第一个是上架天数。女装的销量往往随上架时间先升后降新品期曝光高后期进入清仓。上架天数这个数值特征能捕捉部分趋势但线性关系不够我一般会额外加入上架天数的平方项让模型拟合倒 U 型曲线。第二个是折扣率。用成交价除以吊牌价得到范围在 0 到 1 之间。它在业务上非常敏感——折扣率下降 10 个百分点销量通常会显著上升。线性回归对这类连续变量解释最舒服系数直接告诉你“每多打一折日销平均能涨多少件”。第三个是 0/1 标记。是否周末、是否大促、是否换季。这些变量看似简单却能把销量序列里的周期和脉冲解释掉一大半。如果你的数据粒度是周甚至可以考虑“距最近一次大促的天数”这种连续特征。第四个是评论数和收藏数的对数变换。这两个字段呈明显的长尾分布少数爆款拥有几十万评论大量商品只有几百。直接把原始数值作为特征极值对回归的拉动太强取 log 之后分布更平滑也更符合线性回归对输入特征的基本假设。第五个是价格带分箱。把价格字段按业务常识切段比如 0-99、100-199、200-499、500 以上再转成 0/1 哑变量。这样模型不用强行学习价格与销量之间的连续单调关系可以捕捉到“199 和 200 是两个心理价位”这种真实消费现象。特征做出来后记得用相关系数矩阵和 scatter plot 快速过一遍看看哪些特征与销量明显相关、哪些特征彼此高度相关。这个动作花不了几分钟却能在建模前替你排除掉一大批潜在问题。3. 建模实操线性回归假设、代码实现与参数解读3.1 线性回归的核心假设以及它在销售场景中的现实偏差线性回归不是把数据丢进 LinearRegression 就结束它背后有四个基础假设线性关系、误差独立、同方差、误差正态分布。放到销售数据里这四个假设几乎每条都会被现实打脸但你要做的就是发现偏差、解释偏差、尽量修正偏差。这才是课题的专业含量所在。举个例子。折扣率与销量的关系严格来说不是直线而是近似 S 形曲线折扣极低时销量增长趋缓折扣极高时销量也受限。这时候普通线性回归会系统性低估极端折扣下的销量。解决思路有两条一是对特征做非线性变换比如加入折扣率的平方项或交互项二是改用广义线性模型或岭回归来缓解非线性扭曲。开题报告阶段不要求你把模型改成最完美但必须展示你理解和验证假设的能力。3.2 时间序列数据如何正确划分训练集与测试集这是我强调最多的一点每年都能看到人犯用 train_test_split 的默认参数随机切分销售数据。对时序数据而言这种做法极其危险——它会让模型在训练时“偷偷看到”未来信息。随机切分后模型可能已经见过 8 月的促销效应再拿它去预测 7 月的销量测试集 R²高得离谱完全失真。正确做法是按时间顺序切分比如取前 80% 的时间段作为训练集后 20% 作为测试集。如果数据量允许再做时间序列交叉验证即滚动地逐段训练和验证模拟真实的预测环境。代码很直接import pandas as pd df df.sort_values(order_date) train_size int(len(df) * 0.8) train df.iloc[:train_size] test df.iloc[train_size:]这个切分方法本身就是开题报告里的一个亮点你在用正确的方式回答“你的模型究竟有没有泛化能力”。3.3 一次完整的建模流程代码特征工程做完、数据集切好之后建模代码其实非常短。下面这段代码覆盖了从特征筛选到输出系数的完整流程我用的是 sklearn 自带接口from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error feature_cols [ shelf_days, shelf_days_sq, discount_rate, is_weekend, is_promotion, log_comment, price_range_2 ] X_train train[feature_cols] y_train train[sales_volume] X_test test[feature_cols] y_test test[sales_volume] model LinearRegression() model.fit(X_train, y_train) y_pred model.predict(X_test) print(R2:, r2_score(y_test, y_pred)) print(MAE:, mean_absolute_error(y_test, y_pred)) print(RMSE:, mean_squared_error(y_test, y_pred, squaredFalse)) coef_df pd.DataFrame({ feature: feature_cols, coef: model.coef_ }).sort_values(coef, keyabs, ascendingFalse) print(coef_df)跑完这段代码你会得到三组结果测试集上的评价指标以及每个特征的回归系数。别急着看 R²高不高先把系数表逐行读一遍看看符号方向是否符合业务直觉。比如折扣率系数是负的意味着折扣越大discount_rate 数值越小销量越高这说明模型学到的方向是对的。4. 评估与调参R²、残差、共线性三个关口4.1 用哪些指标判断模型质量很多新手眼里只有 R²看到 0.85 就开心看到 0.4 就觉得自己完了。其实在销售预测场景里单一指标不能说明全部问题。三个指标搭配看指标关注点适用场景备注R²模型解释的方差比例适合对比特征组合对异常值非常敏感MAE平均绝对误差业务汇报常用量纲直观便于解释RMSE大误差的惩罚需要警惕大偏差时对离群点惩罚重如果 RMSE 明显大于 MAE说明预测误差中存在少量特别大的离群点比如大促当天某些款式的销量远高于模型预期。这时候先别想换模型回到特征工程看看是不是漏了“是否参与主推位”“是否首页曝光”这类信息。很多时候指标不好不是线性回归不行而是特征没喂够。4.2 残差图暴露的问题怎么修评估模型不要只看数字画图同样重要。我每次都会画一张“预测值-残差图”import matplotlib.pyplot as plt residuals y_test - y_pred plt.scatter(y_pred, residuals, alpha0.5) plt.axhline(0, colorred, linestyle--) plt.xlabel(Predicted Sales Volume) plt.ylabel(Residuals) plt.show()如果残差均匀分布在零轴上下说明模型没有系统性偏差。如果出现明显的“喇叭形”——预测值越大残差波动越大——这就是异方差问题。处理方法最常见的是对目标变量取 logy_train_log np.log1p(y_train) y_test_log np.log1p(y_test)取 log 之后模型学的不再是“销量”而是“销量的对数”预测值需要再指数化还原。这一操作的副作用是模型对小销量商品的误差变得更敏感但整体稳定性会好很多。如果残差图呈现明显波浪形态说明时间维度上还有周期性没被特征覆盖。这时候补进去的往往不是新算法而是诸如“距最近一次大促的天数”“月份哑变量”这样的特征。4.3 多重共线性诊断与岭回归兜底方案女装数据里特征之间经常高度相关。典型例子是评论数和收藏数二者都反映商品热度相关系数轻松超过 0.8。特征高度相关会导致回归系数不稳定——你把其中一个删掉另一个的系数可能翻倍。这不仅影响解释还会让模型在新数据上的表现忽高忽低。诊断多重共线性最常用的是 VIF方差膨胀因子。一般来说VIF 大于 10 的特征需要处理大于 5 就要警觉。计算很简单from statsmodels.stats.outliers_influence import variance_inflation_factor X_vif X_train.copy() vif_data pd.DataFrame({ feature: X_vif.columns, VIF: [variance_inflation_factor(X_vif.values, i) for i in range(X_vif.shape[1])] }) print(vif_data)处理策略按优先级排序先做相关性分析把相关性超过 0.8 的特征只保留业务含义更强的一个如果还不行考虑用岭回归L2 正则化代替普通最小二乘。岭回归通过给系数施加惩罚能显著提升系数稳定性代价只是损失一点点训练集拟合度。这在开题报告里也是一个很好的加分点——证明你不是只会调包而是懂得在模型层面处理问题。from sklearn.linear_model import Ridge ridge Ridge(alpha1.0) ridge.fit(X_train, y_train) y_pred_ridge ridge.predict(X_test)alpha 的选择可以用网格搜索配合时间序列交叉验证来调。不过开题阶段不必追求最优 alpha只要能说明“我对比了普通线性回归和岭回归最终选择了 XXX”就足够。5. 把项目写成开题报告框架、进度与答辩准备5.1 开题报告的章节结构与写作思路开题报告不是项目说明书它的核心目标是向评审老师证明三件事你选的问题值得做、你能把握研究现状、你制定的技术路线可行。常见的章节结构如下选题背景与研究意义国内外相关研究综述主要研究内容与关键问题研究方法与技术路线进度安排与预期成果参考文献写作时最容易犯的毛病是背景部分写一大堆“随着我国电子商务快速发展”。这种表达既没有信息量也无法展示你对该课题的理解。更聪明的写法是直接抛出业务痛点“女装品类 SKU 数量庞大、款式生命周期短销售波动受折扣与促销影响显著传统的经验备货方式已经难以适应当前速度。”一句话就把问题的来源、现状、为什么需要数据驱动讲完了。5.2 研究进度安排与预期成果开题报告里导师一定会看进度安排是否合理。不要凭感觉写“第 1 周熟悉 Python、第 2 周调通模型”那等于告诉导师你还没想清楚。一个贴合实际的时间表大概是阶段时间跨度主要任务产出物数据准备与清洗第 1-2 周获取脱敏数据、字段整理、缺失值与异常值处理清洗后的数据集探索性数据分析第 3-4 周销量分布、相关性分析、按品类和促销维度交叉观察EDA 分析图表特征工程第 5-6 周构造上架天数、折扣类、促销标记等特征建模特征矩阵模型构建与评估第 7-8 周线性回归建模、残差诊断、VIF 检验、岭回归对比基准模型结果分析与论文撰写第 9-10 周整理实验结论、撰写开题/论文正文论文初稿预期成果不建议写得太夸张。写“建立一套预测准确率达到 95% 的模型”是给自己挖坑写“形成可复用的数据清洗与特征工程流程得到可解释的销量影响因素回归模型为后续复杂模型提供基线对照”既实在又符合开题报告的性质。5.3 答辩现场的高频问题清单我陪学弟模拟答辩时发现导师的问题基本集中在几个点上。提前准备能防住 80% 的突然提问Q1为什么用线性回归不用更复杂的模型答本课题重点在于量化影响女装销量的关键因素线性回归系数具备明确业务含义。同时它是对比实验的基线模型后续可以在此基础上引入 XGBoost 或 Prophet评估复杂模型带来的增量收益。Q2如果模型 R² 只有 0.5课题还有意义吗答有。销售数据噪声大0.5 的 R²在业务上已经具备参考价值关键是通过回归系数识别出显著的影响因素并解释清楚模型未能解释的部分主要来自哪些未采集变量比如主推资源位、竞品价格变动等。Q3如何处理数据来源的合规问题答所有数据均来自公开渠道或脱敏后的教学数据集不涉及用户个人隐私。这一步我会在开题报告的数据说明部分明确写出数据来源与使用边界。Q4你的模型能不能在业务里落地答能。模型输出的系数可以直接辅助运营决策比如根据折扣系数估算某商品降价 10% 带来的销量增量帮助判断是否值得参加下一轮促销活动。6. 最后分享一点我自己的实操体会做这个项目最耗时间的不是建模而是和理解数据较劲的过程。我印象很深学弟第一次画出残差图后愣了半天因为怎么都不认识那个喇叭形状后来翻了一晚上资料才明白是异方差。等到他把目标变量取了对数、把评论数做了平滑再看残差图整个模型才顺过来。说句实话线性回归能让人学到的东西往往就在这些反复试错里。如果你的数据结构类似——时间粒度是日、存在促销节点、特征数量在 5 到 20 个——完全可以按这条路径走一遍。数据量不超过几十万行的话普通笔记本跑起来毫无压力。做的时候记得多画图、多记录实验参数论文和答辩的素材其实都是中途攒下来的。另外一个很实用的小技巧把所有回归系数的绝对值画成柱状图观察哪个特征贡献最大。这一步看似简单却是你答辩时展示“从数据到业务”能力的最佳材料。