本文将带你深入理解时间序列数据处理的核心技术,从基础概念到实战应用,全面掌握从数据预处理到模型构建的完整流程。
时间序列数据的基本概念和特征
时间序列数据是按照时间顺序排列的一系列数据点,广泛应用于金融、气象、工业监控等领域。与横截面数据不同,时间序列数据具有独特的时间依赖性和顺序性。
核心特征
趋势性(Trend):数据在长期内呈现的持续上升或下降模式。例如,某电商平台的月销售额可能呈现逐年增长的趋势。
季节性(Seasonality):在固定时间周期内重复出现的模式。如零售业的销售额在节假日期间通常会出现周期性增长。
周期性(Cyclical):非固定周期的波动,通常与经济周期相关。比如房地产市场的繁荣-衰退周期。
随机性(Irregular):不可预测的随机波动,通常由突发事件引起。
graph TD
A[时间序列数据] --> B[趋势性]
A --> C[季节性]
A --> D[周期性]
A --> E[随机性]
B --> B1[长期增长]
B --> B2[长期下降]
C --> C1[日周期]
C --> C2[周周期]
C --> C3[年周期]
数据预处理技术
缺失值处理
时间序列中的缺失值处理需要特别谨慎,因为简单删除可能会破坏时间连续性。
import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer
# 创建示例时间序列数据
dates = pd.date_range('2023-01-01', periods=100, freq='D')
values = np.sin(np.linspace(0, 20, 100)) + np.random.normal(0, 0.1, 100)
ts_data = pd.Series(values, index=dates)
# 模拟缺失值
ts_data_missing = ts_data.copy()
ts_data_missing.iloc[10:15] = np.nan
# 1. 前向填充
forward_filled = ts_data_missing.fillna(method='ffill')
# 2. 线性插值
linear_interpolated = ts_data_missing.interpolate(method='linear')
# 3. 基于KNN的插值(考虑时间特征)
def create_time_features(data):
"""创建时间特征用于KNN插值"""
df = pd.DataFrame({'value': data})
df['hour'] = df.index.hour
df['day_of_week'] = df.index.dayofweek
df['day_of_year'] = df.index.dayofyear
return df
ts_features = create_time_features(ts_data_missing)
imputer = KNNImputer(n_neighbors=5)
ts_imputed = imputer.fit_transform(ts_features)
result = pd.Series(ts_imputed[:, 0], index=ts_data_missing.index)异常值检测
时间序列的异常值检测需要考虑时间依赖性,常用的方法包括:
from scipy import stats
import matplotlib.pyplot as plt
def detect_outliers_iqr(data, window=7):
"""基于滑动窗口IQR方法检测异常值"""
outliers = pd.Series(index=data.index, dtype=bool)
for i in range(len(data)):
start_idx = max(0, i - window // 2)
end_idx = min(len(data), i + window // 2 + 1)
window_data = data.iloc[start_idx:end_idx]
Q1 = window_data.quantile(0.25)
Q3 = window_data.quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers.iloc[i] = (data.iloc[i] < lower_bound) or (data.iloc[i] > upper_bound)
return outliers
def detect_outliers_zscore(data, window=7, threshold=3):
"""基于滑动窗口Z-score方法检测异常值"""
rolling_mean = data.rolling(window=window, center=True).mean()
rolling_std = data.rolling(window=window, center=True).std()
z_scores = np.abs((data - rolling_mean) / rolling_std)
return z_scores > threshold
# 应用异常值检测
outliers_iqr = detect_outliers_iqr(ts_data)
outliers_zscore = detect_outliers_zscore(ts_data)
print(f"IQR方法检测到 {outliers_iqr.sum()} 个异常值")
print(f"Z-score方法检测到 {outliers_zscore.sum()} 个异常值")平滑处理
平滑处理有助于减少噪声,突出数据的潜在模式:
from statsmodels.tsa.seasonal import seasonal_decompose
# 移动平均平滑
def moving_average_smooth(data, window=7):
return data.rolling(window=window, center=True).mean()
# 指数平滑
def exponential_smooth(data, alpha=0.3):
return data.ewm(alpha=alpha).mean()
# 应用平滑
ma_smooth = moving_average_smooth(ts_data)
exp_smooth = exponential_smooth(ts_data)
# STL分解进行平滑
decomposition = seasonal_decompose(ts_data, model='additive', period=7)
trend_smooth = decomposition.trend
seasonal_smooth = decomposition.seasonal特征工程方法
滞后特征
滞后特征是时间序列预测中最重要的时间依赖特征:
def create_lag_features(data, lags=[1, 2, 3, 7, 14, 30]):
"""创建滞后特征"""
df = pd.DataFrame({'target': data})
for lag in lags:
df[f'lag_{lag}'] = data.shift(lag)
return df
# 创建滞后特征
lag_features = create_lag_features(ts_data)
print("滞后特征示例:")
print(lag_features.head(10))