店铺销售数据收到季节性和活动影响比较大,建议采用时间序列模型,推荐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)