AI驱动的需求预测数据管道:历史销量、季节性与促销因子的特征工程
AI驱动的需求预测数据管道历史销量、季节性与促销因子的特征工程一、备货5000件实际卖了150件预测失败的沉没成本某生鲜电商在樱桃季前根据去年同期销量×1.2的简单预测向产地采购了5000箱烟台樱桃。结果当季实际销量仅150箱。复盘发现漏掉了三个关键变量当年是樱桃产量大年导致市场价格暴跌供给侧冲击、竞品平台搞了车厘子买一送一活动替代品促销、连续一周阴雨天气降低了生鲜购买意愿天气因子。传统的时间序列预测ARIMA/Holt-Winters只能捕捉历史销量的周期性无法融入天气、竞品促销、宏观经济等外部因子。而AI预测的关键不在于模型选型——LSTM、Prophet、XGBoost在这个问题上效果差不多——而在于特征的丰富度和新鲜度。二、需求预测的特征工程与数据管道三、特征管道实现import pandas as pd import numpy as np from datetime import datetime, timedelta from sklearn.preprocessing import LabelEncoder class DemandForecastFeaturePipeline: def __init__(self, mysql_pool, redis_client, weather_api): self.mysql mysql_pool self.redis redis_client self.weather weather_api def build_features(self, sku_id: str, forecast_date: datetime, horizon_days: int 30) - pd.DataFrame: 构建预测所需的特征矩阵 features {} # 1. 历史销量特征滞后特征 features.update(self._build_lag_features(sku_id, forecast_date)) # 2. 时间特征 features.update(self._build_temporal_features(forecast_date)) # 3. 促销特征 features.update(self._build_promotion_features( sku_id, forecast_date, horizon_days )) # 4. 天气特征 features.update(self._build_weather_features( forecast_date, horizon_days )) # 5. 库存特征 features.update(self._build_inventory_features(sku_id)) # 6. 品类趋势特征 features.update(self._build_category_features( sku_id, forecast_date )) return pd.DataFrame([features]) def _build_lag_features(self, sku_id: str, forecast_date: datetime) - dict: 构建滞后特征过去N天的销量 query SELECT date, quantity_sold, avg_price, discount_rate, is_promotion FROM daily_sales WHERE sku_id %s AND date %s AND date %s ORDER BY date start_date forecast_date - timedelta(days90) try: df pd.read_sql(query, self.mysql.get_connection(), params(sku_id, start_date, forecast_date)) except Exception as e: raise FeatureBuildException(f销量查询失败: {sku_id}, e) if df.empty: return self._default_lag_features() features { # 最基础昨天、前天、上周同天的销量 sales_lag_1: float(df[quantity_sold].iloc[-1]) if len(df) 1 else 0, sales_lag_2: float(df[quantity_sold].iloc[-2]) if len(df) 2 else 0, sales_lag_7: float(df[quantity_sold].iloc[-7]) if len(df) 7 else 0, sales_lag_14: float(df[quantity_sold].iloc[-14]) if len(df) 14 else 0, sales_lag_30: float(df[quantity_sold].iloc[-30]) if len(df) 30 else 0, # 移动平均 sales_ma_7: float(df[quantity_sold].tail(7).mean()) if len(df) 7 else 0, sales_ma_14: float(df[quantity_sold].tail(14).mean()) if len(df) 14 else 0, sales_ma_30: float(df[quantity_sold].tail(30).mean()) if len(df) 30 else 0, # 趋势 sales_trend_7: self._calc_trend(df[quantity_sold].tail(7)), sales_trend_30: self._calc_trend(df[quantity_sold].tail(30)), # 波动性 sales_std_7: float(df[quantity_sold].tail(7).std()) if len(df) 7 else 0, sales_std_30: float(df[quantity_sold].tail(30).std()) if len(df) 30 else 0, } return features def _build_temporal_features(self, date: datetime) - dict: 时间特征 return { day_of_week: date.weekday(), is_weekend: 1 if date.weekday() 5 else 0, day_of_month: date.day, month: date.month, quarter: (date.month - 1) // 3 1, is_month_start: 1 if date.day 3 else 0, is_month_end: 1 if date.day 28 else 0, # 是否为节假日 is_holiday: self._is_holiday(date), days_to_holiday: self._days_to_next_holiday(date), } def _build_promotion_features(self, sku_id: str, forecast_date: datetime, horizon: int) - dict: 促销特征预测期内是否有计划促销 end_date forecast_date timedelta(dayshorizon) try: promotions pd.read_sql( SELECT COUNT(*) AS promo_count, AVG(discount_rate) AS avg_discount, MAX(discount_rate) AS max_discount FROM planned_promotions WHERE sku_id %s AND start_date %s AND end_date %s , self.mysql.get_connection(), params(sku_id, end_date, forecast_date)) if not promotions.empty: row promotions.iloc[0] return { has_promotion: 1 if row[promo_count] 0 else 0, promo_avg_discount: row[avg_discount] or 0, promo_max_discount: row[max_discount] or 0, } except Exception: pass return {has_promotion: 0, promo_avg_discount: 0, promo_max_discount: 0} def _build_weather_features(self, date: datetime, horizon: int) - dict: 天气特征从天气API获取 try: cache_key fweather:forecast:{date:%Y%m%d}:{horizon} cached self.redis.get(cache_key) if cached: return json.loads(cached) weather self.weather.get_forecast(date, horizon) features { avg_temp: weather.get(avg_temp, 20), min_temp: weather.get(min_temp, 15), max_temp: weather.get(max_temp, 25), precipitation_prob: weather.get(precip_prob, 0), precipitation_mm: weather.get(precip_mm, 0), is_rain: 1 if weather.get(precip_mm, 0) 1 else 0, is_extreme: 1 if ( weather.get(max_temp, 0) 38 or weather.get(min_temp, 0) -5 ) else 0, } # 缓存3小时 self.redis.setex(cache_key, 10800, json.dumps(features)) return features except Exception: return {avg_temp: 20, min_temp: 15, max_temp: 25, precipitation_prob: 0, precipitation_mm: 0, is_rain: 0, is_extreme: 0}四、需求预测的四个特征陷阱陷阱一促销的挤占效应。大促前7天的销量通常会下降50%消费者在等降价大促后7天也会下降30%需求被提前透支。简单的促销特征只关注了促销期间漏掉了促销前后的异常波动。需要将促销窗口扩展为[-7, 7]天的特征。陷阱二新品冷启动的特征缺失。新SKU没有历史销量数据滞后特征全为0。此时需要依赖同品类相似SKU的历史表现作为代理特征——用协同过滤从历史SKU中找最相似的品类。陷阱三特征的时变衰减。6个月前的销量对今天的预测权重应该比昨天的销量低得多。在模型层面可以通过时间衰减加权采样样本权重 exp(-delta_days/90)来处理。陷阱四外部特征的采集延迟。天气API的预报数据可能在凌晨2点才更新而凌晨3点就需要跑当日预测。采集管道的定时任务和重试机制需要精确到分钟级。五、总结AI需求预测的精度90%取决于特征工程10%取决于模型选型。历史销量提供基数通常卖多少时间特征提供模式周末通常比工作日多促销特征提供扰动打了5折会多卖多少天气特征提供外部冲击高温天雪糕销量翻倍。特征管道是数据基础设施业务理解的结合体——管道的代码任何人都能写但哪些特征对销量有预测力只有深入业务的人才知道。本文属于「行业场景与项目复盘」系列解析AI需求预测中多维特征工程的数据管道设计。

相关新闻

OpenHarmony动态权限申请与隐私合规实践

OpenHarmony动态权限申请与隐私合规实践

一、前言在 OpenHarmony 应用开发中,相机、麦克风、定位、文件读写、相册等敏感系统资源,不支持静态直接授权,必须在运行时动态向用户申请。Android、iOS、鸿蒙均遵循「隐私最小权限原则」,而 OpenHarmony 的权限体系更严谨、分层…

2026/10/7 2:44:43 阅读更多 →
Kali Linux安装全攻略:从入门到精通

Kali Linux安装全攻略:从入门到精通

1. Kali Linux安装方式全景解析作为渗透测试领域的瑞士军刀,Kali Linux的安装方式选择直接影响后续使用体验。目前主流安装方案可分为三类:U盘启动的便携式方案、双系统的原生性能方案以及虚拟机的隔离安全方案。每种方案都有其独特的适用场景和技术实现…

2026/10/11 13:36:08 阅读更多 →
如何轻松破解极域电子教室限制:JiYuTrainer完整使用指南

如何轻松破解极域电子教室限制:JiYuTrainer完整使用指南

如何轻松破解极域电子教室限制:JiYuTrainer完整使用指南 【免费下载链接】JiYuTrainer 极域电子教室防控制软件, StudenMain.exe 破解 项目地址: https://gitcode.com/gh_mirrors/ji/JiYuTrainer 还在为课堂上被极域电子教室锁定屏幕而烦恼吗?当老…

2026/10/11 1:40:29 阅读更多 →

最新新闻

【yyds】大模型开发新风向:上下文工程接管AI编程,RAG真的凉了吗?用TaoToken统一Key实测进阶指南

【yyds】大模型开发新风向:上下文工程接管AI编程,RAG真的凉了吗?用TaoToken统一Key实测进阶指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:42:54 阅读更多 →
LeetCode 151:双指针与双端队列搞定字符串单词反转

LeetCode 151:双指针与双端队列搞定字符串单词反转

老铁们,今天咱们来啃一道大厂机考笔试里出镜率极高的题:LeetCode 151. 反转字符串中的单词。题目本身只有一句话,但能把“字符串处理”“双端队列”“双指针”这几个高频考点全塞进去,面试官还特别爱在这道题上追问空间复杂度。很…

2026/10/12 13:42:54 阅读更多 →
3月最新!AIGC公司生态地图;开发者实用ChatGPT工具清单;上手必会的SD绘图教程;字幕组全自动化流程大公开 | ShowMeAI日报

3月最新!AIGC公司生态地图;开发者实用ChatGPT工具清单;上手必会的SD绘图教程;字幕组全自动化流程大公开 | ShowMeAI日报

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:42:54 阅读更多 →
春节狂飙之后,TaoToken 视角下的 Agentic AI 半人马时代

春节狂飙之后,TaoToken 视角下的 Agentic AI 半人马时代

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:42:54 阅读更多 →
Python旅游网站数据分析与可视化:从清洗到pyecharts大屏

Python旅游网站数据分析与可视化:从清洗到pyecharts大屏

简介:面向Python数据分析与可视化课程期末大作业的完整项目源码包,聚焦2020年五一假期旅游网站公开数据,覆盖数据清洗、统计分析、可视化图表生成与网页展示全流程,适合需要参考高分大作业或快速搭建数据可视化项目的高校学生。压…

2026/10/12 13:42:54 阅读更多 →
website-rebuild-skill 源码化阶段:如何把逐字移植的机器产物重构成人能读的工程

website-rebuild-skill 源码化阶段:如何把逐字移植的机器产物重构成人能读的工程

【免费下载链接】website-rebuild-skill 复刻网站的 Agent Skill:抓只读镜像、从压缩代码逐行还原、自动比对验收。An agent skill that mirrors a website, rebuilds it from the minified code, and verifies the result with automated diffs. 项目地址&#xff…

2026/10/12 13:41:54 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →