binder

摘要: 本 notebook 介绍了 sktime 的内存数据容器和数据集,以及相关的内存格式验证、转换和数据集加载等功能。

设置说明: 在 binder 上,此 notebook 应可直接运行。

为了按预期运行此 notebook,请确保您的 Python 环境中安装了 sktime 及其基本依赖项。

要运行 sktime 的本地开发版本,请取消注释并运行以下代码,或 pip install -e sktime main 分支的本地克隆。

[1]:
# from os import sys
# sys.path.append("..")

内存数据表示和数据加载#

sktime 为许多时间序列相关的学习任务提供了模块。

这些模块使用 sktime 特定的内存(即 Python 工作空间)表示来处理时间序列及相关对象,最重要的是单个时间序列和时间序列面板。 sktime 的内存表示依赖于 pandasnumpy,并对 pandasnumpy 对象附加了一些约定。

sktime 的用户应了解这些表示形式,因为将数据呈现为 sktime 兼容的表示形式通常是使用任何 sktime 模块的第一步。

本 notebook 介绍了 sktime 中使用的数据类型、相关的转换器和有效性检查器等功能,以及常见的数据加载和转换工作流程。

第 1 节 介绍了 sktime 中使用的内存数据容器格式,并提供示例。

第 2 节 介绍了内存数据容器的有效性检查器和转换功能。

第 3 节 介绍了加载预定义基准数据集的常见工作流程。

第 4 节 展示了从表格 csv 格式加载数据的常见工作流程。

第 1 节:内存数据容器#

本节提供了 sktime 中用于时间序列及相关对象的数据容器参考。

概念上,sktime 区分

  • 数据容器的 数据科学抽象数据类型(简称:scitype),由所表示数据的关系和统计特性以及对其进行的常见操作定义——例如,抽象的“时间序列”或抽象的“时间序列面板”,而不指定具体的 Python 机器实现

  • 数据容器的 机器实现类型(简称:mtype),它为已定义的 scitype 指定 Python 类型以及 Python 内存对象的结构和值约定。例如,在 sktime 中,一个具体的(数学)时间序列由一个具体的 pandas.DataFrame 表示,该 pandas.DataFrame 必须遵守某些约定。形式上,这些约定构成一个特定的 mtype,即表示(抽象的)“时间序列”scitype 的一种方式。

在 sktime 中,同一个 scitype 可以由多个 mtype 实现。例如,sktime 允许用户将时间序列指定为 pandas.DataFramepandas.Seriesnumpy.ndarray。这些是不同的 mtype,它们是同一个 scitype“时间序列”的可接受表示。此外,并非所有 mtype 都包含同样丰富的元数据——例如,pandas.DataFrame 可以存储列名,而 numpy.ndarray 则无法做到。

在 sktime 中,scitype 和 mtype 使用字符串编码,以便于引用。

本节介绍以下 scitype 的 mtype

  • "Series",sktime 中表示任何类型时间序列的 scitype

  • "Panel",sktime 中表示任何类型时间序列面板的 scitype

  • "Hierarchical",sktime 中表示分层时间序列的 scitype

第 1.1 节:时间序列 - "Series" scitype#

sktime 中时间序列的主要表示形式是

  • "pd.DataFrame" - 一种单变量或多变量 pandas.DataFrame,行表示时间点,列表示变量

  • "pd.Series" - 一种(单变量)pandas.Series,其条目对应不同的时间点

  • "np.ndarray" - 一种 2D numpy.ndarray,行表示时间点,列表示变量

pandas 对象必须具有以下 pandas 索引类型之一:Int64IndexRangeIndexDatetimeIndexPeriodIndex;如果是 DatetimeIndex,必须设置 freq 属性。

numpy.ndarray 2D 数组的行被解释为具有 RangeIndex,并且通常等同于使用 pandas.DataFrame 构造函数进行默认强制转换后获得的 pandas.DataFrame

[2]:
# import to retrieve examples
from sktime.datatypes import get_examples

第 1.1.1 节:时间序列 - "pd.DataFrame" mtype#

"pd.DataFrame" mtype 中,时间序列由以下内存容器 obj: pandas.DataFrame 表示。

  • 结构约定:obj.index 必须是单调的,并且是 Int64IndexRangeIndexDatetimeIndexPeriodIndex 之一。

  • 变量:obj 的列对应不同的变量

  • 变量名:列名 obj.columns

  • 时间点:obj 的行对应不同的、离散的时间点

  • 时间索引:obj.index 被解释为时间索引。

  • 能力:可以表示多变量时间序列;可以表示不等间隔时间序列

"pd.DataFrame" 表示形式中的单变量时间序列示例。单个变量名为 "a",在四个时间点 0、1、2、3 进行观测。

[3]:
get_examples(mtype="pd.DataFrame", as_scitype="Series")[0]
[3]:
a
0 1.0
1 4.0
2 0.5
3 -3.0

"pd.DataFrame" 表示形式中的双变量时间序列示例。此时间序列有两个变量,命名为 "a""b"。两者都在相同四个时间点 0、1、2、3 进行观测。

[4]:
get_examples(mtype="pd.DataFrame", as_scitype="Series")[1]
[4]:
a b
0 1.0 3.000000
1 4.0 7.000000
2 0.5 2.000000
3 -3.0 -0.428571

第 1.1.2 节:时间序列 - "pd.Series" mtype#

"pd.Series" mtype 中,时间序列由以下内存容器 obj: pandas.Series 表示。

  • 结构约定:obj.index 必须是单调的,并且是 Int64IndexRangeIndexDatetimeIndexPeriodIndex 之一。

  • 变量:只有一个变量,对应 obj 的值。只能表示单变量时间序列。

  • 变量名:默认情况下没有列名。如果需要,可以将变量名作为 obj.name 提供。

  • 时间点:obj 的条目对应不同的、离散的时间点

  • 时间索引:obj.index 被解释为时间索引。

  • 能力:不能表示多变量时间序列;可以表示不等间隔时间序列

"pd.Series" mtype 表示形式中的单变量时间序列示例。单个变量名为 "a",在四个时间点 0、1、2、3 进行观测。

[5]:
get_examples(mtype="pd.Series", as_scitype="Series")[0]
[5]:
0    1.0
1    4.0
2    0.5
3   -3.0
Name: a, dtype: float64

第 1.1.3 节:时间序列 - "np.ndarray" mtype#

"np.ndarray" mtype 中,时间序列由以下内存容器 obj: np.ndarray 表示。

  • 结构约定:obj 必须是 2D 的,即 obj.shape 的长度必须为 2。对于单变量时间序列也是如此。

  • 变量:变量对应 obj 的列。

  • 变量名:"np.ndarray" mtype 不能表示变量名。

  • 时间点:obj 的行对应不同的、离散的时间点。

  • 时间索引:时间索引是隐式的,并通过约定定义。第 i 行(整数 i)被解释为在时间点 i 的观测值。

  • 能力:可以表示多变量时间序列;不能表示不等间隔时间序列

"np.ndarray" mtype 表示形式中的单变量时间序列示例。有一个(未命名)变量,在四个时间点 0、1、2、3 进行观测。

[6]:
get_examples(mtype="np.ndarray", as_scitype="Series")[0]
[6]:
array([[ 1. ],
       [ 4. ],
       [ 0.5],
       [-3. ]])

"np.ndarray" mtype 表示形式中的双变量时间序列示例。有两个(未命名)变量,它们都在四个时间点 0、1、2、3 进行观测。

[7]:
get_examples(mtype="np.ndarray", as_scitype="Series")[1]
[7]:
array([[ 1.        ,  3.        ],
       [ 4.        ,  7.        ],
       [ 0.5       ,  2.        ],
       [-3.        , -0.42857143]])

第 1.2 节:时间序列面板 - "Panel" scitype#

sktime 中时间序列面板的主要表示形式是

  • "pd-multiindex" - 一种 pandas.DataFrame,行多重索引为(实例,时间),列为变量

  • "numpy3D" - 一种 3D np.ndarray,轴 0 为实例,轴 1 为变量,轴 2 为时间点

  • "df-list" - 一个 pandas.DataFramelist,列表索引为实例,数据框行表示时间点,数据框列表示变量

这些表示形式在 sktime 中被认为是主要表示形式,并且是内部计算的核心。

sktime 中还有其他次要的时间序列面板表示形式

  • "nested_univ" - 一种 pandas.DataFrame,单元格中包含 pandas.Series。数据框行表示实例,数据框列表示变量,序列轴表示时间点

  • "numpyflat" - 一种 2D np.ndarray,行表示实例,列通过(变量,时间点)对索引。此格式只能被转换成,不能从其转换(因为变量和时间点数量可能模糊)。

  • "pd-wide" - 一种宽格式的 pandas.DataFrame:具有列多重索引(变量,时间点),行表示实例;对于单变量时间序列,“变量”索引可以省略

  • "pd-long" - 一种长格式的 pandas.DataFrame:具有列 instancestimepointsvariablevaluevalue 中的条目由 (instances, timepoints`, variable`) 中的值元组索引。

次要表示形式目前尚未完全在代码中整合,下文不再进一步讨论。欢迎贡献。

第 1.2.1 节:时间序列面板 - "pd-multiindex" mtype#

"pd-multiindex" mtype 中,时间序列面板由以下内存容器 obj: pandas.DataFrame 表示。

  • 结构约定:obj.index 必须是类型为 (Index, t) 的对多重索引,其中 tInt64IndexRangeIndexDatetimeIndexPeriodIndex 之一且单调。obj.index 必须有两个级别(可以命名或不命名)。

  • 实例索引:obj.index 中对的第一个元素(第 0 级别值)被解释为实例索引,下文我们称之为“实例索引”。

  • 实例:具有相同“实例索引”索引值的行对应同一个实例;具有不同“实例索引”值的行对应不同的实例。

  • 时间索引:obj.index 中对的第二个元素(第 1 级别值)被解释为时间索引,下文我们称之为“时间索引”。

  • 时间点:obj 中具有相同“时间索引”值的行对应同一个时间点;obj 中具有不同“时间索引”的行对应不同的时间点。

  • 变量:obj 的列对应不同的变量

  • 变量名:列名 obj.columns

  • 能力:可以表示多变量时间序列面板;可以表示不等间隔时间序列;可以表示不等支持长度的时间序列面板;不能表示具有不同变量集的时间序列面板。

"pd-multiindex" mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个变量,名称分别为 "var_0""var_1"。所有时间序列都在三个时间点 0、1、2 进行观测。

[8]:
get_examples(mtype="pd-multiindex", as_scitype="Panel")[0]
[8]:
var_0 var_1
实例 时间点
0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6

第 1.2.2 节:时间序列面板 - "numpy3D" mtype#

"numpy3D" mtype 中,时间序列面板由以下内存容器 obj: np.ndarray 表示。

  • 结构约定:obj 必须是 3D 的,即 obj.shape 的长度必须为 3。

  • 实例:实例对应 obj 的轴 0 元素。

  • 实例索引:实例索引是隐式的,并通过约定定义。轴 0 的第 i 个元素(整数 i)被解释为指示观测实例 i

  • 变量:变量对应 obj 的轴 1 元素。

  • 变量名:"numpy3D" mtype 不能表示变量名。

  • 时间点:时间点对应 obj 的轴 2 元素。

  • 时间索引:时间索引是隐式的,并通过约定定义。轴 2 的第 i 个元素(整数 i)被解释为在时间点 i 的观测值。

  • 能力:可以表示多变量时间序列面板;不能表示不等间隔时间序列;不能表示不等支持长度的时间序列面板;不能表示具有不同变量集的时间序列面板。

"numpy3D" mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个(未命名)变量。所有时间序列都在三个时间点 0、1、2 进行观测。

[9]:
get_examples(mtype="numpy3D", as_scitype="Panel")[0]
[9]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 1,  2,  3],
        [ 4, 55,  6]],

       [[ 1,  2,  3],
        [42,  5,  6]]])

第 1.2.3 节:时间序列面板 - "df-list" mtype#

"df-list" mtype 中,时间序列面板由以下内存容器 obj: List[pandas.DataFrame] 表示。

  • 结构约定:obj 必须是 pandas.DataFrames 的列表。 obj 的单个列表元素必须遵循 "Series" scitype 的 "pd.DataFrame" mtype 约定。

  • 实例:实例对应 obj 的不同列表元素。

  • 实例索引:实例的实例索引是其在 obj 中所在的列表索引。也就是说,obj[i] 中的数据对应于索引为 i 的实例的观测值。

  • 时间点:obj[i] 的行对应不同的、离散的时间点,即实例 i 被观测的时间点。

  • 时间索引:obj[i].index 被解释为实例 i 的时间索引。

  • 变量:obj[i] 的列对应实例 i 的不同可用变量。

  • 变量名:列名 obj[i].columns 是实例 i 的可用变量名称。

  • 能力:可以表示多变量时间序列面板;可以表示不等间隔时间序列;可以表示不等支持长度的时间序列面板;可以表示具有不同变量集的时间序列面板。

"df-list" mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个变量,名称分别为 "var_0""var_1"。所有时间序列都在三个时间点 0、1、2 进行观测。

[10]:
get_examples(mtype="df-list", as_scitype="Panel")[0]
[10]:
[   var_0  var_1
 0      1      4
 1      2      5
 2      3      6,
    var_0  var_1
 0      1      4
 1      2     55
 2      3      6,
    var_0  var_1
 0      1     42
 1      2      5
 2      3      6]

第 1.3 节:分层时间序列 - "Hierarchical" scitype#

sktime 目前只有一种分层时间序列表示形式

  • "pd_multiindex_hier" - 一种 pandas.DataFrame,具有行多重索引,最后一级解释为时间,其他级别解释为层次结构,列为变量

分层时间序列 - "pd_multiindex_hier" mtype#

  • 结构约定:obj.index 必须是 3 级或更多级别的多重索引,类型为 (Index, ..., Index, t),其中 tInt64IndexRangeIndexDatetimeIndexPeriodIndex 之一且单调。我们将最后一个索引称为“类时间”索引。

  • 层次级别:具有相同非类时间索引值的行对应同一层次单元;具有不同非类时间索引组合的行对应不同层次单元。

  • 层次结构:obj.index 中的非类时间索引被解释为标识层次结构的索引。

  • 时间索引:obj.index 中元组的最后一个元素被解释为时间索引。

  • 时间点:obj 中具有相同 "timepoints" 索引的行对应同一个时间点;obj 中具有不同 "timepoints" 索引的行对应不同的时间点。

  • 变量:obj 的列对应不同的变量

  • 变量名:列名 obj.columns

  • 能力:可以表示分层时间序列;可以表示不等间隔时间序列;可以表示不等支持长度的分层时间序列;不能表示具有不同变量集的分层时间序列。

[11]:
get_examples(mtype="pd_multiindex_hier", as_scitype="Hierarchical")[0]
[11]:
var_0 var_1
foo bar 时间点
a 0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6
b 0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6

第 2 节:有效性检查和 mtype 转换#

sktime 的 datatypes 模块为用户提供了通用功能,用于

  • 检查内存容器是否符合 mtype 约定,并提供有用的错误消息,帮助将数据转换为正确格式

  • 在给定 scitype 下,将不同的 mtype 相互转换

本节将介绍这些功能和预期用法工作流程。

第 2.1 节:准备数据,检查内存容器的有效性#

sktime 的 datatypes 模块提供了方便的功能,用户可以使用 check_is_mtypecheck_raise 函数检查其内存数据容器的有效性。这两个函数都提供了通用的有效性检查功能,check_is_mtype 作为返回值返回元数据和潜在问题,而 check_raise 在容器不符合给定的 mtype 时直接产生有用的错误消息。

确保给定数据容器符合 sktime mtype 规范的推荐 notebook 工作流程如下

  1. 将数据加载到内存数据容器中

  2. 确定 scitype,例如,这是时间序列(Series)还是时间序列面板(Panel

  3. 选择目标 mtype(列表参见第 1 节),如果数据尚不符合要求,尝试手动重新格式化数据以符合 mtype 规范

  4. 对数据容器运行 check_raise,以检查其是否符合 mtypescitype

  5. 如果引发错误,重复步骤 3 和 4,直到不再引发错误

第 2.1.1 节:有效性检查,示例 1(简单错误)#

假设我们有以下 numpy.ndarray 表示单变量时间序列

[12]:
import numpy as np

y = np.array([1, 6, 3, 7, 2])

检查与 sktime 的兼容性

(说明:取消注释并运行代码以查看有用的错误消息)

[13]:
from sktime.datatypes import check_raise

# check_raise(y, mtype="np.ndarray")

这告诉我们,如果使用 np.ndarray mtype,sktime 对时间序列使用 2D numpy 数组。虽然大多数方法都提供了自动执行此强制转换的便捷功能,但“正确”格式应为 2D,如下所示

[14]:
check_raise(y.reshape(-1, 1), mtype="np.ndarray")
[14]:
True

为了在自己的代码或附加元数据中使用,可以使用 check_is_mtype 函数获取错误消息

[15]:
from sktime.datatypes import check_is_mtype

check_is_mtype(y, mtype="np.ndarray", return_metadata=True)
[15]:
(True,
 None,
 {'is_empty': False,
  'is_univariate': True,
  'n_features': 1,
  'feature_names': [0],
  'dtypekind_dfip': [<DtypeKind.FLOAT: 2>],
  'feature_kind': [<DtypeKind.FLOAT: 2>],
  'is_equally_spaced': True,
  'has_nans': False,
  'mtype': 'np.ndarray',
  'scitype': 'Series'})

如果参数通过有效性检查,则会产生元数据

[16]:
check_is_mtype(y.reshape(-1, 1), mtype="np.ndarray", return_metadata=True)
[16]:
(True,
 None,
 {'is_empty': False,
  'is_univariate': True,
  'n_features': 1,
  'feature_names': [0],
  'dtypekind_dfip': [<DtypeKind.FLOAT: 2>],
  'feature_kind': [<DtypeKind.FLOAT: 2>],
  'is_equally_spaced': True,
  'has_nans': False,
  'mtype': 'np.ndarray',
  'scitype': 'Series'})

注意:如果 mtype 的名称含糊不清,可能指代多个 scitype,则必须提供附加参数 scitype。对于任何常见的内存容器,都不应出现这种情况,我们在此提及是为了完整性。

[17]:
check_is_mtype(y, mtype="np.ndarray", scitype="Series")
[17]:
True

第 2.1.2 节:有效性检查,示例 2(不明显错误)#

假设我们将数据转换成了多重索引面板,即,我们想要一个 mtype 为 pd-multiindexPanel

[18]:
import pandas as pd

cols = ["instances", "time points"] + [f"var_{i}" for i in range(2)]
X = pd.concat(
    [
        pd.DataFrame([[0, 0, 1, 4], [0, 1, 2, 5], [0, 2, 3, 6]], columns=cols),
        pd.DataFrame([[1, 0, 1, 4], [1, 1, 2, 55], [1, 2, 3, 6]], columns=cols),
        pd.DataFrame([[2, 0, 1, 42], [2, 1, 2, 5], [2, 2, 3, 6]], columns=cols),
    ]
).set_index(["instances", "time points"])

X 是否满足 pd-multiindex 规范并不明显,所以我们来检查一下

(说明:取消注释并运行代码以查看有用的错误消息)

[19]:
from sktime.datatypes import check_raise

# check_raise(X, mtype="pd-multiindex")

有用的错误消息突出了多重索引列中的一个拼写错误,所以我们这样做

[20]:
X.index.names = ["instances", "timepoints"]

现在有效性检查通过了

[21]:
check_raise(X, mtype="pd-multiindex")
[21]:
True

第 2.1.3 节:推断 mtype#

sktime 还提供了推断内存数据容器 mtype 的功能,这在确定容器符合要求但忘记了确切字符串,或者想要知道内存容器是否已处于某种受支持的、符合要求的格式时非常有用。为此,只需指定 scitype

[22]:
from sktime.datatypes import mtype

mtype(X, as_scitype="Panel")
[22]:
'pd-multiindex'

第 2.2 节:mtype 之间的转换#

sktime 的 datatypes 模块还提供了统一的 mtype 转换功能。这对用户和方法开发者都很有用。

convert 函数需要指定要从哪种 mtype 转换以及要转换成哪种 mtype。convert_to 函数只需要指定要转换成的 mtype,如果输入可以推断,它会自动推断输入的 mtype。如果输入可以有多种 mtype,应使用 convert_to

第 2.2.1 节:简单转换#

示例:将 numpy3D 时间序列面板转换为 pd-multiindex mtype

[23]:
from sktime.datatypes import get_examples

X = get_examples(mtype="numpy3D", as_scitype="Panel")[0]
X
[23]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 1,  2,  3],
        [ 4, 55,  6]],

       [[ 1,  2,  3],
        [42,  5,  6]]])
[24]:
from sktime.datatypes import convert

convert(X, from_type="numpy3D", to_type="pd-multiindex")
[24]:
var_0 var_1
实例 时间点
0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6
[25]:
from sktime.datatypes import convert_to

convert_to(X, to_type="pd-multiindex")
[25]:
var_0 var_1
实例 时间点
0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6

第 2.2.2 节:高级转换功能#

convert_to 还允许指定多个输出类型。to_type 参数可以是 mtype 列表。在这种情况下,如果输入的 mtype 在列表中,则输入将不作更改地传递;如果输入的 mtype 不在列表中,则将其转换为列表中的第一个 mtype。

示例:将时间序列面板转换为 "pd-multiindex""numpy3D"。如果输入是 "numpy3D",则保持不变。如果输入是 "df-list",则转换为 "pd-multiindex"

[26]:
from sktime.datatypes import get_examples

X = get_examples(mtype="numpy3D", as_scitype="Panel")[0]
X
[26]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 1,  2,  3],
        [ 4, 55,  6]],

       [[ 1,  2,  3],
        [42,  5,  6]]])
[27]:
from sktime.datatypes import convert_to

convert_to(X, to_type=["pd-multiindex", "numpy3D"])
[27]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 1,  2,  3],
        [ 4, 55,  6]],

       [[ 1,  2,  3],
        [42,  5,  6]]])
[28]:
X = get_examples(mtype="df-list", as_scitype="Panel")[0]
X
[28]:
[   var_0  var_1
 0      1      4
 1      2      5
 2      3      6,
    var_0  var_1
 0      1      4
 1      2     55
 2      3      6,
    var_0  var_1
 0      1     42
 1      2      5
 2      3      6]
[29]:
convert_to(X, to_type=["pd-multiindex", "numpy3D"])
[29]:
var_0 var_1
实例 时间点
0 0 1 4
1 2 5
2 3 6
1 0 1 4
1 2 55
2 3 6
2 0 1 42
1 2 5
2 3 6

第 2.2.3 节:检查已实现的转换#

目前,转换功能正在开发中,并非所有可能的转换都已可用——欢迎贡献。要查看某个 scitype 当前已实现哪些转换,请使用 datatypes._convert 模块中的开发者方法 _conversions_defined。这将生成一个表格,如果已实现从行中的 mtype 到列中的 mtype 的转换,则显示“1”。

[30]:
from sktime.datatypes._convert import _conversions_defined

_conversions_defined(scitype="Panel")
[30]:
df-list gluonts_ListDataset_panel gluonts_PandasDataset_panel nested_univ numpy3D numpyflat pd-long pd-multiindex pd-wide
df-list 1 1 1 1 1 1 1 1 0
gluonts_ListDataset_panel 1 1 1 1 1 1 1 1 0
gluonts_PandasDataset_panel 1 1 1 1 1 1 1 1 0
nested_univ 1 1 1 1 1 1 1 1 1
numpy3D 1 1 1 1 1 1 1 1 0
numpyflat 1 1 1 1 1 1 1 1 0
pd-long 1 1 1 1 1 1 1 1 0
pd-multiindex 1 1 1 1 1 1 1 1 0
pd-wide 0 0 0 1 0 0 0 0 1

第 3 节:加载预定义数据集#

sktime 的 datasets 模块允许加载数据集用于测试和基准测试。这包括

  • 直接随 sktime 提供的示例数据集

  • 从常见仓库下载数据集的下载器

以这种方式检索的所有数据都采用 sktime 兼容的内存和/或文件格式。

目前尚未实现对可用数据集的系统性标记和注册表检索功能——非常欢迎对此做出贡献。

第 3.1 节:预测数据集#

sktime 的 datasets 模块目前允许加载以下预测示例数据集

数据集名称

加载函数

属性

Box/Jenkins 航班数据

load_airline

单变量

Lynx 销售数据

load_lynx

单变量

洗发水销售数据

load_shampoo_sales

单变量

药物福利计划数据

load_PBS_dataset

单变量

Longley 美国宏观经济数据

load_longley

多变量

MTS 消费/收入数据

load_uschange

多变量

sktime 目前没有连接到预测数据仓库的连接器——非常感谢贡献。

预测数据集都是 Series scitype,可以是单变量或多变量。

单变量数据的加载器没有参数,并且始终返回 "pd.Series" mtype 的数据

[31]:
from sktime.datasets import load_airline

load_airline()
[31]:
Period
1949-01    112.0
1949-02    118.0
1949-03    132.0
1949-04    129.0
1949-05    121.0
           ...
1960-08    606.0
1960-09    508.0
1960-10    461.0
1960-11    390.0
1960-12    432.0
Freq: M, Name: Number of airline passengers, Length: 144, dtype: float64

多变量数据的加载器可以通过两种方式调用

  • 不带参数,这种情况下返回 "pd.DataFrame" mtype 的多变量时间序列

[32]:
from sktime.datasets import load_longley

load_longley()
[32]:
(Period
 1947    60323.0
 1948    61122.0
 1949    60171.0
 1950    61187.0
 1951    63221.0
 1952    63639.0
 1953    64989.0
 1954    63761.0
 1955    66019.0
 1956    67857.0
 1957    68169.0
 1958    66513.0
 1959    68655.0
 1960    69564.0
 1961    69331.0
 1962    70551.0
 Freq: A-DEC, Name: TOTEMP, dtype: float64,
         GNPDEFL       GNP   UNEMP   ARMED       POP
 Period
 1947       83.0  234289.0  2356.0  1590.0  107608.0
 1948       88.5  259426.0  2325.0  1456.0  108632.0
 1949       88.2  258054.0  3682.0  1616.0  109773.0
 1950       89.5  284599.0  3351.0  1650.0  110929.0
 1951       96.2  328975.0  2099.0  3099.0  112075.0
 1952       98.1  346999.0  1932.0  3594.0  113270.0
 1953       99.0  365385.0  1870.0  3547.0  115094.0
 1954      100.0  363112.0  3578.0  3350.0  116219.0
 1955      101.2  397469.0  2904.0  3048.0  117388.0
 1956      104.6  419180.0  2822.0  2857.0  118734.0
 1957      108.4  442769.0  2936.0  2798.0  120445.0
 1958      110.8  444546.0  4681.0  2637.0  121950.0
 1959      112.6  482704.0  3813.0  2552.0  123366.0
 1960      114.2  502601.0  3931.0  2514.0  125368.0
 1961      115.7  518173.0  4806.0  2572.0  127852.0
 1962      116.9  554894.0  4007.0  2827.0  130081.0)
  • 带有参数 y_name,该参数必须与某个列/变量名一致,在这种情况下返回一对时间序列 yX,其中 y"pd.Series" mtype,X"pd.DataFrame" mtype——这对于包含外生变量的单变量预测很方便。

[33]:
y, X = load_longley(y_name="TOTEMP")
[34]:
y
[34]:
Period
1947    60323.0
1948    61122.0
1949    60171.0
1950    61187.0
1951    63221.0
1952    63639.0
1953    64989.0
1954    63761.0
1955    66019.0
1956    67857.0
1957    68169.0
1958    66513.0
1959    68655.0
1960    69564.0
1961    69331.0
1962    70551.0
Freq: A-DEC, Name: TOTEMP, dtype: float64
[35]:
X
[35]:
GNPDEFL GNP UNEMP ARMED POP
周期
1947 83.0 234289.0 2356.0 1590.0 107608.0
1948 88.5 259426.0 2325.0 1456.0 108632.0
1949 88.2 258054.0 3682.0 1616.0 109773.0
1950 89.5 284599.0 3351.0 1650.0 110929.0
1951 96.2 328975.0 2099.0 3099.0 112075.0
1952 98.1 346999.0 1932.0 3594.0 113270.0
1953 99.0 365385.0 1870.0 3547.0 115094.0
1954 100.0 363112.0 3578.0 3350.0 116219.0
1955 101.2 397469.0 2904.0 3048.0 117388.0
1956 104.6 419180.0 2822.0 2857.0 118734.0
1957 108.4 442769.0 2936.0 2798.0 120445.0
1958 110.8 444546.0 4681.0 2637.0 121950.0
1959 112.6 482704.0 3813.0 2552.0 123366.0
1960 114.2 502601.0 3931.0 2514.0 125368.0
1961 115.7 518173.0 4806.0 2572.0 127852.0
1962 116.9 554894.0 4007.0 2827.0 130081.0

第 3.2 节:时间序列分类数据集#

sktime 的 datasets 模块目前允许加载以下时间序列分类示例数据集

数据集名称

加载函数

属性

电器功耗数据

load_acsf1

单变量,等长/索引

箭头形状数据

load_arrow_head

单变量,等长/索引

Gunpoint 运动数据

load_gunpoint

单变量,等长/索引

意大利电力需求数据

load_italy_power_demand

单变量,等长/索引

日语元音数据

load_japanese_vowels

单变量,等长/索引

OSUleaf 叶形数据

load_osuleaf

单变量,等长/索引

基本运动数据

load_basic_motions

多变量,等长/索引

目前,sktime 中没有直接包含不等长或不等索引的时间序列分类示例数据。

sktime 还通过 load_UCR_UEA_dataset 函数提供了对 UCR/UEA 时间序列数据集存档的完整接口。UCR/UEA 存档也包含多变量或不等长/不等索引(任一组合)的时间序列分类数据集。

第 3.2.2 节:sktime 中的时间序列分类数据集#

时间序列分类数据集由 Panel scitype 的时间序列面板以及分类标签组成,每个时间序列对应一个标签。

如果使用最小参数调用加载器,数据将以 "nested_univ" mtype 返回,标签和待分类的时间序列都在同一个 pd.DataFrame 中。使用 return_X_y=True 参数,数据会分离返回特征 X 和标签 y,其中 Xnested_univ mtype 的 Panelysklearn 兼容的标签 numpy 向量。

[36]:
from sktime.datasets import load_arrow_head

X, y = load_arrow_head(return_X_y=True)
[37]:
X
[37]:
dim_0
0 0 -1.963009 1 -1.957825 2 -1.95614...
1 0 -1.774571 1 -1.774036 2 -1.77658...
2 0 -1.866021 1 -1.841991 2 -1.83502...
3 0 -2.073758 1 -2.073301 2 -2.04460...
4 0 -1.746255 1 -1.741263 2 -1.72274...
... ...
206 0 -1.625142 1 -1.622988 2 -1.62606...
207 0 -1.657757 1 -1.664673 2 -1.63264...
208 0 -1.603279 1 -1.587365 2 -1.57740...
209 0 -1.739020 1 -1.741534 2 -1.73286...
210 0 -1.630727 1 -1.629918 2 -1.62055...

211 行 × 1 列

[38]:
y
[38]:
array(['0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0',
       '1', '2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '1',
       '2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '0', '0',
       '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
       '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
       '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
       '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
       '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
       '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
       '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
       '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
       '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
       '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
       '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
       '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
       '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
       '2', '2', '2'], dtype='<U1')

面板可以从 "nested_univ" mtype 转换为其他 mtype 格式,使用 datatypes.convertconvert_to(参见上文)

[39]:
from sktime.datatypes import convert_to

convert_to(X, to_type="pd-multiindex")
[39]:
dim_0
0 0 -1.963009
1 -1.957825
2 -1.956145
3 -1.938289
4 -1.896657
... ... ...
210 246 -1.513637
247 -1.550431
248 -1.581576
249 -1.595273
250 -1.620783

52961 行 × 1 列

可以使用 split 参数调用数据集加载器,以获取可重现的训练集和测试集,用于跨研究进行比较。如果 split="train",则检索预定义的训练集;如果 split="test",则检索预定义的测试集。

[40]:
X_train, y_train = load_arrow_head(return_X_y=True, split="train")
X_test, y_test = load_arrow_head(return_X_y=True, split="test")
# this retrieves training and test X/y for reproducible use in studies

第 3.2.3 节:来自 UCR/UEA 时间序列分类仓库的时间序列分类数据集#

load_UCR_UEA_dataset 工具将从 UCR/UEA 时间序列分类仓库下载数据集,并以与 sktime 本地数据集加载器相同的语法将其作为内存数据集提供。

数据集通过唯一的字符串标识符进行索引,可以在 仓库本身 查看,或者通过 datasets.tsc_dataset_names 模块中的注册表按属性查看

[41]:
from sktime.datasets.tsc_dataset_names import univariate

导入的变量都是字符串列表,其中包含具有某些属性的数据集的唯一字符串标识符,如下所示

注册名称

单变量/多变量

等长/不等长

包含/不包含缺失值

单变量

仅单变量

两者都包含

两者都包含

多变量

仅多变量

两者都包含

两者都包含

univariate_equal_length

仅单变量

仅等长

两者都包含

univariate_variable_length

仅单变量

仅不等长

两者都包含

univariate_missing_values

仅单变量

两者都包含

仅包含缺失值

multivariate_equal_length

仅多变量

仅等长

两者都包含

multivariate_unequal_length

仅多变量

仅不等长

两者都包含

老实说,使用这些列表进行查找和检索有点不方便——非常欢迎对 sktime 做出贡献,编写基于数据集能力或属性标签的查找函数,例如 all_estimatorsall_tags

下面显示一个示例列表

[42]:
univariate
[42]:
['ACSF1',
 'Adiac',
 'AllGestureWiimoteX',
 'AllGestureWiimoteY',
 'AllGestureWiimoteZ',
 'ArrowHead',
 'AsphaltObstacles',
 'Beef',
 'BeetleFly',
 'BirdChicken',
 'BME',
 'Car',
 'CBF',
 'Chinatown',
 'ChlorineConcentration',
 'CinCECGTorso',
 'Coffee',
 'Computers',
 'CricketX',
 'CricketY',
 'CricketZ',
 'Crop',
 'DiatomSizeReduction',
 'DistalPhalanxOutlineCorrect',
 'DistalPhalanxOutlineAgeGroup',
 'DistalPhalanxTW',
 'DodgerLoopDay',
 'DodgerLoopGame',
 'DodgerLoopWeekend',
 'Earthquakes',
 'ECG200',
 'ECG5000',
 'ECGFiveDays',
 'ElectricDevices',
 'EOGHorizontalSignal',
 'EOGVerticalSignal',
 'EthanolLevel',
 'FaceAll',
 'FaceFour',
 'FacesUCR',
 'FiftyWords',
 'Fish',
 'FordA',
 'FordB',
 'FreezerRegularTrain',
 'FreezerSmallTrain',
 'Fungi',
 'GestureMidAirD1',
 'GestureMidAirD2',
 'GestureMidAirD3',
 'GesturePebbleZ1',
 'GesturePebbleZ2',
 'GunPoint',
 'GunPointAgeSpan',
 'GunPointMaleVersusFemale',
 'GunPointOldVersusYoung',
 'Ham',
 'HandOutlines',
 'Haptics',
 'Herring',
 'HouseTwenty',
 'InlineSkate',
 'InsectEPGRegularTrain',
 'InsectEPGSmallTrain',
 'InsectWingbeatSound',
 'ItalyPowerDemand',
 'LargeKitchenAppliances',
 'Lightning2',
 'Lightning7',
 'Mallat',
 'Meat',
 'MedicalImages',
 'MelbournePedestrian',
 'MiddlePhalanxOutlineCorrect',
 'MiddlePhalanxOutlineAgeGroup',
 'MiddlePhalanxTW',
 'MixedShapesRegularTrain',
 'MixedShapesSmallTrain',
 'MoteStrain',
 'NonInvasiveFetalECGThorax1',
 'NonInvasiveFetalECGThorax2',
 'OliveOil',
 'OSULeaf',
 'PhalangesOutlinesCorrect',
 'Phoneme',
 'PickupGestureWiimoteZ',
 'PigAirwayPressure',
 'PigArtPressure',
 'PigCVP',
 'PLAID',
 'Plane',
 'PowerCons',
 'ProximalPhalanxOutlineCorrect',
 'ProximalPhalanxOutlineAgeGroup',
 'ProximalPhalanxTW',
 'RefrigerationDevices',
 'Rock',
 'ScreenType',
 'SemgHandGenderCh2',
 'SemgHandMovementCh2',
 'SemgHandSubjectCh2',
 'ShakeGestureWiimoteZ',
 'ShapeletSim',
 'ShapesAll',
 'SmallKitchenAppliances',
 'SmoothSubspace',
 'SonyAIBORobotSurface1',
 'SonyAIBORobotSurface2',
 'StarLightCurves',
 'Strawberry',
 'SwedishLeaf',
 'Symbols',
 'SyntheticControl',
 'ToeSegmentation1',
 'ToeSegmentation2',
 'Trace',
 'TwoLeadECG',
 'TwoPatterns',
 'UMD',
 'UWaveGestureLibraryAll',
 'UWaveGestureLibraryX',
 'UWaveGestureLibraryY',
 'UWaveGestureLibraryZ',
 'Wafer',
 'Wine',
 'WordSynonyms',
 'Worms',
 'WormsTwoClass']

加载函数 load_UCR_UEA_dataset 的行为与 sktime 数据加载器完全相同,但增加了一个参数 name,该参数应设置为 UCR/UEA 数据集的唯一标识字符串之一,例如

[43]:
from sktime.datasets import load_UCR_UEA_dataset

X, y = load_UCR_UEA_dataset(name="ArrowHead", return_X_y=True)

这会将数据集下载到本地目录(默认情况下:如果是本地克隆,则下载到本地仓库的 datasets/data 目录中;如果是发布安装,则下载到本地 Python 环境文件夹中)。要更改该目录,请使用 load_UCR_UEA_dataset 函数的 extract_path 参数进行指定。

第 4 节:从 csv 文件加载数据#

本节展示了如何将一些常见的表格 csv 格式加载到 sktime 兼容的容器中。

我们将涵盖

  • 将时间序列数据集转换为 sktime 兼容的容器

  • 将面板数据集转换为 sktime 兼容的容器

我们假设 所有 csv 文件都具有某些表格格式

这意味着 csv 文件包含时间索引列,或者面板数据的实例索引,或者采用宽格式表格。

注意:在每一步,我们都可以使用 check_is_mtype 来检查是否符合目标格式。读者可以这样做。

第 4.1 节:简单时间序列示例#

[44]:
import pandas as pd

df_series = pd.read_csv("../sktime/datasets/data/Airline/Airline.csv")
df_series.head()
[44]:
日期 乘客
0 1949-01 112
1 1949-02 118
2 1949-03 132
3 1949-04 129
4 1949-05 121
[45]:
df_series = df_series.set_index(
    "Date"
).squeeze()  # replace "Period" with the column name of the time index
df_series.index = pd.DatetimeIndex(df_series.index)
[46]:
mtype(df_series, as_scitype="Series")
[46]:
'pd.Series'

第 4.2 节:简单面板数据示例#

[47]:
# mimicking a scenario where we already have a csv file in the right format
from sktime.datasets import load_arrow_head

df_panel = load_arrow_head(split="TRAIN", return_type="pd-multiindex")[0].reset_index()
# imagine this is the result of df_panel = pd.read_csv
[48]:
df_panel.head()
[48]:
level_0 level_1 dim_0
0 0 0 -1.963009
1 0 1 -1.957825
2 0 2 -1.956145
3 0 3 -1.938289
4 0 4 -1.896657

这类似于 pd-multiindex 格式,所以我们尝试将其转换为该格式。

我们需要改变的一点是将实例/时间设置为索引

[49]:
df_panel = df_panel.set_index(["level_0", "level_1"])
type(df_panel.index)
[49]:
pandas.core.indexes.multi.MultiIndex

sktime 现在将其识别为 pd-multiindex 格式

[50]:
mtype(df_panel, as_scitype="Panel")
# in general:
# replace "timepoints" with the time index column name
# replace "level_0" with the higher level column name of your file
[50]:
'pd-multiindex'

第 4.3 节:复杂面板数据示例#

现在我们尝试从一个格式有点挑战性的文件中加载面板数据

在下面的文件中

  1. 分隔符不是默认的逗号,而是制表符。为此,我们设置 sep=\t

  2. 文件中没有头部

  3. 没有实例索引,所以我们需要添加它

  4. 索引方式与 sktime 不同——第一列是变量索引,列是时间索引

这些或类似的挑战在面板数据的 csv 文件中很常见,因此我们将在下面展示如何解决它们。

建议将数据转换为纯粹基于 pandasnumpy 的格式。在下面的例子中,我们将把数据转换为 pd-multiindex 格式。

[51]:
# 1, 2 - dealing with the separator and header
import pandas as pd

df_panel = pd.read_csv(
    "../sktime/datasets/data/ArrowHead/ArrowHead_TRAIN.tsv",
    sep="\t",
    header=None,
)
df_panel.head()
[51]:
0 1 2 3 4 5 6 7 8 9 ... 242 243 244 245 246 247 248 249 250 251
0 0 -1.963009 -1.957825 -1.956145 -1.938289 -1.896657 -1.869857 -1.838705 -1.812289 -1.736433 ... -1.583857 -1.655329 -1.719153 -1.750881 -1.796273 -1.841345 -1.884289 -1.905393 -1.923905 -1.909153
1 1 -1.774571 -1.774036 -1.776586 -1.730749 -1.696268 -1.657377 -1.636227 -1.609807 -1.543439 ... -1.471688 -1.484666 -1.539972 -1.590150 -1.635663 -1.639989 -1.678683 -1.729227 -1.775670 -1.789324
2 2 -1.866021 -1.841991 -1.835025 -1.811902 -1.764390 -1.707687 -1.648280 -1.582643 -1.531502 ... -1.584132 -1.652337 -1.684565 -1.743972 -1.799117 -1.829069 -1.875828 -1.862512 -1.863368 -1.846493
3 0 -2.073758 -2.073301 -2.044607 -2.038346 -1.959043 -1.874494 -1.805619 -1.731043 -1.712653 ... -1.678942 -1.743732 -1.819801 -1.858136 -1.886146 -1.951247 -2.012927 -2.026963 -2.073405 -2.075292
4 1 -1.746255 -1.741263 -1.722741 -1.698640 -1.677223 -1.630356 -1.579440 -1.551225 -1.473980 ... -1.547111 -1.607101 -1.635137 -1.686346 -1.691274 -1.716886 -1.740726 -1.743442 -1.762729 -1.763428

5 行 × 252 列

[52]:
# 2 - adding an instance index manually
import numpy as np

df_panel["instance"] = np.repeat(range(len(df_panel) // 3), 3)

现在我们通过反透视将数据转换为长格式

[53]:
# 3 - add instance index
df_panel.columns = ["var"] + [f"value{i}" for i in range(251)] + ["instance"]
# 4 - move to long format
df_panel = pd.wide_to_long(df_panel, "value", i=["var", "instance"], j="time")
[54]:
df_panel.head()
[54]:
变量 实例 时间
0 0 0 -1.963009
1 -1.957825
2 -1.956145
3 -1.938289
4 -1.896657

现在“变量”索引在行中,但它应该在列中

[55]:
# 3 - move variable index to columns
df_panel = df_panel.reset_index("var")
df_panel = df_panel.pivot(columns="var", values="value")
[56]:
df_panel.head()
[56]:
变量 0 1 2
实例 时间
0 0 -1.963009 -1.774571 -1.866021
1 -1.957825 -1.774036 -1.841991
2 -1.956145 -1.776586 -1.835025
3 -1.938289 -1.730749 -1.811902
4 -1.896657 -1.696268 -1.764390

这现在是 pd-multiindex 格式了

[57]:
mtype(df_panel, as_scitype="Panel")
[57]:
'pd-multiindex'

另一种方法是删除索引,然后在 numpy 中使用 reshape。

[57]:


使用 nbsphinx 生成。Jupyter notebook 可在此处找到:here