专栏名称: 新语数据故事汇
《新语数据故事汇,数说新语》科普数据科学、讲述数据故事,深层次挖掘数据价值。
目录
相关文章推荐
51好读  ›  专栏  ›  新语数据故事汇

解锁时间序列洞察:掌握LOESS 的季节性、趋势分解 (STL)

新语数据故事汇  · 公众号  ·  · 2024-06-20 19:04

正文

在经济、零售和气候科学等等领域,理解和预测时间序列数据(例如每月航空旅客人数)对做出明智决策至关重要。然而,时间序列数据通常包含复杂的模式,包括趋势、季节性和随机噪声,使得准确分解和预测未来数值变得具有挑战性。

将一个复杂的时间序列中的基本模式拆解出来,揭示隐藏其中的不同季节周期、长期趋势和随机波动。这种强大的分析能力正是使用 LOESS 的季节性、趋势分解 (Seasonal-Trend Decomposition Using LOESS,STL) 所提供的,它改变了我们理解和预测时间相关数据的方式。无论你是跟踪季度 GDP 的经济学家、研究月度销售的零售分析师,还是研究温度变化的气候科学家,STL 分解都为将时间序列数据分解为其基本组成部分提供了一个强有力的框架。

Seasonal-Trend Decomposition Using LOESS (STL)

理解STL分解

STL(Seasonal-Trend Decomposition Using LOESS)分解的核心是一种将时间序列分解为三个关键组成部分的方法:

  • 季节性(Seasonal )成分:这一部分捕捉数据中重复出现的模式或周期。例如,零售销售在假日季节可能会显示出较高的数值,这就是季节性效应。

  • 趋势(Trend )成分:这一部分反映了数据的长期进展或方向。趋势可能表明由于业务增长而导致的销售增加,或由于气候变化而导致的温度逐渐上升。

  • 残差(Residual)成分:在考虑了季节性和趋势效应之后,数据中剩余的噪声或随机变化,包括任何异常或离群值。

STL 的工作原理

STL 使用 LOESS(局部回归平滑,Locally Estimated Scatterplot Smoothing),这是一种非参数方法,可将平滑曲线拟合到数据点上。分解过程包括对季节性和趋势成分进行迭代平滑,然后从原始序列中提取这些成分。剩余部分则是减去这些平滑成分后的结果。

STL 的优点在于其灵活性和鲁棒性。与假设固定季节模式的其他分解方法不同,STL 允许季节性和趋势随时间变化。这使得它对实际数据特别有用,因为现实世界的数据通常表现出复杂且不断变化的模式。

STL 分解的应用场景

  • 经济分析:经济学家使用 STL 分离经济指标中的季节性效应。例如,使用 STL 分析 GDP 数据可以帮助区分短期季节性波动和长期金融趋势。

  • 零售和销售预测:分析师利用 STL 识别季节性销售模式和潜在的增长趋势。这种分解有助于做出关于库存管理和营销策略的明智决策。

  • 气候和环境研究:气候科学家应用 STL 于温度和降水数据,以隔离季节性变化和长期气候趋势。这有助于理解和预测气候变化的影响。

实际示例

下面是一个全面的 Python 代码块,演示了如何在航空乘客数据集上使用 LOESS 进行季节性-趋势分解 (STL) 的过程。这包括特征工程、超参数调优、交叉验证、构建预测模型、评估模型以及可视化结果。

import pandas as pdimport numpy as npfrom statsmodels.tsa.seasonal import STLfrom sklearn.model_selection import TimeSeriesSplit, GridSearchCVfrom sklearn.metrics import mean_squared_error, mean_absolute_errorfrom sklearn.linear_model import LinearRegressionimport matplotlib.pyplot as plt
# Load the time series datadata = pd.read_csv( 'airline-passengers.csv', #'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv', index_col='Month', parse_dates=True)series = data['Passengers']
# Perform STL decompositionstl = STL(series, seasonal=13)result = stl.fit()
# Extracting componentsseasonal = result.seasonaltrend = result.trendresidual = result.resid
# Feature Engineeringdata['Trend'] = trenddata['Seasonal'] = seasonaldata['Residual'] = residualdata['Month'] = data.index.month
# Lag Featuresfor lag in range(1, 13): data[f'Lag_{lag}'] = series.shift(lag)
data.dropna(inplace=True)
# Define features and targetX = data.drop(columns=['Passengers'])y = data['Passengers']
# Train-Test Split using TimeSeriesSplittscv = TimeSeriesSplit(n_splits=5)model = LinearRegression()
# Hyperparameter Tuning using GridSearchCVparam_grid = {'fit_intercept': [True, False]}gsearch = GridSearchCV(model, param_grid, cv=tscv, scoring='neg_mean_squared_error')gsearch.fit(X.iloc[0:20,:], y.iloc[0:20])
# Best Modelbest_model = gsearch.best_estimator_
# Predictions and Evaluationpredictions = best_model.predict(X)






请到「今天看啥」查看全文