一、为什么是Darts?
时间序列预测,是数据科学里最古老、也最让人头疼的战场。
你是否经历过这样的绝望:用statsmodels跑一个ARIMA,调参调到怀疑人生;用Prophet换个数据集就得重写一遍代码;好不容易训完一个LSTM,发现还不如移动平均准?
Darts的出现,就是为了终结这种混乱。
它不是一个模型,而是一把"瑞士军刀"——一个旨在统一时间序列预测生态的开源Python库。从经典统计模型到前沿深度学习,从零样本推理到自动化特征工程,它用一套简洁一致的API,把这些原本割裂的工具焊成了一个整体。
Darts的全称是DataAnalysis inReal-Time withSklearn——它的目标很明确:让时间序列预测像使用scikit-learn一样简单。
核心数据说话:支持ARIMA、Prophet、Exponential Smoothing等统计模型,同时集成N-BEATS、TFT、TCN、Transformer等深度学习架构,所有模型共享同一套fit()和predict()接口。
这不是营销话术,这是工业级的体验升级。
二、Darts生态全景:四大核心能力
Darts不是一个库,而是一组职责分明的"特种部队"。
| 能力模块 | 核心功能 | 代表模型 |
|---|---|---|
| 预测(Forecasting) | 单变量/多变量时间序列预测 | ARIMA、Prophet、N-BEATS、TFT、Transformer、LightGBM |
| 异常检测(Anomaly Detection) | 基于预测残差的异常评分与检测 | ForecastingAnomalyModel、KMeansScorer |
| 滤波(Filtering) | 对噪声数据进行去噪平滑 | KalmanFilter、GaussianProcessFilter |
| 回测评估(Backtesting) | 滑动窗口自动评估模型表现 | model.backtest()、TimeSeriesCrossValidator |
它们共享同一套数据格式和API范式——这才是Darts最精妙的设计。
三、统一数据格式:一切的起点
在动手之前,必须先把数据整理成Darts要求的TimeSeries格式:
importpandasaspdfromdartsimportTimeSeries df=pd.read_csv('sales.csv',parse_dates=['date'])series=TimeSeries.from_dataframe(df,time_col='date',value_cols='sales',fill_missing_dates=True,# 自动补全缺失日期freq='D'# 设定频率)这个约束看似简单,实则解决了多序列处理中80%的混乱。忘了补全缺失日期?模型会对时间索引产生致命误解。这是实战中最容易踩的坑。
四、实战一:5分钟建好基线——统计模型
这是日常使用频率最高的组件,也是整个工作流的基石。
fromdarts.modelsimport(NaiveSeasonal,# 季节性基准ExponentialSmoothing,# 指数平滑ARIMA,# 自回归积分滑动平均Prophet# Facebook Prophet)fromdarts.metricsimportmape,rmse# 1. 划分训练集和测试集(8:2)train,test=series.split_after(pd.Timestamp('2025-01-01'))# 2. 定义模型列表models=[NaiveSeasonal(K=12),# 月度季节性基准ExponentialSmoothing(seasonal_periods=12),ARIMA(p=1,d=1,q=1),Prophet()]# 3. 训练并评估formodelinmodels:model.fit(train)forecast=model.predict(n=len(test))error=mape(test,forecast)print(f"{model.__class__.__name__:25s}MAPE:{error:.2f}%")关键细节:
NaiveSeasonal(K=12)是最强基准线——如果你的模型连它都打不过,就别上深度学习了split_after()按时间切分,绝不会造成数据泄露- 所有模型都是
fit()→predict(),零学习成本
五、实战二:深度学习登场——N-BEATS与TFT
当统计模型遇到瓶颈,Darts的深度学习模型就是你的攻坚利器。
5.1 N-BEATS:开箱即用的SOTA
fromdarts.modelsimportNBEATSModel model=NBEATSModel(input_chunk_length=24,# 回看24个时间步output_chunk_length=12,# 预测未来12步n_epochs=50,batch_size=64,random_state=42)model.fit(train)forecast=model.predict(n=len(test))# 可视化series.plot(label='Actual')forecast.plot(label='Forecast')5.2 TFT:融合协变量的终极武器
TFT(Temporal Fusion Transformer)是Darts支持的最强大模型之一,它能同时处理:
| 协变量类型 | 含义 | 示例 |
|---|---|---|
past_covariates | 历史已知的外部变量 | 过去的天气、价格 |
future_covariates | 未来已知的外部变量 | 节假日表、天气预报 |
static_covariates | 不随时间变化的特征 | 门店等级、商品类别 |
fromdarts.modelsimportTFTModel# 假设有天气数据作为协变量weather_series=TimeSeries.from_dataframe(weather_df,'date','temp')model=TFTModel(input_chunk_length=30,output_chunk_length=7,hidden_size=64,lstm_layers=2,num_attention_heads=4,add_relative_index=True)model.fit(train,future_covariates=weather_series,val_series=test)forecast=model.predict(n=7,future_covariates=weather_series)TFT的杀手锏:它能告诉你每个特征对预测的贡献度——这对业务解释性至关重要。
六、实战三:多序列训练——一个模型打天下
Darts支持在多条时间序列上同时训练,这对零售、能源等场景极其有价值。
fromdarts.modelsimportNBEATSModel# 假设有100家门店的销售数据series_list=[TimeSeries.from_dataframe(df,'date',f'store_{i}')foriinrange(100)]model=NBEATSModel(input_chunk_length=24,output_chunk_length=7)model.fit(series_list)# 在100条序列上同时训练# 预测时可以一次性处理多条序列forecasts=model.predict(series=series_list,n=7)单个模型学习所有序列的共同模式,比逐条训练快10倍以上,且泛化能力更强。
七、回测评估:别让过拟合骗了你
Darts内置的回测工具,是验证模型真实能力的唯一可靠方式。
fromdarts.metricsimportsmape# 滑动窗口回测:从50%数据开始,每次预测12步error=model.backtest(series=train,forecast_horizon=12,start=0.5,metric=smape)print(f"回测SMAPE:{error:.2f}%")更高级的交叉验证:
fromdarts.utils.model_selectionimportTimeSeriesCrossValidator cv=TimeSeriesCrossValidator(cv=3,horizon=6,start=0.5)fortrain_split,val_splitincv.split(series):model.fit(train_split)pred=model.predict(len(val_split))# 评估验证集表现铁律:永远不要只看训练集上的误差。回测结果才是你能信任的数字。
八、模型对比:让数据说话
当评估多个模型时,Darts的ModelComparison工具能帮你系统对比:
fromdarts.utils.model_selectionimportModelComparison models=[NBEATSModel(input_chunk_length=24,output_chunk_length=12),TCNModel(input_chunk_length=24,output_chunk_length=12),TransformerModel(input_chunk_length=24,output_chunk_length=12)]comparison=ModelComparison(models=models)comparison.fit(train)metrics=comparison.score(test,metrics=['mae','rmse','mape'])print(metrics)输出一个清晰的对比表格,谁强谁弱一目了然。
九、数据预处理:决定成败的隐形战场
Darts提供了完整的数据处理工具链:
| 操作 | 代码 | 用途 |
|---|---|---|
| 填充缺失值 | fill_missing_values(series) | 补全缺失日期 |
| 标准化 | Scaler().fit_transform(series) | 消除量纲差异 |
| 添加时间特征 | series.add_datetime_attribute('month') | 注入月份/星期等特征 |
| 检查季节性 | check_seasonality(series) | 自动检测是否存在季节性 |
fromdarts.dataprocessing.transformersimportScaler,MissingValuesFillerfromdarts.utils.statisticsimportcheck_seasonality# 检查季节性is_seasonal,period=check_seasonality(series,alpha=0.05)print(f"是否存在季节性:{is_seasonal}, 周期:{period}")# 填充 + 标准化filler=MissingValuesFiller()scaler=Scaler()series_clean=filler.transform(series)series_scaled=scaler.fit_transform(series_clean)十、异常检测:Darts的隐藏王牌
Darts不仅能预测,还能检测异常。基于ForecastingAnomalyModel,它通过比较预测值与实际值的偏差来识别异常:
fromdarts.adimportForecastingAnomalyModel,KMeansScorer# 用Prophet作为底层预测模型fromdarts.modelsimportProphet predictor=Prophet()# KMeans评分器检测异常scorer=KMeansScorer(window=24)anomaly_model=ForecastingAnomalyModel(predictor,scorer)anomaly_model.fit(train)anomalies=anomaly_model.score(series)这在运维监控、金融风控等场景中价值连城。
十一、最佳实践:三步走策略
根据大量实战经验,最有效的预测工作流是:
统计模型建基线 → 深度学习模型攻坚 → 回测验证定终局
第一步:NaiveSeasonal / ExponentialSmoothing 快速建基线 ↓ 如果MAPE > 15%,说明数据有复杂模式 第二步:N-BEATS / TFT 深度学习模型上场 ↓ 加入协变量(天气、节假日、促销) 第三步:TimeSeriesCrossValidator 回测,确认泛化能力 ↓ ModelComparison 对比,选出最终模型实战建议:
| 建议 | 原因 |
|---|---|
先从NaiveSeasonal开始 | 它是最强基准线,打不过它就别上深度学习 |
fill_missing_dates=True必开 | 时间索引不连续是预测失败的第一杀手 |
| 训练集:测试集 = 8:2 或 7:3 | 时间序列不能随机划分,必须按时间切分 |
多用backtest()而非单次预测 | 滑动窗口回测才能反映真实泛化能力 |
model.save()保存最优模型 | 避免重复训练,生产环境直接加载 |
十二、安装与保存
# 基础安装pipinstalldarts# 深度学习模型(需PyTorch)pipinstalldarts[u]# 异常检测模块pipinstalldarts[ad]模型保存与加载:
# 保存model.save("my_nbeats.pt")# 加载loaded_model=NBEATSModel.load("my_nbeats.pt")写在最后
Darts不是在发明新轮子,它是在消灭轮子之间的摩擦。
当你不再需要为ARIMA写50行代码、为Prophet调三天参数、为LSTMdebug一整周时,你才能把精力真正花在理解数据和业务上。
安装只需一行:
pipinstalldarts然后,开始预测你的未来。
本文基于Darts官方文档与实战经验整理,Darts GitHub Stars已超7k,是目前最活跃的时间序列预测开源项目之一。如需深入了解,建议访问 Darts官方文档。