店铺销售数据收到季节性和活动影响比较大,建议采用时间序列模型,推荐FACEBOOK科学团队的Prophet模型。
Prophet 使用加性回归模型将时间序列分解为以下四个部分:
趋势项:捕捉随时间变化的长期增长或下降(如产品的生命周期)。
季节性项:处理周期性变化(如每日、每周、每年的销量波动)。
节假日/事件项:融合已知的促销活动、节假日等事件影响。
误差项:服从正态分布的随机噪声。
优势:通过显式分解,模型更易解释业务逻辑(如辨别趋势是自然增长还是季节性促销驱动)。
import pandas as pd from prophet import Prophet import matplotlib.pyplot as plt # 读取CSV文件(需确保文件路径正确) df = pd.read_csv('d:\\storesales2024.csv', encoding='GBK') # 中文编码用GBK df.columns = ['日期', '销售笔数', '销售金额'] # 重命名列 # 格式转换:仅保留日期和销售金额 df = df[['日期', '销售金额']].rename(columns={'日期':'ds', '销售金额':'y'}) df['ds'] = pd.to_datetime(df['ds'], format='%Y/%m/%d') # 假设2025年春节为1月28日,定义影响期(节前15天至节后3天) spring_festival = pd.DataFrame({ 'holiday': 'spring_festival', 'ds': pd.to_datetime(['2024-2-10', # 历史春节日期 '2024-1-28' # 未来春节日期 ]), 'lower_window': -15, # 节前15天开始影响 'upper_window': 3 # 节后3天 }) # 假设2025年元旦为1月1日,定义影响期(节前1天至节后1天) new_year = pd.DataFrame({ 'holiday': 'new_year', 'ds': pd.to_datetime([ '2024-01-01', # 历史元旦日期 '2025-01-01' # 未来元旦日期 ]), 'lower_window': -1, # 节前1天 'upper_window': 1 # 节后1天(共3天影响) }) # 合并所有节假日 holidays = pd.concat([spring_festival, new_year], ignore_index=True) model = Prophet( #holidays=spring_festival, # 添加春节假期 holidays=holidays, #yearly_seasonality=True, # 年季节性 #weekly_seasonality=True, # 周季节性 #seasonality_mode='multiplicative' # 乘法模型(更适应幅度变化) holidays_prior_scale=10, # 控制节假日影响的灵活度(默认10,越大灵敏度越高) seasonality_mode='additive' # 可选'multiplicative'(若节假日影响为乘性) ) # 自动添加中国的法定节假日(如国庆、五一) model.add_country_holidays(country_name='CN') model.fit(df) future = model.make_future_dataframe(periods=31) # 预测到2025-01-31 forecast = model.predict(future) # 提取春节前30天(2025-01-01至2025-01-28) mask = (forecast['ds'] >= '2025-01-01') & (forecast['ds'] <= '2025-01-28') spring_forecast = forecast.loc[mask] #绘制24年至25年春节前的销售趋势图# fig1 = model.plot(forecast) plt.title("202501salesamountforecast") plt.xlabel("salesdate") plt.ylabel("salesamount(yuan)") plt.show() #绘制25年春节前1个月的销售趋势图# plt.figure(figsize=(10, 6)) plt.plot(spring_forecast['ds'], spring_forecast['yhat'], label='predictedvalue') plt.fill_between( spring_forecast['ds'], spring_forecast['yhat_lower'], spring_forecast['yhat_upper'], alpha=0.2, label='confidenceinterval' ) plt.axvline(pd.to_datetime('2025-01-28'), color='red', linestyle='--', label='springfestival') plt.title("202501salesamountforecast") plt.xlabel("salesdate") plt.ylabel("salesamount(yuan)") plt.legend() plt.grid(True) plt.show() #25年春节前1个月的预测销售数据明细# spring_forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].round(1)