TowardsDataScience 博客中文翻译 2020(八百八十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

时间序列分析与理论、图表和代码第 2 部分

原文:https://towardsdatascience.com/time-series-analysis-with-theory-plots-and-code-part-2-c72b447da634?source=collection_archive---------32-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在第一部分中,我们看了:

  • 什么是时间序列
  • 预测任务的基本步骤
  • 时间序列图形,包括时间图、季节图和季节子序列图
  • 时间序列成分和分解。

一切都伴随着理论和代码。

在第 2 部分,我们将继续我们的旅程:

  • 平稳性
  • 自相关
  • 滞后散点图
  • 简单移动平均线
  • 指数加权移动平均
  • 双重和三重指数平滑

让我们先看一下我们的数据集的第一行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

海面温度和盐度的月数据。

1.平稳性

平稳时间序列的性质不依赖于序列被观察的时间。因此,具有趋势或季节性的时间序列并不是平稳的 —趋势和季节性会影响时间序列在不同时间的值。另一方面,白噪声序列是稳定的——当你观察它时,这并不重要,它在任何时间点看起来都应该差不多。

具有周期行为(但没有趋势或季节性)的时间序列是平稳的。这是因为周期不是固定长度的,所以在我们观察序列之前,我们不能确定周期的波峰和波谷在哪里。也就是说,序列的统计属性(如平均值、方差和自相关性)是恒定的。

大多数统计预测方法都是针对平稳的时间序列而设计的。预测过程的第一步通常是进行一些转换,将非平稳序列转换为平稳序列。预测平稳序列相对容易,预测结果也更可靠。

我们知道,如果预测值(X 个变量)彼此不相关,线性回归效果最好。因此,平稳化序列解决了这个问题,因为它消除了任何持久的自相关,从而使预测模型中的预测因子(序列的滞后)几乎独立。

为了使成为一个时间序列静止我们可以:

  • 将序列差分一次或多次(用当前值减去下一个值)
  • 取序列的对数(有助于稳定时间序列的方差。)
  • 以 nₜₕ根为例
  • 以上各项的组合

但是首先,为了测试时间序列是否平稳**,我们可以:**

  • 看时间图。
  • 将序列分成两部分,并计算描述性统计数据。如果它们不同,那么它就不是静止的。
  • 执行被称为单位根检验的统计检验,如增广迪基富勒检验 (ADF 检验)、科维亚特科夫斯基-菲利普斯-施密特-申-KPSS 检验(趋势平稳)和飞利浦佩龙检验(PP 检验)。

最常用的是 ADF 因此,如果 ADF 检验中的 P 值小于显著性水平(0.05),您拒绝零假设,序列是平稳的。

这将输出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ADF 测试统计的输出。

数列是平稳的。然而,p 值=0.04967,我们可以应用差异来查看其效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了使数列看起来稳定,需要三阶差分。

2.自相关

正如相关性测量两个变量之间线性关系的程度一样,自相关测量一个时间序列的滞后值之间的线性关系,例如 yₜ和 yₜ₋₁.之间的线性关系如果一个序列是显著自相关的,这意味着该序列以前的值(滞后)可能有助于预测当前值。

部分自相关在去除影响两个变量的其他变量的影响后,测量一个变量的线性相关性。也就是说,滞后 k 处的部分自相关是未被滞后 1 至k1 考虑在内的 y ₜ和 y ₜ+yₜ₊ₖ之间的自相关。我们本质上绘制出前一天/前一个月的残差与当天的真实值之间的关系。一般来说,我们预计偏相关会很快下降。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

60 个月的自相关和偏相关(海表温度)。

对于自相关,y 轴是值与其滞后时间之间的相关值。滞后在 x 轴上。零滞后的相关性为 1,因为它与自身完全相关。该图显示了 6ₜₕ和 12ₜₕ月份以及之前和之后月份的高度自相关性。

3.滞后散点图

探索每个观察值和该观察值的滞后之间的关系的一种有用的图称为散点图。

Pandas 对此有一个内置的函数,叫做滞后图。它在 x 轴上绘制了时间 t 时的观察值,在 y 轴上绘制了 lag1 观察值(t-1)。

  • 如果这些点沿着从图的左下角到右上角的对角线聚集,这表明正相关关系。
  • 如果这些点沿着从左上到右下的对角线聚集,这表明负相关关系。
  • 这两种关系都很好,因为它们可以被建模。
  • 越靠近对角线的点表示关系越强,越远离对角线的点表示关系越弱。
  • 中间有一个球或分布在图中表明关系很弱或没有关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.移动平均数

移动平均是对时间 t 的趋势周期的估计,通过对 t 的 k 个周期内的时间序列值进行平均来获得。时间上接近的观测值也可能在数值上接近。因此,平均值消除了数据中的一些随机性,留下了平滑的趋势周期成分。

基本的 SMA 有一些弱点:

  • 较小的窗口会导致更多的噪音,而不是信号。
  • 它将总是滞后于窗口的大小。
  • 由于求平均值,它将永远不会达到数据的最大峰值或谷值。
  • 它并不真正告诉你未来可能的行为,它真正做的只是描述你的数据的趋势。
  • 极端的历史值会显著扭曲 SMA。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

窗口=3 的初始数据和简单移动平均。

简单移动平均线有一个变种叫做指数加权移动平均线 (EWMA)。

它将允许我们减少来自 SMA 的滞后效应,并且它将把更多的权重放在最近发生的值上(通过将更多的权重应用到最近发生的值,因此得名)。应用于最近值的权重量将取决于 EWMA 中使用的实际参数和给定窗口大小的周期数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始数据、简单移动平均和简单指数平滑

5.双重和三重指数平滑

简单指数平滑仅使用一个平滑因子α (alpha),双指数平滑添加了第二个平滑因子 β (beta),用于处理数据趋势。与 alpha 因子一样,beta 因子的值介于零和一之间(0 < β ≤10 < β≤1)。这里的好处是,模型可以预测未来的增长或下降,而水平模型只能根据最近的计算来工作。

我们还可以处理趋势中不同类型的变化(增长/衰退)。如果时间序列显示直线倾斜趋势,您可以使用加法调整。如果时间序列显示指数(曲线)趋势,您可以使用乘法调整。

三重指数平滑,与 Holt-Winters 关系最密切的方法,增加了对数据中趋势和季节性的支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始数据,双重和三重指数平滑。

就是这样!感谢您的阅读,下次见!

参考资料:

自动取款机现金需求预测:时间序列回归模型

原文:https://towardsdatascience.com/time-series-and-regression-methods-for-forecasting-atms-filling-in-cc6d5f7dde1e?source=collection_archive---------12-----------------------

机器学习在 ATM 取现需求预测

使用时间序列和回归模型进行需求预测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

自动取款机中的烟灰需求需要准确的预测,这与其他自动售货机没有什么不同。唯一的区别是现金产品需要在一段时间内补充。如果预测是错误的,它会导致大量的成本。在高预测和高未使用的情况下,ATM 中存储的现金会给银行带来成本。银行根据其与货币运输公司的政策支付不同的重新填充费用。银行通常为重新填充支付大量的固定费用,为安全运输安排支付额外的额外费用。

一些银行可能会在自动取款机中储存比实际需求多 40%的现金,而且银行可能在全国范围内拥有数千台自动取款机。因此,业务运营的小优化将有助于高收益。

业务用例

自动柜员机不应装满大量现金,这可能会带来低运输/物流成本,但高冷冻和高保险成本。另一方面,如果银行没有适当的机制来跟踪使用模式,那么频繁地重新填充 ATM 将降低冻结和保险成本,但会增加物流成本。

我们的目标

很明显,每天的现金提取量是时间序列。因此,在这个典型的现金需求预测模型中,我们将展示时间序列和回归机器学习模型,以解决上述用例的问题。我们将针对单个自动柜员机(也可以将一组自动柜员机作为单个自动柜员机处理)的需求,为给定的数据集开发一个模型。

我们必须记住,从 ATM 机提取现金不仅仅是时间相关的。可能存在季节性,例如:1)人们倾向于在周末的周五或 2)月底领工资时取款,或 3)在每个月的 7-10 日之间,一些人会领养老金。因此,开发 ATM 网络现金需求预测模型是一项具有挑战性的任务。此外,每台 ATM 的时序现金需求随时间波动,并且经常与用户的非平稳行为叠加。

数据加载

我们有 2011 年到 2017 年的每日交易数据。实际取款(total _ amount _ extracted)包括从自动柜员机提取实际金额的所有交易。这些交易实际上反映在 ATM 机的可用余额中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了简单起见,我们在这里没有进行任何数据挖掘活动。建议进行广泛的挖掘工作,从数据中提取隐藏的信息。此外,建议消除可能导致多重共线性问题的不重要要素。

模拟每日现金需求

我们将尝试拟合几个时间序列模型,并为我们的数据找到最佳拟合模型,这将允许预测未来的需求。有很多机器学习模型可供选择,决定从哪里开始可能会令人生畏。一般来说,从简单的、可解释的模型(如线性回归)开始是一个好主意,如果性能不够好,就转向更复杂但通常更精确的方法。因此,受到塞尔维亚银行的[案例分析](http://Broda, P., Levajković, T., Kresoja, M., Marčeta, M., Mena, H., Nikolić, M., & Stojančević, T. (2014). Optimization of ATM filling-in with cash.) 的启发,其中时间序列分析和线性模型被用于获得每个 ATM* 的每日现金需求预测,我们选择从一个简单的线性模型开始我们的用例。*

我们在这里的特征中既有数字变量也有分类变量。观察箱线图,我们没有观察到分类变量对现金提取的任何显著影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

*plt.figure(figsize=(14,6))
plt.subplot(1,2,1)
data['total_amount_withdrawn'].hist(bins=50)
plt.title('Total amount withdrawan')
plt.subplot(1,2,2)
stats.probplot(data['total_amount_withdrawn'], plot=plt);
data['total_amount_withdrawn'].describe().T.round()*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以从直方图中看到,中心在 60 附近。数据集中的大多数值(提取的总金额)接近 60 万,而更远的值(14 万)很少,这也符合我们的心理模型。分布大致对称,提取的值落在大约 100 和 100,000 之间,这可以从图表上方所示的统计汇总中得到验证。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

OneHotEncoding

下面的代码片段将数字特征分开,选择分类特征并对这些特征使用一键编码,然后将两个集合连接在一起。这听起来像是复杂的工作,但却相对简单明了。

*# Copy the original data
features = df.copy()# Select the numeric columns
numeric_subset = df[['trans_date_set','trans_month','trans_year','prevweek_mean', 'total_amount_withdrawn']]# Select the categorical columns
# dropped atm_name
categorical_subset = df[['weekday','festival_religion', working_day',  'holiday_sequence']]# One hot encoding
categorical_subset = pd.get_dummies(categorical_subset)# Join the two dataframes using concat
features = pd.concat([numeric_subset, categorical_subset], axis = 1)*

OHE 之后,我们有 27 列(特征)的 2244 个观察值。

通常测试集的大小范围是数据的 25- 35 %,尽管没有关于大小的硬性规定。我们必须记住,随着训练数据集规模的缩小,训练模型的性能会下降。从训练集中提取太多数据可能会对最终性能造成不利影响。

*X = features.copy().drop(columns = ['total_amount_withdrawn', 'trans_date_set', 'trans_month','trans_year', 'working_day_H', 'working_day_W'])
y = features['total_amount_withdrawn'].copy()Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, shuffle= False, test_size = 0.2, random_state = 42)
print('length of Xtrain and Xtest: ', len(Xtrain), len(Xtest))
print('length of ytrain and ytest: ', len(ytrain), len(ytest))*

线性回归

我们考虑了一个线性模型的形式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 αi 为数据中待估计模型的参数, hi 为现金需求历史的不同统计。该模型针对特定日期 d 进行评估。值 li 是元参数,控制统计 hi 的计算,如所考虑的历史长度。

我们总是可以使用训练数据来拟合最小最大缩放器,然后在预测之前将该缩放器应用于测试数据。此外,可以测试线性模型附加正则化参数。

*linear = LinearRegression()
linear.fit(Xtrain, ytrain)# make predictions
lin_pred = linear.predict(Xtest)# Prediction vs Actual
linpred = pd.DataFrame(lin_pred[-10:]) # predicting last 10 values
linpred.rename(columns = {0: 'lin_predicted'}, inplace=True) # renaming the column
linpred = linpred.round(decimals=0) # rounding the decimal values
d = pd.DataFrame(data['total_amount_withdrawn']).tail(10) # calling last 10 values of original amt wothdrawn
linpred.index = d.index # mapping the index of both dataframe
linok = pd.concat([linpred, d], axis=1)
linok['accuracy'] = round(linok.apply(lambda row: row.lin_predicted /row.total_amount_withdrawn *100, axis = 1),2)
linok['accuracy'] = pd.Series(["{0:.2f}%".format(val) for val in linok['accuracy']],index = linok.index)
linok = linok.assign(day_of_week = lambda x: x.index.day_name())*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们在这里看到,线性回归预测平均超过 100%。

XGBoost 回归

虽然我在这里扩展了 ohe 的使用,但是在实践中应该小心谨慎。

虽然基于回归的模型,我们通常使用 ohe 特征,但我们应该小心使用决策树算法。理论上,决策树能够处理分类数据。然而,它的 scikit-learn 实现仍然要求所有特征都是数字的。一种可能的解决方案是使用不同种类的编码(标签/目标编码)或处理分类特征的实现,如 h2o 库中的随机森林。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面,我们绘制了预测值和实际值,以及这些值的组合,以获得更好的可视性。与 LinReg 相比,XGBoost 模型做得相当好,并且使用默认参数,与 LinReg 的大约 50%相比,平均应计率超过 90%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

变量重要性图如下所示:

*shap_values = shap.TreeExplainer(xgb).shap_values(Xtest)
shap.summary_plot(shap_values, Xtest, plot_type="bar")*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

轻型 GBM

LightGBM 通过整数编码的分类特征提供了良好的准确性。它通常比一位热编码执行得更好。

*X = df.iloc[:, 2:10].copy()
y = df.iloc[:, 10].values# Transform categorical features into the appropriate type that is expected by LightGBM
for c in X.columns:
col_type = X[c].dtype
if col_type == 'object' or col_type.name == 'category':
X[c] = X[c].astype('category')# Splitting the dataset into the Training set and Test set
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle= False, test_size = 0.2, random_state = 42)
print('length of X_train and X_test: ', len(X_train), len(X_test))
print('length of y_train and y_test: ', len(y_train), len(y_test))*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的平均预测在这里是相当准确的。虽然这个模型漏掉了一些日子,但是平均来说,这个预测比 XG 模型要好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CatBoost

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

像 LGB 一样,CatBoost 也显示了几乎相似预测结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

观察 LightGBM 和 CatBoost 如何从训练集中决定重要的特征总是很有趣的。但是,我将在另一篇文章中讨论这个问题。

对比分析

企业可能会有兴趣看到最终的表格报告。根据这里观察到的结果,选择 Catboost 或 LightGBM 建模方法进行进一步优化是可行的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们上面的练习是为了举例说明。在机器学习练习中,有三个更广泛的部分:(1)数据提取和挖掘,这有助于确定特征(这通常需要大约 60-70%),(2)确定和拟合包括超参数优化的模型(这通常需要 10-15%),(3)准确性度量和测试需要 10-15%的时间)。因此,我们看到第一阶段对于机器学习生命周期的成功至关重要。

这里,我们分析了一台特定的自动柜员机。对于多台柜员机,可以使用聚类方式进行现金需求预测,这带来了额外的优势:

  1. 提高了现金需求预测的准确性,这是因为在预测具有类似的一周中现金提取季节性模式的 ATM 中心组的 ATM 每日现金需求时,计算复杂性降低了,
  2. 运营成本的潜在巨大节约,因为类似的现金补充模式可用于属于同一集群的 ATM 中心。

结论

LightGBM 和 CatBoost 在没有对给定数据集进行任何优化的情况下表现出了良好的预测能力。然而,有相当多的金融机构和使用案例可用于简单的线性回归或复杂的神经网络。作为一名分析顾问,当我们解决一个业务问题时,我们想到的第一个问题是我们能否使用线性规划(LP)来解决。考虑到 LP 更快的处理时间和清晰的可见性,它在商业中非常受欢迎。甚至 LP 也可以用来一次解决多个目标。

在这里,自动柜员机提款预测的关键是捕获和处理历史数据,以洞察未来。然而,现金需求天生具有高方差和非平稳的随机过程,这会影响许多方法的可靠性。此外,对现金的需求不仅受时间的影响,而且它遵循不同的趋势,这使得建模更加困难。比如节假日如何影响 ATM 的使用,取决于柜员所在的位置。根据取款金额和取款交易次数,可根据需求(如高、中、低)将多台 ATM 分为几大类。集群级别的补充计划可以为在类似地理区域运行的 ATM 节省大量运营成本。

我可以到达 这里

参考:

  1. 加雷斯,詹姆斯;丹妮拉·威滕;哈斯蒂,特雷弗;罗伯特·蒂布拉尼(2015)。统计学习导论。纽约:施普林格

基于“异常化”库的时间序列异常检测

原文:https://towardsdatascience.com/time-series-anomaly-detection-with-anomalize-library-67472003c003?source=collection_archive---------23-----------------------

时间序列异常检测的 3 个简单步骤

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Samantha GadesUnsplash 上拍摄

时间序列数据具有广泛的应用案例,从跟踪关键绩效指标(KPI)和了解业务趋势到高级建模和预测。异常检测就是这样一种有用的应用。信用卡欺诈检测等业务应用需要强大的技术,这些技术可以将时间序列数据作为输入,并实时识别异常情况。

异常检测是一个经过充分研究的领域,有许多可用的工具和技术。有很多用于异常检测的 R 包,例如tsoutlierAnomalyDetection.,但是,我最近开始相信[anomalize](https://cran.r-project.org/web/packages/anomalize/index.html)是最直观、最易于使用的库——对于新手和高级数据科学家都是如此。

所以今天这篇文章的目的是用三个简单的步骤来演示anomalize异常检测库的实现。

让我们开始吧。

步骤 1:安装库并准备数据

就像任何其他机器学习算法一样,准备数据可能是异常检测中最重要的一步。但是从积极的方面来看,您可能一次只使用一列。因此,与其他机器学习技术中的数百个特征不同,您可以只关注用于建模的一列。

确保您完成了通常的数据清理和准备程序,例如处理丢失的值等。一个重要的步骤是确保数据集最终在一个tibletbl_time 对象中。

让我们首先安装我们将需要的库:

# install libraries
library(anomalize)
library(tidyverse)
library(tibbletime)
library(tidyquant)

对于这个演示,我们运气不错,不需要数据处理。我们将使用tidyquant库获取股票价格数据。

# fetch data
data <- tq_get('AAPL',
               from = "2019-09-01",
               to = "2020-02-28",
               get = "stock.prices")# take a peek
head(data)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二步:执行anomalize

首先,让我们用刚刚获取的数据实现anomalize,然后讨论发生了什么。

# anomalize 
anomalized <- data %>% 
  time_decompose(close) %>%
  anomalize(remainder) %>%
  time_recompose()

这里很少发生什么事情,库接收输入数据并对其应用三个独立的函数。

首先,time_decompose()函数将时间序列数据的“收盘”列分解为“观察”、“季节”、“趋势”和“余数”分量。

其次,anomalize()函数对“余数”列执行异常检测,并在 3 列中给出输出:“余数 _l1”、“余数 _l2”和“异常”。这里的最后一列是我们想要的,如果观察结果是异常的,那么它是“是”,对于正常的数据点,它是“否”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

异常实现的输出

最后一个函数time_recompose()通过重新组合之前创建的“trend”和“season”列,将所有内容重新整理好。

步骤 3:绘制异常数据

实际上,我们的异常检测已经在前一步完成了。但是我们仍然需要将数据和异常现象可视化。让我们这样做,并直观地检查出异常值。

# plot data with anomalies
anomalized %>%
  plot_anomalies(time_recomposed = TRUE, ncol = 3, alpha_dots = 0.25) + labs(title = "AAPL Anomalies")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个图非常直观。每个点是数据集中观察到的数据点,红色圆圈是模型识别的异常。阴影区域是余数的上限和下限。

下一步是什么?

如果到目前为止,您已经通过三个简单的步骤成功地实现了复杂的异常检测技术。这很简单,因为我们使用了默认参数,没有做任何改变。正如我们在上图中看到的,这个开箱即用模型在检测异常值方面表现得非常好。但是,您可能会遇到复杂的时间序列数据,这需要通过在步骤 2 中调整参数来提高模型性能。您可以阅读模型文档快速入门指南来了解参数、它们的作用以及如何&何时改变它们。

如果你喜欢这篇文章,你可以在 Twitter 或 LinkedIn 上关注我。

基于“真实世界”数据的时间序列异常检测

原文:https://towardsdatascience.com/time-series-anomaly-detection-with-real-world-data-984c12a71acb?source=collection_archive---------22-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来自这里

时间序列异常检测是一个非常困难的问题,尤其是在处理“真实世界”数据时。为了说明我所说的“真实世界”数据的含义,让我们假设你正在与多个客户合作,每个客户都在进行不同的纵向研究。客户希望您在研究进行过程中帮助他们检测数据中的异常,以便他们有可能修复这些异常并提高数据收集质量。你可能已经知道这是一个多么困难的问题。首先,不像你可能在 Kaggle 竞赛中看到的那样,数据可能没有被标记(也就是说,你实际上不知道什么是异常,什么不是),这实际上很常见!也许客户端没有资源来创建带标签的数据集。第二,在这种情况下,每个客户端都运行不同的研究,很可能每个客户端的数据集中都有不同的要素,不允许一个模型用于所有客户端。第三,纵向研究通常运行起来非常昂贵,因此,每个客户的数据集可能相对较小。最后,由于这些研究都还在进行中,可能会有很多“缺失数据”在这种情况下,我所说的缺失数据是指不同的受试者将处于研究的不同阶段,其中一些受试者可能只完成了两次随访,而另一些受试者可能已经完全完成了研究。

简而言之,在这个例子中,有很多东西对我们不利:我们有(1)未标记的数据,(2)具有不同特征的数据集,(3)小数据集,以及(4)具有大量缺失数据的数据集。对于许多数据科学家来说,这听起来像是一场噩梦!但是我们仍然有办法在数据中发现价值并发现异常。在这里,我简单介绍一下我最近使用的一种方法,我发现这种方法可以拾取合理的信号。不幸的是,目前,我不能公布这个项目的细节,但我希望你也尝试这个方法,让我知道它是如何工作的。

该方法

我最近成了隔离森林的忠实粉丝。隔离森林是一种集成学习方法,是随机森林的近亲。与随机林类似,隔离林使用决策树,您可以在其中对功能进行决策拆分。随机林和隔离林的最大区别在于,在隔离林中,拆分是随机的。通常所做的是隔离林选择随机特征并在特征中进行随机分割,直到所有数据点都被隔离;这个过程要用你想要的任意多的树进行几次。我们假设如果一个数据点需要很多分裂才能隔离,那么它不是异常的(下图左图),但是如果一个数据点需要很少的分裂,那么它就是异常的(下图右图)。隔离林的输出是异常分数,它指示数据点被认为有多异常。从这个算法的描述中你可能可以看出,这是一种无监督的异常检测方法,这对于我们来说是必要的,因为我们没有标记的数据。这是一个非常简单的方法,但是效果相当好!此外,隔离林包含在 scikit-learn 中,因此相对容易实现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自原创隔离林纸

好吧,听起来隔离森林解决了我们很多问题,对吧?没有。我们仍然有“缺失数据”的问题让我们回到目前仍在进行的纵向研究,我们在研究中的不同点有受试者。你可能知道,大多数机器学习算法都不能包含缺失数据,所以处理缺失数据的一个常用方法是用中位数来估算缺失值(或者为分类数据创建一个新的类别)。这在许多情况下可能很好,但是在我们的例子中,假设有许多受试者仍然处于研究的早期,那该怎么办呢?对于这些受试者,我们可以用他们尚未完成的访问的中值来估算缺失值,并在我们的数据集上运行隔离森林。然而,如果你这样做,你可能会注意到完成很少访问的受试者从未出现异常,这仅仅是因为我们通过用中位数来估算缺失值,使他们看起来更正常。这可不好!我们希望检测任何受试者中可能出现的异常,无论他们是在研究的早期还是已经完成了研究。

那么我们能做什么呢?这个问题有一个相对简单的解决方案。我们对完成每次访问的受试者运行单独的隔离森林。例如,假设一项研究有五个受试者。受试者 1、3 和 5 已经完成了六次就诊,而受试者 2 和 4 只完成了前三次就诊。我们要做的是使用受试者 1、3 和 5 的所有六次访问的数据运行隔离林,并输出异常分数。然后,对于受试者 2 和 4,我们仅使用前三次就诊的数据,并且也包括来自其他受试者的数据(仅来自前三次就诊的数据),但是我们仅输出受试者 2 和 4 的异常分数。这种方法极大地减少了我们需要用中值估算缺失值的数据点的数量,因此,允许所有数据点潜在地被认为是异常的。太好了!

模型解释

如果你读过我的前一篇博文,你就会知道我热衷于模型解释。理解驱动预测的特征对于解决业务问题通常至关重要。例如,回到纵向研究的例子,如果你发现一个受试者是异常的,你可能会想知道为什么他们是异常的,如果可能的话,试图解决导致他们异常的任何问题。那么我们如何解释一个隔离森林模型呢?这种方法非常类似于我在之前的博文中讨论的特性重要性分析方法。首先,我们正常运行隔离林并输出异常分数——这些是基线异常分数。然后,我们选取一个特征,调整其值,在隔离林中重新运行数据集,并输出异常分数。我们对数据集中的每个要素执行此过程。然后,将每个混洗特征的异常分数与基线分数进行比较。我们可以推断,如果异常分数有很大的变化,那么这是检测异常的一个重要特征。这甚至可以在单个受试者的水平上进行检查,其中我们可以检查来自单个受试者的异常分数的变化。非常简单,我发现给出了一个合理的输出!

结论

好了,你知道了。我承认这种方法并不完美,而且有许多替代方法,但是我想分享一种我发现相当有效的方法。非常欢迎反馈和替代想法!

基于 TensorFlow 2 和 Keras 的人体活动识别时间序列分类

原文:https://towardsdatascience.com/time-series-classification-for-human-activity-recognition-with-lstms-using-tensorflow-2-and-keras-b816431afdff?source=collection_archive---------7-----------------------

了解如何使用 Python 中的 Keras 和 TensorFlow 2 从加速度计数据中对人类活动进行分类

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Fitsum Admasu 提供

TL;DR 了解如何使用 Keras 中的 LSTMs 对来自加速度计传感器的时间序列数据进行分类

可以使用时间序列数据从加速度计数据中识别用户活动吗?你的手机/腕带/手表已经在做了。你能做得多好?

我们将使用从多个用户处收集的加速度计数据来构建一个双向 LSTM 模型,并尝试对用户活动进行分类。您可以在任何具有加速度计的设备(几乎是所有智能设备)上部署/重用经过训练的模型。

计划是这样的:

  • 加载人员活动识别数据
  • 为分类建立 LSTM 模型
  • 评估模型

在浏览器中运行完整的笔记本

GitHub 上的完整项目

[## 用 Python 进行机器学习的黑客指南

这本书给你带来了机器学习的基础,使用工具和技术来解决现实世界…

leanpub.com](https://leanpub.com/Hackers-Guide-to-Machine-Learning-with-Python)

人类活动数据

我们的数据是通过受控的实验室条件收集的。它是由无线传感器数据挖掘实验室提供的。

论文中使用的数据:使用手机加速度计的活动识别。看看这篇文章,感受一下一些基线模型的表现。

加载数据

让我们下载数据:

!gdown --id 152sWECukjvLerrVG2NUO8gtMFg83RKCF --output WISDM_ar_latest.tar.gz 
!tar -xvf WISDM_ar_latest.tar.gz

原始文件缺少列名。另外,其中一列有一个多余的“;”在每个值之后。让我们来解决这个问题:

(1098203, 6)

该数据具有以下特征:

  • user_id -执行活动的用户的唯一标识符
  • activity -当前活动的类别
  • x_axisy_axisz_axis -每个轴的加速度计数据

我们能从数据中学到什么?

探测

我们有六个不同的类别。让我们看看他们的分布:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

散步和慢跑严重过剩。您可以应用一些技术来平衡数据集。

我们有多个用户。每个用户有多少数据?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大多数用户(除了最后 3 个)都有相当多的记录。

不同类型的活动是什么样子的?让我们看看前 200 条记录:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

坐着很好,很放松。慢跑怎么样?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这看起来更有弹性。很好,可以通过观察数据对活动类型进行分离/分类(至少对于这两种活动的样本)。

我们需要找出一种方法,将数据转换成序列,以及每个序列的类别。

预处理

我们需要做的第一件事是将数据分成训练数据集和测试数据集。我们将使用来自 id 低于或等于 30 的用户的数据。其余的将用于培训:

接下来,我们将缩放加速度计数据值:

请注意,我们仅在训练数据上拟合缩放器。我们如何创建序列?我们将稍微修改一下create_dataset函数:

我们通过使用序列中所有类别的模式来选择标签(类别)。也就是说,给定一个长度为time_steps的序列,我们将它归类为最常出现的类别。

以下是创建序列的方法:

让我们看看新序列的形状:

(22454, 200, 3) (22454, 1)

我们已经大大减少了训练和测试数据的数量。让我们希望我们的模型仍然能够学到一些有用的东西。

最后一个预处理步骤是类别编码:

完成预处理!我们的模型在识别用户活动方面会有多好?

人类活动分类

我们将从一个简单的双向 LSTM 模型开始。你可以试着增加复杂度。请注意,该模型的训练速度相对较慢:

实际的训练过程很简单(记住不要乱来):

我们的模型有多好?

估价

培训过程如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你当然可以提出一个更好的模型/超参数并加以改进。它能多好地预测测试数据?

[0.3619675412960649, 0.8790064]

~88% 准确率。对于一个又快又脏的模特来说还不错。让我们来看看混淆矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的模型混淆了楼上和楼下的活动。这是意料之中的。此外,在开发真实世界的应用程序时,您可能会将这两者合并,并将其视为一个类/类别。回想一下,我们的数据集中也存在着严重的不平衡。

结论

你做到了!您已经建立了一个模型,它可以从 200 条加速度计数据记录中识别活动。你的模型在测试数据上达到了 ~88% 的准确率。以下是您采取的步骤:

  • 加载人员活动识别数据
  • 为分类建立 LSTM 模型
  • 评估模型

您学习了如何构建双向 LSTM 模型并对时间序列数据进行分类。接下来还有更多关于 LSTMs 和时间序列的有趣内容:)

在浏览器中运行完整的笔记本

GitHub 上的完整项目

参考

[## 用 Python 进行机器学习的黑客指南

这本书给你带来了机器学习的基础,使用工具和技术来解决现实世界…

leanpub.com](https://leanpub.com/Hackers-Guide-to-Machine-Learning-with-Python)

原载于https://www.curiousily.com

基于深度学习的时间序列分类

原文:https://towardsdatascience.com/time-series-classification-with-deep-learning-d238f0147d6f?source=collection_archive---------2-----------------------

用于时间序列分类的最重要的深度学习算法的架构和实现细节的概述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来自https://www . pexels . com/it-it/foto/borsa-commercio-cres cita-dati-159888/

为什么要进行时间序列分类?

首先,重要的是要强调为什么这个问题在今天如此重要,以及为什么理解深度学习在这个领域的作用和潜力是非常有趣的。

近年来,时间序列分类已经成为数据科学中最具挑战性的问题之一。这是因为任何使用数据的分类问题,只要考虑到某种排序的概念,都可以被视为时间序列分类问题。

时间序列存在于许多现实世界的应用中,包括医疗保健、人类活动识别、网络安全、金融、营销、自动疾病检测、异常检测等。近年来,随着时态数据可用性的显著提高,许多领域对基于时间序列的应用产生了浓厚的兴趣,并提出了许多新的算法。

除了基于深度学习的算法之外,所有这些算法在执行分类之前都需要某种特征工程作为单独的任务,这可能意味着一些信息的丢失和开发时间的增加。相反,深度学习模型已经在内部纳入了这种特征工程,对其进行了优化,并消除了手动操作的需要。因此,他们能够以更快、更直接、更完整的方式从时间序列中提取信息。

应用程序

我们来看看时间序列分类的一些重要应用。

心电图记录可用于发现各种心脏问题,并以时间序列形式保存。区分正常心脏的心电图和患有疾病的心脏的心电图,并识别疾病,是一个时间序列分类问题。

如今,许多设备都可以通过简单的手势来控制,而无需物理接触。为此,这些设备记录一系列图像,用于解释用户的手势。从这个图像序列中识别正确的手势是一个时间序列
分类问题。异常检测是对与大多数数据明显不同的异常事件或观察结果的识别。

通常,异常检测中的数据是时间序列,例如与电子设备相关的量值的时间趋势,被监控以检查设备是否正常工作。区分正常操作的时间序列和有一些异常的设备的时间序列,并识别异常,是一个时间序列分类问题。

问题定义

现在我们给出一个时间序列分类问题的正式定义。假设有一组具有相同结构的对象(例如相同大小的实数值、向量或矩阵等)。),以及不同类的固定集合。我们将数据集定义为一组对*(对象,类)*,这意味着每个对象都与一个确定的类相关联。给定一个数据集,分类问题是建立一个与新对象相关联的模型,该新对象具有与其他对象相同的结构,根据与每个类相关联的对象的特征,建立属于可能的类的概率。

单变量时间序列是实值的有序集合,而 M 维多元时间序列是由 M 个长度相同的不同单变量时间序列组成。时间序列分类问题是数据集的对象是单变量或多变量时间序列的分类问题。

感知器(神经元)

在介绍不同类型的深度学习架构之前,我们回忆一下它们使用的一些基本结构。首先,我们介绍感知器,这是许多机器学习算法的基本元素。它受到生物神经回路功能的启发,因此也被称为神经元。

此图显示了感知器的架构。感知器有一个或多个输入值,每个输入值都与一个权重相关联。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

感知器的目标是计算输入值的加权和,然后对结果应用激活函数。最常见的激活函数是 sigmoid、双曲线正切和 rectifier:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

激活函数的结果被称为感知器的激活,并代表其输出值。

多层感知器

现在我们介绍多层感知器(MLP),它是许多深度学习架构中用于时间序列分类的构建模块。它是一类前馈神经网络,由几层节点组成:一个输入层、一个或多个隐藏层和一个输出层。每个节点都连接到其所在层、前一层和下一层的所有节点。为此,我们说多层感知器是完全连接的。隐藏层和输出层的每个节点都是一个感知器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

多层感知器的输出是通过依次计算其感知器的激活而获得的,连接输入和输出的函数取决于权值。

多层感知器分类

多层感知器通常用于分类问题:给定一个数据集(我们记得它是对*(对象,类别)*的集合),它可以计算任何新对象属于每个可能类别的概率。为此,首先我们需要以更合适的方式表示数据集中的对(对象、类):

  • 每个对象必须被展平,然后用一个向量表示,这将是训练的输入向量。
  • 数据集中的每个类都必须用其独热标签向量来表示。独热标签向量是大小等于数据集中不同类的数量的向量。数组的每个元素对应一个可能的类,除了与所代表的类相关的值外,每个值都是 0 ,即 1 。独热标签向量将是训练的目标。在此图中,我们可以看到一个简单的热标签向量示例:在原始数据集中,列类有三个不同的值,具有一个热标签向量的数据集有三列,每个类一列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

这样,我们获得了一个新的数据集对(输入向量,目标),我们为训练做好了准备。在这个过程中,MLP 使用了一种称为反向传播的监督学习技术,它对数据集的输入向量进行迭代:

  • 在每次迭代中,使用当前输入向量计算 Mlp 的输出。
  • 输出是一个向量,其分量是属于每个类别的估计概率。
  • 使用成本函数计算模型的预测误差。
  • 然后,使用梯度下降,在反向传递中更新权重以传播误差。

因此,通过迭代地向前传递,然后反向传播,以最小化训练数据损失的方式更新模型的权重。在训练之后,当多层感知器的输入是对应于具有给定结构的对象的向量(也不存在于数据集中)时,输出是其分量是属于每个类别的估计概率的向量。

现在,自然的问题是:为什么不使用多层感知器进行时间序列分类,把整个多元时间序列作为输入?答案是,多层感知器和许多其他机器学习算法一样,对于时间序列分类来说效果不佳,因为时间序列的长度确实会影响计算速度。因此,为了获得时间序列分类的良好结果,有必要提取输入时间序列的相关特征,并将它们用作分类算法的输入,以便在非常低的计算时间内获得更好的结果。

深度学习算法相对于其他算法的一大优势是,这些相关特征是在训练期间学习的,而不是手工制作的。这极大地提高了结果的准确性,并大大缩短了数据准备时间。然后,在许多层用于提取这些相关特征之后,许多深度学习架构可以使用像 MLP 这样的算法来获得所需的分类。

时间序列分类的深度学习

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

该图显示了用于时间序列分类的通用深度学习框架。它是实现非线性功能的几个层的组合。输入是一个多元时间序列。每一层都将前一层的输出作为输入,并应用其非线性变换来计算自己的输出。

这些非线性变换的行为由每层的一组参数控制。这些参数将层的输入链接到其输出,并且是可训练的(像多层感知器的权重)。通常,最后一层是多层感知器或岭回归器。

本文提出了 3 种不同的时间序列分类深度学习架构:

  • 卷积神经网络,这是用于时间序列分类问题的最经典和最常用的架构
  • 初始时间,这是一种基于卷积神经网络的新架构
  • 回声状态网络,这是另一种基于递归神经网络的最新架构

卷积神经网络

卷积神经网络是一种深度学习算法,它将图像或多变量时间序列作为输入,能够通过应用程序可训练的过滤器成功捕获空间和时间模式,并使用可训练的权重为这些模式分配重要性。与其他分类算法相比,卷积神经网络中所需的预处理要低得多。虽然在许多方法中滤波器是手工设计的,但是卷积神经网络具有学习这些滤波器的能力。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

如图所示,卷积神经网络由三个不同的层组成:

  • 卷积层
  • 汇集层
  • 全连接层

通常,在完全连接层之前交替几个卷积层和池层。

回旋层

卷积运算之所以得名于回旋神经网络,是因为它是这类网络的基本构造块。它对输入的一系列特征映射与一个滤波器矩阵执行一次卷积,以获得一系列不同的特征映射作为输出,目的是提取高级特征。

卷积由一组滤波器定义,它们是固定大小的矩阵。当对具有相同大小的输入要素图的子矩阵应用过滤器时,结果由过滤器的每个元素与子矩阵的相同位置的元素的乘积之和给出(我们可以在此图中看到这一点)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者形象

一个输入要素图和一个过滤器之间的卷积结果是在输入要素图的宽度和高度上应用过滤器获得的有序要素图,如图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者形象

卷积层执行每个滤波器和每个输入特征映射之间的卷积,获得一系列特征映射作为输出。如已经强调的,过滤器的值被认为是可训练权重,然后在训练期间被学习。

必须为卷积层选择的两个重要参数是步长填充

跨步

Stride 控制过滤器如何围绕一个输入要素图进行卷积。特别是,stride 的值表示一次必须移动多少个单位,如图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者形象

填充

填充指示在应用卷积过滤器之前,要在输入要素图外部添加多少额外的列和行,如图所示。新列和新行的所有单元都有一个伪值,通常为 0。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者形象

之所以使用填充,是因为当对输入要素图应用卷积滤波器时,其大小会减小。然后,经过应用许多过滤器的大小可以变得太小。增加额外的行和列,我们可以保留原来的大小,或使其减少较慢。

当在应用卷积滤波器之后获得的特征图的大小小于输入特征图的大小时,我们将该操作称为有效填充(Valid Padding)。当输出大小等于或大于输入大小时,我们将此操作称为“相同填充”。

汇集层

池操作的目的是实现要素地图的降维,尽可能多地保留信息。这对于提取旋转和位置不变的主要特征也是有用的。其输入是一系列特征地图,其输出是具有较低维度的一系列不同的特征地图。

池化应用于每个输入要素地图的宽度和高度上固定大小的滑动窗口。有两种类型的池:最大池和平均池。正如我们在图中看到的,对于每个滑动窗口,池操作的结果是其最大值或平均值,分别用于最大池或平均池。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

最大池也作为噪音抑制剂,完全丢弃嘈杂的激活。因此,它的性能通常比平均池要好。对于混合层,还必须指定步幅和填充。

池操作的优点是对卷积输出频带进行下采样,从而减少隐藏激活的可变性。

全连通层

全连接层的目标是学习卷积层和汇集层的输出所表示的高级特征的非线性组合。通常全连接层是用多层感知器实现的。

经过几次卷积和合并操作后,原始时间序列由一系列特征图表示。所有这些特征图被展平成列向量,这是原始输入多元时间序列的最终表示。扁平列连接到多层感知器,其输出具有与时间序列的可能类别数量相等的神经元数量。

反向传播应用于训练的每次迭代。在一系列时期内,由于其主要的高级特征,该模型能够区分输入时间序列并对其进行分类。

超参数

对于卷积神经网络,神经网络有许多超参数要指定。最重要的如下:

  • 卷积滤波器数量- 显然太少的滤波器无法提取足够的特征来实现分类。然而,当滤波器已经足以表示相关特征时,更多的滤波器是无能为力的,并且使得训练在计算上更加昂贵。
  • 卷积滤波器大小和初始值 -较小的滤波器收集尽可能多的局部信息,较大的滤波器代表更多的全局、高级和代表性信息。过滤器通常用随机值初始化。
  • 池化方法和大小 -如前所述,有两种类型的池化:最大池化和平均池化,最大池化通常表现更好,因为它也可以作为噪声抑制。汇集大小也是要优化的一个重要参数,因为如果汇集大小增加,维度减少得更多,但丢失的信息更多。
  • 权重初始化 -权重通常用小随机数初始化,以防止死神经元,但也不能太小,以避免零梯度。均匀分布通常效果很好。
  • 激活函数 -激活函数将非线性引入模型。通常选择整流器、sigmoid 或双曲线正切。
  • 时期数 -时期数是整个训练集通过模型的次数。如果计算性能允许,这个数字应该增加,直到测试误差和训练误差之间有一个小的间隙。

履行

使用 Keras 构建卷积神经网络非常容易。Keras 是一个简单易用但功能强大的 Python 深度学习库。在 Keras 中构建卷积神经网络只需几个步骤:

  • 首先声明一个顺序类;每个 Keras 模型都是使用 Sequential 类构建的,它表示层的线性堆栈,或者使用 model 类,它更灵活。由于 CNN 是层的线性堆栈,我们可以使用更简单的顺序类;
  • 在顺序类中添加所需的卷积、最大池和密集 Keras 层;
  • 指定卷积层的过滤器数量和过滤器大小;
  • 指定池层的池大小。

为了编制模型,Keras 需要更多信息,即:

  • 输入形状(一旦输入形状被指定,Keras 自动推断后面层的输入形状);
  • 优化器(例如随机梯度下降或 Adagrad);
  • 损失函数(例如均方误差或平均绝对百分比误差);
  • 指标列表(例如准确度)。

在 Keras 中训练模型实际上只包括调用函数 fit() 指定所需的参数,即:

  • 训练数据(输入数据和标签),
  • 要训练的时期数(整个数据集的迭代次数),
  • 验证数据,在训练过程中使用它来定期测量网络相对于以前未见过的数据的性能。

使用训练好的模型进行预测很容易:我们将一个输入数组传递给函数 predict() ,它返回一个输出数组。

初始时间

最近推出了一种叫做初始时间的深度卷积神经网络。这种网络具有很高的精度和很好的可扩展性。

初始网络架构

初始网络的架构类似于卷积神经网络的架构,不同之处在于卷积层和汇集层被初始模块取代。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

如图所示,初始网络由一系列初始模块组成,之后是一个全局平均池层和一个全连接层(通常是一个多层感知器)。此外,每三个初始模块添加一个剩余连接。每个残差块的输入通过快捷的线性连接进行传输,以添加到下一个块的输入,从而通过允许梯度的直接流动来缓解消失梯度问题。

初始模块

初始网络的主要构件是初始模块,如图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

它由 4 层组成:

  • 第一层是瓶颈层,它降低了输入的维度。这也减少了计算成本和参数数量,加快了训练速度,提高了泛化能力。
  • Inception 模块的第二个主要组件是一组不同大小的并行卷积层,作用于相同的输入特征映射。例如,在该图中,有三种不同的卷积,过滤器尺寸为 10、20 和 40。
  • 第三层是最大池,它引入了对小扰动不变的模型的能力。
  • 第四和最后一层是深度级联层,其中每个独立并行卷积和最大池的输出被级联以形成当前初始模块的输出多元时间序列。

通过堆叠多个初始模块并经由反向传播训练滤波器的值,由于使用不同大小的滤波器,网络能够提取多个分辨率的潜在分层特征。这是 Inception 模块的巨大优势,因为它允许内部层挑选和选择与学习所需信息相关的过滤器大小。这对于识别在不同输入要素地图上可能具有不同大小的高级要素非常有帮助。

感受野

理解初始网络的关键参数是它的感受野。与全连接网络不同,初始网络中的神经元仅依赖于输入特征图的一个区域。这个区域被称为神经元的感受野。显然,底层神经元所依赖的区域比顶层神经元要小。然后,底层神经元被期望捕捉时间序列的局部结构,而顶层神经元被期望识别更复杂的模式。

对于时间序列数据,初始网络的总感受野由该公式定义,其仅取决于滤波器的长度 k_i 和网络的深度 d (即初始模块的数量):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

研究初始网络的准确性如何随着感受野的变化而变化是非常有趣的。为了改变感受野,我们可以改变过滤器的长度或网络的深度。

大多数情况下,需要更长的过滤器来产生更精确的结果。这是因为较长的过滤器比较短的过滤器能够以更高的概率捕获较长的模式。相反,通过增加更多层来增加感受野并不一定会提高网络的性能,尤其是对于训练集较小的数据集。因此,为了提高精度,通常最好增加过滤器的长度,而不是增加更多的层。

初始时间架构

许多实验已经表明,单个初始网络有时在准确性上表现出很大的差异。这可能是因为随机权重初始化所带来的可变性。

为了克服这种不稳定性,通常初始时间被实现为许多初始网络的集合,并且每个预测具有相同的权重。以这种方式,该算法提高了他的稳定性,并且显示出已经提到的高准确性和非常好的可扩展性。

特别地,不同的实验表明,它的时间复杂度随着训练集大小和时间序列长度线性增长,这是一个非常好的结果,因为许多其他算法相对于相同的幅度平方增长。

履行

《盗梦空间》的完整实现可以在 GitHub(https://github.com/hfawaz/InceptionTime)上找到。实现是用 Python 写的,使用 Keras。该实现基于 3 个主要文件:

  • 文件 main.py 包含运行实验所需的代码;
  • 文件 inception.py 包含了 inception 网络实现;
  • 文件 nne.py 包含了集合一组初始网络的代码。

特别是,实现使用已经提到的 Keras 模块类,因为 InceptionTime 的一些层并行工作,不像卷积神经网络使用顺序类,因为它们的层都是串行的。

实现初始模块构建块的代码与针对卷积神经网络描述的代码非常相似,因为它使用 Keras 层进行卷积和最大池化,因此它可以很容易地用于或包含在基于 Keras 的代码中,以便实现定制的架构。

递归神经网络

回声状态网络是一种递归神经网络,因此对它们做一个小的介绍可能是有用的。递归神经网络是组织成连续层的神经元样节点的网络,具有类似于标准神经网络的架构。事实上,像在标准神经网络中一样,神经元被分为输入层、隐藏层和输出层。神经元之间的每个连接都有相应的可训练权重。

不同之处在于,在这种情况下,每个神经元都被分配到一个固定的时间步长。隐藏层中的神经元也在依赖于时间的方向上被转发,这意味着它们中的每一个都仅与具有相同分配时间步长的隐藏层中的神经元完全连接,并且与分配给下一个时间步长的每一个神经元单向连接。输入和输出神经元仅连接到具有相同指定时间步长的隐藏层。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

由于一个时间步长的隐藏层的输出是下一个时间步长的输入的一部分,神经元的激活是按时间顺序计算的:在任何给定的时间步长,只有分配给该时间步长的神经元计算它们的激活。

递归神经网络很少用于时间序列分类,主要是由于三个因素:

  • 这种体系结构的类型主要设计用于预测时间序列中每个元素的输出。
  • 当在长时间序列上训练时,递归神经网络通常会遇到消失梯度问题,这意味着隐藏层中的参数要么不会改变太多,要么会导致数值不稳定和混沌行为。
  • 递归神经网络的训练很难并行化,并且计算量也很大。

回声状态网络被设计成通过消除计算隐藏层的梯度的需要、减少训练时间和避免消失梯度问题来减轻递归神经网络的问题。事实上,许多结果表明回声状态网络确实有助于处理混沌时间序列。

回声状态网络

如图所示,回声状态网络的架构由输入层、称为储层的隐藏层、降维层、称为读出的全连通层和输出层组成。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

  • 贮存器是回声状态网络的主要构件,并且像稀疏连接的随机递归神经网络一样组织。
  • 降维算法通常用主成分分析来实现。
  • 读出通常实现为多层感知器或岭回归器。

输入层和储层之间的权重以及储层中的权重是随机分配的,不可训练。读数中的权重是可训练的,因此网络可以学习和复制特定的模式。

蓄水池

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

如前所述,储层的组织类似于稀疏连接的随机递归神经网络。储层连接到输入层,由一组内部稀疏连接的神经元和自己的输出神经元组成。在储罐中有 4 种类型的砝码:

  • 输入层和内部神经元之间的输入权重
  • *内部权重,*将内部神经元相互连接;
  • 内部神经元和输出之间的输出权重
  • 反向传播权重,将输出连接回内部神经元。所有这些权重都是随机初始化的,对于每个时间步长都是相等的,并且是不可训练的。

与 RNNs 一样,由于一个时间步长的输出是下一个时间步长输入的一部分,因此每个时间步长都单独计算水库的输出。在每个时间步长,计算每个内部和输出神经元的激活,并获得当前时间步长的输出。

ESNs 的最大优点是库创建了输入到更高维表示中的递归非线性嵌入,但是因为只有读出中的权重是可训练的,所以训练计算时间保持很低。

降维

许多实验表明,选择正确的降维方法可以在不降低精度的情况下减少执行时间。此外,降维提供了正则化,提高了模型的整体泛化能力和鲁棒性。

在大多数情况下,训练时间随着子空间维度几乎线性地增加,而只要子空间维度低于某个阈值,准确度就快速增加,然后在该阈值之后,准确度显著减慢并保持几乎恒定。因此,该阈值是子空间维度的最佳选择,因为使用更高的值,我们将具有更长的执行时间,而精度没有相应的提高。

履行

在 GitHub(https://GitHub . com/FilippoMB/Reservoir-Computing-framework-for-multivariate-time-series-class ification)上可以获得回声状态网络的 Python 完整实现。代码使用了 Scikit-learn 和 SciPy 库。包含在文件模块中的主类 RC_classifier。py 允许建立、训练和测试储层计算分类器,即回声状态网络所属的算法家族。

储层所需的超参数必须进行优化,以获得执行时间所需的精度和性能;最重要的是:

  • 水库中神经元的数量;
  • 非零连接权重的百分比(通常小于 10%);
  • 连接权重的水库矩阵的最大特征值。

其他层中最重要的超参数是:

  • 降维层算法(对于多元时间序列数据可以是零或张量 PCA
  • 降维层后的子空间维度;
  • 用于分类的读出类型(多层感知器、岭回归或 SVM);
  • 时期数,即优化过程中的迭代次数。

实现模型的训练和使用的代码结构非常类似于为卷积神经网络描述的结构。

结论

卷积神经网络是时间序列分类中最受欢迎的深度学习技术,因为它们能够通过使用可训练的过滤器成功捕捉空间和时间模式,并使用可训练的权重为这些模式分配重要性。

使用 CNN 的主要困难是它们非常依赖于训练数据的大小和质量。特别是,时间序列的长度会降低训练速度,对于混乱的输入时间序列或相同相关特征可能具有不同大小的输入时间序列,结果可能不像预期的那样准确。为了解决这个问题,最近提出了许多新的算法,在这些算法中,初始时间和回声状态网络的性能优于其他算法。

InceptionTime 源自卷积神经网络,并在最重要的构建模块(初始模块)中使用有效的降维来加速训练过程。此外,它在处理输入时间序列方面表现得非常好,在输入时间序列中,相同的相关特征可能具有不同的大小。

回声状态网络基于递归神经网络,并且由于它们非常稀疏地连接,并且它们的大部分权重先验地固定于随机选择的值,因此加快了训练过程。由于这一点,他们在快速训练后表现出色。此外,它们对处理混沌时间序列非常有帮助。

因此,总之,高精度和高可扩展性使这些新架构成为产品开发的完美候选。

作者

我关于走向数据科学的文章:https://medium.com/@marcodelpra

我的 LinkedIn 个人资料:【https://www.linkedin.com/in/marco-del-pra-7179516/

领英集团 AI 学习:https://www.linkedin.com/groups/8974511/

参考

  1. Hassan Ismail Fawaz、Benjamin Lucas、Germain Forestier、Charlotte Pelletier、Daniel F. Schmidt、Jonathan Weber、Geoffrey I. Webb、Lhassane Idoumghar、Pierre-Alain Muller、Franç ois Petitjean。 InceptionTime:寻找 AlexNet 进行时间序列分类
  2. 菲利普·玛利亚·比安奇、西蒙·斯卡达潘、齐格鲁德·洛克斯、罗伯特·杰森。多变量时间序列表示和分类的油藏计算方法

时间序列数据挖掘技术及其应用

原文:https://towardsdatascience.com/time-series-data-mining-techniques-and-applications-5159b8ad26ec?source=collection_archive---------24-----------------------

预测、异常检测、预测分析、计量经济学等等

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

UnsplashNeONBRAND 拍摄的照片

所有行业都生成并使用时间序列数据来做出重要的商业决策。

使用过去的数据,杂货连锁店想知道一年中的哪个时间对特定产品的市场需求最大;呼叫中心需要预测未来的呼叫量,以便保持足够的人员配备;信用卡公司密切关注欺诈交易,所有这些商业决策都受益于时间序列数据的使用。

因此,本文的目的是讨论一些关键的应用案例,以及在不同行业的时间序列数据分析中使用的技术类型。

1。了解过去

时间序列数据点是过去的快照。了解历史事件、模式和趋势是所有企业追踪的一些基本指标。他们希望了解自己过去的表现有多好,以及未来的发展方向。如今,随着“大数据”数量的不断增长以及对近实时洞察的需求,时间序列分析正成为商业决策的重要组成部分。以下是历史数据帮助决策的几种方式:

  • 衡量和跟踪关键绩效指标(KPI)
  • 识别影响产品需求的特殊事件
  • 跨产品类别和位置比较 KPI
  • 了解趋势并获得业务方向的早期指示
  • 识别季节性和长期商业周期
  • 影响企业绩效的假设因素
  • 审查政策变化的影响

通过时间序列数据对历史事件的基本理解不需要花哨的建模,只需绘制数据与时间的关系就可以产生非常强大的洞察力。在过去,电子表格足以创造强大的视觉故事和洞察力。如今,大多数统计和数据分析工具(例如 Python、Tableau、PowerBI)可以很好地处理时间序列数据,以创建时间序列图表、仪表板等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

历史数据揭示了重要的见解——趋势、季节性、商业周期等等

2.预测未来

时间序列数据的另一个引人注目的用途是预测——对短期、中期和长期的未来进行预测。企业每天通常面临的许多预测问题都有时间维度,这也是时间序列数据对于预测如此重要的原因。以下是不同领域的一些预测应用:

  • 政府对人口增长进行预测,以发展足够的公共基础设施
  • 气候科学家重建历史数据,并用它们来预测未来的气候
  • 公用事业公司预测未来需求以进行必要的业务扩张
  • 企业预测其产品的未来需求,以确保充足的产品库存

时间序列预测是数据科学和机器学习技术的重要组成部分,涉及拟合统计/机器学习模型来进行预测。这些工具很简单,从历史趋势向未来的外推,到复杂的随机自回归模型,如 ARIMA[阅读:时间序列预测:从天真到 ARIMA 和超越 ]。长期短期记忆(【LSTM】)和计量经济学等深度学习模型正日益增加预测实践的复杂性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 ARIMA 根据历史数据预测零售额(来源)

3.专业业务应用

3.1 异常检测

异常(或异常值)是数据中任何不寻常的观察结果。鉴于客户的历史交易行为,如果信用卡交易的突然激增是意料之外的,则可能被视为异常。类似地,如果在任何交易/数据点的时间序列图中有尖峰和下降,这些也可以被视为异常值。

异常检测是一个经过充分研究的领域,有许多可用的工具和技术。有几个 R 包专门用于异常检测,如[tsoutlier](https://cran.r-project.org/web/packages/tsoutliers/tsoutliers.pdf)[AnomalyDetection](https://github.com/twitter/AnomalyDetection).下面是一些商业应用:

  • 金融:信用卡和金融交易中的欺诈检测
  • 网络安全:根据计算机网络中的异常流量检测网络入侵
  • 医疗保健:基于读取心跳脉冲的心电图(ECG)记录的异常患者状况
  • 天文学:在对恒星和星系的特征和特性的观察中发现异常值。最著名的可能是引力波探测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LIGO 的引力波探测:异常探测的一个例子(来源:维基百科

3.2 比较分析

比较分析是一种显示与时间相关的观察结果之间的相似性和差异的方法。它还可以用来比较多个实体的性能。例如,绘制不同国家的人口增长时间序列数据可以揭示一个国家与另一个国家相比的重要信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示北欧国家人口增长的比较时间序列图(资料来源:世界银行)

3.3 相关性分析

相关性通常被理解为两个随机变量之间的关系,并且通常在双变量散点图中可视化。两个随机时间序列变量同样可以揭示相关性/关联性。通过绘制多元时态数据,很容易识别两个特征之间的关联(例如,销售额与利润)。这种关联可能意味着因果关系,也可能不意味着因果关系,但这是寻找与输出变量相关的特征并在统计分析中使用它们的良好起点。

除了可视化时间序列图之外,还有用于测量时间序列相关性的定量指标— 皮尔逊系数就是这样一种指标。

3.4 经济计量分析

预测分析是一个成熟的技术领域,它大量利用统计学和机器学习来预测未来的结果。该领域还从一个专门的经济学子学科— 计量经济学中汲取方法。高级统计分析,如面板数据模型(如固定和随机效应模型)严重依赖多元纵向(时间序列)数据集。下面是一些计量经济学的应用:

结论

时间序列数据在所有应用领域提供了丰富的分析和应用可能性。历史分析、预测、异常检测和预测分析只是这些可能性中的一部分。随着新工具和技术的发展,新的分析领域也在出现。人工神经网络(如 LSTM)和计量经济学是时间序列数据分析的前沿领域。有经验和有抱负的数据科学家可以通过利用这些工具,或者开发新的工具,为他们的领域做出巨大贡献。

时序分解和 Statsmodels 参数

原文:https://towardsdatascience.com/time-series-decomposition-and-statsmodels-parameters-69e54d035453?source=collection_archive---------5-----------------------

注:本文于 2020 年 7 月 11 日更新,以反映对stats modelsPython 模块的新更改,并包括乘法模型的结果。

时间序列分解是将时间序列数据分离成其核心部分的过程。这些组成部分包括潜在趋势(平均值的总体上升或下降)、季节性(循环周期)和剩余的随机残差。几乎所有你会遇到的时间序列都不是自然平稳的,这意味着均值、方差或协方差将依赖于时间。这就是为什么数据科学家在应用模型之前必须从时间序列数据中识别和分离趋势和季节性。

您可以通过应用变换、减去滚动平均值和差分来手动移除趋势,以使您的数据保持平稳,或者您可以使用 Python 的 statsmodels 库来识别趋势和季节性。

在过去的几周里,我已经讨论了一些时间序列主题,我将在这里建立这些主题,包括 OHLC 可视化时间序列数据 EDA趋势分析平稳性

分解

所有的时间序列数据都可以分解成四个核心部分:平均值、趋势(即增加的平均值)、季节性(即重复的循环模式)和残差(随机噪声)。趋势和季节性并不总是出现在与时间相关的数据中。残差是除去趋势和季节性之后剩下的东西。时间序列模型假设数据是平稳的,只有剩余分量满足平稳性条件。

Python 的 statsmodels 库有一个用于时间序列分解的方法叫做seasonal_decompose()。我利用过去五年标准普尔 500 指数的历史日平均收盘价来说明时间序列分解。数据来自于 UniBit API (注意:由于 API 的限制,在后面的部分我只使用三年的价格)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

过去五年的标准普尔 500 指数历史价格——由 UniBit API 提供

我将数据存储在 pandas dataframe 中,并使用.set_index()方法将索引设置为 date 列。然后,我确保日期索引列的数据类型是 pandas datetime 对象。您需要确保您的数据是正确的格式,UniBit API 以年-月-日(即 2015–01–20)的格式提供日期。

seasonal_decompose()方法最多可以接受六个参数。我关注数据本身、模型类型和频率(文档中的周期)。我使用了 pandas 数据框架的调整后收盘价列,其中的索引是一个 datetime 对象。模型类型参数可以是加法乘法,这取决于数据的季节性幅度是否与水平(平均值)相关。如果季节性的振幅独立于水平,那么你应该使用加法模型,如果季节性的振幅依赖于水平,那么你应该使用乘法模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

加法与乘法时间序列数据。请注意右边乘法数列中季节性变化的扩大。Source“加法和乘法季节性——你能正确识别它们吗?”由尼古拉·考伦茨

您可以对数据的图形可视化进行初步的视觉浏览,以确定哪种模型类型与您的数据相匹配,在本文中,我将测试这两种模型。

频率参数

我处理的最后一个参数是频率参数。(注:statsmodels 的 *seasonal_decompose()* 方法的 *frequency* 参数已被弃用,替换为 *period* 参数)。我没有想到必须选择这个参数,因为它是可选的,季节分解方法与教程中的数据配合得非常好,我最初使用时没有指定这个参数。当我将该方法应用于 S & P 500 数据帧时,我收到了以下错误:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当我对标准普尔 500 数据应用季节分解方法时,出现了错误

我搜索了一些为什么会出现这个错误的原因,一个 GitHub 对话讨论了一个熊猫系列的[inferred_freq](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DatetimeIndex.inferred_freq.html)属性,另一个讨论了一个最近用seasonal_decompose()方法出现的 bug 。这个错误也出现在我正在关注的 Jason Brownlee 的教程的评论部分。对于观察值不一致的时间序列数据,可能会出现问题,周末在日常数据中缺失。这是我最初使用的教程数据和标准普尔 500 指数调整后的每日收盘价之间的唯一区别。

那么,如何为频率参数选择合适的值呢?在这些 GitHub 对话的评论部分,几个用户指定了一个他们可以合理解释的频率。Brownlee 的指导链接到 Rob J. Hyndman 和 George Athanasopoulos 的书《预测:原理和实践》。作者在他们关于经典分解的文章中也给出了选择这个参数的相似的逻辑理由。我对我的时间序列数据测试了三个频率:5、20 和 253。五个因为那是一周有多少个交易日,一个月有 20 个交易日,一年有 253 个*(注意:你的数据中必须有至少两倍于你想要测试的频率的观察值;即如果你想将频率设置为* 253 那么你至少需要 506 观测值)

加性模型

我比较了具有三个频率值的加性模型的 Dickey-Fuller 检验结果,周期为 5 天的模型具有最小的 p 值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标准普尔 500 数据的季节分解,采用加法模型,周期设置为 5。

季节性分解方法将数据分解为三部分,趋势、季节性和随机残差分量。周期设置为 5 的序列的剩余分量是稳定的,因为 4.576743e-21 的 p 值远小于 0.05

乘法模型

然后,我比较了具有三个相同频率值的乘法模型的 Dickey-Fuller 测试结果,周期为 5 天的模型再次具有最小的 p 值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用乘法模型对标准普尔 500 数据进行季节性分解,周期设置为 5。

周期设置为 5 的序列的剩余分量是稳定的,因为 3.053408e-20 的 p 值远小于 0.05

结果比较

在三个测试周期中的两个周期,Dickey-Fuller 测试的 p 值对于乘法模型是最小的;20 和 253 天。表现最好的模型是周期设置为 5 天的加性模型。只有 253 天的 p 值高于 0.05,结果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不同时期标准普尔 500 指数数据的 Dickey-Fuller 检验结果比较

摘要

Statsmodels 的季节性分解方法巧妙地将时间序列数据分解成多个部分。数据科学家和统计学家必须使用逻辑来证明为加法和乘法季节分解模型选择的周期,因为自动推断序列频率的方法并不总是可靠的。然而,statsmodels 包含的包大大减少了猜测的需要。

我的这个项目的资源库可以在这里找到,这个具体文章使用的文件是time _ series _ removaling _ trends _ and _ decomposition . ipynb

初学者的时间序列预测

原文:https://towardsdatascience.com/time-series-essentials-fe6727ab6a94?source=collection_archive---------15-----------------------

关键概念、民间智慧和常见错误

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

乔治·霍丹在 Needpix 上的图片

不幸的是,数据科学导论经常被分成回归/分类/聚类。应该有第四大类:时间序列。

时间序列很难建模。它们与典型的平面表格数据完全不同。当我们不把时间序列作为一个独特的问题来讨论时,数据科学的新人会在不了解模型如何完全失败的情况下,不经意地应用标准的回归算法。

这篇文章主要是针对新手的,但是有经验的建模者可能会得到一些有用的信息。这是解决常见基本错误的系列文章的一部分,例如误解了 t 检验从 pairs 图中得出不必要的结论

重点将放在 ARIMA,它的表现非常好,因为它很容易调整,非常适合初学者。虽然许多其他文章提供了时间序列的介绍,但本文通过讨论 1)民间智慧和 2)要避免的常见错误增加了价值,奇怪的是,许多指南中都没有这些内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了简单起见,我们将使用经典的航空乘客数据。这篇文章的目标是交流思想;复杂的数据会模糊概念。

自相关

自相关是时间序列中最重要的概念。正是这一点让建模变得如此困难。

许多模型假设误差是不相关的,并且是独立的。例如,你点击一个广告不应该影响你的邻居是否点击同样的广告。

在时间序列中,当前值取决于过去的值。如果今天的温度是华氏 80 度,明天的温度很可能是华氏 80 度左右,而不是华氏 40 度。

如果您交换表格数据中的第一个和第十个观察值,数据一点也没有改变。如果你交换一个时间序列中的第一个和第十个观察值,你会得到一个不同的时间序列。秩序很重要。不考虑自相关几乎和这个永恒经典一样傻。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们经常使用自相关函数(ACF)图和部分 ACF 图来检查自相关。x 轴具有分数滞后,因为我们的时间序列包含月数据,这里的滞后 1 表示前一年的同一个月。滞后 k 处的 ACF 只是时间 t 和时间 t-k 处的值之间的相关性,例如,滞后 1 和 2 处的 ACF:

cor(
  passengers, 
  shift(passengers, n = 1L), 
  use = 'complete.obs'
)
cor(
  passengers, 
  shift(passengers, n = 2L), 
  use = 'complete.obs'
)

我用的是 data.table 的 shift()函数。PACF 是在控制了所有以前的滞后之后剩下的相关性。例如,如果您想要获得滞后 3 的 PACF,您可以使用第一个和第二个滞后进行回归拟合,然后计算残差的相关性:

adjustment <- lm(
  passengers~shift(passengers, n = 1L)+
    shift(passengers, n = 2L)
)
cor(
  residuals(adjustment), 
  shift(passengers, n = 3L)[-(1:2)], 
  use = 'complete.obs'
)

从频率主义者的角度来看,时间序列建模的一个主要目标是从残差中移除自相关,以便残差是合理的 iid 白噪声。

**你不能只看 RMSE 或者任何你喜欢的指标来选择时间序列模型。**这是分析师犯下的最大罪过。始终绘制残差的时间序列,并检查残差的 ACF/PACF。我们稍后再讨论这个。

有些人错误地认为,你可以只根据 ACF 和 PACF 来选择最佳的时间序列模型。这是真的只有对于纯 AR 或纯 MA 工艺,但那些是罕见的。这些主要是诊断图。

平稳性

平稳性是第二个关键概念,通常用来表示时间序列具有恒定的均值和方差。回想一下飞机乘客时间序列:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这显然不具有恒定的意义。一个常见的技巧是求一阶差,从时间 t 的观测值中减去时间 t-1 的观测值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个数列有常数均值,但不是常数方差。如果我们认为时间序列遵循指数增长,我们可以取 log(Y)和 difference:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个系列现在表现得更好了。在使用经典时间序列预测方法时,将此过程作为 EDA 的一部分。当序列呈指数(倍增)增长时,对数变换有意义。

很多时间序列模型都需要平稳性,尤其是关于常数均值的部分。这么想吧。只要平均值是恒定的,我们可以预测接近平均值的某个地方,我们将大致正确;否则,我们不知道这个系列在未来会有什么结局。

季节性趋势分解

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

季节性趋势分解对于可视化很有用,但通常不能用于预测。这个方法很容易理解。对于周-季数据,我们可以:

  1. 计算 7 日移动平均线(从 t-3 到 t+3)。这是你的趋势。
  2. 从你的数据中减去趋势。然后取一周中每一天的平均值(星期一、星期二……)。这是你的季节性成分。
  3. 从原始观测值中减去趋势和季节性之后,剩下的就是残差。

第一步要非常仔细地看。趋势是一个移动平均线,你实际上需要未来的观察来估计趋势。

我见过一些人执行分解,然后训练一个模型来预测趋势,因为这样“更容易”。呃,不。首先,这是“作弊”,因为它人为地降低了 RMSE。其次,趋势是吸收了未来值的移动平均线——大量数据泄露。

ARIMA

ARIMA(p,d,q)有三个分量:

  1. AR§自回归。这使用滞后值。例如,AR(2)使用时间 t-1 和 t-2 的观测值来预测时间 t 的值。这可以被视为时间序列的持久结构部分。
  2. I(d)集成。这是你需要使数列变得稳定的次数。如果完成,AR 和 MA 组件使用差异系列。
  3. MA(q)均线。这使用残差的滞后值。例如,MA(2)使用时间 t-1 和 t-2 的残差来预测时间 t 的值。这可以视为时间序列的局部趋势。

我们经常用(2,1,2)来表示一个 ARIMA 模型,它有 AR(2),I(1)和 MA(2)三个分量。根据经验,任何超过(2,1,2)的都可能是过度拟合。(超级重要!)如果你要拟合一个(1,1,6)模型,你最好添加一个季节性因素(下一节)。

ARIMA 很容易调整,因为我们只需要尝试 3 x 2 x 3 = 18 个可能的模型,然后选择最好的一个。I(2)可能发生在一些科学过程中,但大多数业务数据只需要 I(1)。

参数不直观,但模型具有某些含义。值得注意的是(1,1,2),阻尼趋势模型。你可以把这个模型看作是对观察到的趋势进行外推,但是进行了一些正则化(我们知道正则化在实践中效果很好)。有人认为,( 1,1,2)应该是 ARIMA 的默认设置,因为它在很多情况下都能很好地工作。当您拥有非常少的数据时,例如新推出的产品,衰减趋势尤其明显。

ARIMA 在短期预测方面确实很难被击败,但在长期预测方面却失败了,因为许多时间序列需要 MA 成分。假设你有马①。你可以用 t 时刻的观测残差来预测 t+1,但是你没有 t+1 时刻的残差来预测 t+2。如果你需要做长期预测,看看脸书的先知之类的东西。

我不喜欢 r 中的 auto.arima()函数,前面我提到过时间序列模型不应该只在单一指标上进行评估。具有最低 AIC 或 BIC 的模型可能具有表现不佳的残差;我们希望从具有良好残差的模型中挑选出具有最佳度量的模型。

此外,auto.arima()默认情况下在(2,1,2)之外搜索,因此它可以挑选不必要的复杂模型——并且由于搜索空间更大,它使用试探法,因此您可以陷入局部最优。

我们之前看到,记录的值与一阶差分相结合会产生一个稳定的分布,所以让我们应用对数变换并搜索参数,排除过去 14 个月(应该是 12 个月,但我没有重新运行整个测试集)的数据:

library(forecast)log_passengers <- ts(log(passengers), frequency = 12)
train <- ts(
  log_passengers[1:(length(log_passengers) - 14)], 
  frequency = 12
)placeholder <- list()
i <- 1
for(p in 0:2){
  for(d in 0:1){
    for(q in 0:2){
      model <- Arima(train, order = c(p, d, q))
      placeholder[[i]] <- c(p, d, q, AIC(model))
      i <- i + 1
    }
  }
}
performance <- do.call('rbind', placeholder)
colnames(performance) <- c('p', 'd', 'q', 'AIC')

最低的 AIC 来自(2,1,1)。这里我们检查残差的 ACF 和 PACF:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些都不令人满意,尤其是滞后 1 时的峰值。下一个最好的 AIC 来自(1,1,2):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于滞后 1 处的尖峰,这些也不令人满意。看看原始的时间序列,我们显然需要一个季节性的组成部分。我们有月度数据;峰值对应于年度(12 个月)季节性。

萨里玛

SARIMA(p,D,q)×(P,D,Q)m 的工作方式与 ARIMA 类似,但有季节性成分。你可以把它想成是两个模型的组合:一个滞后步长为 1 (t-1,t-2,…),一个滞后步长为 m (t-m,t-2m,…)。但是为了获得更精确的理解,你应该学习后移符号,因为 D 和 D 部分有一些相互作用。

就像 ARIMA 一样,我们可以测试所有可能的参数值,将它们保持在(2,1,2)以内。m 取决于你的时间序列的粒度。对于每小时的数据,尝试一天 24 小时中 m = 24 对于每日数据,尝试 m = 7,一周 7 天;而对于月度数据,尝试 m = 12。SARIMA 的最大限制是它只允许一个季节性项。当你有每日数据时,有理由相信有每周和每年的季节性,但遗憾的是,我们只能将其中一个纳入模型。一种变通方法是加入傅立叶项,如果时间序列不是大致稳定的,这在 SARIMA 框架中可能是一个难题。

总之,找到合适的环境。让我们冒险进入末日金字塔:

placeholder <- list()
i <- 1
for(p in 0:2){
  for(d in 0:1){
    for(q in 0:2){
      for(P in 0:2){
        for(D in 0:1){
          for(Q in 0:2){
            model <- tryCatch({
              Arima(train,
                    order = c(p, d, q),
                    seasonal = c(P, D, Q)
                    )
            }, error = function(err){
              Arima(train,
                    order = c(p, d, q),
                    seasonal = c(P, D, Q),
                    method = 'CSS'
                    )
            })
            placeholder[[i]] <- c(p, d, q, P, D, Q, AIC(model))
            i <- i + 1
          }
        }
      }
    }
  }
}
performance <- do.call('rbind', placeholder)
colnames(performance) <- c('p', 'd', 'q', 'P', 'D', 'Q', 'AIC')

这比以前运行得慢多了,因为我们必须考虑 18 x 18 = 324 个参数组合。这里我们必须使用 tryCatch,因为有时默认的优化算法不起作用。我们最终以(2,1,2) × (1,0,1)12 作为最佳模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些诊断图看起来很好。但是我们仍然需要检查残差。这里有一个比较,显示了增加季节性带来的改善:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ACF 和 PACF 图看起来很好,残差看起来很像白噪声。还有一件事我们不能忘记检查:预测的合理性:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有时其他诊断看起来不错,但预测看起来真的很差。这看起来不错。

其他人可能会选择不同的模型。只要所有的诊断看起来都没问题,那就没问题。记住所有的模型都是错的,但有些是有用的。不要纠结于“真实”的模型,要确保模型是有用的。

消除预测偏差

这部分是很常见的错误。我们取了时间序列的对数,所以要创建预测,我们只需要取指数,对吗?**未必。**选择归结为我们是想要中值(最小化 MAE)还是平均值(最小化 MSE)。在这里,预测中位数也可以解释为最小化%误差(kinda)。有时,业务环境希望最小化 MSE,而分析师忘记了让模型预测平均值。

在模型假设下,时间序列的对数具有正态分布的残差。换言之,残差遵循对数正态分布。分布的平均值是 exp(μ + 0.5 σ),而不是 exp(μ),后者是中位数。σ项可以通过计算残差的方差来估计。

您可以保留原始时间序列并在 Arima()中转换它,而不是手动获取时间序列的日志:

Arima(..., lambda = 0, biasadj = TRUE)

预测会自动计算 exp(μ + 0.5 σ)。

这是我们带有偏差调整的 SARIMA 模型:

model <- Arima(
  subset(passengers, start = 1, end = 132),
  order = c(2, 1, 2),
  seasonal = c(1, 0, 1),
  lambda = 0,
  biasadj = TRUE
)
plot(forecast(model, 12, biasadj = TRUE), 
     ylim = c(300, 700), xlim = c(1959, 1961))
par(new = TRUE)
plot(passengers, add = TRUE, 
     ylim = c(300, 700), xlim = c(1959, 1961))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你问我的话,我会说,这个预测看起来真的很不错。

时间序列回归

有时称为(S)ARIMAX,其中 X 代表外部回归量。程序很简单:

  1. 拟合 y~x1+x2+…
  2. 对残差进行 ARIMA 拟合

就是这样。

第一步其实超级棘手。不幸的是,就其本质而言,时间序列有一个共同的混淆因素:时间。你可以得到在训练数据上表现良好的模型,但是由于虚假相关性,该模型是无意义的。独立随机漫步通常是强相关的!

rw1 <- cumsum(rnorm(100, 0, 1))
rw2 <- cumsum(rnorm(100, 0, 1))
plot(
  rw1, 
  type = 'l',
  main = paste0(
    'Correlation = ', round(cor(rw1, rw2), 2), 
    ', p approx. ', round(cor.test(rw1, rw2)$p.value, 2)),
  ylim = c(min(c(rw1, rw2)), max(c(rw1, rw2))))
lines(rw2)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一些计量经济学模型要求趋势平稳性,即每个时间序列在去除(线性)趋势后变得平稳。这是一个相对简单的检查,但我除了大多数序列不是趋势平稳的。

我们将这一概念概括为协整。简单地说,如果所有的时间序列(Y 和 X)都是 I(1),那么步骤 1 中的回归必然会产生 I(0)残差。或者,如果所有时间序列都是 I(2),那么步骤 1 中的回归必然会产生 I(1)或 I(0)残差。不,你不能欺骗说“这个 I(1)序列在再求一次差后仍然是静止的。”那还是我①。

如果时间序列不是协整的,那么就不能进行时间序列回归。思考一下协整在概念上意味着什么。假设 Y 是一只狗,X 是它们的主人。

如果 Y 和 X 是协整的,那么这条狗就被拴住了。狗可以在皮带半径范围内的任何地方行走,但它是依附于它的主人的。如果我们知道主人在哪里,我们就知道狗在哪里。

如果 Y 和 X 不是协整的,那么这条狗就没有被拴住。它可以逃跑,探索整个城市。知道了主人的位置并不能告诉我们狗的大概位置。时间差越大,不确定性越大。可能狗刚跑了,未来五分钟还在街区内;但是一个小时后,我们不知道它在哪里。

在商业环境中,大多数时间序列是 I(1)。检查回归残差是否平稳。如果不是,那么你需要一个比 ARIMA 更先进的模型(脸书先知是可能的候选人)。

关于通用机器学习的注记

如果时间序列是稳定的,随机森林和其他树算法可以工作。他们使用外部回归来捕捉季节性,而不对残差应用(S)ARIMA。

然而,当时间序列有趋势时会发生什么呢?理解机器学习算法如何在引擎盖下工作绝对至关重要。

考虑一棵有一个裂口的树,X 和 Y 都有向上的趋势。拆分说“如果 X > x,预测 Y = yhigh 否则预测 Y = ylow”。它预测一条平坦的线。即使你的 X 提供了一个趋势,一个预测只是看到 X > x,并预测在 Y = yhigh 处是一条平线。树木无法学习趋势。

改善这种情况的一种方法是,如果可能的话,对原始时间序列进行差分,使其变得平稳。然后,您可以通过采用最近的观察点并添加预测的累积和来进行预测。然而,由于该算法不理解序列相关性,预计会看到长串的预测不足/预测过度。

关于季节性的说明

如果你的时间序列看起来“大致平稳”——具有细微周期的平坦——那么你可以添加傅立叶项来表示季节性。例如,我们不期望转换率有一个大的恒定趋势,但它可能有很强的每日和每周季节性。你可以在这上面训练一个逻辑回归。

如果您有每小时的数据,请尝试添加:

  • 使用预测因子 sin(2πkt/24)和 cos(2πkt/24)的每日季节性
  • 使用预测值 sin(2πkt/(247))和 cos(2πkt/(247))的每周季节性

其中 t 是时间,k = 1,2,3,…您可以使用正则化来选择 k。

实际制约因素

有时人们会犯一个可爱的错误,忘记了模型的最终目的是预测。如果业务要求你预测未来 7 天,你最好确保你使用的任何回归变量都可以提前 7 天获得。如果使用任何外部回归变量,请确保将其滞后。

模型验证

交叉验证对于获得样本外误差的感觉是惊人的。当然,CV 因其在超参数调整中的作用而受到关注,但对于我们许多人(咳嗽 Bayesians 咳嗽)来说,我们使用 CV 来评估模型的泛化能力,而不是选择超参数。

我见过有人在时间序列上使用常规 CV。 CV 完全无效,因为自相关是一个东西。

对时间序列进行交叉验证有两种主要方法,每种方法都有不同的假设。

第一个是留在未来之外交叉验证 (LFOCV)。例如,我们可以使用 t = 1:36 来训练模型,并预测未来的 12 个步骤并记录误差。然后使用 t = 1:48 进行训练,并预测未来的 12 步。那么 t = 1:60。诸如此类。

理想情况下,我们预测未来的 1 步,并用 t = 1:36、1:37、1:38 等重新调整模型。然而,这实际上是 LOOCV 且计算非常昂贵。使用 12 的增量是出于方便,比如选择 k = 5 或 10。

二是使用推拉窗。这里我们固定了训练数据和幻灯片的长度,所以 t = 1:36,13:48,25:60 等等。这篇文章对这两种方法进行了很好的可视化。

哪个更好?这取决于时间序列的行为有多“粘”。如果行为看起来一致,那么 LFOCV 工作得更好,因为您将使用所有的数据来训练最终的模型。如果行为更加不稳定,并且会随时间变化,那么滑动窗口会更好,因为每次您做出预测时,模型都会根据您最近的数据子集进行训练。

(啊,之前忘了提了。与表格数据不同,更多的数据不一定意味着更好的预测。如果您的时间序列不断改变行为,只使用最近的子集是更明智的。还有动态 AR 模型,但这些超出了本文的范围。)

请记住,我们的目标是评估模型在野外漫游时的表现,因此我们希望尽可能接近模型部署时的情况。

评估指标

我们还没有讨论评估指标。就我个人而言,我真的不喜欢 MAPE 和梅。根据你的时间序列,优化这两个中的任何一个都会引入系统偏差——预测值太低。

在 MAPE 的例子中,预测不足的误差最多是 100%,而预测过度的误差是无限的。

在 MAE 的例子中,如果你有指数增长,中间值会比平均值低很多。

如果企业关心百分比误差,尝试使用 log(预测/实际)代替。换句话说,预测日志时间序列的残差。当取指数时,其平均值会产生一个“更合理”的百分比误差。

如果企业关心平方误差,那么你应该在偏差调整预测的基础上计算 RMSE。

超越

如果你是时间序列的新手,想了解更多,我建议浏览一下《预测:原则与实践》这本书,这是一本免费的在线教材,作者是 Rob Hyndman,他是 R’s forecast package 的作者。它更侧重于理解和应用,而不是数学,这对新手来说是完美的。

像 ARIMA 这样的模型的一个主要缺点是缺乏可解释性。滞后值的系数很难解释。此外,尽管 ARIMA 能做出很好的短期预测,但它无法预测更长期的情况。脸书的先知包通过提供季节性趋势分解式方法解决了这两个问题。他们线性推断趋势进行预测。

如果你正在寻找高级的时间序列方法,我建议学习一下贝叶斯结构时间序列 (bsts)模型。它们是状态空间模型——把它们想象成隐马尔可夫模型,更加灵活,能够处理连续的潜在状态。这类模型非常有前途,原因如下:

  • 它明确说明了测量误差。像 ARIMA 这样的频率主义方法假设测量是完美的,所以在做预测时,模型会传播测量误差。如果你那么喜欢 ARIMA,它可以被公式化为一个状态空间模型。
  • 可以应用于因果推断。我相信谷歌的 CausalImpact 是准实验最有用的软件包。这对于衡量营销活动的影响非常有用。
  • 它允许动态回归。许多模型用一组系数来拟合训练数据,并假设这些系数是静态的。当我们建模的内容不断变化时,我们可能希望让系数随时间变化。
  • 它以一种巧妙的方式结合了正规化。它使用尖峰和厚片先验,一个质量为 0 的点加上一个高斯。它类似于 elasticnet,但允许 0 的后拉伸。

为时间序列预测奠定基础

原文:https://towardsdatascience.com/time-series-forecasting-968192b3781a?source=collection_archive---------11-----------------------

时间数列预测法

关于时间序列 EDA 和使用 Python 进行数据准备的教程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

背景

时间序列预测是机器学习的一个重要领域,各行各业都有很多涉及时间成分的用例,如零售商下周的需求预测、解决劳动力优化问题的呼叫量预测、预测能源消耗、用于主动灾难管理的天气预报等等。时间序列分析和预测也可以用于异常检测。

什么是时间序列预测,它与其他机器学习问题有何不同?

在这两种类型的问题中,时间都扮演着重要的角色,历史数据被用来训练预测未来的模型。两个机器学习数据集都是观察值的集合。那么,有什么区别呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在正常的机器学习数据集中,所有的历史观测值都被同等对待,而时间序列是一系列观测值,它们是按时间顺序捕获的,因此时间序列增加了观测值之间的顺序依赖性。

让我们了解一些常见的符号。

  • t-n:之前的时间或滞后,如 t-1 是之前的时间,也称为 1 的滞后
  • t:当前时间
  • t+n:未来的时间,例如 t+1 是要预测的下一个时间

时间序列组件

在任何机器学习问题中,我们都从探索性分析开始,以更好地理解数据,这有助于选择适当的算法。同样,在时间序列中,我们将序列分解为 4 个组成部分:水平、趋势、季节性和噪声,以便更好地理解数据。

水平、趋势和季节性被进一步归类为系统成分,因为它们以一致的模式表征基础数据,并且可以建模,而噪声是一种非系统成分,因为它具有随机变化,不能直接建模。

让我们来看看这 4 个组件。

  1. 级别 :级别描述系列的平均值
  2. 趋势 :趋势是序列在两个相邻期间之间的变化,这是可选成分,不一定出现在所有序列中
  3. :季节性描述了一段时间内的短期循环行为,这也是一个可选的组成部分,不一定出现在所有序列中
  4. 噪声 :模型无法解释的随机变化,在所有系列中都有所体现

一个系列被认为是这四个部分的组合,它们可以相加或相乘地组合,让我们通过下面的例子来理解这一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

共同趋势和季节性的例子

  • 加法模型:yₜ =水平+趋势+季节性+噪声
  • 乘法模型:yₜ =水平 x 趋势 x 季节性 x 噪音

预测方法是如何工作的?

这些方法试图隔离系统部分并量化非系统部分,即噪声。系统部分有助于生成点预测,而噪声水平有助于估计相关的不确定性。

我们已经简要介绍了时间序列。在接下来的章节中,我们将讨论将时间序列分解为系统和非系统部分并检测初始模式的各种技术。

时间序列数据准备和分析

预测的第一步也是最重要的一步是描述时间序列的性质,并调查潜在的问题,这些问题必须在应用任何预测方法以获得有效结果之前加以注意。

我们将通过一些开源数据集和一些随机生成的数据集来逐一讨论所有这些步骤。我们将在 Google Colab 中使用 Jupyter 笔记本。

  1. 加载和浏览时间序列数据
  2. 特征工程
  3. 数据可视化
  4. 重采样
  5. 电力转换
  6. 探索时间结构

首先,让我们下载以下数据集,打开 Jupyter 笔记本,并导入这些 python 函数。

1.加载和浏览时间序列数据

加载时间序列数据

我们通常将数据集作为 pandas 数据帧来加载,这里我们可以使用 read_csv()函数将时间序列数据作为一个 series 对象来加载,这是一个一维数组,每行都有时间标签。

我们不应该忘记指定一些参数,以确保数据作为一个系列正确加载。下面我们来看看这些参数。

  • 标头:“0”指定标头信息可供使用。
  • parse_dates: 'True '帮助 pandas 识别第一列中的数据包含需要解析的日期。但是总有一些奇怪的格式需要手动定义,在这种情况下,添加 date_parser()函数是更好的方法。
  • index_col: '0 '暗示我们的第一列,即时间序列列包含我们的索引信息
  • 挤压:“真”暗示熊猫,我们只有一个专栏,我们想用这个作为系列

探索时间序列数据

加载后,建议浏览一下数据,我们可以使用 head()函数来查看前五条记录,也可以指定前 n 条记录来查看。

验证给定系列中的观察值的数量以避免任何错误总是一个好主意。

我们可以通过查询不同的时间间隔来分割时间序列。例如,让我们看看 1981 年 1 月以来的所有观测数据。

与其他机器学习问题一样,计算和查看汇总统计数据也是时间序列数据探索中的一个重要步骤,它让我们了解值的分布和传播。describe()函数将帮助我们计算这些统计数据。

2.特征工程

时间序列数据必须转换为监督学习数据集,才能用任何机器学习算法建模。正如我们在上面看到的,时间序列没有任何因变量和自变量。我们必须构建一个数据集,其中包含要预测的目标变量和用于预测的输入变量。

创建滞后要素

这是将时间序列预测问题转化为监督学习问题的经典方法。在这种方法中,一个时间(t)的值被用来预测下一个时间(t+1)的值。

在 Pandas 中,可以通过 shift()函数创建滞后要素,这通过将数据集移位 1 来创建列 t,并且没有移位的原始序列表示 t+1。

我们可以看到,在我们的监督学习问题中,前一个时间步长(t+1)是输入(X),下一个时间步长(t)是输出(y)。这个概念被称为滑动窗口方法。我们可以看到,第一个观察值没有可用于预测序列的输入,最后一个观察值没有已知的输出(y)。因此,我们必须丢弃这些行。

类似地,我们可以如下创建多个滞后特征。

使用汇总统计数据作为特征

此外,我们可以使用一些滞后值的汇总统计数据作为特征,例如前面几个值的平均值。这可以通过 rolling()函数来实现。

或者,我们可以使用每个时间戳的所有先前值的汇总统计数据作为我们预测模型的特征。这些特性可以通过扩展()函数来创建。

日期和时间作为特征

与任何其他监督学习数据集类似,许多日期相关的特征可以从时间戳中导出,例如一天中的小时、一周中的天、月、季度、工作日和周末、公共假日等。我们经常发现它非常有用。

3.数据可视化

时间序列自然会产生相当流行的可视化效果,甚至在我们引入数据科学之前,我们都见过股票市场运动的折线图。除了线形图之外,还有很多可视化的东西。我们将在本节中学习这些工具。

线形图

线形图可能是时间序列最流行的可视化方式。在该图中,x 轴表示时间,y 轴表示观察值。

比较不同时间间隔的相同时间间隔的折线图通常很有帮助,例如每天、每月和每年。在下面的例子中,我们比较了 10 年中 365 天的最低日温度。让我们按年份将数据分组,并为每一年创建一个线图。

直方图和密度图

另一个重要的可视化是观察值的分布。一些线性时间序列预测方法假设正态分布的观测值。我们可以通过绘制原始观察值的直方图和密度图来检查这一点,如果需要,可以对原始值的记录等转换变量重复这一检查。

盒须图

另一种有助于总结观察值分布的图是盒须图。此图有助于检测系列中的任何异常值。

我们可以在每年的水平上使用这些并排的箱线图来比较时间序列中的每个时间间隔。

热图

热图是一个神奇的可视化工具,我们可以用它来可视化不同颜色的温度分布。它不言自明,较大的值用暖色(黄色)显示,较小的值用冷色(绿色)显示。

滞后散点图

时间序列建模假设当前观察值和先前观察值之间存在关系,这也称为滞后 1。我们可以在散点图上显示这种关系。

通常,分析多个滞后值之间的关系很有帮助。我们可以在一个循环中运行相同的代码来绘制多个滞后。

自相关图

观察值和它们的滞后之间的相关性强度可以用自相关图来量化。在时间序列中,它也被称为自相关,因为我们计算的是同一序列的滞后值的相关性。

4.重采样时间序列

有时我们的观测频率不对,观测频率可能高于或低于我们期望的预报频率。例如,一个企业需要一个每日预测,但它有每小时或每月的观察。在这种情况下,以下两种技术可以帮助我们根据业务目标修正频率。

上采样

这是增加采样频率的过程,例如从每周一次增加到每天一次。在下面的例子中,我们将从每月到每天对数据进行插值。Pandas 系列对象提供了一个 interpolate()函数,该函数提供了一系列简单和复杂的方法。这里我们使用线性方法。

让我们将线性插值数据可视化。

我们可以尝试另一种流行的插值方法,即多项式或样条来连接值。我们必须指定多项式中的项数。

我们可以想象新的情节,这创造了更多的曲线,看起来更自然。

向下采样

降低采样频率,例如从每天一次降低到每周一次。销售数据是月度的,但业务需要季度预测。让我们根据业务需求对数据进行重新采样。

可视化重新采样的数据。

5.电力转换

数据转换是机器学习问题中一种常用的方法,用于提炼原始特征以提高它们的重要性。类似地,在时间序列预测中,我们使用各种数学变换去除噪声并改善信号。

在这一节中,我们将首先使用随机生成的数据讨论这些技术,然后将该技术应用于开源数据。

多项式变换

具有二次或三次增长趋势的时间序列可以通过将原始数据转换为平方根或立方根来实现线性。

我们用三次函数随机生成一个数列,检查一下变换效果。

现在,将这些数据转换成立方根,我们可以观察到这个系列看起来是正态分布的。

对数变换

有时我们会遇到具有更极端趋势的数据,更好的说法是指数趋势,这样的时间序列数据可以通过取原始值的对数而变成线性。这称为对数变换。

让我们使用下面的代码从指数分布中生成数据。

同样,我们可以通过取原始值的自然对数将这些数据转换回线性。

博克斯-考克斯

在现实生活中,我们经常会遇到没有明确趋势的观察结果,在得出适当的转换方法之前,必须测试不同的转换。幸运的是,我们有这种统计技术来分析给定的序列,并根据下面的 lambda 值自动执行最合适的转换。这些是 lambda 和相应变换的一些常见值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

常见的 Box-Cox 变换

首先,我们将根据我们的直觉手动转换,接下来,我们将使用 box-cox 转换并查看差异。

手动转换

在可视化原始线图后,我们假设取一个对数将是一个理想的变换,并指定λ= 0。我们可以看看对数转换的时间序列图。

Box-Cox 变换

现在,我们将依靠 Box-Cox 来选择一个理想的 lambda 并对其进行相应的转换。

我们可以看到 lambda 值接近 0,该图看起来也类似于手动转换,但仔细观察直方图,我们可以看到新的直方图看起来更正常。

6.探索时间结构

我们已经探索并准备了时间序列数据,进行了必要的转换,现在是时候研究时间结构了,包括数据的预测能力。

白噪声

这是时间序列预测中的一个重要概念。如果序列是白噪声,这只是一系列随机数,无法预测。

要检测白噪声,必须调查以下条件。

  • 检查序列是否有零均值
  • 检查方差是否随时间保持不变
  • 检查滞后值的相关性是否为 0

让我们探索一下可以帮助我们检测白噪声的统计工具。

  1. 汇总统计:检查和比较不同时间间隔的整个时间序列的平均值和方差。
  2. 折线图:折线图会给我们一个关于不一致均值和方差随时间变化的基本概念。
  3. 自相关图:检查滞后观测值之间的相关性强度。

我们将使用合成创建的白噪声时间序列数据来讨论上述工具。我们将使用均值为 0、标准差为 1 的高斯分布来创建这个变量。

现在,查看汇总统计数据,均值接近 0,标准差为 1,这在本例中是意料之中的。在现实生活中,查看该摘要后,系列可以分布在多个子系列中,并且可以比较各自的统计数据,以发现一段时间内均值和方差的任何不一致性。

接下来我们来看这个数据的折线图,它看起来不像任何时间序列,这只是随机数的集合。

带有钟形曲线的直方图证实了均值为 0、方差为 1 的高斯分布。同样,我们可以验证不同时间间隔的分布。

最后,我们可以使用自相关图来研究滞后观测值之间的相关性强度。

我们可以看到滞后观测值之间没有关联。因此,我们可以得出结论,这个序列是白噪声,不能很好地预测。

随机游动

让我们讨论另一个概念,它可以帮助我们理解时间序列预测的可预测性。随机游走是一系列从一个时间段(t)到下一个时间段(t+1)的变化是随机的。有一种误解认为随机漫步是一个类似白噪声的随机数序列。让我们看看这有什么不同。

用于生成随机游走的过程强制从一个时间步长到下一个时间步长的相关性,我们可以通过以下等式来理解这种相关性,其中 X(t)是序列中的下一个值,X(t-1)是前一个时间步长的值,e(t)是下一个时间步长的白噪声。

X(t) = X(t-1) + e(t)

让我们通过麻省理工学院的网站来理解这一点。

要理解最简单的随机行走是一维行走。假设下面的黑点位于一条数字线上。黑点从中心开始。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://www . MIT . edu/~ kardar/teaching/projects/chemotization(Andrea Schmidt)/random . htm

然后,它以相等的概率向前或向后迈一步。它每次都向前或向后迈进一步。让我们称第一步为 a₁,第二步为 a₂,第三步为 a₃,依此类推。每个“a”要么等于+1(如果向前一步),要么等于-1(如果向后一步)。下图是一个黑点,走了 5 步,最后在数轴上-1 结束。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://www . MIT . edu/~ kardar/teaching/projects/chemotization(Andrea Schmidt)/random . htm

现在,我们将使用相同的方法模拟随机行走,并将这些观察结果绘制在一条线上。

我们可以看到这个形状看起来像真实股票指数的运动。

现在,让我们探索可以帮助我们识别任何时间序列中的随机游走的工具

自相关图

我们知道随机游走是如何产生的,因此通过它的设计,我们期望与先前的观察有非常高的相关性,并且这种相关性将逐渐降低。

增强的 Dickey-Fuller 检验,以确认序列的非平稳性

随机游走被创建的方式,期望序列是不稳定的,即,均值和方差随时间的不一致性。

该检验的无效假设是时间序列是非平稳的。检验统计量是正的,远远高于临界值,这意味着我们将不得不拒绝时间序列是非平稳结构的零假设。

我们可以通过一阶差分使时间序列平稳,然后再分析其特征。

这种差异线图还表明,除了一系列随机数之外,没有其他信息可供使用。

最后,我们可以通过自相关图看到模式,并确认滞后观测值之间没有关系。

我们已经看到随机漫步也像白噪声一样不可预测;我们可以做出的最佳预测是使用前一个时间步长的值来预测下一个时间步长,因为我们知道下一个时间步长是前一个时间步长的函数。这种预测方法也被称为天真预测,

分解时间序列

我们在本文开始时讨论了时间序列的四个组成部分(水平、趋势、季节性和噪声),在这一部分,我们将探索自动分解工具。

我们知道时间序列是这四个部分的组合,通过分解,我们将时间序列分解成这些单独的部分,以便更好地理解数据并选择正确的预测方法。

Statsmodels 库在一个名为 seasonal_decompose()的函数中提供了简单的或者经典的分解方法的实现。它要求我们指定模型是加法模型还是乘法模型。我们应该在仔细检查了线图之后指定这个信息。

加法分解

我们可以随机生成一个具有线性增长趋势的时间序列,并将其分解为一个可加模型。让我们看看下面的例子,我们可以看到趋势成分是序列中最主要的成分,没有季节性。残差图显示零噪声,我们的简单方法可能没有分离噪声,我们可以测试一些高级方法,如 STL 分解。

乘法分解

以下示例将航班乘客数据集分解为一个乘法模型。

我们可以看到,从序列中提取的趋势和季节性信息似乎是合理的,数据中也有噪声,从图中可以观察到序列早期和后期的高可变性时期。

摘要

我们试图为时间序列预测问题建立一个坚实的基础。我们学习了时间序列的基础知识,并通过可视化发现见解和差异,如何纠正一些数据差异,以及通过特征工程和功率转换优化时间序列数据以实现准确预测。

虽然我们使用单变量时间序列讨论了所有的技术,但是这些技术可以容易地应用于多变量时间序列预测问题。

感谢您的阅读,希望您发现这篇文章内容丰富。在接下来的几篇文章中,我将讨论不同的预测技术,我将从经典技术开始。

参考

[1] Galit Shmueli 和 Kenneth Lichtendahl,实用时间序列预测与 R:实践指南,2016 年。

*[2]杰森·布朗利,【https://machinelearningmastery.com/ *

* [## 随机漫步

随机漫步一维数学什么是随机漫步?随机漫步是这样一个过程…

www.mit.edu](https://www.mit.edu/~kardar/teaching/projects/chemotaxis%28AndreaSchmidt%29/random.htm)*

时间序列预测和因果分析与脸书先知和谷歌因果影响

原文:https://towardsdatascience.com/time-series-forecasting-and-causal-analysis-in-r-with-facebook-prophet-and-google-causalimpact-22046fbcb49a?source=collection_archive---------38-----------------------

蒙特利尔犯罪预测与 COVID 锁定影响的联合研究

这篇文章将是我每年 R 潜水的一部分;想法将是在时间序列预测和因果推断中使用两个 R 库。

我想写一篇文章已经很久了,但是我从来没有找到时间/资源来写它,主要是因为我缺少一个真正的数据集来写它,但是猜猜 2020 年是哪一年来拯救我。从经济死亡率的角度来看,在此次 COVID /封锁期间,该事件对我们社会的大部分影响是负面的。不过,我在想蒙特利尔封锁期间。在人群中可能有一些与病毒传播无关的积极影响(例如,比人们烘烤更多)。我的研究引导我找到了多个数据集,但最吸引我眼球的是蒙特利尔的犯罪活动。

这篇文章的观点是:

  • 深入数据集
  • 使用脸书先知构建 2019 年的犯罪预测器
  • 评估锁定对有因果影响的犯罪的影响

这篇文章的所有代码都可以在这个 资源库 Github 中找到。

数据探索

这个实验用的数据集是这里(不好意思说英语的,数据挺公开的从网站上的描述,在license Creative Commons CC-BY 4.0下);这是 2015 年至 2020 年 8 月间所有犯罪的清单。每起犯罪都与大的类别相关联,并且有关于地点、一天中的时刻等信息。

很快就有了蒙特利尔每天犯罪数量的图表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

时间序列有点嘈杂,但我们可以注意到信号的某种趋势,随着时间的推移,信号逐渐减弱,这在周线视觉中更加明显。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

从这个角度来看,蒙特利尔的犯罪似乎没有季节性(比如夏天的犯罪比冬天多)。

数据集上的犯罪类别有:

  • 车辆盗窃
  • 恶作剧
  • 抢劫
  • 车内/车上盗窃
  • 闯入
  • 谋杀

有一个关于不同种类的犯罪随时间演变的次要情节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

对不同类别没有真正的季节性影响,但值得注意的是,每年的下降似乎是由车内/车上盗窃、恶作剧和闯入造成的。

对于本文的下一步,我们将关注每周犯罪,以便于分析。

脸书先知图书馆的时间序列预测

项目《脸书先知》由脸书开发,2017 年出版;文章包含模型设计的所有细节,但主要是它应该知道的内容:

  • 建立在线性回归的基础上;这是 GAM 型号的变体。
  • 这种模型预测的输出由趋势、季节和假日分量组成,以处理信号随时间的演变。

你可以用 python 或者 R 来使用这个库,快速入门文档很好用。就设置而言,您需要对输入数据进行一点格式化(列名、格式),但这很简单。提醒一下,目标是根据 2015 年到 2018 年的数据,建立 2019 年蒙特利尔每周犯罪的预测系统。

这是建立在 Prophet 上的模型提出的预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

预测看起来没那么糟糕,而且它抓住了长期下降的趋势。该模型提供了信号的高低投影。从模型中,前面提到的每个组件都是可访问的;例如,有趋势成分或季节性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

使用 Prophet,可以添加外部因素,如可能影响信号的特定事件的节日,这相对容易做到。

在 Prophet 的论文中,该模型被描述为分析师的预测系统,该系统可能没有时间浏览所设计的模型,并且可以快速构建预测系统并添加外部特征,而无需考虑模型的参数。

是时候用 Google 的因果影响包走得更远了。

谷歌影响下的因果分析

这是谷歌开发的 2015 年的一个项目;第篇文章给出了关于这个库的更多细节,但是我强烈推荐看看 Kay Brodersen(这个包的作者之一)的这篇演讲,它是如此清晰,以至于在它的基础上建立一个解释将是浪费时间。

需要记住的重要一点是,该软件包提供了以下功能

  • 通过快速添加一些特征来建立模型,从而预测时间序列
  • 评估预测和现实之间的差异;这是一个因果推断,用来估计一个事件的影响

正如在介绍中提到的,让我们用这个包来评估蒙特利尔的封锁对犯罪的影响。这个分析的协议非常简单;首先,我用数据训练了一个模型。为了进行训练,我们需要拥有与犯罪无关的特征(例如,拥有被捕人数听起来是个坏主意)。

我决定使用蒙特利尔的天气(由每周平均温度/降水量及其周方差设计),因为它似乎与犯罪无关。作为参考,NASA 有一个令人兴奋的资源叫做 NASA power ( **这些数据来自 NASA 兰利研究中心的 power 项目,该项目由 NASA 地球科学理事会应用科学计划资助,**数据似乎非常开放)存储每日天气信息(感谢@juliettetroadec 的帮助)。这是一张温度和降水量平均值随时间变化的曲线图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

这是锁定期预测系统的一个可视化视图(从黑色垂直线开始)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

该软件包提供了分析预测结果与现实结果的能力,在本例中,在 2020 年 3 月 15 日到 2020 年 6 月 15 日之间,并在报告中总结比较结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

从这份报告中,有意思的摘录如下:

  • 在这种情况下,相对效果是减少 29%(在 22-36%之间)
  • 测量的显著性,在这种情况下,我们可以说有 99.89%置信度的影响

我决定把分析扩展到所有的犯罪,结果就有了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

封锁似乎对减少恶作剧、抢劫、闯入和车辆盗窃产生了积极影响,但封锁对车辆盗窃和死亡犯罪没有影响,因此这种封锁至少有一些好处。
最后,我决定比较先知模型和因果模型的预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图来自作者

与预言者相比,因果影响提供了更广泛的预测范围。

结论

本文的一些要点:

  • 这是一个潜水休息极好机会;我对这种语言有某种斯德哥尔摩综合症,一开始我很讨厌,但后来开始喜欢上了
  • 禁闭也有一些好处

更严重的是,我认为应该保留的是

  • Prophet 可以直接用于建立一个简单的基线模型来预测时间序列
  • CausalImpact 包提供了快速进行影响分析的能力(对于 Pythonista,有一个 python 实现,但是它没有使用相同的模型)。
  • 有替代因果影响的方法,比如微软的Dow why软件包

我对做这个项目很感兴趣,我想我会在未来写另一篇关于时间序列预测的文章,但更多的是从各种模型的评估角度(比如 ARIMA 或 LSTM)。

这篇文章的所有代码都可以在这个 资源库 Github 中找到。

原载于 2020 年 9 月 9 日 https://www.the-odd-dataguy.com

现实生活中的时间序列预测:用 ARIMA 进行预算预测

原文:https://towardsdatascience.com/time-series-forecasting-in-real-life-budget-forecasting-with-arima-d5ec57e634cb?source=collection_archive---------3-----------------------

关于如何使用 ARIMA 进行预测的深入示例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们被可以用时间序列来描述的现象所包围。这是一种奇特的说法,许多事情或事件可以被描述为在某个时期发生的一系列观察结果。

这听起来仍然很复杂,所以这里有几个可以用时间序列表示的“事物”的例子

  • 股票价格
  • 特定地区的天气状况
  • 家庭用电量
  • 心率监测
  • 商店的总销售额

但是时间序列不仅仅是随着时间推移而发生的事情。有几个因素造就了它们的现状:

  1. 趋势时间序列中的值是越来越高还是越来越低?
  2. 季节性数据集中是否存在受季节影响的模式?例如,在线销售是在假期增加还是冰淇淋销售在夏天增加而在冬天减少?
  3. 周期我们能看到独立于时间框架的某种变化模式吗?意义并不依附于某个季节。
  4. 不规则性还有哪些可能影响数据的随机因素?

如果我们了解这些组成部分,并有足够大的数据集,我们可以使用过去的观察,即历史数据,以及我们知道的关于时间序列的其他信息来预测它在未来的行为。比如天气预报,或者下个月的销量预测。

新年决心是件大事,因为今年才刚刚开始,这是设定目标的最佳时机。

你的新年计划是更有理财意识,所以你决定制定一个月度预算。问题是,你不知道该在哪里划线。

当然,每月的开销并不总是恒定的,但有些模式可能会在一年中出现,比如在圣诞节期间和休假时花更多的钱。

我们可以把我们的月支出想象成一个时间序列,可以用时间来衡量。

所以你开始挖掘旧的银行对账单来创建你的支出数据集。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

美丽的虚拟数据

厉害!一段时间内✅的每月费用✅值

让我们预测一下!嗯…没那么快😁

慢下来,直到它停下来

为了建立一个时间序列模型,一个可以用来预测未来值的模型,数据集需要是稳定的

这意味着首先我们需要删除序列可能具有的任何趋势,这样数据集就具有以下属性:

  1. 平均值为常数
  2. 方差为常数,即时间序列中不同点的方差相同。这个性质通常被称为同质性
  3. 两个数据点之间的自协方差不依赖于时间,一个在时间 t1,另一个在时间 t2。这些数据点之间的自协方差仅取决于 t1 和 t2 之间的差异

我的时间序列是平稳的吗?

和许多数据问题一样,这个问题的答案是一个两步过程:1)绘制数据,2)测试你的假设

绘制数据

在开始任何分析之前,抽查数据并更加熟悉它是非常重要和有价值的。如果您花一些时间查看数据,您会发现更容易发现应该删除或单独分析的数据质量问题或异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每月费用数据集的图表

测试你的假设

您可能无法通过简单地查看数据集来判断它是否是静止的。这种情况下,真的不好说!

这就是迪基-富勒测试可以帮助我们的地方。这是一个统计检验,其中零假设表明对于给定的序列有一个单位根,而替代假设表明序列是平稳的

像在任何其他统计测试中一样,如果 p 值小于或等于显著性水平(通常为 1%、5%或 10%),我们将拒绝零假设。让我们将显著性水平设为 1%,这样我们就可以 99%的置信度拒绝零假设。

为了使我们的时间序列稳定,p 值必须≤ 0.01。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

测试时间序列是否平稳

☹️却不是这样

因此,我们必须转换数据集,并再次执行 Dickey-Fuller 测试。数学中常用的一种变换是对数变换,因为它不会影响数据的属性。这意味着我们将计算时间序列中每个数据点的对数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对数变换后测试时间序列是否平稳

我们还没有到达那里,我们的时间序列不是静止的。

下面是我用来运行 Dickey-Fuller 测试的代码,带有进行对数变换的选项。

# log_dataset: boolean indicating if we want to log-transform the dataset before running Augmented Dickey-Fuller testdef adf_test(dataset, log_dataset):
  ds = datasetif log_dataset:
    ds = dataset.apply(lambda x: log(x))
    ds.dropna(inplace=True) result = adfuller(ds) print('Augmented Dickey-Fuller Test')
  print('test statistic: %.10f' % result[0])
  print('p-value: %.10f' % result[1])
  print('critical values') for key, value in result[4].items():
    print('\t%s: %.10f' % (key, value))

我们的时间序列仍然不是稳定的

我们已经测试了原始数据集和经过对数变换的数据集,但是我们的时间序列仍然不是静态的。

我们还有其他选择吗?我们可以应用其他技术来转换数据,而不改变其属性:

  1. 差分将每个数据点减去序列中特定时间点的值,例如,总是减去下一个周期的值
  2. 分解 这种技术将分离出开始时提到的时间序列的每个组成部分(趋势、季节性、周期、不规则性)并提供残差

在我们的例子中,我们将尝试区分数据集。

区别

因为求差是减法,所以让我们保持简单,从求每个数据点与它之前的数据点的差开始,即求连续值的差。

# data: our dataset
# column_name: column to differencepd.DataFrame(data=np.diff(np.array(data[column_name])))
n_diff_dataset.columns = [column_name]

# dropping NAN values
n_diff_dataset.dropna(inplace=True)

再次运行 Dickey-Fuller 检验,我们看到我们仍然不能以 1%的显著性水平拒绝零假设。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

连续值差分后的 Dickey-Fuller 检验结果

p 值≤ 0.01。数据集是固定的🎉🎉🎉

让我们来看看平稳的时间序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二阶差分后的时间序列——终于平稳了!

n 阶差分和季节差分

差分后,我们的时间序列最终是平稳的。但是如果情况不是这样,我们可以继续对时间序列进行差分。

差异并不意味着你要减去 n 个前期的值,或者减去滞后值。这就是季节差异。

季节性差异

这个名字透露了一点。如果您对数据集应用季节差异,您将减去同一季节的前一个数据点。

在我们的示例中,我们处理的是月度数据,因此每年都对应于包含 12 个月的季节。因此,计算任何给定年份的一月份的季节性差异,意味着用当前值减去上一年一月份的值。

概括地说,它看起来像这样

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

季节性差异

在每月费用的例子中,一个季节是一年,所以 n=12

n 阶差分

这就是我们对数据集所做的,我们应用了一阶差分。这实际上意味着将时间序列中的每个数据点减去它之前的时间段中的数据点,如 lag=1。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一阶差分

但是如果我们继续保持差异呢?嗯,我们实际上只是不断区分不同之处🤯🤯🤯

在这种情况下,看数学实际上有帮助!让我们以二阶差分为例,这里我们差分两次。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二阶差分

通过查看该公式,现在更有意义,并且更容易看出n-阶差分并不意味着n 周期的滞后,而是实际执行差分运算 n

如果需要对数据集进行任意次数的微分,可以使用 numpy 中的 diff 方法并设置参数 n.

现在,回到预测📈

时间序列建模

有几种方法可以对时间序列进行建模,最常用的有:

简单移动平均线

使用这种方法,你是说预测是基于 n 个先前数据点的平均值。

指数平滑法

它以指数方式降低了先前观测的权重,因此越来越老的数据点对预测的影响越来越小。

ARIMA:自回归综合移动平均数

这是我们将要使用的方法。

ARIMA 模型可以分解成三个不同的部分,每个部分都有一个代表时间序列特征的参数。

1。自回归:AR§

自回归模型将随机过程解释为线性组合,因此输出变量线性依赖于其先前值和随机变量。

简而言之,这是一个基于先验值或滞后的模型。

如果你在预测一只股票的未来价格,AR 模型将会根据这只股票以前的价格做出预测。

如果我们看看数学,我们可以用参数 p 来描述 AR§模型:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

参数 p 表示自回归项的数量,即线性组合中的项数。

2。综合:I(d)

这个名字具有误导性,但这实际上与数据集被差分的次数有关,这由参数 d 的值表示。

3。移动平均线:MA (q)

与自回归模型相似,在移动平均模型中,输出变量被解释为线性,但这次是过去误差的平均值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

综上所述, ARIMA(p,d,q) 的公式如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是现在的问题是我们如何确定使用哪些参数?

ARIMA(p,d,q)的提货参数

我们已经知道需要对数据集进行多少次差分,所以参数 d 的值是 1。

但是我们还是要搞清楚 pq 的值。为此,我们将寻找自相关、AR§和移动平均、MA(q)曲线。

自相关(AR)曲线

这是通过测试时间序列中的数据点在不同滞后(即,在时间上的处)与其自身之间的相关性来完成的。

为此,我们将使用自相关函数图,简称 ACF 图。

利用 ACF 图,我们可以发现自相关(AR)曲线

  • ACF 数据点是正弦或指数衰减的
  • PACF 有一个尖峰信号,或几个连续的尖峰信号,然后突然切断

移动平均(MA)曲线

为了确定移动平均曲线,我们将使用 ACF 的子集,部分自相关函数图,通常称为 PACF 图。

PACF 表示不同滞后的自相关,但它移除了低阶相关,即 1 和滞后-1 之间的所有相关,因为它们之间的一切都将是内在相关的。

使用 ACF 图,我们可以发现自相关(AR)曲线,当我们看到 AR 曲线描述的反转时:

  • PACF 数据点是正弦或指数衰减的
  • ACF 有一个尖峰,或几个连续的尖峰,然后突然切断

最重要的是,图中的尖峰必须具有统计显著性,这意味着它们在置信区间的区域之外。这个置信区间要么用水平线表示,要么用面积图中的面积表示,这取决于您使用的软件。

让我们一起来看看 ACF 和 PACF 的情节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集的自相关和偏自相关图

滞后= 0 时的 ACF 和 PACF 通常为 1,因为每个数据点总是与其自身相关。

分析 ACF 图,我们可以看到任何稍微超出置信带的尖峰,因此我们假设 AR(2)。

至于图,我们可以在滞后=2 处看到第一个尖峰,因此我们将选择 MA(2)。

我们有自己的模型,ARIMA(2,1,2)🙌

为了适应模型,我决定将数据集分为训练和测试子集,使用最后 30%的观察值作为测试数据。

# split dataset between training and testing
cutoff_30pct = len(y) — int(len(y)*0.3)
y_train = diff_dataset[y_col][:cutoff_30pct]
y_test = diff_dataset[y_col][cutoff_30pct:] # building the model with the parameters we've discovered and fitting it to the training set
model = arima_model.ARIMA(y_train, order=(2,1,2)) 
arima_model_fit = model.fit(disp=-1)
print(arima_model_fit.summary())

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ARIMA 的结果(2,1,2)

AICBIC 值用于比较不同模型应用于同一数据集时的拟合质量。在我们的例子中,我们没有比较多个模型,所以我们不会过多关注这些值。

为了理解这个特定模型的质量,我们需要使用工具箱中的其他指标。

这个模型对我们的数据集有好处吗?

为了评估模型的质量,我们首先将预测值与测试子集中的实际值进行比较。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将实际值与预测值进行比较

从这里我们可以看到,绿色的预测值与橙色的实际值相比有些偏差。

根据整个数据集进行预测时,这一点变得更加清晰。

fig, ax = plt.subplots(figsize=(15,7))
model = arima_model.ARIMA(differenced_dataset, order=(2,1,2)) 
arima_model_fit = model_all.fit(disp=0)
# dynamic=False meaning in-sample lagged values are used for prediction
arima_all_fit.plot_predict(dynamic=False)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

针对整个数据集进行预测

好吧,我们知道我们的预测有点偏差,但是偏差有多大呢?

为了了解实际值和预测值之间的差异,我们可以使用平均绝对误差。

arima_mae = mean_absolute_error(y_test.values, forecast)
print('Mean absolute error %.2f' % arima_mae)

我们的 ARIMA(2,1,2)的平均绝对误差为 235.89,这意味着这些值平均相差 235.89 个单位。

这可能意味着:

  • 没有足够的数据来做出准确的预测
  • ARIMA 参数可以进一步调整
  • ARIMA 可能不是这个问题的最佳模型,一个想法是尝试简单的线性回归或指数平滑,并比较 AIC 和 BIC

结论

在我们一直在做的例子中,数据是随机生成的,并做了一些调整来创建一个趋势,所以这个结果可能会稍微有些偏差。本文的主要目标是通过不同的步骤来拟合 ARIMA 模型。

有了真实数据,你需要在你的问题的特定背景下观察平均绝对误差和残差。

这听起来可能有点模糊,但在数据科学中,上下文和您对该问题的了解非常重要。如果你预测一家价值数百万美元的公司的月收入,相差 235 美元可能并不重要。另一方面,如果你预测一个家庭的月预算是 235 美元,那就更令人担忧了。

希望你喜欢阅读这个例子,并愉快的预测📈

感谢阅读!

基于 Python ARIMA 的许可证使用时间序列预测

原文:https://towardsdatascience.com/time-series-forecasting-on-license-usage-using-arima-with-python-c7317d13c0ac?source=collection_archive---------37-----------------------

自动化许可证使用情况收集、ML 模型的网格搜索、预测未来使用情况、在达到阈值之前发出警报

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

克里斯·利维拉尼在 Unsplash 上的照片

假设你需要买卫生纸。你会怎么做?你不是每天都买,可能一个月一次,甚至三个月一次。你不希望你买的太少,很快就需要再买。不希望你买太多,堆很多马桶。那你会怎么做?

首先,你会检查可用的卫生纸数量,然后你会预测你一个月会用多少,并购买相应数量的卫生纸。听起来是不是很熟悉的过程?是的,它是。许多公司重复这一过程进行采购。电信公司需要定期购买的常见项目之一是许可证。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

摄盒装水更好Unsplash

背景:许可证购买

在移动网络中,有各种执行特定网络功能的网络元件。每个网络元件具有许多许可证控制的项目,以限制特定资源的功能和容量。例如,电信供应商将控制 LTE 附加用户的数量,即可以连接到移动网络的手机数量。如果运营商想要同时服务更多的用户,他们必须从他们的供应商那里购买相应的许可证。就像卫生纸,用完了就需要重新买。然而,在移动运营商内部,标准的购买程序可能很漫长,需要花费几个月的时间。因此,作为一个工程部门,当我们从供应商那里购买许可证时,我们需要精确地预测几个月后许可证的使用情况。

以前的工作流程

在过去,首先,我们手动收集许可证使用记录。设备供应商通常提供一个 GUI,在其中我们可以根据他们自己的人机语言(MML)语法键入命令,以在屏幕上显示当前的许可证使用情况。然后我们把信息复制下来,以 Excel 的形式保存下来。这是一项令人讨厌的工作,有时负责人员可能会忘记显示或 Excel 文件损坏。我们也不能经常这样做,因为太耗费人力了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

项目前的手动程序

幸运的是,设备供应商还允许我们 telnet 到一台叫做网络管理系统(NMS)的机器上。我们可以键入特殊的命令来与它下面的不同网络元素进行交互。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示许可证使用情况的 MML 命令

新的自动化工作流程

为了自动化这个过程,我们使用 python 库包 telnetlib 来收集许可证使用情况。telnetlib模块提供了实现 Telnet 协议的Telnet类。使用tn = Telnet(NMS_IP, NMS_Port)建立连接后,我们可以使用tn.write()功能发送命令。我定义了一个发送命令的函数,如下所示。

发送命令功能

获取您需要的许可证数据的流程是,首先,您需要登录到 NMS,然后您需要注册您想要检查的网元,如下所示:

登录并注册网元

当我们键入显示许可证使用情况所需的命令时,系统会返回一个文本表格,我们将每行分成两个空格。然后,我们将每一行作为一个元组添加到一个名为 data 的列表中。

发送命令以获取许可证使用数据

然后我们将输出结果解码成有用的数据帧。我们将数据库表设计为遍历的,因为如果网络元素已经升级,可能会添加或删除许可证项目。每次修改表模式是不可行的:首先,每周在不同的网络元件上有几次升级,其次,我们不能知道先前的升级添加或移除了哪些许可项目。我们最终确定了以下栏目:

result_time :采集时间; object _ name*:网元的名称;* 资源名称 :许可项目名称; total _ resource*:许可证容量,即该许可证允许的最大数量;* used _ resource*:该时刻许可项的占用量;* 用法 :简单用 _ 资源除以总 _ 资源。

这种结构能够在不改变数据库模式的情况下添加或删除任意许可项。

(注:这是一项繁琐的工作,因为每个网络元素都有其命令和显示格式。我们需要一个一个定制。)

最后,我们收集了所有许可证项目!总共超过 60 个网络元素中的 1742 个不同项目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

许可证使用自动化和人工智能预测的整个工作流程

预测许可证使用情况

有了数据后,我们现在可以使用 ARIMA 模型进行预测。ARIMA(自回归综合移动平均)是一种用于分析和预测时间序列数据的机器学习模型。这符合我们预测依赖于时间的许可证使用的目的。更多细节可以在这篇文章中找到:如何用 Python 创建 ARIMA 时间序列预测模型作者杰森·布朗利

[## 如何用 Python 创建用于时间序列预测的 ARIMA 模型

一个流行的和广泛使用的时间序列预测的统计方法是 ARIMA 模型。ARIMA 是…的首字母缩写

machinelearningmastery.com](https://machinelearningmastery.com/arima-for-time-series-forecasting-with-python/)

我们使用 StatsModels 执行网格搜索,从总共 63 个组合中找到(p,d,q)的最佳参数集。

p = [0,1,2,4,6,8,10]
d = [0,1,2]
q = [0,1,2]

我们对 60 个网络元素和 1742 个许可证进行了循环,并运行了近一周的网格搜索!

用于网格搜索的代码

之后,我们有了每个许可证的最佳参数,并每天进行预测。过去,我们只能选择一些重要的许可证项目,并且只能预测每个季度的使用情况,这令人难以置信。但是现在,我们可以每天预测我们的许可证使用情况,并在许可证使用出现危险时向我们发出警报。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

网络容量许可证使用的仪表板

如果许可证使用率在 1 个月内达到 80%,我们会收到红色警报。必须立即采取行动。否则,如果许可证使用率在 3 个月内达到 80 %,它将发出橙色警报,最后,如果使用率在 6 个月内达到 80%,我们将收到黄色警报。

结论

这个项目极大地减少了我们收集许可证使用数据的工作量,我们建立了一个提醒系统,提醒我们在许可证用完之前购买它。

要了解这个项目的更多信息,请点击查看我的 Github 链接

时间序列预测:使用 ARIMA 模型预测股票价格

原文:https://towardsdatascience.com/time-series-forecasting-predicting-stock-prices-using-an-arima-model-2e3b3080bd70?source=collection_archive---------0-----------------------

在这篇文章中,我将向你展示如何使用预测 ARIMA 模型来预测特斯拉的股票价格

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ARIMA 模型在测试集上的性能

1.介绍

1.1.时间序列和预测模型

时间序列预测模型是能够根据以前的 观测值****来预测** 未来值的模型。时间序列预测广泛用于非平稳数据非平稳数据被称为其统计属性(如平均值和标准偏差)不随时间保持不变,而是随时间变化的数据。**

这些非平稳输入数据(用作这些模型的输入)通常被称为时间序列。时间序列的一些例子包括随时间变化的温度值、随时间变化的股票价格、随时间变化的房屋价格等。因此,输入是一个信号**(时间序列),它是由在时间上连续进行的观察所定义的**。****

时间序列是按时间顺序进行的一系列观察。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

时间序列的一个例子。作者用 Python 创作的情节。

****观察:时序数据记录在离散时间刻度时间刻度上。

免责声明:已经有人尝试使用时间序列分析算法来预测股票价格,尽管它们仍然不能用于在真实市场中下注。这只是一篇教程文章,并不打算以任何方式“指导”人们购买股票。

2.自回归综合移动平均(ARIMA)模型

用于时间序列预测的一种著名且广泛使用的预测方法是自回归综合移动平均(ARIMA)** 模型。 ARIMA 模型能够捕捉时间序列数据中一套不同的标准时间结构。**

术语

让我们来分解这些术语:

  • AR:<>表示模型使用一个观测值和一些预定义数量的滞后观测值(也称为“时间滞后”或“滞后”)之间的依赖关系。
  • I: < Integrated > 是指该模型采用原始观测值的差分(例如,它从前一时间步的一个观测值中减去一个观测值),以使时间序列平稳。马😗***
  • **MA:<>表示模型利用了残差与观测值之间的关系。

模型参数

标准 ARIMA 模型期望 3 个自变量作为输入参数,即 p、d、q

  • p 是滞后观测值的**个数。**
  • d 是差分的**度。**
  • q 是移动平均线窗口的**大小/宽度。**

如果你想在交互式路线图和活跃的学习社区的支持下自学数据科学,看看这个资源:https://aigents.co/learn

3.获取股票价格历史数据

感谢雅虎财经 T21,我们可以免费得到数据。使用以下链接获取特斯拉**:https://finance.yahoo.com/quote/TSLA/history?的股价历史周期 1=1436486400 &周期 2=1594339200 &间隔=1d &过滤器=历史&频率=1d**

您应该看到以下内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击下载并保存。csv** 文件本地保存在您的计算机上。**

数据是从 2015 到现在( 2020 )!

4.Python 工作示例

所需模块:Numpy,Pandas, Statsmodels ,Scikit-Learn

4.1。加载&检查数据

我们的进口**😗*

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
from pandas.plotting import lag_plot
from pandas import datetime
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error

现在让我们加载特斯拉股票历史数据**😗*

df = pd.read_csv("TSLA.csv")
df.head(5)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 我们的目标变量将是关闭值。

在建立 ARIMA 模型之前,让我们看看我们的数据中是否有一些交叉相关。

plt.figure()
lag_plot(df['Open'], lag=3)
plt.title('TESLA Stock - Autocorrelation plot with lag = 3')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特斯拉股票-滞后= 3 的自相关图

我们现在可以确认 ARIMA 将是一个适用于这种类型数据的好模型(数据中存在自相关)。

最后,让我们用来描绘股价随时间的演变。****

plt.plot(df["Date"], df["Close"])
plt.xticks(np.arange(0,1259, 200), df['Date'][0:1259:200])
plt.title("TESLA stock price over time")
plt.xlabel("time")
plt.ylabel("price")
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.2。建立预测 ARIMA 模型

接下来,让我们的数据分成一个训练** (70 %)和测试 (30%)的集合。对于本教程,我们选择以下 ARIMA 参数:p=4,d=1,q=0。**

train_data, test_data = df[0:int(len(df)*0.7)], df[int(len(df)*0.7):]training_data = train_data['Close'].values
test_data = test_data['Close'].valueshistory = [x for x **in** training_data]
model_predictions = []
N_test_observations = len(test_data)for time_pointin range(N_test_observations):
    model = ARIMA(history, order=(4,1,0))
    model_fit = model.fit(disp=0)
    output = model_fit.forecast()
    yhat = output[0]
    model_predictions.append(yhat)
    true_test_value = test_data[time_point]
    history.append(true_test_value)MSE_error = mean_squared_error(test_data, model_predictions)
print('Testing Mean Squared Error is {}'.format(MSE_error))

守则摘要

  • 我们将训练数据集分为训练集和测试集,并使用训练集来拟合模型,并为测试集上的每个元素生成预测。****
  • 考虑到差分和 AR 模型对先前时间步观测值的依赖性,需要一个滚动预测程序。为此,我们在收到每个新的观察结果后重新创建 ARIMA 模型。
  • 最后,我们在一个名为历史的列表中手动跟踪所有的观察值,该列表以训练数据为种子,并且在每次迭代中向其追加新的观察值。

检验的均方误差为 7。38860 . 68686886861

测试集的 MSE 相当大,表明精确预测是一个困难的问题。但是,这是所有测试集预测的平均平方值。让我们可视化预测,以更好地理解模型的性能。

test_set_range = df[int(len(df)*0.7):].indexplt.plot(test_set_range, model_predictions, color='blue', marker='o', linestyle='dashed',label='Predicted Price')plt.plot(test_set_range, test_data, color='red', label='Actual Price')plt.title('TESLA Prices Prediction')
plt.xlabel('Date')
plt.ylabel('Prices')
plt.xticks(np.arange(881,1259,50), df.Date[881:1259:50])
plt.legend()
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ARIMA 模型在测试集上的性能

没那么糟吧?

我们的 ARIMA 模型产生了可观的结果。就训练/拟合时间和复杂性而言,该模型提供了良好的预测准确性,并且与其他替代方案相比相对较快。

那都是乡亲们!希望你喜欢这篇文章!

敬请关注并支持这一努力

如果你喜欢这篇文章,并且觉得它有用,那么关注我就可以看到我所有的新帖子。

有问题吗?把它们作为评论贴出来,我会尽快回复。

您可能也会喜欢我以前的文章:

LSTM 时间序列预测:利用 LSTM 模型预测股票价格

** [## LSTM 时间序列预测:使用 LSTM 模型预测股票价格

在这篇文章中,我将向你展示如何使用预测 LSTM 模型来预测股票价格

towardsdatascience.com](/lstm-time-series-forecasting-predicting-stock-prices-using-an-lstm-model-6223e9644a2f)

时间序列预测:利用脸书先知模型预测股票价格

[## 时间序列预测:用脸书的先知模型预测股票价格

使用可从《先知脸书》公开获得的预测模型预测股票价格

towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5)

参考

[1]https://en . Wikipedia . org/wiki/auto regressive _ integrated _ moving _ average

其他员额

[## 最佳免费数据科学资源:免费书籍和在线课程

最有用的免费书籍和在线课程,适合想了解更多数据科学知识的人。

medium.com](https://medium.com/@seralouk/the-best-free-data-science-resources-free-books-online-courses-9c4a2df194e5) [## 用新冠肺炎假设的例子解释 ROC 曲线:二分类和多分类…

在这篇文章中,我清楚地解释了什么是 ROC 曲线以及如何阅读它。我用一个新冠肺炎的例子来说明我的观点,我…

towardsdatascience.com](/roc-curve-explained-using-a-covid-19-hypothetical-example-binary-multi-class-classification-bab188ea869c) [## 支持向量机(SVM)解释清楚:分类问题的 python 教程…

在这篇文章中,我解释了支持向量机的核心,为什么以及如何使用它们。此外,我还展示了如何绘制支持…

towardsdatascience.com](/support-vector-machines-svm-clearly-explained-a-python-tutorial-for-classification-problems-29c539f3ad8) [## PCA 清楚地解释了——如何、何时、为什么使用它以及特性的重要性:Python 指南

在这篇文章中,我解释了什么是 PCA,何时以及为什么使用它,以及如何使用 scikit-learn 在 Python 中实现它。还有…

towardsdatascience.com](/pca-clearly-explained-how-when-why-to-use-it-and-feature-importance-a-guide-in-python-7c274582c37e) [## 关于 Python 中的最小-最大规范化,您需要知道的一切

在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它

towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79) [## Scikit-Learn 的标准定标器如何工作

在这篇文章中,我将解释为什么以及如何使用 scikit-learn 应用标准化

towardsdatascience.com](/how-and-why-to-standardize-your-data-996926c2c832)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值