在这里插入图片描述在这里插入图片描述

IoTDB AINode 实战指南:SQL 原生时序 AI 建模,毫秒级预测 / 异常检测落地

AINode 作为 IoTDB 原生时序 AI 节点,内置 Timer 系列等业界领先时序大模型,支持通过标准 SQL 语句完成模型注册、管理与推理全流程,无需 Python/Java 编程,更无需迁移 IoTDB 存储的数据。本文详细拆解 AINode 的核心优势、模型注册 / 调用 / 权限管理等关键操作,结合电力负载预测、变电站电压预测、民航旅客异常检测三大工业级案例,手把手演示如何通过简单 SQL 实现时序数据的趋势预测、缺失值填补与异常识别,助力开发者快速落地毫秒级实时时序 AI 应用。

在这里插入图片描述

AINode 是支持时序相关模型注册、管理、调用的 IoTDB 原生节点,内置业界领先的自研时序大模型,如清华自研时序模型 Timer 系列,可通过标准 SQL 语句进行调用,实现时序数据的毫秒级实时推理,可支持时序趋势预测、缺失值填补、异常值检测等应用场景。

系统架构如下图所示:

三种节点的职责如下:

  • ConfigNode:负责保存和管理模型的元信息;负责分布式节点管理。
  • DataNode:负责接收并解析用户的 SQL请求;负责存储时间序列数据;负责数据的预处理计算。
  • AINode:负责模型文件的导入创建以及模型推理。

1. 优势特点

与单独构建机器学习服务相比,具有以下优势:

  • 简单易用:无需使用 Python 或 Java 编程,使用 SQL 语句即可完成机器学习模型管理与推理的完整流程。如创建模型可使用CREATE MODEL语句、使用模型进行推理可使用CALL INFERENCE(…)语句等,使用更加简单便捷。
  • 避免数据迁移:使用 IoTDB 原生机器学习可以将存储在 IoTDB 中的数据直接应用于机器学习模型的推理,无需将数据移动到单独的机器学习服务平台,从而加速数据处理、提高安全性并降低成本。

  • 内置先进算法:支持业内领先机器学习分析算法,覆盖典型时序分析任务,为时序数据库赋能原生数据分析能力。如:
    • 时间序列预测(Time Series Forecasting):从过去时间序列中学习变化模式;从而根据给定过去时间的观测值,输出未来序列最可能的预测。
    • 时序异常检测(Anomaly Detection for Time Series):在给定的时间序列数据中检测和识别异常值,帮助发现时间序列中的异常行为。
    • 时间序列标注(Time Series Annotation):为每个数据点或特定时间段添加额外的信息或标记,例如事件发生、异常点、趋势变化等,以便更好地理解和分析数据。

2. 基本概念

  • 模型(Model):机器学习模型,以时序数据作为输入,输出分析任务的结果或决策。模型是 AINode 的基本管理单元,支持模型的增(注册)、删、查、用(推理)。
  • 创建(Create): 将外部设计或训练好的模型文件或算法加载到 AINode 中,由 IoTDB 统一管理与使用。
  • 推理(Inference):使用创建的模型在指定时序数据上完成该模型适用的时序分析任务。
  • 内置能力(Built-in):AINode 自带常见时序分析场景(例如预测与异常检测)的机器学习算法或自研模型。

3. 安装部署

AINode 的部署可参考文档 部署指导 章节。

4. 使用指导

AINode 对时序模型提供了模型创建及删除功能,内置模型无需创建,可直接使用。

4.1 注册模型

通过指定模型输入输出的向量维度,可以注册训练好的深度学习模型,从而用于模型推理。

符合以下内容的模型可以注册到AINode中:

  1. AINode 目前支持基于 PyTorch 2.4.0 版本训练的模型,需避免使用 2.4.0 版本以上的特性。
  2. AINode 支持使用 PyTorch JIT 存储的模型(<font style="color:rgb(60, 60, 67);">model.pt</font>),模型文件需要包含模型的结构和权重。
  3. 模型输入序列可以包含一列或多列,若有多列,需要和模型能力、模型配置文件对应。
  4. 模型的配置参数必须在<font style="color:rgb(60, 60, 67);">config.yaml</font>配置文件中明确定义。使用模型时,必须严格按照<font style="color:rgb(60, 60, 67);">config.yaml</font>配置文件中定义的输入输出维度。如果输入输出列数不匹配配置文件,将会导致错误。

下方为模型注册的SQL语法定义。

create model <model_name> using uri <uri>

SQL中参数的具体含义如下:

  • model_name:模型的全局唯一标识,不可重复。模型名称具备以下约束:
    • 允许出现标识符 [ 0-9 a-z A-Z _ ] (字母,数字,下划线)
    • 长度限制为2-64字符
    • 大小写敏感
  • uri:模型注册文件的资源路径,路径下应包含模型结构及权重文件**** model.pt ****文件和模型配置文件 config.yaml
    • 模型结构及权重文件:模型训练完成后得到的权重文件,目前支持 pytorch 训练得到的 .pt 文件
    • 模型配置文件:模型注册时需要提供的与模型结构有关的参数,其中必须包含模型的输入输出维度用于模型推理:
参数名 参数描述 示例
input_shape 模型输入的行列,用于模型推理 [96,2]
output_shape 模型输出的行列,用于模型推理 [48,2]
    * <font style="color:rgb(60, 60, 67);">除了模型推理外,还可以指定模型输入输出的数据类型:</font>
参数名 参数描述 示例
input_type 模型输入的数据类型 [‘float32’,‘float32’]
output_type 模型输出的数据类型 [‘float32’,‘float32’]
    * <font style="color:rgb(60, 60, 67);">除此之外,可以额外指定备注信息用于在模型管理时进行展示</font>
参数名 参数描述 示例
attributes 可选,用户自行设定的模型备注信息,用于模型展示 ‘model_type’: ‘dlinear’,‘kernel_size’: ‘25’

除了本地模型文件的注册,还可以通过URI来指定远程资源路径来进行注册,使用开源的模型仓库(例如HuggingFace)。

示例

在当前的example文件夹下,包含model.pt和config.yaml文件,model.pt为训练得到,config.yaml的内容如下:

configs:                
    # 必选项
    input_shape: [96, 2]      # 表示模型接收的数据为96行x2列
    output_shape: [48, 2]     # 表示模型输出的数据为48行x2列
    
    # 可选项 默认为全部float32,列数为shape对应的列数
    input_type: ["int64","int64"] #输入对应的数据类型,需要与输入列数匹配
    output_type: ["text","int64"] #输出对应的数据类型,需要与输出列数匹配

attributes:           # 可选项 为用户自定义的备注信息
   'model_type': 'dlinear'
   'kernel_size': '25'

指定该文件夹作为加载路径就可以注册该模型

IoTDB> create model dlinear_example using uri "file://./example"

也可以从huggingFace上下载对应的模型文件进行注册

IoTDB> create model dlinear_example using uri "https://huggingface.co/google/timesfm-2.0-500m-pytorch"

SQL执行后会异步进行注册的流程,可以通过模型展示查看模型的注册状态(见模型展示章节),注册成功的耗时主要受到模型文件大小的影响。

模型注册完成后,就可以通过使用正常查询的方式调用具体函数,进行模型推理。

4.2 查看模型

注册成功的模型可以通过show models指令查询模型的具体信息。其SQL定义如下:

show models

show models <model_name>

除了直接展示所有模型的信息外,可以指定model id来查看某一具体模型的信息。模型展示的结果中包含如下信息:

ModelId State Configs Attributes
模型唯一标识 模型注册状态(INACTIVE,LOADING,ACTIVE,DROPPING) InputShape, outputShapeInputTypes, outputTypes 模型备注信息

其中,State用于展示当前模型注册的状态,包含以下三个阶段

  • INACTIVE:模型处于不可用状态
  • LOADING:模型加载中状态
  • ACTIVE:模型处于可用状态
  • DROPPING:模型删除中状态
示例
IoTDB> show models

+---------------------+--------------------+--------+--------+
|              ModelId|           ModelType|Category|   State|
+---------------------+--------------------+--------+--------+
|                arima|               Arima|BUILT-IN|  ACTIVE|
|          holtwinters|         HoltWinters|BUILT-IN|  ACTIVE|
|exponential_smoothing|ExponentialSmoothing|BUILT-IN|  ACTIVE|
|     naive_forecaster|     NaiveForecaster|BUILT-IN|  ACTIVE|
|       stl_forecaster|       StlForecaster|BUILT-IN|  ACTIVE|
|         gaussian_hmm|         GaussianHmm|BUILT-IN|  ACTIVE|
|              gmm_hmm|              GmmHmm|BUILT-IN|  ACTIVE|
|                stray|               Stray|BUILT-IN|  ACTIVE|
|             timer_xl|            Timer-XL|BUILT-IN|  ACTIVE|
|              sundial|       Timer-Sundial|BUILT-IN|  ACTIVE|
+---------------------+--------------------+--------+--------+

4.3 删除模型

对于注册成功的模型,用户可以通过SQL进行删除,该操作会删除所有 AINode 下的相关模型文件,其SQL如下:

drop model <model_id>

需要指定已经成功注册的模型 model_id 来删除对应的模型。由于模型删除涉及模型数据清理,操作不会立即完成,此时模型的状态为 DROPPING,该状态的模型不能用于模型推理。请注意,该功能不支持删除内置模型。

4.4 使用内置模型推理

SQL语法如下:

call inference(<model_id>,inputSql,(<parameterName>=<parameterValue>)*)

window_function:
    head(window_size)
    tail(window_size)
    count(window_size,sliding_step)

内置模型推理无需注册流程,通过call关键字,调用inference函数就可以使用模型的推理功能,其对应的参数介绍如下:

  • model_id: 模型名称
  • parameterName:参数名
  • parameterValue:参数值

请注意,使用内置时序大模型进行推理的前提条件是本地存有对应模型权重,目录为 /IOTDB_AINODE_HOME/data/ainode/models/weights/model_id/。若本地没有模型权重,则会自动从 HuggingFace 拉取,请保证本地能直接访问 HuggingFace。

内置模型及参数说明

目前已内置如下机器学习模型,具体参数说明请参考以下链接。

模型 built_in_model_name 任务类型 参数说明
Arima _Arima 预测 Arima参数说明
STLForecaster _STLForecaster 预测 STLForecaster参数说明
NaiveForecaster _NaiveForecaster 预测 NaiveForecaster参数说明
ExponentialSmoothing _ExponentialSmoothing 预测 ExponentialSmoothing参数说明
GaussianHMM _GaussianHMM 标注 GaussianHMM参数说明
GMMHMM _GMMHMM 标注 GMMHMM参数说明
Stray _Stray 异常检测 Stray参数说明

在完成模型的注册后,通过call关键字,调用inference函数就可以使用模型的推理功能,其对应的参数介绍如下:

  • model_name: 对应一个已经注册的模型
  • sql:sql查询语句,查询的结果作为模型的输入进行模型推理。查询的结果中行列的维度需要与具体模型config中指定的大小相匹配。(这里的sql不建议使用<font style="color:rgb(60, 60, 67);">SELECT *</font>子句,因为在IoTDB中,<font style="color:rgb(60, 60, 67);">*</font>并不会对列进行排序,因此列的顺序是未定义的,可以使用<font style="color:rgb(60, 60, 67);">SELECT s0,s1</font>的方式确保列的顺序符合模型输入的预期)
  • window_function: 推理过程中可以使用的窗口函数,目前提供三种类型的窗口函数用于辅助模型推理:
    • head(window_size): 获取数据中最前的window_size个点用于模型推理,该窗口可用于数据裁剪
    • tail(window_size):获取数据中最后的window_size个点用于模型推,该窗口可用于数据裁剪
    • count(window_size, sliding_step):基于点数的滑动窗口,每个窗口的数据会分别通过模型进行推理,如下图示例所示,window_size为2的窗口函数将输入数据集分为三个窗口,每个窗口分别进行推理运算生成结果。该窗口可用于连续推理

说明1: window可以用来解决sql查询结果和模型的输入行数要求不一致时的问题,对行进行裁剪。需要注意的是,当列数不匹配或是行数直接少于模型需求时,推理无法进行,会返回错误信息。

说明2: 在深度学习应用中,经常将时间戳衍生特征(数据中的时间列)作为生成式任务的协变量,一同输入到模型中以提升模型的效果,但是在模型的输出结果中一般不包含时间列。为了保证实现的通用性,模型推理结果只对应模型的真实输出,如果模型不输出时间列,则结果中不会包含。

示例

下面是使用深度学习模型推理的一个操作示例,针对上面提到的输入为<font style="color:rgb(60, 60, 67);">[96,2]</font>,输出为<font style="color:rgb(60, 60, 67);">[48,2]</font><font style="color:rgb(60, 60, 67);">dlinear</font>预测模型,我们通过SQL使用其进行推理。

IoTDB> select s1,s2 from root.**
+-----------------------------+-------------------+-------------------+
|                         Time|    root.eg.etth.s0|    root.eg.etth.s1|
+-----------------------------+-------------------+-------------------+
|1990-01-01T00:00:00.000+08:00|             0.7855|              1.611|
|1990-01-02T00:00:00.000+08:00|             0.7818|               1.61|
|1990-01-03T00:00:00.000+08:00|             0.7867|             1.6293|
|1990-01-04T00:00:00.000+08:00|              0.786|              1.637|
|1990-01-05T00:00:00.000+08:00|             0.7849|              1.653|
|1990-01-06T00:00:00.000+08:00|             0.7866|             1.6537|
|1990-01-07T00:00:00.000+08:00|             0.7886|              1.662|
......
|1990-03-31T00:00:00.000+08:00|             0.7585|              1.678|
|1990-04-01T00:00:00.000+08:00|             0.7587|             1.6763|
|1990-04-02T00:00:00.000+08:00|               0.76|             1.6813|
|1990-04-03T00:00:00.000+08:00|             0.7669|              1.684|
|1990-04-04T00:00:00.000+08:00|             0.7645|              1.677|
|1990-04-05T00:00:00.000+08:00|             0.7625|               1.68|
|1990-04-06T00:00:00.000+08:00|             0.7617|             1.6917|
+-----------------------------+-------------------+-------------------+
Total line number = 96

IoTDB> call inference(dlinear_example,"select s0,s1 from root.**", generateTime=True)
+-----------------------------+--------------------------------------------+-----------------------------+
|                         Time|                                   _result_0|                    _result_1|
+-----------------------------+--------------------------------------------+-----------------------------+
|1990-04-06T00:00:00.000+08:00|                           0.726302981376648|           1.6549958229064941|
|1990-04-08T00:00:00.000+08:00|                          0.7354921698570251|           1.6482787370681763|
|1990-04-10T00:00:00.000+08:00|                          0.7238251566886902|           1.6278168201446533|
......
|1990-07-07T00:00:00.000+08:00|                          0.7692174911499023|            1.654654049873352|
|1990-07-09T00:00:00.000+08:00|                          0.7685555815696716|           1.6625318765640259|
|1990-07-11T00:00:00.000+08:00|                          0.7856493592262268|           1.6508299350738525|
+-----------------------------+--------------------------------------------+-----------------------------+
Total line number = 48
使用tail/head窗口函数的示例

当数据量不定且想要取96行最新数据用于推理时,可以使用对应的窗口函数tail。head函数的用法与其类似,不同点在于其取的是最早的96个点。

IoTDB> select s1,s2 from root.**
+-----------------------------+-------------------+-------------------+
|                         Time|    root.eg.etth.s0|    root.eg.etth.s1|
+-----------------------------+-------------------+-------------------+
|1988-01-01T00:00:00.000+08:00|             0.7355|              1.211|
......
|1990-01-01T00:00:00.000+08:00|             0.7855|              1.611|
|1990-01-02T00:00:00.000+08:00|             0.7818|               1.61|
|1990-01-03T00:00:00.000+08:00|             0.7867|             1.6293|
|1990-01-04T00:00:00.000+08:00|              0.786|              1.637|
|1990-01-05T00:00:00.000+08:00|             0.7849|              1.653|
|1990-01-06T00:00:00.000+08:00|             0.7866|             1.6537|
|1990-01-07T00:00:00.000+08:00|             0.7886|              1.662|
......
|1990-03-31T00:00:00.000+08:00|             0.7585|              1.678|
|1990-04-01T00:00:00.000+08:00|             0.7587|             1.6763|
|1990-04-02T00:00:00.000+08:00|               0.76|             1.6813|
|1990-04-03T00:00:00.000+08:00|             0.7669|              1.684|
|1990-04-04T00:00:00.000+08:00|             0.7645|              1.677|
|1990-04-05T00:00:00.000+08:00|             0.7625|               1.68|
|1990-04-06T00:00:00.000+08:00|             0.7617|             1.6917|
+-----------------------------+-------------------+-------------------+
Total line number = 996

IoTDB> call inference(dlinear_example,"select s0,s1 from root.**", generateTime=True, window=tail(96))
+-----------------------------+--------------------------------------------+-----------------------------+
|                         Time|                                   _result_0|                    _result_1|
+-----------------------------+--------------------------------------------+-----------------------------+
|1990-04-06T00:00:00.000+08:00|                           0.726302981376648|           1.6549958229064941|
|1990-04-08T00:00:00.000+08:00|                          0.7354921698570251|           1.6482787370681763|
|1990-04-10T00:00:00.000+08:00|                          0.7238251566886902|           1.6278168201446533|
......
|1990-07-07T00:00:00.000+08:00|                          0.7692174911499023|            1.654654049873352|
|1990-07-09T00:00:00.000+08:00|                          0.7685555815696716|           1.6625318765640259|
|1990-07-11T00:00:00.000+08:00|                          0.7856493592262268|           1.6508299350738525|
+-----------------------------+--------------------------------------------+-----------------------------+
Total line number = 48
使用count窗口函数的示例

该窗口主要用于计算式任务,当任务对应的模型一次只能处理固定行数据而最终想要的确实多组预测结果时,使用该窗口函数可以使用点数滑动窗口进行连续推理。假设我们现在有一个异常检测模型anomaly_example(input: [24,2], output[1,1]),对每24行数据会生成一个0/1的标签,其使用示例如下:

IoTDB> select s1,s2 from root.**
+-----------------------------+-------------------+-------------------+
|                         Time|    root.eg.etth.s0|    root.eg.etth.s1|
+-----------------------------+-------------------+-------------------+
|1990-01-01T00:00:00.000+08:00|             0.7855|              1.611|
|1990-01-02T00:00:00.000+08:00|             0.7818|               1.61|
|1990-01-03T00:00:00.000+08:00|             0.7867|             1.6293|
|1990-01-04T00:00:00.000+08:00|              0.786|              1.637|
|1990-01-05T00:00:00.000+08:00|             0.7849|              1.653|
|1990-01-06T00:00:00.000+08:00|             0.7866|             1.6537|
|1990-01-07T00:00:00.000+08:00|             0.7886|              1.662|
......
|1990-03-31T00:00:00.000+08:00|             0.7585|              1.678|
|1990-04-01T00:00:00.000+08:00|             0.7587|             1.6763|
|1990-04-02T00:00:00.000+08:00|               0.76|             1.6813|
|1990-04-03T00:00:00.000+08:00|             0.7669|              1.684|
|1990-04-04T00:00:00.000+08:00|             0.7645|              1.677|
|1990-04-05T00:00:00.000+08:00|             0.7625|               1.68|
|1990-04-06T00:00:00.000+08:00|             0.7617|             1.6917|
+-----------------------------+-------------------+-------------------+
Total line number = 96

IoTDB> call inference(anomaly_example,"select s0,s1 from root.**", generateTime=True, window=count(24,24))
+-----------------------------+-------------------------+
|                         Time|                _result_0|
+-----------------------------+-------------------------+
|1990-04-06T00:00:00.000+08:00|                        0|
|1990-04-30T00:00:00.000+08:00|                        1|
|1990-05-24T00:00:00.000+08:00|                        1|
|1990-06-17T00:00:00.000+08:00|                        0|
+-----------------------------+-------------------------+
Total line number = 4

其中结果集中每行的标签对应每24行数据为一组,输入该异常检测模型后的输出。

5. 权限管理

使用AINode相关的功能时,可以使用IoTDB本身的鉴权去做一个权限管理,用户只有在具备 USE_MODEL 权限时,才可以使用模型管理的相关功能。当使用推理功能时,用户需要有访问输入模型的SQL对应的源序列的权限。

权限名称 权限范围 管理员用户(默认ROOT) 普通用户 路径相关
USE_MODEL create model / show models / drop model x
READ_DATA call inference

6. 实际案例

6.1 电力负载预测

在部分工业场景下,会存在预测电力负载的需求,预测结果可用于优化电力供应、节约能源和资源、支持规划和扩展以及增强电力系统的可靠性。

我们所使用的 ETTh1 的测试集的数据为ETTh1

包含间隔1h采集一次的电力数据,每条数据由负载和油温构成,分别为:High UseFul Load, High UseLess Load, Middle UseLess Load, Low UseFul Load, Low UseLess Load, Oil Temperature。

在该数据集上,IoTDB-ML的模型推理功能可以通过以往高中低三种负载的数值和对应时间戳油温的关系,预测未来一段时间内的油温,赋能电网变压器的自动调控和监视。

步骤一:数据导入

用户可以使用tools文件夹中的<font style="color:rgb(60, 60, 67);">import-csv.sh</font> 向 IoTDB 中导入 ETT 数据集

bash ./import-csv.sh -h 127.0.0.1 -p 6667 -u root -pw root -f ../../ETTh1.csv
步骤二:模型导入

我们可以在iotdb-cli 中输入以下SQL从 huggingface 上拉取一个已经训练好的模型进行注册,用于后续的推理。

create model dlinear using uri 'https://huggingface.co/hvlgo/dlinear/tree/main'

该模型基于较为轻量化的深度模型DLinear训练而得,能够以相对快的推理速度尽可能多地捕捉到序列内部的变化趋势和变量间的数据变化关系,相较于其他更深的模型更适用于快速实时预测。

步骤三:模型推理
IoTDB> select s0,s1,s2,s3,s4,s5,s6 from root.eg.etth LIMIT 96
+-----------------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
|                         Time|root.eg.etth.s0|root.eg.etth.s1|root.eg.etth.s2|root.eg.etth.s3|root.eg.etth.s4|root.eg.etth.s5|root.eg.etth.s6|
+-----------------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
|2017-10-20T00:00:00.000+08:00|         10.449|          3.885|          8.706|          2.025|          2.041|          0.944|          8.864|
|2017-10-20T01:00:00.000+08:00|         11.119|          3.952|          8.813|           2.31|          2.071|          1.005|          8.442|
|2017-10-20T02:00:00.000+08:00|          9.511|           2.88|          7.533|          1.564|          1.949|          0.883|           8.16|
|2017-10-20T03:00:00.000+08:00|          9.645|           2.21|          7.249|          1.066|          1.828|          0.914|          7.949|
......
|2017-10-23T20:00:00.000+08:00|          8.105|          0.938|          4.371|         -0.569|          3.533|          1.279|          9.708|
|2017-10-23T21:00:00.000+08:00|          7.167|          1.206|          4.087|         -0.462|          3.107|          1.432|          8.723|
|2017-10-23T22:00:00.000+08:00|            7.1|           1.34|          4.015|          -0.32|          2.772|           1.31|          8.864|
|2017-10-23T23:00:00.000+08:00|          9.176|          2.746|          7.107|          1.635|           2.65|          1.097|          9.004|
+-----------------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
Total line number = 96

IoTDB> call inference(dlinear_example, "select s0,s1,s2,s3,s4,s5,s6 from root.eg.etth", generateTime=True, window=head(96))
+-----------------------------+-----------+----------+----------+------------+---------+----------+----------+
|                         Time|    output0|   output1|   output2|     output3|  output4|   output5|   output6|
+-----------------------------+-----------+----------+----------+------------+---------+----------+----------+
|2017-10-23T23:00:00.000+08:00|  10.319546| 3.1450553|  7.877341|   1.5723765|2.7303758| 1.1362307|  8.867775|
|2017-10-24T01:00:00.000+08:00|  10.443649| 3.3286757| 7.8593454|   1.7675098| 2.560634| 1.1177158|  8.920919|
|2017-10-24T03:00:00.000+08:00|  10.883752| 3.2341104|   8.47036|   1.6116762|2.4874182| 1.1760603|  8.798939| 
......
|2017-10-26T19:00:00.000+08:00|  8.0115595| 1.2995274| 6.9900327|-0.098746896|  3.04923|  1.176214|  9.548782|
|2017-10-26T21:00:00.000+08:00|   8.612427| 2.5036244| 5.6790237|  0.66474205|2.8870275| 1.2051733|  9.330128|
|2017-10-26T22:00:00.000+08:00|  10.096699|  3.399722|    6.9909|   1.7478468|2.7642853| 1.1119363|  9.541455|
+-----------------------------+-----------+----------+----------+------------+---------+----------+----------+
Total line number = 48

我们将对油温的预测的结果和真实结果进行对比,可以得到以下的图像。

图中10/24 00:00之前的数据为输入模型的过去数据,10/24 00:00后的蓝色线条为模型给出的油温预测结果,而红色为数据集中实际的油温数据(用于进行对比)。

可以看到,我们使用了过去96个小时(4天)的六个负载信息和对应时间油温的关系,基于之前学习到的序列间相互关系对未来48个小时(2天)的油温这一数据的可能变化进行了建模,可以看到可视化后预测曲线与实际结果在趋势上保持了较高程度的一致性。

6.2 功率预测

变电站需要对电流、电压、功率等数据进行电力监控,用于检测潜在的电网问题、识别电力系统中的故障、有效管理电网负载以及分析电力系统的性能和趋势等。

我们利用某变电站中的电流、电压和功率等数据构成了真实场景下的数据集。该数据集包括变电站近四个月时间跨度,每5 - 6s 采集一次的 A相电压、B相电压、C相电压等数据。

测试集数据内容为data

在该数据集上,IoTDB-ML的模型推理功能可以通过以往A相电压,B相电压和C相电压的数值和对应时间戳,预测未来一段时间内的C相电压,赋能变电站的监视管理。

步骤一:数据导入

用户可以使用tools文件夹中的<font style="color:rgb(60, 60, 67);">import-csv.sh</font> 导入数据集

bash ./import-csv.sh -h 127.0.0.1 -p 6667 -u root -pw root -f ../../data.csv
步骤二:模型导入

我们可以在iotdb-cli 中选择内置模型或已经注册好的模型用于后续的推理。

我们采用内置模型STLForecaster进行预测,STLForecaster 是一个基于 statsmodels 库中 STL 实现的时间序列预测方法。

步骤三:模型推理
IoTDB> select * from root.eg.voltage limit 96
+-----------------------------+------------------+------------------+------------------+
|                         Time|root.eg.voltage.s0|root.eg.voltage.s1|root.eg.voltage.s2|
+-----------------------------+------------------+------------------+------------------+
|2023-02-14T20:38:32.000+08:00|            2038.0|            2028.0|            2041.0|
|2023-02-14T20:38:38.000+08:00|            2014.0|            2005.0|            2018.0|
|2023-02-14T20:38:44.000+08:00|            2014.0|            2005.0|            2018.0|
......
|2023-02-14T20:47:52.000+08:00|            2024.0|            2016.0|            2027.0|
|2023-02-14T20:47:57.000+08:00|            2024.0|            2016.0|            2027.0|
|2023-02-14T20:48:03.000+08:00|            2024.0|            2016.0|            2027.0|
+-----------------------------+------------------+------------------+------------------+
Total line number = 96

IoTDB> call inference(_STLForecaster, "select s0,s1,s2 from root.eg.voltage", generateTime=True, window=head(96),predict_length=48)
+-----------------------------+---------+---------+---------+
|                         Time|  output0|  output1|  output2|
+-----------------------------+---------+---------+---------+
|2023-02-14T20:48:03.000+08:00|2026.3601|2018.2953|2029.4257|
|2023-02-14T20:48:09.000+08:00|2019.1538|2011.4361|2022.0888|
|2023-02-14T20:48:15.000+08:00|2025.5074|2017.4522|2028.5199|
......

|2023-02-14T20:52:15.000+08:00|2022.2336|2015.0290|2025.1023|
|2023-02-14T20:52:21.000+08:00|2015.7241|2008.8975|2018.5085|
|2023-02-14T20:52:27.000+08:00|2022.0777|2014.9136|2024.9396|
|2023-02-14T20:52:33.000+08:00|2015.5682|2008.7821|2018.3458|
+-----------------------------+---------+---------+---------+
Total line number = 48

我们将对C相电压的预测的结果和真实结果进行对比,可以得到以下的图像。

图中 02/14 20:48 之前的数据为输入模型的过去数据, 02/14 20:48 后的蓝色线条为模型给出的C相电压预测结果,而红色为数据集中实际的C相电压数据(用于进行对比)。

可以看到,我们使用了过去10分钟的电压的数据,基于之前学习到的序列间相互关系对未来5分钟的C相电压这一数据的可能变化进行了建模,可以看到可视化后预测曲线与实际结果在趋势上保持了一定的同步性。

6.3 异常检测

在民航交通运输业,存在着对乘机旅客数量进行异常检测的需求。异常检测的结果可用于指导调整航班的调度,以使得企业获得更大效益。

Airline Passengers一个时间序列数据集,该数据集记录了1949年至1960年期间国际航空乘客数量,间隔一个月进行一次采样。该数据集共含一条时间序列。数据集为airline
在该数据集上,IoTDB-ML的模型推理功能可以通过捕捉序列的变化规律以对序列时间点进行异常检测,赋能交通运输业。

步骤一:数据导入

用户可以使用tools文件夹中的<font style="color:rgb(60, 60, 67);">import-csv.sh</font> 导入数据集

bash ./import-csv.sh -h 127.0.0.1 -p 6667 -u root -pw root -f ../../data.csv
步骤二:模型推理

IoTDB内置有部分可以直接使用的机器学习算法,使用其中的异常检测算法进行预测的样例如下:

IoTDB> select * from root.eg.airline
+-----------------------------+------------------+
|                         Time|root.eg.airline.s0|
+-----------------------------+------------------+
|1949-01-31T00:00:00.000+08:00|             224.0|
|1949-02-28T00:00:00.000+08:00|             118.0|
|1949-03-31T00:00:00.000+08:00|             132.0|
|1949-04-30T00:00:00.000+08:00|             129.0|
......
|1960-09-30T00:00:00.000+08:00|             508.0|
|1960-10-31T00:00:00.000+08:00|             461.0|
|1960-11-30T00:00:00.000+08:00|             390.0|
|1960-12-31T00:00:00.000+08:00|             432.0|
+-----------------------------+------------------+
Total line number = 144

IoTDB> call inference(_Stray, "select s0 from root.eg.airline", generateTime=True, k=2)
+-----------------------------+-------+
|                         Time|output0|
+-----------------------------+-------+
|1960-12-31T00:00:00.000+08:00|      0|
|1961-01-31T08:00:00.000+08:00|      0|
|1961-02-28T08:00:00.000+08:00|      0|
|1961-03-31T08:00:00.000+08:00|      0|
......
|1972-06-30T08:00:00.000+08:00|      1|
|1972-07-31T08:00:00.000+08:00|      1|
|1972-08-31T08:00:00.000+08:00|      0|
|1972-09-30T08:00:00.000+08:00|      0|
|1972-10-31T08:00:00.000+08:00|      0|
|1972-11-30T08:00:00.000+08:00|      0|
+-----------------------------+-------+
Total line number = 144

我们将检测为异常的结果进行绘制,可以得到以下图像。其中蓝色曲线为原时间序列,用红色点特殊标注的时间点为算法检测为异常的时间点。

可以看到,Stray模型对输入序列变化进行了建模,成功检测出出现异常的时间点。

🌐 附:IoTDB的各大版本

📄 Apache IoTDB 是一款工业物联网时序数据库管理系统,采用端边云协同的轻量化架构,支持一体化的物联网时序数据收集、存储、管理与分析 ,具有多协议兼容、超高压缩比、高通量读写、工业级稳定、极简运维等特点。

版本 IoTDB 二进制包 IoTDB 源代码 发布说明
2.0.5 - All-in-one
- AINode
- SHA512
- ASC
- 源代码
- SHA512
- ASC
release notes
1.3.5 - All-in-one
- AINode
- SHA512
- ASC
- 源代码
- SHA512
- ASC
release notes
0.13.4 - All-in-one
- Grafana 连接器
- Grafana 插件
- SHA512
- ASC
- 源代码
- SHA512
- ASC
release notes

✨ 去获取:https://archive.apache.org/dist/iotdb/

联系博主

    xcLeigh 博主全栈领域优质创作者,博客专家,目前,活跃在CSDN、微信公众号、小红书、知乎、掘金、快手、思否、微博、51CTO、B站、腾讯云开发者社区、阿里云开发者社区等平台,全网拥有几十万的粉丝,全网统一IP为 xcLeigh。希望通过我的分享,让大家能在喜悦的情况下收获到有用的知识。主要分享编程、开发工具、算法、技术学习心得等内容。很多读者评价他的文章简洁易懂,尤其对于一些复杂的技术话题,他能通过通俗的语言来解释,帮助初学者更好地理解。博客通常也会涉及一些实践经验,项目分享以及解决实际开发中遇到的问题。如果你是开发领域的初学者,或者在学习一些新的编程语言或框架,关注他的文章对你有很大帮助。

    亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。

     愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。

    至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。


     💞 关注博主 🌀 带你实现畅游前后端!

     🏰 大屏可视化 🌀 带你体验酷炫大屏!

     💯 神秘个人简介 🌀 带你体验不一样得介绍!

     🥇 从零到一学习Python 🌀 带你玩转Python技术流!

     🏆 前沿应用深度测评 🌀 前沿AI产品热门应用在线等你来发掘!

     💦 :本文撰写于CSDN平台,作者:xcLeigh所有权归作者所有)https://xcleigh.blog.csdn.net/,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。


在这里插入图片描述

     📣 亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(或者关注下方公众号,看见后第一时间回复,还有海量编程资料等你来领!),博主看见后一定及时给您答复 💌💌💌

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐