使用 Python 进行 AI – 分析时间序列数据

预测给定输入序列中的下一个序列是机器学习中的另一个重要概念。本章将为您详细解释如何分析时间序列数据。

简介

时间序列数据是指一系列特定时间间隔内的数据。如果我们想在机器学习中建立序列预测,那么我们必须处理顺序数据和时间。序列数据是顺序数据的抽象。数据排序是顺序数据的一个重要特征。

序列分析或时间序列分析的基本概念

序列分析或时间序列分析是根据先前观察到的序列预测给定输入序列中的下一个序列。预测可以是接下来可能出现的任何事物:符号、数字、第二天的天气、语音中的下一个术语等。序列分析在股票市场分析、天气预报和产品推荐等应用中非常方便。

示例

请考虑以下示例以了解序列预测。这里 A、B、C、D 是给定值,您必须使用序列预测模型预测值 E

sequence prediction model

安装有用的软件包

对于使用 Python 进行时间序列数据分析,我们需要安装以下软件包 −

Pandas

Pandas 是一个开源的 BSD 许可库,它为 Python 提供了高性能、易于使用的数据结构和数据分析工具。您可以借助以下命令安装 Pandas −

pip install pandas

如果您正在使用 Anaconda 并希望使用 conda 包管理器进行安装,则可以使用以下命令 −

conda install -c anaconda pandas

hmmlearn

它是一个开源 BSD 许可库,包含用于在 Python 中学习隐马尔可夫模型 (HMM) 的简单算法和模型。您可以使用以下命令安装它 −

pip install hmmlearn

如果您使用的是 Anaconda 并希望使用 conda 包管理器进行安装,那么您可以使用以下命令 −

conda install -c omnia hmmlearn

PyStruct

它是一个结构化学习和预测库。在 PyStruct 中实现的学习算法有条件随机场 (CRF)、最大边际马尔可夫随机网络 (M3N) 或结构支持向量机等名称。您可以使用以下命令安装它−

pip install pystruct

CVXOPT

它用于基于 Python 编程语言的凸优化。它也是一个免费软件包。您可以在以下命令的帮助下安装它 −

pip install cvxopt

如果您正在使用 Anaconda 并希望使用 conda 包管理器进行安装,那么您可以使用以下命令 −

conda install -c anaconda cvdoxt

Pandas:处理、切片和提取时间序列数据的统计数据

如果您必须处理时间序列数据,Pandas 是一个非常有用的工具。借助 Pandas,您可以执行以下操作 −

  • 使用 pd.date_range 包创建日期范围

  • 使用 pd.Series 包使用日期索引 pandas

  • 使用 ts.resample 包执行重新采样

  • 更改频率

示例

以下示例向您展示如何使用 Pandas 处理和切分时间序列数据。请注意,这里我们使用的是月度北极涛动数据,可以从 monthly.ao.index.b50.current.ascii 下载,并可转换为文本格式供我们使用。

处理时间序列数据

要处理时间序列数据,您必须执行以下步骤 −

第一步涉及导入以下包 −

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

接下来,定义一个函数,它将从输入文件中读取数据,如下所示在下面给出的代码中−

def read_data(input_file):
   input_data = np.loadtxt(input_file, delimiter = None)

现在,将此数据转换为时间序列。为此,创建时间序列的日期范围。在此示例中,我们将一个月作为数据频率。我们的文件包含从 1950 年 1 月开始的数据。

dates = pd.date_range('1950-01', periods = input_data.shape[0], freq = 'M')

在此步骤中,我们在 Pandas Series 的帮助下创建时间序列数据,如下所示 −

output = pd.Series(input_data[:, index], index = dates)
return output

if __name__=='__main__':

输入输入文件的路径,如下所示 −

input_file = "/Users/admin/AO.txt"

现在,将列转换为时间序列格式,如下所示 −

timeseries = read_data(input_file)

最后,使用所示命令绘制并可视化数据 −

plt.figure()
timeseries.plot()
plt.show()

您将观察到以下图像中所示的图 −

测试系列

绘图

切片时间序列数据

切片涉及仅检索时间序列数据的某些部分。作为示例的一部分,我们仅从 1980 年到 1990 年对数据进行切片。观察执行此任务的以下代码 −

timeseries['1980':'1990'].plot()
   <matplotlib.axes._subplots.AxesSubplot at 0xa0e4b00>

plt.show()

当您运行对时间序列数据进行切片的代码时,您可以观察到以下图表,如下图所示 −

切片时间序列数据

从时间序列数据中提取统计数据

当您需要得出一些重要结论时,您必须从给定数据中提取一些统计数据。平均值、方差、相关性、最大值和最小值就是其中一些统计数据。如果要从给定的时间序列数据中提取此类统计数据,可以使用以下代码 −

平均值

您可以使用 mean() 函数来查找平均值,如下所示 −

timeseries.mean()

然后,您将观察到讨论的示例的输出是 −

-0.11143128165238671

最大值

您可以使用 max() 函数来查找最大值,如下所示 −

timeseries.max()

然后,您将观察到的所讨论示例的输出是 −

3.49529999999999999

最小值

您可以使用 min() 函数查找最小值,如下所示 −

timeseries.min()

然后,您将观察到的所讨论示例的输出是 −

-4.2656999999999998

一次获取所有内容

如果您想一次计算所有统计数据,可以使用 describe() 函数,如下所示 −

timeseries.describe()

那么您将观察到的讨论示例的输出是 −

count   817.000000
mean     -0.111431
std       1.003151
min      -4.265700
25%      -0.649430
50%      -0.042744
75%       0.475720
max       3.495300
dtype: float64

重新采样

您可以将数据重新采样到不同的时间频率。执行重新采样的两个参数是 −

  • 时间段
  • 方法

使用 mean() 重新采样

您可以使用以下代码通过 mean() 方法重新采样数据,这是默认方法 −

timeseries_mm = timeseries.resample("A").mean()
timeseries_mm.plot(style = 'g--')
plt.show()

然后,您可以观察到以下图表作为使用 mean() − 重新采样的输出

使用均值方法重新采样

使用 median() 重新采样

您可以使用以下代码使用 median() 方法 −

重新采样数据
timeseries_mm = timeseries.resample("A").median()
timeseries_mm.plot()
plt.show()

然后,您可以观察到以下图表作为使用 median() 重新采样的输出 −

使用中位数方法重新采样

滚动平均值

您可以使用以下代码计算滚动(移动)平均值 −

timeseries.rolling(window = 12, center = False).mean().plot(style = '-g')
plt.show()

然后,您可以观察下图作为滚动(移动)平均值 − 的输出

滚动平均值

通过隐马尔可夫模型分析序列数据(HMM)

HMM 是一种统计模型,广泛用于具有连续性和可扩展性的数据,例如时间序列股票市场分析、健康检查和语音识别。本节详细介绍了使用隐马尔可夫模型 (HMM) 分析序列数据。

隐马尔可夫模型 (HMM)

HMM 是一种随机模型,它建立在马尔可夫链的概念之上,该概念基于未来统计数据的概率仅取决于当前过程状态而不是之前的任何状态的假设。例如,当抛硬币时,我们不能说第五次抛出的结果将是正面。这是因为硬币没有任何记忆,下一个结果不依赖于前一个结果。

从数学上讲,HMM 由以下变量组成 −

状态 (S)

它是 HMM 中存在的一组隐藏或潜在状态。它用 S 表示。

输出符号 (O)

它是 HMM 中存在的一组可能的输出符号。它用 O 表示。

状态转换概率矩阵 (A)

它是从一个状态转换到其他每个状态的概率。它用 A 表示。

观察发射概率矩阵 (B)

它是在特定状态下发射/观察符号的概率。它用 B 表示。

先验概率矩阵 (Π)

它是从系统的各种状态开始特定状态的概率。它用 Π 表示。

因此,HMM 可以定义为 𝝀 = (S,O,A,B,𝝅)

其中,

  • S = {s1,s2,…,sN> 是一组 N 个可能的状态,
  • O = {o1,o2,…,oM> 是一组 M 个可能的观察符号,
  • A 是 N𝒙N 状态转换概率矩阵 (TPM),
  • B 是 N𝒙M 观察或发射概率矩阵 (EPM),
  • π 是N 维初始状态概率分布向量。

示例:股票市场数据分析

在此示例中,我们将逐步分析股票市场数据,以了解 HMM 如何处理顺序或时间序列数据。请注意,我们正在使用 Python 实现此示例。

导入必要的包,如下所示 −

import datetime
import warnings

现在,使用 matpotlib.finance 包中的股票市场数据,如下所示−

import numpy as np
from matplotlib import cm, pyplot as plt
from matplotlib.dates import YearLocator, MonthLocator
try:
   from matplotlib.finance import quotes_historical_yahoo_och1
except ImportError:
   from matplotlib.finance import (
      quotes_historical_yahoo as quotes_historical_yahoo_och1)

from hmmlearn.hmm import GaussianHMM

从开始日期和结束日期加载数据,即两个特定日期之间,如下所示 −

start_date = datetime.date(1995, 10, 10)
end_date = datetime.date(2015, 4, 25)
quotes = quotes_historical_yahoo_och1('INTC', start_date, end_date)

在此步骤中,我们将提取每天的收盘报价。为此,请使用以下命令 −

closing_quotes = np.array([quote[2] for quote in quotes])

现在,我们将提取每天交易的股票量。为此,请使用以下命令 −

volumes = np.array([quote[5] for quote in quotes])[1:]

在这里,使用下面显示的代码 − 计算收盘价的百分比差异

diff_percentages = 100.0 * np.diff(closing_quotes) / closing_quotes[:-]
dates = np.array([quote[0] for quote in quotes], dtype = np.int)[1:]
training_data = np.column_stack([diff_percentages, volumes])

在此步骤中,创建并训练高斯 HMM。为此,请使用以下代码 −

hmm = GaussianHMM(n_components = 7, covariance_type = 'diag', n_iter = 1000)
with warnings.catch_warnings():
   warnings.simplefilter('ignore')
   hmm.fit(training_data)

现在,使用 HMM 模型生成数据,使用显示的命令 −

num_samples = 300
samples, _ = hmm.sample(num_samples)

最后,在此步骤中,我们绘制并可视化差异百分比和交易股票数量,以图形形式输出。

使用以下代码绘制并可视化差异百分比 −

plt.figure()
plt.title('差异百分比')
plt.plot(np.arange(num_samples), samples[:, 0], c = 'black')

使用以下代码绘制并可视化交易股票数量 −

plt.figure()
plt.title('Volume of shares')
plt.plot(np.arange(num_samples), samples[:, 1], c = 'black')
plt.ylim(ymin = 0)
plt.show()