时间序列的在线学习与概率模型
1. 在线学习中的概念漂移与自适应学习
1.1 概念漂移与漂移检测器
概念漂移指的是数据与学习目标之间关系的变化,这种变化会严重影响机器学习模型的性能,甚至使模型过时。漂移检测器并不直接监测数据本身,而是用于监测模型性能,能让流学习方法对概念漂移具有鲁棒性。不同的漂移检测器对输入数据有不同的假设,在使用时需要根据数据集选择合适的检测器。常见的漂移检测方法都需要标签成本,因为它们监测的是基础分类器或集成的预测结果,要求在预测后立即获得类标签,但在一些实际问题中,这种约束并不现实。
1.2 自适应学习方法
自适应学习是指带有漂移调整的增量方法,其目标是通过在线更新预测模型来应对概念漂移,使模型与当前数据分布保持一致。集成方法可以与漂移检测器结合,触发基础模型的重新训练。例如,Adaptive XGBoost 算法(AXGB)是 XGBoost 针对不断演变的数据流的改进版本,当新数据可用时,会从数据的小批量中创建新的子树。
以下是一些结合机器学习方法和漂移检测方法的自适应学习算法:
| 算法 | 描述 |
| — | — |
| K - Nearest Neighbors (KNN) classifier with ADWIN change detector | KNN 结合 ADWIN 变化检测器,决定保留或遗忘哪些样本 |
| Adaptive Random Forest | 每棵树都包含漂移检测器,检测到警告后在后台开始训练,发生漂移时替换旧树 |
| Additive Expert ensemble classifier | 实施剪枝策略,移除最旧或最弱的基础模型 |
| Hoeffding Adaptive Tree (HAT) | 配对 ADWIN 检测漂移,使用 Hoeffding Tree 模型进行学习 |
| Very Fast Decision Rules | 类似于 VFDT,但使用规则集成而非树,在 Scikit - Multiflow 中支持使用 ADWIN、DDM 和 EDDM 进行漂移检测 |
| Oza Bagging ADWIN | 每个样本被赋予一个权重,在 River 中可与 ADWIN 变化检测器结合 |
| Online CSB2 | 一种在线提升算法,在 AdaBoost 和 AdaC2 之间进行折衷,可选择使用变化检测器 |
| Online Boosting | 带有 ADWIN 漂移检测的 AdaBoost |
1.3 Python 实践
1.3.1 安装 River 库
在本章中,我们只使用 River 库,可以通过以下命令从终端快速安装:
pip install river
1.3.2 漂移检测
我们先创建一个人工时间序列来测试漂移检测:
import numpy as np
np.random.seed(12345)
data_stream = np.concatenate(
(np.random.randint(2, size=1000), np.random.randint(8, size=1000))
)
def perform_test(drift_detector, data_stream):
detected_indices = []
for i, val in enumerate(data_stream):
in_drift, in_warning = drift_detector.update(val)
if in_drift:
detected_indices.append(i)
return detected_indices
import matplotlib.pyplot as plt
def show_drift(data_stream, indices):
fig, ax = plt.subplots(figsize=(16, 6))
ax.plot(data_stream)
ax.plot(
indices,
data_stream[indices],
"ro",
alpha=0.6,
marker=r'$\circ$',
markersize=22,
linewidth=4
)
plt.tight_layout()
1.3.3 回归任务
我们将使用 UCI 机器学习库中的太阳耀斑数据集来估计中等规模太阳耀斑的发生情况。
from river import stream
from river.datasets import base
class SolarFlare(base.FileDataset):
def __init__(self):
super().__init__(
n_samples=1066,
n_features=10,
n_outputs=1,
task=base.MO_REG,
filename="solar-flare.csv.zip",
)
def __iter__(self):
return stream.iter_csv(
self.path,
target="m-class-flares",
converters={
"zurich-class": str,
"largest-spot-size": str,
"spot-distribution": str,
"activity": int,
"evolution": int,
"previous-24h-flare-activity": int,
"hist-complex": int,
"hist-complex-this-pass": int,
"area": int,
"largest-spot-area": int,
"c-class-flares": int,
"m-class-flares": int,
"x-class-flares": int,
},
)
from pprint import pprint
from river import datasets
for x, y in SolarFlare():
pprint(x)
pprint(y)
break
import numbers
from river import compose
from river import preprocessing
from river import tree
num = compose.SelectType(numbers.Number) | preprocessing.MinMaxScaler()
cat = compose.SelectType(str) | preprocessing.OneHotEncoder(sparse=False)
model = tree.HoeffdingTreeRegressor()
pipeline = (num + cat) | model
from river import evaluate
from river import metrics
metric = metrics.MAE()
evaluate.progressive_val_score(SolarFlare(), pipeline, metric)
errors = []
for x, y in SolarFlare():
y_pred = pipeline.predict_one(x)
metric = metric.update(y, y_pred)
errors.append(metric.get())
pipeline = pipeline.learn_one(x, y)
fig, ax = plt.subplots(figsize=(16, 6))
ax.plot(
errors,
"ro",
alpha=0.6,
markersize=2,
linewidth=4
)
ax.set_xlabel("number of points")
ax.set_ylabel("MAE")
1.3.4 自适应与非自适应模型比较
使用合成数据集比较 Hoeffding Tree Regressor、Hoeffding Adaptive Tree Regressor 和 Adaptive Random Forest Regressor 的性能:
from river import (
synth, ensemble, tree,
evaluate, metrics
)
models = [
tree.HoeffdingTreeRegressor(),
tree.HoeffdingAdaptiveTreeRegressor(),
ensemble.AdaptiveRandomForestRegressor(seed=42)
]
for model in models:
metric = metrics.MSE()
dataset = synth.ConceptDriftStream(
seed=42, position=500, width=40
).take(1000)
evaluate.progressive_val_score(dataset, model, metric)
print(f"{str(model.__class__).split('.')[-1][:-2]}: {metric.get():e}")
1.4 模型选择
使用 UCBRegressor 为线性回归模型选择最佳学习率:
from river import compose
from river import linear_model
from river import preprocessing
from river import optim
models = [
compose.Pipeline(
preprocessing.StandardScaler(),
linear_model.LinearRegression(optimizer=optim.SGD(lr=lr))
)
for lr in [1e-4, 1e-3, 1e-2, 1e-1]
]
from river import datasets
dataset = datasets.TrumpApproval()
from river.expert import UCBRegressor
bandit = UCBRegressor(models=models, seed=1)
for x, y in dataset:
bandit = bandit.learn_one(x=x, y=y)
for model, pct in zip(bandit.models, bandit.percentage_pulled):
lr = model["LinearRegression"].optimizer.learning_rate
print(f"{lr:.1e} — {pct:.2%}")
for model, avg in zip(bandit.models, bandit.average_reward):
lr = model["LinearRegression"].optimizer.learning_rate
print(f"{lr:.1e} — {avg:.2f}")
best_model = bandit.best_model
best_model["LinearRegression"].intercept_lr.learning_rate
2. 时间序列的概率模型
2.1 概率模型的重要性
概率是衡量某件事情发生可能性的指标。在销售预测中,不确定性的估计至关重要,因为这些预测会影响现金流、利润率和收入,进而驱动商业决策。概率模型可以帮助我们在需要量化不确定性的情况下做出决策。
2.2 常见概率模型
2.2.1 Prophet 模型
Prophet 是 Facebook 开发的 Python/R 库和算法,基于可分解模型,具有可解释的参数。其设计目标是可扩展到多个时间序列,适用于各种可能具有特殊性质的业务相关时间序列,并且领域专家可以直观地配置参数。
Prophet 算法类似于广义加性模型(GAM),其预测公式为:$y(t) = g(t) + s(t) + h(t) + \epsilon_t$,其中 $g(t)$ 是趋势(增长)函数,$s(t)$ 是季节性函数,$h(t)$ 是节假日函数,$\epsilon_t$ 是误差项。趋势函数可以是线性或逻辑的,季节性基于傅里叶级数建模,变化点的选择是自动的,参数通过 Broyden–Fletcher–Goldfarb–Shanno(BFGS)算法进行优化。
然而,在一些测试中,Prophet 等概率模型在均方根误差(RMSE)和平均绝对百分比误差(MAPE)方面未能超过一些简单的基线模型,如多层感知器(MLP)和线性回归(LR)。
2.2.2 Markov 模型
Markov 模型在时间序列应用中也具有重要地位,后续会详细介绍其工作原理。
2.2.3 Bayesian Structural Time - Series (BSTS) 模型
BSTS 模型允许量化各个组件的后验不确定性,控制组件的方差,并对模型施加先验信念。可用于特征选择、时间序列预测和推断因果关系,例如在 A/B 测试中理解干预的影响。
2.3 概率模型库的流行度
部分适用于时间序列预测的概率库的流行度有所不同,例如 pyFTS 在某些比较中排名高于其他库,但未包含的 statsmodels 和 Prophet 可能比一些库(如用于隐马尔可夫模型的 HMMs 和用于噪声时间序列的 Pints)更受欢迎。
2.4 概率模型的应用流程
graph LR
A[数据准备] --> B[选择概率模型]
B --> C[模型训练]
C --> D[模型评估]
D --> E[预测与决策]
综上所述,时间序列的在线学习和概率模型在处理不断变化的数据和不确定性方面具有重要作用。通过合理选择和应用这些方法,可以提高模型的性能和决策的准确性。在实际应用中,需要根据具体的数据集和任务需求,选择最适合的模型和算法。
3. 深入了解 Markov 模型
3.1 Markov 模型基础
Markov 模型基于 Markov 性质,即系统的未来状态只依赖于当前状态,而与过去的状态无关。在时间序列分析中,Markov 模型可以用来描述状态之间的转移。
3.2 隐马尔可夫模型(HMM)
隐马尔可夫模型是 Markov 模型的一种扩展,它包含隐藏状态和可观测状态。隐藏状态之间的转移遵循 Markov 性质,而可观测状态则由隐藏状态生成。HMM 在语音识别、生物信息学等领域有广泛应用。
3.3 Markov 模型在时间序列中的应用步骤
- 定义状态 :确定时间序列可能处于的状态,例如在金融时间序列中,状态可以是上涨、下跌或持平。
- 估计转移概率 :根据历史数据估计状态之间的转移概率。
- 模型训练 :使用最大似然估计等方法训练模型。
- 预测 :根据当前状态和转移概率预测未来状态。
3.4 代码示例
import numpy as np
from hmmlearn.hmm import GaussianHMM
# 生成一些示例数据
X = np.random.randn(100, 1)
# 创建 HMM 模型
model = GaussianHMM(n_components=2, covariance_type="diag")
# 训练模型
model.fit(X)
# 预测隐藏状态
hidden_states = model.predict(X)
4. Fuzzy 时间序列模型
4.1 Fuzzy 时间序列的概念
Fuzzy 时间序列模型是一种基于模糊集理论的时间序列分析方法。它可以处理不确定性和模糊性,适用于一些难以用精确数学模型描述的时间序列。
4.2 Fuzzy 时间序列的建模步骤
- 定义模糊集 :将时间序列的值划分为不同的模糊集。
- 建立模糊关系 :根据历史数据建立模糊集之间的关系。
- 进行模糊推理 :根据当前的模糊集和模糊关系进行推理,得到未来的模糊集。
- 去模糊化 :将模糊集转换为具体的数值。
4.3 代码示例
import pyFTS
from pyFTS.data import Enrollments
# 加载示例数据
data = Enrollments.get_data()
# 创建 Fuzzy 时间序列模型
model = pyFTS.models.hofts.HighOrderFTS()
# 训练模型
model.fit(data)
# 进行预测
forecast = model.predict(data)
5. 概率模型的综合应用
5.1 模型选择与组合
在实际应用中,需要根据数据特点和任务需求选择合适的概率模型。有时可以将多个模型组合起来,以提高预测的准确性。
5.2 评估指标
常用的评估指标包括均方根误差(RMSE)、平均绝对百分比误差(MAPE)、平均绝对误差(MAE)等。
5.3 应用案例
5.3.1 销售预测
使用 Prophet 模型预测某商品的未来销售量,结合历史销售数据和节假日信息进行训练。
5.3.2 股票价格预测
使用 Markov 模型分析股票价格的涨跌状态,根据转移概率进行预测。
5.3.3 能源消耗预测
使用 Fuzzy 时间序列模型处理能源消耗数据中的不确定性,提高预测的准确性。
5.4 综合应用流程
graph LR
A[数据收集与预处理] --> B[模型选择与组合]
B --> C[模型训练与评估]
C --> D[预测与优化]
D --> E[决策与应用]
6. 总结
6.1 在线学习与概率模型的优势
- 高效处理大数据 :在线学习方法可以高效处理高速数据流和大规模数据集。
- 适应数据变化 :能够适应数据分布的变化,通过漂移检测和自适应学习保持模型性能。
- 量化不确定性 :概率模型可以提供预测的不确定性估计,帮助做出更明智的决策。
6.2 注意事项
- 模型选择 :根据具体任务和数据特点选择合适的模型,没有一种模型适用于所有情况。
- 数据质量 :数据的质量对模型性能有重要影响,需要进行充分的预处理。
- 参数调优 :合理调整模型的参数可以提高性能,但需要进行适当的实验。
6.3 未来展望
随着数据量的不断增加和应用场景的不断拓展,时间序列的在线学习和概率模型将在更多领域发挥重要作用。未来可以进一步研究模型的融合和优化,提高预测的准确性和可靠性。
通过本文的介绍,我们了解了时间序列的在线学习和概率模型的相关知识,包括概念漂移、自适应学习、常见概率模型(Prophet、Markov、Fuzzy 等)的原理和应用,以及如何进行模型选择、训练和评估。希望这些内容对大家在时间序列分析和预测方面有所帮助。
超级会员免费看
1万+

被折叠的 条评论
为什么被折叠?



