浅谈人工智能里的时间序列是什么?

694 阅读11分钟

提到AI,大家接触最多的是图片识别、文字聊天这些。其实还有一类领域,大众不怎么知道,那就是时间序列。

一、时间序列

时间序列简称“时序”,顾名思义,就是依照时间顺序列举数据。它和时间有比较强的依赖关系。比如气温,春夏秋冬一年四季,随着时间的推移它具有周期性。夏天气温会越来越高,在某个时段它有稳定的趋势性。有时候,某个夏天会来个台风,气温会骤降,它也具有随机扰动的不确定性。

对于这类时间序列的研究,除了天气预报,还广泛应用在各行各业。比如金融领域的预测,股票的价格会随着时间波动,它也具有周期性、随机扰动性。比如医疗领域的异常判断,心电图的波形数据会随着时间而变化,如果出现不对应的情况,可以判断是否异常。比如工业领域,机器的振动会随着时间而变化,可以根据这个判断生产是否正常。甚至水电公司还会根据高龄住户哪天突然不用水或者一直不关水,推断出是否发生意外情况。这都是时间序列的典型应用。

不知不觉,我向你渗透了时序的特点:时间依赖性、趋势性、周期性、随机扰动性,分析任务:预测、异常检测、分类和聚类。以及应用领域,比如销售预测、欺诈识别、行为分类等。看,知识就是这么悄无声息地传递了。

二、时序的预测

下面我们实践一下,看看如何用简单的代码实现一些时序类的项目。另外,也探索一下时序领域都有哪些难点。

我这里有个图,是这样的。

其实它的本质是一组数据,内容是每隔一个小时采集一次的压力值,只是用图的形式展示了出来。

那么现在我问你,随着时间推移,后面的数据可能会是怎样的?

我们用眼看,以我们的认知,感觉它是有趋势和规律的。它是一个周期性的波动。但是,如何让程序识别出这个规律并做出预测呢?

本文属于浅层科普,就直接用框架了。咱们选用百度的PaddleX框架,这是一个低代码平台,支持用统一的命令实现不同的功能。

不管是图像分类还是时序预测,都可以用PaddleX完成,而且代码都一样。

首先,你需要准备一个python 3.8(3.8~3.10都可以)的环境,然后执行以下命令:

# 安装 paddlepaddle
python -m pip install paddlepaddle==3.0.0b2 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/
# 安装 paddlex
pip install https://paddle-model-ecology.bj.bcebos.com/paddlex/whl/paddlex-3.0.0b2-py3-none-any.whl

然后把你的数据拿过来,交给PaddleX,让它来研究并预测。

from paddlex import create_pipeline
# 构建一个时序预测的管道
pipeline = create_pipeline(pipeline="ts_fc")
# 加载数据,让其预测
output = pipeline.predict("test.csv")
for res in output:
    res.print() # 打印预测的结构化输出
    res.save_to_csv("./output/") # 保存csv格式结果

代码就是这点,如果你愿意用命令行的话,更简单,一句就够了:

paddlex --pipeline ts_fc --input test.csv  --save_path ./output

ts_fc代表是时序预测类型,test.csv是输入的数据文件,./output是输出路径。

运行一下。此时我们会从控制台看到预测的结果,并在output文件夹下存了一份csv格式的结果文件。

Using official …… downloaded and saved in .paddlex\official_models.
Connecting to https://paddle-model……paddle3.0b2/DLinear_infer.tar ...
Downloading DLinear_infer.tar ...
[=========================] 100.00%
Extracting DLinear_infer.tar
[=========================] 100.00%               
2024-11-22 00:00:00  9.125996
2024-11-22 01:00:00  8.423722
...
2024-11-25 23:00:00  8.621673
[96 rows x 1 columns]
The result has been saved in output\test.csv.

将这些数据绘制出来,结果是这样的。

这说明,算法已经识别出了这个周期性的波动,并正确预测出了未来的数据。

三、时序异常检测

如果是异常数据检测,该怎么实现呢?自己写肯定很复杂,用工具很方便。还是那几句代码,只不过换一个参数。

from paddlex import create_pipeline
# 构建一个时序预测的管道
pipeline = create_pipeline(pipeline="ts_ad")
# 加载数据,让其预测
output = pipeline.predict("test.csv")
for res in output:
    res.print() # 打印预测的结构化输出
    res.save_to_csv("./output/") # 保存csv格式结果

ts_ad代表是时序异常检测的类型。具体有哪些类似,不是我说的,人家是PaddleX的作者指定的。

产线名称对应参数
通用OCROCR
…………
时序预测ts_fc
时序异常检测ts_ad
时序分类ts_cls

将数据绘制出来,结果是这样的。

从图中我们可以看出,标记红色的那几段,确实有些异常。温度有起伏可以理解,但是很少有骤变的情况。这说明算法对异常的判断还是可以的。

常规习惯里的不正常的行为,就是异常。比如在金融风控中,你这十几年网购都是三十、五十的花钱,突然有一天要支付五万,这很可能是异常情况,平台怎么也得拦一下,加一重验证。

四、时序分类

还有一个时序分类的例子。常见的比如说你身上有一个传感器,它采集你的心率或者加速度。它可以结合你的时序数据,判断你在干什么。

代码或者命令都是一样的,只是参数不同而已。时序分类的参数是ts_cls

paddlex --pipeline ts_fc --input test.csv  --save_path ./output

我们可以分类出这个时序数据是立正。

这个时序数据是跑步。

这个时序数据是打羽毛球。

按照常规理解,猛地动一下然后保持静止就是立正,规律性地一窜一窜就是跑步,而打羽毛球就是一窜一窜而后突然发力。

其实时序还有一项应用,PaddleX没有列出,很冷门,那就是降维,英文叫Dimensionality Reduction。它研究简化时间序列数据,提取重要特征。

比如你有一组成功人士的时序数据,记录了他从小到大的方方面面。那么,哪些数据是它成功的关键因素呢?是每天早上六点起床,还是他喜欢吃洋葱,或者是每个周五的时候出门喜欢先迈左脚。通过时序降维,只保留最重要的特征。

刚刚提到了一个词,叫“特征”。我们刚才进行时序处理的时候,传给模型的每一条数据都包含特征数据,比如设备的温度、传感器检测到的心率。

有的只有一个特征,有的存在多个特征。下面,我们就来分析下数据的特征。

五、特征工程

特征的选取和构建叫特征工程。好的特征工程,可以让你的时序分析模型更准确、更有价值。

比如说员工的时序信息,有的员工下班走的很晚。很多人都走的晚,这分析不出来啥。但是如果加入一个部门信息作为特征,就有价值了。为啥他的部门就他走的晚?是他们部门把活都压给他了,还是他一直没有进入状态,或者利用公司的设备干自己的事情?嗯,这是一个异常信号!

就拿最常见的天气预测来说,我们可以用温度、湿度、气压、风向等数据,来预测天气。

幸好,有个外国人专门研究天气。他从2003年开始,每隔10分钟就记录一次当地的天气。他将这些数据提供给公众做研究。其中2009年至2016年之间的420551条数据,经常被深度学习拿来用做教学。这次,我们也用它作为示例。

数据的构成是这样的。

字段单位和含义
Date Time日期和时间(时间戳)
p (mbar)气压(毫巴)
T (degC)气温(摄氏度)
Tpot (K)位温(开尔文)
Tdew (degC)露点温度(摄氏度)
rh (%)相对湿度(百分比)
VPmax (mbar)最大水汽压(毫巴)
VPact (mbar)实际水汽压(毫巴)
VPdef (mbar)水汽压亏缺(毫巴)
sh (g/kg)比湿(克每千克)
H2OC (mmol/mol)水汽浓度(毫摩尔每摩尔)
rho (g/m³)空气密度(克每立方米)
wv (m/s)风速(米每秒)
max. wv (m/s)最大风速(米每秒)
wd (deg)风向(度,表示风的方向)

我们绘制一下这8年间的它的温度、气压和空气密度的曲线,结果是这样的。

可以看出,总体上很规律。每年高了低,低了高,总体围绕着平均值浮动。这说明,这几年的天气,都是这样的。

但是,我们选取2009的1月份前20天的数据,又发现每天高低起伏,毫无规律可言。

这像极了我们的人生,从生到死都一样,但每人每天的活法又不一样。

这确实是真实的数据。好像数据很全了,也很正规,把它交给算法去分析,然后预测,可以吗?

新手可以,老手不行。新手的产物叫作品,是学习用的。老手的产物叫产品,是要实际应用的。

前面我们说了,时序数据是周期性、趋势化的。我们的特征值输入,最终会对周期性结果有影响。

如果时间是时间戳,作为特征参数就不合格。不仅没有用,可能还起反作用。比如温度是每年循环的,-15℃到15℃, 15℃到-15℃。但是时间戳是自增长的,从1增长到10000,这会导致输入和输出形成不了关系。

这种情况怎么办呢?如何做到一个值不断变大,另一个值还能循环往复呢?正余弦啊!

看,有意思吧。你就是涨到无穷大,数值也是限定在一定范围内。

另外,我们看有关风的特征。

wv 风速max_wv 最大风速wd 风向
1.031.75152.3
0.721.5136.1
0.190.63171.6
0.340.5198
0.320.63214.3
0.210.63192.7

发现什么没有?风向的单位是角度。角度不是一个很好的模型输入,因为360°和0°是差不多的,但他们从数值上却是一个最大、一个最小。输入值为最大和最小,结果却是一样,这也会让模型迷惑不已。

而且,如果无风状态下,角度是没有意义的。你想啊,都没有刮风,哪有风向啊。因此,将风这个特征,变成向量是很合适的。

wd_rad = wd * np.pi / 180

Wx = wv*np.cos(wd_rad)
Wy = wv*np.sin(wd_rad)
maxWx = max_wv*np.cos(wd_rad)
maxWy = max_wv*np.sin(wd_rad)

通过上一步转换,就将风速、最大风速、风向这三个独立列转为了带有方向的向量:往哪个方向吹的多少级风!

另外还有一个重要的特征处理,那就是归一化。

归一化,就是把数据变成0到1之间的数。上面的天气数据,不管是气温35°C,还是风向273度,这都是记录者的原始数据。但是,这并不利于模型训练。举个例子,气压值能从100变到1000,但是相对湿度(百分比为单位)那里最大变化也超不过1。这就好比富人拿出100万不算什么,但是穷人掏出1000也很难。模型又是对数据敏感的,肯定就把数值小的忽略了。因此,要做一个归一化,将大家打成同一个起跑线。

这就是为什么,你学习算法到训练步骤时,训练数据就变成了奇奇怪怪地看不懂的小数了。而归一化的策略,也有很多种,具体还需要看具体情况。

因此,不管是整理特征工程,还是归一化数据,都需要算法工程师对输入数据有深入的理解。这也是一个难点。

当然,现在慢慢地有了大模型,它也会帮忙做一些工作。甚至有些算法可以做到自监督学习或者无监督学习。

个人认为,时间序列的自主学习,虽然不依赖人工标注,然而效率却不一定高。首先评估就是一个很麻烦的事情。你怎么判断它学会了,又怎么判断它没学会呢?让用户用着看呗,看得过程中,再反馈。

好了,以上就是对时间序列的简单介绍。我没有资格教任何人,咱就当是聊聊天。

我是TF男孩,一个爱闲聊的小孩。