ORACLE数据挖掘之 MSET-SPRT

虽然是熟悉的Oracle数据库,但关于机器学习、数据挖掘这方面的知识笔者起初也是不了解的,文中MSET相关设置来源于同事提供的sample,在测试过程中边查资料边学习吸收,也因此看到了别样的Oracle。

Oracle 的 MSET-SPRT 主要用于 高精度异常检测和预测性维护,尤其适用于关键业务系统,如数据库、存储、工业控制系统和数据中心运营环境。

MSET-SPRT翻译成中文是:多变量状态估计技术 - 序列概率比检验。

个人感觉这个名词翻译过来有些绕口.. 下面还是以英文简写词来代替。

在ORACLE官方文档中,是这样描述 MSET-SPRT 的:

The Multivariate State Estimation Technique - Sequential Probability Ratio Test (MSET-SPRT) algorithm monitors critical processes and detects subtle anomalies.

下面记录下MSET的测试过程,这里直接复用之前用于测试TPC-H的环境来验证:

  • 1.新建测试表和配置表
  • 2.创建构造测试数据的存储过程
  • 3.模拟不同规模测试数据并插入
  • 4.创建数据挖掘模型
  • 5.查询预测结果
  • 6.其他测试建议

1.新建测试表和配置表

这里只选择有实际意义的字段,构建TBL_IOT表:

sql 复制代码
  CREATE TABLE "TPCH"."TBL_IOT" 
   ("B1_T1" NUMBER(38,0), 
	"B1_T2" NUMBER(38,0), 
	"B1_T3" NUMBER(38,0), 
	"B2_T1" NUMBER(38,0), 
	"B2_T2" NUMBER(38,0), 
	"B2_T3" NUMBER(38,0), 
	"B3_T1" NUMBER(38,0), 
	"B3_T2" NUMBER(38,0), 
	"B3_T3" NUMBER(38,0), 
	"B4_T1" NUMBER(38,0), 
	"B4_T2" NUMBER(38,0), 
	"B4_T3" NUMBER(38,0), 
	"B5_T1" NUMBER(38,0), 
	"B5_T2" NUMBER(38,0), 
	"B5_T3" NUMBER(38,0), 
	"B6_T1" NUMBER(38,0), 
	"B6_T2" NUMBER(38,0), 
	"B6_T3" NUMBER(38,0), 
	"B7_T1" NUMBER(38,0), 
	"B7_T2" NUMBER(38,0), 
	"B7_T3" NUMBER(38,0), 
	"B8_T1" NUMBER(38,0), 
	"B8_T2" NUMBER(38,0), 
	"B8_T3" NUMBER(38,0), 
	"B9_T1" NUMBER(38,0), 
	"B9_T2" NUMBER(38,0), 
	"B9_T3" NUMBER(38,0), 
	"B10_T1" NUMBER(38,0), 
	"B10_T2" NUMBER(38,0), 
	"B10_T3" NUMBER(38,0), 
	"B11_T1" NUMBER(38,0), 
	"B11_T2" NUMBER(38,0), 
	"B11_T3" NUMBER(38,0), 
	"B12_T1" NUMBER(38,0), 
	"B12_T2" NUMBER(38,0), 
	"B12_T3" NUMBER(38,0), 
	"S" NUMBER(38,1), 
	"K_TS" TIMESTAMP (6)
   );

创建 MSET_IOT_SETTINGS 表,用于存储数据挖掘算法的配置,插入 MSET-SPRT 算法的关键参数:

  • 选择 MSET-SPRT 算法
  • 开启自动数据准备
  • 设置向量存储大小
  • 设定 Alpha(假阳性)概率
  • 设定异常警报阈值(次数 & 窗口大小)
sql 复制代码
-- Create setting table        
CREATE TABLE MSET_IOT_SETTINGS(SETTING_NAME VARCHAR2(30), 
                             SETTING_VALUE VARCHAR2(128));
-- Populate setting table
BEGIN
  -- Select MSET-SPRT as the algorithm
  INSERT INTO MSET_IOT_SETTINGS
         VALUES(DBMS_DATA_MINING.ALGO_NAME,
                DBMS_DATA_MINING.ALGO_MSET_SPRT);
  -- Turn on automatic data preparation   
  INSERT INTO MSET_IOT_SETTINGS
         VALUES(DBMS_DATA_MINING.PREP_AUTO,
                DBMS_DATA_MINING.PREP_AUTO_ON);
  -- Set memory vector
  INSERT INTO MSET_IOT_SETTINGS
    VALUES(DBMS_DATA_MINING.MSET_MEMORY_VECTORS, 100);
  -- Set alpha
  INSERT INTO MSET_IOT_SETTINGS
    VALUES(DBMS_DATA_MINING.MSET_ALPHA_PROB, 0.1);
  -- Set alert count
  INSERT INTO MSET_IOT_SETTINGS
    VALUES(DBMS_DATA_MINING.MSET_ALERT_COUNT, 3);
  -- Set alert window
  INSERT INTO MSET_IOT_SETTINGS
    VALUES(DBMS_DATA_MINING.MSET_ALERT_WINDOW, 5);  
  -- Examples of other possible settings are:
  -- (dbms_data_mining.mset_beta_prob, 0.1)
  -- (dbms_data_mining.mset_adb_height, 0.01)
  -- (dbms_data_mining.mset_std_tolerance, 3)
  -- (dbms_data_mining.mset_heldaside, 500)
  COMMIT;  
END;
/

2.创建构造测试数据的存储过程

具体创建一个存储过程,传入行数作为参数,这样方便随时插入不同规模的数据。

这里模拟IOT场景,要求每秒一条数据。

插入数据前需要手工清空表,因为防止误操作,我没有将truncate表的高危命令直接写入到存储过程中,在执行存储过程之前,由人工来执行truncate表操作,用于插入数据的存储过程如下:

sql 复制代码
CREATE OR REPLACE PROCEDURE INSERT_IOT_DATA(p_total_rows IN NUMBER) AS
    v_start_time TIMESTAMP := TO_TIMESTAMP('2025-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS');
BEGIN
    FOR i IN 1..p_total_rows LOOP
        INSERT INTO TBL_IOT (
            B1_T1, B1_T2, B1_T3, B2_T1, B2_T2, B2_T3, B3_T1, B3_T2, B3_T3, 
            B4_T1, B4_T2, B4_T3, B5_T1, B5_T2, B5_T3, B6_T1, B6_T2, B6_T3, 
            B7_T1, B7_T2, B7_T3, B8_T1, B8_T2, B8_T3, B9_T1, B9_T2, B9_T3, 
            B10_T1, B10_T2, B10_T3, B11_T1, B11_T2, B11_T3, B12_T1, B12_T2, B12_T3, 
            S, K_TS
        ) VALUES (
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), 
            DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55), DBMS_RANDOM.VALUE(50, 55),
            DBMS_RANDOM.VALUE(2, 5), 
            v_start_time + INTERVAL '1' SECOND * i
        );
        
        IF MOD(i, 1000) = 0 THEN
            COMMIT;
        END IF;
    END LOOP;
    
    COMMIT;
END;
/

注意:这里构建数据我预期是插入50到55之间的随机整数,但使用DBMS_RANDOM.VALUE(50,55),实际随机是带小数的,但结果是符合预期的。这是因为当向 NUMBER(38,0) 类型的列插入带小数的数据时,Oracle 并不会报错,而是会自动截断小数部分,只保留整数部分。可手工验证数据是否符合预期。

3.模拟不同规模测试数据并插入

下面需要分别测试不同数据规模:86w、130w、260w。

插入不同规模的数据之前,需要手工truncate表:

sql 复制代码
-- 插入数据前,确保已清空表数据,高危操作手工执行:
truncate table TBL_IOT; 

-- 按需求插入不同规模数据:
-- 插入86万行
EXEC INSERT_IOT_DATA(860000); 

-- 插入130万行
EXEC INSERT_IOT_DATA(1300000); 

-- 插入260万行
EXEC INSERT_IOT_DATA(2600000); 

-- 查询表占用空间
select SEGMENT_NAME, BYTES / 1024 / 1024 "MB" from dba_segments where SEGMENT_NAME = 'TBL_IOT';

4.创建数据挖掘模型

创建数据挖掘模型IOTMSET_MODEL,如果之前存在就删除掉再创建:

sql 复制代码
-- 删除数据挖掘模型IOTMSET_MODEL
exec dbms_data_mining.drop_model('IOTMSET_MODEL'); 

-- 创建数据挖掘模型IOTMSET_MODEL
BEGIN
  dbms_data_mining.create_model(model_name => 'IOTMSET_MODEL',
               mining_function   => 'CLASSIFICATION',
               data_table_name => 'TBL_IOT', --表名
               case_id_column_name => 'K_TS', --时间戳列名
               target_column_name => '',
               settings_table_name => 'mset_iot_settings'); --配置表名
END;
/

创建模型完成后,会发现当前用户下的对象多了一系列以 DM$ 前缀命名的表和视图,这是 Oracle 数据挖掘(Oracle Data Mining, ODM)自动创建的模型存储对象,它们用于存储 MSET-SPRT 模型的相关数据。

5.查询预测结果

查询预测测试数据集的结果:

sql 复制代码
SELECT rownum, K_TS, pred FROM (SELECT K_TS, prediction(IOTMSET_MODEL using *) 
  over (ORDER BY K_TS) pred FROM tbl_iot) 
  where pred < 1 --异常
  order by 2, 1 ;

6.其他测试建议

建议在测试开始和结束,创建awr的snapshot:

  • exec DBMS_WORKLOAD_REPOSITORY.create_snapshot();

测试完成获取AWR报告:

  • @?/rdbms/admin/awrrpt
  • awrrpt_1_220_221.html

测试结果略。

相关推荐
听雪楼主.1 小时前
Oracle adg环境下调整redo日志组以及standby日志组大小
oracle·adg
消失在人海中8 小时前
oracle 会话管理
数据库·oracle
小Tomkk18 小时前
2025年5月15日前 免费考试了! Oracle AI 矢量搜索专业认证
数据库·人工智能·oracle
菲兹园长18 小时前
MySql(基础)
数据库·mysql·oracle
潇湘秦1 天前
Oracle非归档模式遇到文件损坏怎么办?
数据库·oracle
杨云龙UP1 天前
SQL Server 中的 GO 及其与其他数据库的对比
数据库·sql·mysql·oracle·sqlserver
程序员小董1 天前
关于甲骨文(oracle cloud)丢失MFA的解决方案
oracle·mfa·甲骨文·免费账号
betazhou2 天前
oracle goldengate非并行进程转换为并行进程
数据库·oracle·并行·parallel·ogg·同步数据
wuli玉shell2 天前
数仓-范式建模、维度建模、雪花模型、星型模型对比及其适用范围
数据库·oracle
ghie90902 天前
oracle dblink varchar类型查询报错记录
数据库·oracle