binder

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

设置说明: 在binder上,这个笔记本应该可以开箱即用。

要按预期运行此笔记本,请确保在您的 Python 环境中安装了带有基本依赖项要求的 sktime

要在本地开发版本的 sktime 上运行此笔记本,可以取消注释并运行以下内容,或者对 sktime main 分支的本地克隆执行 pip install -e

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

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

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

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

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

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

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

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

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

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

第1节:内存数据容器#

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

从概念上讲,sktime 区分:

  • 数据科学抽象数据类型 - 简称:scitype - 是指数据容器的一种类型,由数据表示的关系和统计属性以及对其的常见操作定义 - 例如,抽象的“时间序列”或抽象的“时间序列面板”,而不指定特定的机器实现,如在Python中。

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

sktime 中,相同的科学类型可以通过多种 mtype 实现。例如,sktime 允许用户将时间序列指定为 pandas.DataFramepandas.Seriesnumpy.ndarray。这些是不同的 mtype,它们是相同科学类型“时间序列”的可接受表示。此外,并非所有 mtype 的元数据都同样丰富——例如,pandas.DataFrame 可以存储列名,而在 numpy.ndarray 中则不可能。

sktime 中,scitypes 和 mtypes 通过字符串进行编码,以便于引用。

本节介绍以下 scitypes 的 mtypes:

第1.1节:时间序列 - "Series" 科学类型#

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

  • "pd.DataFrame" - 一个单变量或多变量的 pandas.DataFrame,行 = 时间点,列 = 变量

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

  • "np.ndarray" - 一个二维 numpy.ndarray ,行 = 时间点,列 = 变量

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

numpy.ndarray 二维数组被解释为在行上具有 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 必须是二维的,即 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" 科学类型#

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

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

  • "numpy3D" - 一个三维的 np.ndarray,其中轴 0 = 实例,轴 1 = 变量,轴 2 = 时间点

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

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

sktime 中还有其他一些次要的时间序列面板表示:

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

  • "numpyflat" - 一个二维 np.ndarray ,行表示实例,列由 (变量, 时间点) 对索引。此格式仅用于转换,不能从其他格式转换(因为变量和时间点的数量可能不明确)。

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

  • "pd-long" - 一个 pandas.DataFrame 的长格式:包含列 instancestimepointsvariablevaluevalue 中的条目由 (instancestimepointsvariable) 中的值的元组索引。

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

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

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

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

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

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

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

  • 时间点:具有相同“时间索引”值的 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
instances timepoints
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 必须是三维的,即 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 的单个列表元素必须遵循 "pd.DataFrame" 的 mtype 约定,用于 "Series" 的 scitype。

  • 实例: 实例对应于 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" 科学类型#

目前,sktime 中只有一种层次时间序列的表示方法:

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

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

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

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

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

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

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

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

  • 变量名:列名 obj.columns

  • 功能:可以表示层次序列;可以表示不等间距序列;可以表示不等支持的层次序列;不能表示具有不同变量集的层次序列。

[11]:
get_examples(mtype="pd_multiindex_hier", as_scitype="Hierarchical")[0]
[11]:
var_0 var_1
foo bar timepoints
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转换#

sktimedatatypes 模块为用户提供了以下通用功能:

  • 检查内存容器是否符合 mtype 约定,并提供信息丰富的错误消息,帮助将数据移动到正确的格式

  • 将不同的 mtypes 相互转换,针对给定的 scitype

在本节中,将介绍此功能及其预期使用的工作流程。

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

sktimedatatypes 模块为用户提供了便捷的功能,用于使用 check_is_mtypecheck_raise 函数检查其内存数据容器的有效性。这两个函数都提供了通用的有效性检查功能,check_is_mtype 返回元数据和潜在问题作为返回参数,而 check_raise 则在容器不符合给定 mtype 时直接生成信息丰富的错误消息。

推荐的笔记本工作流程,以确保给定的数据容器符合 sktime mtype 规范,如下所示:

  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 的名称是模糊的,并且可以指代多种 scitypes,则必须提供额外的参数 scitype。对于任何常见的内存容器,这种情况不应发生,我们提到这一点是为了完整性。

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

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

假设我们已经将数据转换为多索引面板,即我们希望有一个 Panel 类型为 pd-multiindex

[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节:mtypes之间的转换#

sktimedatatypes 模块还提供了不同 mtypes 之间的非统一转换功能。这对用户和方法开发者都很有用。

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
instances timepoints
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
instances timepoints
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
instances timepoints
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节:检查已实现的转换#

目前,转换工作正在进行中,并非所有可能的转换都可用 - 欢迎贡献。要查看为某种科学类型当前实现了哪些转换,请使用 datatypes._convert 模块中的 _conversions_defined 开发者方法。这将生成一个表格,如果从行中的 mtype 转换到列中的 mtypw 已实现,则表格中显示为 “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节:加载预定义数据集#

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

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

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

通过这种方式检索的所有数据都与 sktime 兼容,可以是内存中或文件格式。

目前,尚未实现对可用数据集的系统化标记和注册表检索 - 对此的贡献将非常受欢迎。

第3.1节:预测数据集#

sktimedatasets 模块目前允许加载以下预测示例数据集:

数据集名称

加载函数

属性

Box/Jenkins 航空公司数据

load_airline

单变量

Lynx 销售数据

load_lynx

单变量

洗发水销售数据

load_shampoo_sales

单变量

药品福利计划数据

load_PBS_dataset

单变量

Longley 美国宏观经济数据

load_longley

多变量

MTS 消费/收入数据

load_uschange

多变量

sktime 目前没有连接到预测数据仓库的连接器 - 非常欢迎贡献。

预测数据集都是 Series 科学类型,它们可以是单变量或多变量。

单变量数据的加载器没有参数,并且总是以 "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,该参数必须与某一列/变量名称一致,返回一对序列 y, X,其中 ymtype"pd.Series"Xmtype"pd.DataFrame" - 这对于使用外生变量的单变量预测非常方便。

[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
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

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

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

数据集名称

加载函数

属性

设备功耗数据

load_acsf1

单变量, 等长/等索引

箭头形状数据

load_arrow_head

单变量, 等长/等索引

枪口运动数据

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 科学类型的面板时间序列组成,每个时间序列都有一个分类标签。

如果加载器以最少的参数调用,数据将以 "nested_univ" mtype 返回,标签和系列分类在同一个 pd.DataFrame 中。使用 return_X_y=True 参数,数据将分别返回为特征 X 和标签 y,其中 X 是一个 nested_univ mtype 的 Panel,而 y 是一个与 sklearn 兼容的标签 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 rows × 1 columns

[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')

面板可以通过 datatypes.convertconvert_to``(见上文)从 ``"nested_univ" mtype 转换为其他 mtype 格式:

[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 rows × 1 columns

数据集加载器可以通过 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

仅单变量

两者都包含

两者都包含

multivariate

仅多元

两者都包含

两者都包含

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]:
Date Passengers
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= ``

  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 rows × 252 columns

[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]:
value
var instance time
0 0 0 -1.963009
1 -1.957825
2 -1.956145
3 -1.938289
4 -1.896657

现在“var”索引在行中,但它应该在列中:

[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]:
var 0 1 2
instance time
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 中使用重塑。

[57]:


使用 nbsphinx 生成。Jupyter 笔记本可以在这里找到