ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python大数据内衣销售可视化与预测系统实战解析

Python大数据内衣销售可视化与预测系统实战解析 去年接手了一个内衣品牌的电商数据分析项目业务方一开口就是“我们想看到哪些款式该补货哪些该清仓最好下个月的销量能跑出来”。说实话刚接到需求时心里没底因为内衣品类SKU特别多尺码、颜色、杯型交叉之后动辄几十万个可售单品靠Excel根本撑不住。但整套系统做完之后效果出乎意料从数据仓库搭建到可视化大屏上线再到销量预测模型落地前后大概两个月时间准确率稳定在85%上下。这篇文章就把这套Python大数据时尚内衣销售数据可视化和预测系统的分析与应用过程完整复盘一遍给正在做电商数据项目或者想从报表转向预测决策的同学一个可参考的蓝本。整个项目的核心是用Python串联起数据清洗、存储、可视化和预测四个环节前端用Echarts做交互大屏后端用Flask提供接口大数据部分用了PySpark处理千万级明细数据。这套方案并不需要很强的服务器资源几台普通虚拟机就能跑适合中小企业电商团队的落地场景。1. 项目概览与整体设计思路1.1 业务痛点内衣品类的数据复杂度远超想象很多人觉得内衣就是个服装类目按款式统计一下就行。真做起来才发现这个品类的数据复杂度在服装里算很高的。一件文胸通常有颜色、罩杯、底围三个核心属性光一个SKU就有几十个组合再加上内裤、保暖衣、家居服等子类目如果一个品牌在三个平台同时开店每天产生的订单明细可能有几十万行。这还不算最麻烦的。内衣的销售季节性极强秋冬保暖款和春夏薄款完全两个节奏促销活动又特别密集三八节、618、双11、年货节每次大促都会把销量曲线拉出一个尖峰。如果还用“看上周趋势推断下周”的老办法备货不是积压就是断码。业务方要的不是一堆静态报表而是能直接指导补货、调拨、清仓的决策工具。所以这个系统设计的第一个原则就是不是做一个数据展示页面而是做一个“从数据到行动”的闭环。可视化解决“现在卖得怎么样”预测解决“接下来该怎么办”两者拼在一起才是一个能用的系统。1.2 技术选型为什么偏偏是这一套组合我当时对比过几种方案。底层数据处理可以用纯Pandas也可以用Spark或者Flink可视化可以用FineReport、Superset这类现成工具也可以自己写前端页面。最终敲定的是Python全栈加轻量大数据组件理由很实际。第一团队的技术栈就是Python招聘、维护、交接的成本最低。数据分析从清洗到建模本来就是Python的主场不需要为了“大数据”的名头硬上一套Java体系。第二数据量级决定了技术选型的天花板。以内衣品牌的中等体量来看三五年累计的订单明细撑死两三千万行这个量级PySpark完全够用还不需要搭特别复杂的集群三台八核16G内存的云主机就能跑得很舒服。真上了Flink或者ClickHouse运维成本反而会让小团队崩溃。第三Echarts的定制能力比现成BI工具灵活很多。内衣品类有很多独有分析维度比如罩杯销量分布、底围尺码断码预警这些用FineReport做要写很多自定义脚本但用Echarts就是配置项的事。技术栈最终定为Python 3.10作为主语言Pandas做清洗和特征工程PySpark处理超大数据集的聚合MySQL存汇总结果Flask做后端接口Echarts做前端图表Prophet和XGBoost负责预测。这里说一句MySQL看起来不够“大数据”但数据经PySpark预聚合后落到MySQL的结构化结果集通常就几十万行用MySQL做展示层查询性能完全没问题还省去了团队学习HBase的隐性成本。2. 数据体系搭建与预处理2.1 数据源梳理与核心字段设计系统要用的数据主要来自三个地方电商平台的订单导出接口、ERP系统的库存表以及各门店的POS销售记录。光把三个表导出来还不能直接用因为字段口径不统一平台A叫“实付金额”平台B叫“支付金额”ERP里是“含税零售价”字段名完全对不上。我在第一版就把所有数据统一抽到一个明细层字段设计如下表所示。字段名类型说明来源order_idString平台订单号电商接口product_codeString商品编码SPU级别ERPsku_codeString规格编码SPU色码尺码ERPcategory_1String大类文胸/内裤/家居服ERPcategory_2String小类无钢圈/有钢圈/塑身衣等ERPcolorString颜色ERPsize_cupString罩杯A/B/C/D及以上ERPsize_bandString底围70/75/80/85等ERPsale_qtyInt销售数量订单sale_amountDecimal实付金额订单cost_amountDecimal成本金额ERPstore_codeString门店/仓库编码POSchannelString渠道天猫/京东/抖音/线下订单order_dateDate订单日期订单flag_promoInt是否促销活动订单规则判断这套字段设计看起来平平无奇但有两个细节是踩过坑才加上的。第一个是sku_code必须比product_code低一级因为内衣的尺码和颜色是影响库存的核心属性只看SPU会遗漏断码风险。第二个是flag_promo字段来源是订单备注和价格折扣规则判断这个字段在预测模型里极其重要没有它促销日就会被模型当成普通的高销量日造成节后预测断崖式高估。2.2 数据清洗pandas处理常见脏数据的姿势数据接口拿到的原始表问题很多我总结三大类缺失、重复、口径异常。清洗逻辑用Pandas写了一个独立模块每个任务对应一个函数方便测试和复用。第一个是缺失值处理。订单表里的size_cup和size_band经常有空值尤其是退货订单和手工录入订单。内衣的尺码一旦缺失这个SKU的销售记录基本就没法聚合到尺码维度所以策略是如果同product_code下其他订单有尺码就用众数填充如果整单都没有直接标记为“未知尺码”单独统计不参与尺码分析。这里不建议直接删行因为金额数据可能还有用。第二个是重复订单。很多人以为是order_id重复实际上电商接口返回的数据经常出现同一个order_id下多行相同明细的情况这是平台订单拆单逻辑导致的。我用order_id加sku_code加order_date三个字段做组合去重稳定清除掉了约3%的重复记录。第三个是异常值修正。内衣类目偶尔会出现销售数量为负数的情况这是退款订单没有从原订单中剔除造成的。我处理的方式不是直接过滤而是先把退款单单独提取出来在总销量中冲减同时保留退款原因字段用于后续分析。还有一个常见问题是价格异常比如一件成本68元的文胸成交价变成680元这类记录通常是测试单或者私单我直接按超过同SKU近30天成交均价5倍的规则剔除。2.3 特征工程给预测模型准备真正的输入原始字段只是记录事实直接从明细表进模型效果很差。预测需要的是“可解释的输入特征”我按时间粒度做了三层特征一是趋势特征。过去7天、14天、30天的销量均值、标准差、环比变化率这些特征能让模型感知到销量的近期走势。二是季节性特征。周几、是否周末、月份、是否节假日、距上次大促天数、距下次大促天数。内衣在情人节、三八节前会有明显上升距大促天数这个特征特别有效。三是外部特征。天气温度数据对这个品类有很强的解释力我接了免费的天气接口把每个销售区域的平均气温和温差并进数据里。高温天薄款文胸卖得好气温骤降时保暖内衣销量立刻抬头。这个特征加上去之后预测模型的误差直接降了4个百分点。特征工程这部分代码量不小但逻辑都不复杂。需要注意的是所有特征必须用历史窗口计算比如预测7月1日的销量只能用6月30日及以前的数据严禁用当天数据算均值否则模型在训练集上表现虚高上线后立刻崩掉。2.4 大数据预处理PySpark的亿级数据实战虽然业务问题中“大数据”更多是标识意义但数据量大起来之后Pandas确实跑不动。内衣订单明细一天大概30万行三年就是3000多万行加上尺码维度展开每次全量重算都要十几分钟这显然不行。我的方案是用PySpark做全量数据的分区重算把处理后的聚合结果物化到MySQL。Spark的好处是内存不够可以靠磁盘IO撑住而且能用SQL表达复杂的关联逻辑。我用的是三节点Spark Standalone集群每节点8核16G跑3000万行的聚合任务大概七分钟接受范围内。具体写法不复杂核心逻辑就是读CSV或Parquet到DataFrame做filter、groupBy、agg最后写入MySQL。这里有一个实战建议千万别用Pandas读全量数据再转Spark直接spark.read.csv()读取Spark会自动做资源调度。另外写入MySQL前先建好索引否则下游查询会等到怀疑人生。3. 可视化分析模块从SQL到数据大屏3.1 关键指标与图表规划一张大屏上看懂销售全貌可视化不能想到啥画啥那样大屏会变成垃圾场。我根据业务方的高频问题把指标分成三层核心宏观指标、销售结构指标、库存风险指标。宏观指标包括总GMV、总销量、客单价、连带率单笔订单购买件数放在大屏顶部。结构指标包括品类销量占比、颜色销量Top5、尺码销量分布、渠道对比用来回答“卖的是什么、在哪卖得好”。风险指标包括库销比库存金额/近30天日均销额、断码预警SKU数、清仓款销量趋势放在右侧是运营每天必看的部分。图表规划对应关系如下。分析维度图表类型对应指标整体趋势折线图/面积图GMV、销量按日/周趋势品类结构饼图/环图文胸/内裤/家居服占比颜色偏好柱状图颜色销量Top10尺码健康度热力图罩杯×底围销量矩阵渠道对比雷达图/柱状图各渠道GMV、退货率促销效果双轴图销量柱状折扣率折线库存预警表格状态标记断码SKU、积压SKU尺码热力图是我觉得最值得做的一张图。把罩杯放横轴底围放纵轴格子颜色代表销量高低。热力图上哪一块颜色深哪一块浅一眼分明业务方第一次看到就惊呼“原来75B才是绝对主力”后续补货策略立刻调整了。3.2 Flask Echarts 数据大屏开发大屏前端我用的是Echarts的仪表盘布局整页没有用现成的BI模板自己写的HTML加Echarts配置。后端用Flask暴露一个/overview接口从MySQL按日期和渠道维度聚合数据返回JSON前端通过Ajax拉取。一个简化版的后端接口示例from flask import Flask, jsonify import pymysql app Flask(__name__) def query_db(sql): conn pymysql.connect(host10.0.0.5, userviz_user, password******, dbsale_dw, charsetutf8mb4) cur conn.cursor() cur.execute(sql) cols [d[0] for d in cur.description] rows [dict(zip(cols, r)) for r in cur.fetchall()] cur.close() conn.close() return rows app.route(/overview) def overview(): sql SELECT order_date, SUM(sale_qty) AS total_qty, SUM(sale_amount) AS total_amount, COUNT(DISTINCT order_id) AS order_cnt FROM sales_summary WHERE order_date DATE_SUB(CURDATE(), INTERVAL 30 DAY) GROUP BY order_date ORDER BY order_date data query_db(sql) return jsonify(data) if __name__ __main__: app.run(host0.0.0.0, port5000, debugFalse)前端Echarts的折线图配置就不贴完整代码了核心思路是用fetch拿到JSON后用setOption把日期映射到x轴数值映射到y轴。这里有几个必须注意的坑第一接口返回的日期格式必须统一成“YYYY-MM-DD”否则Echarts会把它识别成字符串导致时间轴错乱第二折线图的数据如果跨天很多不要用点状标记否则页面渲染几千个节点会卡第三大屏刷新频率不要设成1秒否则后台SQL又被拖垮我实测5秒刷新已经足够满足监控需求。3.3 大屏交互与数据权限设计大屏不能只是静态展示运营想看某个品类的细拆就要能点某个品类饼图区块下钻到该品类的尺码分布和渠道分布。我实现了两级下钻第一级点击品类前端拿到category_1参数请求详情接口第二级点击某个具体SKU跳到该SKU的销量趋势和库存详情页。权限这一块是后来补的。因为大屏是整个品牌共用线下门店的运营只能看到自己门店的数据总部可以看到全部。我给每个数据表加了组织维度字段后端请求通过查询参数传递store_code或team_code在SQL的where条件里强制追加“用户可见范围”。这里最容易犯的错误是把权限判断写死在Python代码里。因为用户身份可以伪造必须在数据库层面就过滤。我们的做法是建一张user_scope表记录每个用户能访问的渠道和门店后端在构造SQL时用表连接方式校验而不是先全量查出数据再在Python里筛选。测试阶段用普通账号访问改造后的接口只返回授权范围的数据。4. 销售预测模型从历史数据到未来需求4.1 预测目标与算法选型哪个模型最靠谱预测模块的目标是产出未来30天每个SPU级别的日销量区间。本来也想直接预测到SKU但内衣SKU组合太多很多SKU一个月才卖个位数模型完全学不到规律。折中方案是预测到SPU加颜色尺码按历史占比分配效果好了很多。算法选型上我对比了四套方案。算法优点缺点适用场景ARIMA简单、稳定难以加入外部变量、拐点敏感趋势平稳的单序列Prophet自动处理季节性和节假日对促销爆发反应滞后有明显周、月周期的数据XGBoost能吃大量特征、预测准需要做特征工程、调参有丰富外部特征的表格式数据LSTM能捕捉长期依赖数据要足够、训练慢、解释性差海量数据和GPU环境最后我选择了Prophet和XGBoost双轨并行。Prophet用来做整体大盘预测因为大盘数据平稳节假日效应明显Prophet不需要做复杂特征拿日期序列直接喂进去就能跑SKU级别的预测用XGBoost把天气、促销、历史销量特征全塞进去精度更高。两条线互相校验如果两个模型对未来30天总销量预测方向不一致说明数据里出现了异常波动我会人工探查原因。4.2 Prophet预测的完整流程与参数调优Prophet的使用非常简单但参数调优是门学问。一个最小可用的预测代码from prophet import Prophet import pandas as pd df pd.read_csv(daily_sales_total.csv) # 只需要两列ds日期、y指标值 df df.rename(columns{order_date: ds, total_qty: y}) df[ds] pd.to_datetime(df[ds]) model Prophet( yearly_seasonalityTrue, weekly_seasonalityTrue, daily_seasonalityFalse, changepoint_prior_scale0.05, seasonality_prior_scale10.0, holidays_prior_scale15.0 ) # 加入促销节日作为holiday promo_days pd.DataFrame({ holiday: promo, ds: pd.to_datetime([2024-06-18, 2024-11-11, 2024-12-12]) }) model.add_holidays(promo_days) model.fit(df) future model.make_future_dataframe(periods30, freqD) forecast model.predict(future)这段代码里三个参数值得说。changepoint_prior_scale控制趋势拐点的灵活度默认0.05但内衣品牌每年大促多、趋势骤变多我调到0.08才能追上销量爬坡的速度太高了又会把普通周波动当拐点导致过拟合。seasonality_prior_scale控制季节性成分的强度这个调小一点防止模型把促销噪声当成周期性规律。holidays_prior_scale是给促销日用的促销当天的销量通常是平日的几倍如果不加大这个值预测曲线会平滑掉大促尖峰。4.3 XGBoost建模样例与特征重要性分析SKU级预测的XGBoost模型是我们全项目里效果提升最明显的部分。用Spark把历史数据按sku_code聚合出逐日销量再关联天气、节假日、历史促销标记最终数据集大概有180万行特征17个。训练代码骨架import xgboost as xgb from sklearn.model_selection import train_test_split features [year, month, dayofweek, is_weekend, is_promo, temp_avg, temp_diff, sku_sales_lag7, sku_sales_lag14, sku_sales_lag30, sku_ma7, sku_ma30, cat_id, color] X df[features].values y df[sale_qty].values train_x, test_x, train_y, test_y train_test_split( X, y, test_size0.2, shuffleFalse) model xgb.XGBRegressor( n_estimators500, max_depth5, learning_rate0.05, subsample0.8, colsample_bytree0.7, eval_metricmae, early_stopping_rounds50 ) model.fit(train_x, train_y, eval_set[(test_x, test_y)], verboseFalse)这里有两个行业经验。第一个是shuffleFalse时间序列数据不能随机打乱顺序。按时间顺序切分训练集和测试集否则会出现“用未来数据预测过去”的数据泄露。第二个是特征里一定要有sku_sales_lag7这类滞后项。做内衣预测时我发现很多SKU的销量今天是昨天和前天的强相关滞后特征能帮模型抓住短期连续性少了这个模型基本只能预测出平均值。特征重要性排序出来后促销标记、距大促天数、温度这三个特征排在前五。这说明内衣销售受这几个因素驱动很强运营后来也根据这个调整了广告投放节奏。4.4 预测结果落地从模型输出到补货建议模型出来的是一堆预测区间不能直接把数字扔给采购。我包装了一个“补货建议器”把预测结果转成可执行的SKU补货单。逻辑分三步第一步用预测销量中位数乘未来30天销售天数得到预计销量第二步结合当前库存和采购提前期内衣生产提前7到15天计算安全库存线第三步如果预计销量加上安全库存仍小于当前库存则给出“建议补货数量预计销量安全库存-当前库存-在途库存”。这里有个关键细节补货要按尺码拆分。因为SPU预测是整个颜色维度具体到每个底围和罩杯还得用历史尺码占比拆分。比如75B历史占35%某SPU预测总件数1000件75B补货数量就是350件。但要注意尺码占比会随季节波动夏季薄款集中在小罩杯冬季厚款集中在B罩杯占比更大所以拆分系数要按月滚动更新。这样输出的建议表格才真正有指导意义。采购部拿到的是“产品编码、颜色、尺码、建议补货量、建议发货仓库”的Excel而不是一张看不懂的趋势图。项目上线后断码率从21%降到了12%这就是预测模型最大的价值。5. 常见问题与排坑实录5.1 Pandas处理大数据时的内存优化技巧刚开始我用Pandas处理全量数据跑一个任务内存就飙升到30G然后OOM被杀。后来用了三个技巧解决。一是按需读列pd.read_csv(usecols[...])只读需要的字段3000万行数据直接从几个G降到几百M。二是数据类型压缩把int64转int32把对象类型转category特别是尺码、颜色、渠道这些低基数列。三是分块处理chunksize参数配合apply聚合把一个大任务拆成多个小任务。实测同样一个聚合任务优化后内存占用从20G降到6G运行时间反而没有明显变长因为内存换页少了。生产环境配置只有16G内存的机器也能顺利跑完。5.2 Echarts大屏渲染卡顿和动态刷新的坑有一次大屏展示全国门店地图地图上要画几百个门店点位每个点位上还有弹窗和闪烁动画。上线后运营反馈点开页面要十几秒才能看到地图而且滚动弹窗时有明显顿挫。排查后发现问题不在图表本身而在于我一次性setOption传入了几千个城市的完整坐标和销售数据图表节点数过高。解决方法是把地图拆成两个图层底图只加载轮廓点位图用自定义marker点按区域分批渲染。同时把动画特效减少只保留Top20门店的有效果。刷新机制也从全量刷新改成增量更新新增数据先push进series再调setOption效果非常顺滑。这里提醒一句Echarts的性能瓶颈通常不在库本身而在数据量和DOM节点数能用dataset尽量用不要画一堆没用的系列。5.3 预测模型效果差根因排查思路有一次模型跑完业务方说未来一周预测值明显低于实际销量。我没有急着调参数而是先做了数据体检。一查发现最近三天刚好有天猫“新风尚”标签活动但我的promo表里没有收录这个活动模型完全没感知到。排查的过程总结成一个清单第一检查预测日期区间内是否有已知活动活动标记是否纳入了特征第二检查训练数据的最后日期是否包含了最近一次活动如果活动前几天数据没进训练集模型对活动的记忆自然缺失第三检查该SKU近期是否涨价或者变相折扣影响了销量第四检查是不是有某一个渠道的订单接口延迟导致最近几天数据没有全量入库。按这个顺序排查大部分预测偏差都能定位到根因。5.4 行权限设计中的SQL注入与性能问题我们系统最初的行权限判断是通过Python字符串拼接动态sql如梦“WHERE store_code ” store_code “”当时一看就知道迟早出问题。后来统一改成参数化查询并且在权限过滤字段上加了索引。改造前每个接口耗时60毫秒左右加索引后降到20毫秒以下算是解决了性能问题。另外还碰过一个坑缓存大屏数据时没有把用户维度放进缓存key导致杭州门店的人看到了上海门店的数据。缓存key要加上user_id或权限域这样才能保证多租户隔离。现在的做法是缓存时间控制在30秒以内同时权限过滤始终在SQL层做不准在Python层过滤之后缓存。6. 项目复盘与可扩展方向6.1 上线后的实际效果整套系统上线八周后我拿数据做了对比老报表模式下运营每天要花两个小时汇总Excel上线大屏后每天只看一次大屏加一次预测报告时间缩短到二十分钟。预测部分SKU级销量平均绝对百分比误差MAPE在18%左右大盘总量的MAPE在9%上下。断码率从21%降到12%清仓折扣力度平均降低了5个百分点因为库存决策提前了不用一再降价甩卖。虽然没有把整个GMV提升都归功于系统但至少补货建议让爆款缺货的机会成本明显减少。双11那一个月的销售预测模型给出的总销量区间和实际偏差不到5%运营主管当时就说“以后备货就按这个来”。6.2 可以继续做的几个升级方向这个系统现在还是离线批处理T1的数据延迟。下一步我想引入实时流处理把电商订单数据用Kafka接入Flink做窗口聚合这样大屏上的GMV秒级刷新促销活动期间的实时监控能力能提升一个档次。预测模型方面可以尝试用LightGBM和Prophet模型融合再把退货率也作为目标变量做退货预测。另外结合RFM模型做客户分群分析不同购买力人群的文胸偏好把可视化从“货”延展到“人”。最后再说一个做这类项目的心得别被“大数据”这个词吓住也不要被“预测准确率100%”这种目标绑架。商业场景里预测准到大盘、结构准到品类、预警准到断码已经是非常有价值的系统。先把可视化和预测做成一个能稳定跑的闭环再一步一步加复杂度这条路最省力也最不容易翻车。我在做这个项目的过程中最大的体会是数据团队最容易被业务质疑的就是“图做得好看但没用”。要让系统真正被用起来关键不是炫技而是把输出格式和业务决策动作对齐。补货单、清仓清单、断码预警这些能让采购直接干活的东西比任何花哨的图表都更能体现数据分析的价值。如果你手上的项目也卡在“报表好看但没人用”的阶段建议先和业务方坐下来问清楚他们拿到数据后下一次行动是什么再回来设计你的可视化——这个步骤做完项目基本就成功了一半。
返回列表