从零开始用 Python 做销量预测(保姆级教程)
一、为什么要学销量预测想象你是某连锁奶茶店的运营备货太少 → 顾客喝不到差评 备货太多 → 过期倒掉亏钱 销量预测Sales Forecasting 就是为了解决这个“黄金平衡点”。在本教程中我们将用Python 真实逻辑完成一次完整的销量预测项目。二、准备工作环境与数据1️⃣ 安装必备库pip install pandas numpy matplotlib scikit-learn statsmodels2️⃣ 构造示例数据假设我们有某店铺过去 90 天的销量数据import pandas as pd import numpy as np # 构造日期 date_rng pd.date_range(start2024-01-01, end2024-03-30, freqD) np.random.seed(42) # 构造销量含趋势 波动 sales ( 100 0.5 * np.arange(len(date_rng)) 10 * np.sin(2 * np.pi * date_rng.dayofyear / 7) np.random.normal(0, 5, len(date_rng)) ) df pd.DataFrame({ date: date_rng, sales: sales }) df.set_index(date, inplaceTrue) print(df.head())三、第一步数据可视化EDA永远先看图再建模。import matplotlib.pyplot as plt plt.figure(figsize(12, 5)) plt.plot(df.index, df[sales], labelDaily Sales) plt.title(Daily Sales Trend) plt.xlabel(Date) plt.ylabel(Sales) plt.legend() plt.show()观察要点是否有上升趋势是否有周期性周几卖得好是否有异常值四、方法一线性回归初学者必学1️⃣ 特征工程给时间编号机器不懂“日期”只懂数字。df[day_index] np.arange(len(df))2️⃣ 划分训练集 测试集from sklearn.model_selection import train_test_split X df[[day_index]] y df[sales] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, shuffleFalse )3️⃣ 训练模型from sklearn.linear_model import LinearRegression model LinearRegression() model.fit(X_train, y_train)4️⃣ 预测 评估from sklearn.metrics import mean_absolute_error y_pred model.predict(X_test) mae mean_absolute_error(y_test, y_pred) print(fMAE平均绝对误差{mae:.2f})线性回归适合✅ 趋势明显❌ 忽略季节性五、方法二时间序列Prophet 实战Facebook 开源的Prophet 非常适合业务人员。1️⃣ 安装 Prophetpip install prophet2️⃣ 数据格式转换Prophet 要求两列ds日期y数值from prophet import Prophet prophet_df df.reset_index().rename(columns{date: ds, sales: y})3️⃣ 训练 预测model Prophet( yearly_seasonalityFalse, weekly_seasonalityTrue, daily_seasonalityFalse ) model.fit(prophet_df)4️⃣ 生成未来 30 天预测future model.make_future_dataframe(periods30) forecast model.predict(future) model.plot(forecast) plt.show()✅ Prophet 自动识别周规律周末爆单节假日效应趋势变化六、模型对比哪个更好模型优点缺点适用场景线性回归简单、快忽略周期稳定趋势Prophet自动处理周期黑盒商业预测神经网络精度高数据要求高大规模预测七、落地建议非常重要7.1 不要只看 MAE还要看 RMSE、MAPE7.2 业务解释性 精度老板要听得懂7.3 定期重训模型每月更新一次7.4 做区间预测给出“乐观 / 中性 / 悲观”八、完整项目结构推荐sales_forecast/ ├── notebooks/ │ └── 01_EDA.ipynb ├── .gitignore ├── main.py ├── requirements.txt ├── models/ │ ├── prophet_model.py │ └── linear_regression_model.py ├── data/ │ └── sales.csv └── utils/ └── metrics.py1️⃣requirements.txt放在项目根目录用于一键安装依赖pandas1.5.0 numpy1.21.0 matplotlib3.5.0 scikit-learn1.0.0 prophet1.1.0 jupyter1.0.02️⃣data/sales.csv这是我们的原始数据源你可以手动创建也可以用代码生成date,sales 2024-01-01,105.2 2024-01-02,108.7 2024-01-03,112.4 2024-01-04,115.1 2024-01-05,118.9 2024-01-06,122.3 2024-01-07,119.8 2024-01-08,125.6 2024-01-09,128.4 2024-01-10,130.2 2024-01-11,127.5 2024-01-12,135.8 2024-01-13,138.2 2024-01-14,142.7 2024-01-15,140.1 2024-01-16,145.3 2024-01-17,148.9 2024-01-18,152.4 2024-01-19,149.7 2024-01-20,155.2 2024-01-21,158.6 2024-01-22,162.1 2024-01-23,165.8 2024-01-24,168.3 2024-01-25,172.9 2024-01-26,175.4 2024-01-27,178.8 2024-01-28,182.3 2024-01-29,179.6 2024-01-30,185.1✅提示真实项目中这里通常是几十万行的数据这里仅做演示。3️⃣notebooks/01_EDA.ipynbJupyter Notebook 文件用于探索性分析# %% import pandas as pd import matplotlib.pyplot as plt # 读取数据 df pd.read_csv(../data/sales.csv, parse_dates[date]) df.set_index(date, inplaceTrue) # 查看前5行 print(df.head()) # %% # 基础统计信息 print(df.describe()) # %% # 销量趋势图 plt.figure(figsize(12, 6)) plt.plot(df.index, df[sales], markero, linestyle-) plt.title(Daily Sales Trend) plt.xlabel(Date) plt.ylabel(Sales) plt.grid(True) plt.show() # %% # 按周聚合查看周期性 weekly_sales df.resample(W).mean() print(weekly_sales.tail())4️⃣utils/metrics.py工具函数专门用于评估模型好坏from sklearn.metrics import mean_absolute_error, mean_squared_error import numpy as np def evaluate_model(y_true, y_pred): 计算回归模型的常用评估指标 mae mean_absolute_error(y_true, y_pred) rmse np.sqrt(mean_squared_error(y_true, y_pred)) # 避免除以0 if y_true.mean() ! 0: mape np.mean(np.abs((y_true - y_pred) / y_true)) * 100 else: mape np.nan return { MAE: round(mae, 2), RMSE: round(rmse, 2), MAPE: f{round(mape, 2)}% }5️⃣models/prophet_model.py封装 Prophet 模型便于主程序调用from prophet import Prophet import pandas as pd class SalesProphet: def __init__(self): self.model None def train(self, df: pd.DataFrame): df 必须包含两列ds (日期), y (销量) self.model Prophet( yearly_seasonalityFalse, weekly_seasonalityTrue, daily_seasonalityFalse ) self.model.fit(df) def predict(self, periods30): 预测未来 N 天 future self.model.make_future_dataframe(periodsperiods) forecast self.model.predict(future) return forecast def plot(self, forecast): fig self.model.plot(forecast) return fig6️⃣models/linear_regression_model.py备选模型线性回归from sklearn.linear_model import LinearRegression import numpy as np class LinearSalesModel: def __init__(self): self.model LinearRegression() def train(self, X, y): self.model.fit(X, y) def predict(self, X): return self.model.predict(X) def get_coefficients(self): return { intercept: self.model.intercept_, coefficient: self.model.coef_[0] }7️⃣main.py项目的主入口文件串联整个流程import pandas as pd from utils.metrics import evaluate_model from models.prophet_model import SalesProphet def main(): print( 启动销量预测项目...) # 1. 加载数据 df pd.read_csv(data/sales.csv, parse_dates[date]) df_prophet df.rename(columns{date: ds, sales: y}) # 2. 训练模型 model SalesProphet() model.train(df_prophet) # 3. 预测未来 30 天 forecast model.predict(periods30) # 4. 评估使用历史数据进行回测 y_true df_prophet[y].values[-30:] y_pred forecast[yhat].values[-30:] metrics evaluate_model(y_true, y_pred) print( 模型评估结果) for k, v in metrics.items(): print(f{k}: {v}) # 5. 可视化 model.plot(forecast) import matplotlib.pyplot as plt plt.show() if __name__ __main__: main()8️⃣.gitignore可选但推荐# Python __pycache__/ *.pyc *.pyo # Jupyter .ipynb_checkpoints/ # 数据文件如果是敏感数据 # data/*.csv # 虚拟环境 venv/ .env✅ 运行顺序安装依赖pip install -r requirements.txt打开 Notebookjupyter notebook notebooks/01_EDA.ipynb运行主程序python main.py九、总结一句话销量预测不是“算命”而是用历史数据 数学模型降低经营的不确定性。