这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

用于预测分析的机器学习

Vertica 提供了许多用于执行数据库内分析的机器学习函数。这些函数执行数据准备、模型训练和预测任务。Vertica 支持下面的数据库内机器学习算法:

有关直接与 Vertica 数据库中的数据集成的类似 scikit 的机器学习库,请参阅 VerticaPy

有关特定机器学习函数的详细信息,请参阅机器学习函数

1 - 下载机器学习示例数据

您需要多个数据集来运行机器学习示例。可以从 Vertica GitHub 存储库下载这些数据集。

您可以通过以下两种方式之一下载示例数据:

  • 下载 ZIP 文件。将文件内容解压缩到目录中。

  • 克隆 Vertica 机器学习 GitHub 存储库。使用终端窗口,运行以下命令:

    $ git clone https://github.com/vertica/Machine-Learning-Examples
    

加载示例数据

您可以通过执行以下操作之一加载示例数据。请注意,模型不会自动删除。您必须重新运行 load_ml_data.sql 脚本来删除模型,或者手动删除模型。

  • 在 vsql 提示符或其他 Vertica 客户端中,使用 load_ml_data.sql 复制并粘贴 DDL 和 DML 操作。

  • 从 Machine-Learning-Examples 目录的 data 文件夹中的终端窗口运行以下命令:

    $ /opt/vertica/bin/vsql -d <name of your database> -f load_ml_data.sql
    

您还必须在 Machine-Learning-Examples 目录中加载 naive_bayes_data_prepration.sql 脚本:

$ /opt/vertica/bin/vsql -d <name of your database> -f ./naive_bayes/naive_bayes_data_preparation.sql

示例数据描述

存储库包含以下数据集。

2 - 数据准备

在分析数据之前,必须进行数据准备。您可以在 Vertica 中执行以下数据准备任务:

2.1 - 对不平衡的数据进行平衡

当数据中类的分布不均匀时,就会出现不平衡的数据。如果在不平衡的数据集上构建预测模型,则会导致模型看起来可产生高准确度,但不能很好地推广到少数类中的新数据。为了防止创建具有错误准确度的模型,您应该在创建预测模型之前对不平衡的数据进行重新平衡。

开始示例之前,请加载机器学习示例数据

您会在金融交易数据中看到很多不平衡的数据,其中大多数交易不是欺诈性的,少数交易是欺诈性的,如下例所示。

  1. 查看类的分布。

    => SELECT fraud, COUNT(fraud) FROM transaction_data GROUP BY fraud;
     fraud | COUNT
    -------+-------
     TRUE  |    19
     FALSE |   981
    (2 rows)
    
  2. 使用 BALANCE 函数创建更平衡的数据集。

    => SELECT BALANCE('balance_fin_data', 'transaction_data', 'fraud', 'under_sampling'
                      USING PARAMETERS sampling_ratio = 0.2);
             BALANCE
    --------------------------
     Finished in 1 iteration
    
    (1 row)
    
  3. 查看分类器的新分布。

    => SELECT fraud, COUNT(fraud) FROM balance_fin_data GROUP BY fraud;
     fraud | COUNT
    -------+-------
     t     |    19
     f     |   236
    (2 rows)
    

另请参阅

2.2 - 检测异常值

异常值是与数据集中的其他数据点有很大区别的数据点。您可以将异常值检测用于欺诈检测和系统运行状况监控等应用程序,或者您可以检测异常值并将其从数据中移除。如果在训练机器学习模型时在数据中留下异常值,则生成的模型存在偏差和偏斜预测的风险。Vertica 支持两种检测异常值的方法:DETECT_OUTLIERS 函数和 IFOREST 算法。

隔离森林

隔离森林 (iForest) 是一种无监督算法,它在异常值很少且不同的假设下运行。这种假设使异常值容易受到称为隔离的分离机制的影响。隔离不是将数据实例与每个数据特征的构造正态分布进行比较,而是关注异常值本身。

为了直接隔离异常值,iForest 构建了名为隔离树 (iTree) 的二叉树结构来对特征空间进行建模。这些 iTree 以随机和递归方式拆分特征空间,使得树的每个节点代表一个特征子空间。例如,第一次拆分将整个特征空间分成两个子空间,由根节点的两个子节点表示。当数据实例是特征子空间的唯一成员时,它被认为是孤立的。由于假设异常值很少且不同,因此异常值可能比正常数据实例更早被隔离。

为了提高算法的强健性,iForest 构建了一个 iTree 集合,每个 iTree 以不同的方式分隔特征空间。该算法计算跨所有 iTree 隔离数据实例所需的平均路径长度。此平均路径长度有助于确定数据集中每个数据实例的 anomaly_scoreanomaly_score 高于给定阈值的数据实例被视为异常值。

您不需要大型数据集来训练 iForest,即使是小样本也足以训练准确的模型。数据可以具有 CHAR、VARCHAR、BOOL、INT 或 FLOAT 类型的列。

训练好 iForest 模型后,您可以使用 APPLY_IFOREST 函数检测向数据集中添加的任何新数据中的异常值。

以下示例演示了如何训练 iForest 模型和检测棒球数据集上的异常值。

要构建和训练 iForest 模型,请调用 IFOREST

=> SELECT IFOREST('baseball_outliers','baseball','hr, hits, salary' USING PARAMETERS max_depth=30, nbins=100);
IFOREST
----------
Finished
(1 row)

您可以使用 GET_MODEL_SUMMARY 查看训练模型的摘要:

=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='baseball_outliers');
GET_MODEL_SUMMARY
---------------------------------------------------------------------------------------------------------------------------------------------

===========
call_string
===========
SELECT iforest('public.baseball_outliers', 'baseball', 'hr, hits, salary' USING PARAMETERS exclude_columns='', ntree=100, sampling_size=0.632,
col_sample_by_tree=1, max_depth=30, nbins=100);

=======
details
=======
predictor|      type
---------+----------------
   hr    |      int
  hits   |      int
 salary  |float or numeric

===============
Additional Info
===============
       Name       |Value
------------------+-----
tree_count        | 100
rejected_row_count|  0
accepted_row_count|1000

(1 row)

您可以使用 APPLY_IFOREST 将经过训练的 iForest 模型应用于棒球数据集。要仅查看标识为异常值的数据实例,可以运行以下查询:

=> SELECT * FROM (SELECT first_name, last_name, APPLY_IFOREST(hr, hits, salary USING PARAMETERS model_name='baseball_outliers', threshold=0.6)
   AS predictions FROM baseball) AS outliers WHERE predictions.is_anomaly IS true;
 first_name | last_name |                      predictions
------------+-----------+--------------------------------------------------------
 Jacqueline | Richards  | {"anomaly_score":0.8572338674053986,"is_anomaly":true}
 Debra      | Hall      | {"anomaly_score":0.6007846156043213,"is_anomaly":true}
 Gerald     | Fuller    | {"anomaly_score":0.6813650107767862,"is_anomaly":true}
(3 rows)

您可以设置 contamination 参数,而不是为 APPLY_IFOREST 指定 threshold 值。此参数设置一个阈值,以便标记为异常值的训练数据点的比率大约等于 contamination 的值:

=> SELECT * FROM (SELECT first_name, last_name, APPLY_IFOREST(team, hr, hits, avg, salary USING PARAMETERS model_name='baseball_anomalies',
   contamination = 0.1) AS predictions FROM baseball) AS outliers WHERE predictions.is_anomaly IS true;
 first_name | last_name |                      predictions
------------+-----------+--------------------------------------------------------
 Marie      | Fields    | {"anomaly_score":0.5307715717521868,"is_anomaly":true}
 Jacqueline | Richards  | {"anomaly_score":0.777757463074347,"is_anomaly":true}
 Debra      | Hall      | {"anomaly_score":0.5714649698133808,"is_anomaly":true}
 Gerald     | Fuller    | {"anomaly_score":0.5980549926114661,"is_anomaly":true}
(4 rows)

DETECT_OUTLIERS

DETECT_OUTLIERS 函数假定每个数据维度的正态分布,然后标识与任何维度的正态分布有很大差异的数据实例。该函数使用稳健的 Z-score 检测方法对每个输入列进行标准化。如果数据实例包含大于指定阈值的标准化值,则将其标识为异常值。该函数输出一个包含所有异常值的表。

该函数接受仅具有数字输入列的数据,独立处理每一列,并假定每一列上的高斯分布。如果要检测添加到数据集的新数据中的异常值,则必须重新运行 DETECT_OUTLIERS

以下示例演示了如何根据 hr、hits 和 salary 列检测棒球数据集中的异常值。DETECT_OUTLIERS 函数创建一个包含异常值的表,其中包含输入列和键列:

=> SELECT DETECT_OUTLIERS('baseball_hr_hits_salary_outliers', 'baseball', 'hr, hits, salary', 'robust_zscore'
                         USING PARAMETERS outlier_threshold=3.0);
     DETECT_OUTLIERS
--------------------------
 Detected 5 outliers

(1 row)

要查看异常值,请查询包含异常值的输出表:

=> SELECT * FROM baseball_hr_hits_salary_outliers;
id  | first_name | last_name |    dob     |   team    |   hr    |  hits   |  avg  |        salary
----+------------+-----------+------------+-----------+---------+---------+-------+----------------------
73  | Marie      | Fields    | 1985-11-23 | Mauv      |    8888 |      34 | 0.283 | 9.99999999341471e+16
89  | Jacqueline | Richards  | 1975-10-06 | Pink      |  273333 | 4490260 | 0.324 |  4.4444444444828e+17
87  | Jose       | Stephens  | 1991-07-20 | Green     |      80 |   64253 |  0.69 |          16032567.12
222 | Gerald     | Fuller    | 1991-02-13 | Goldenrod | 3200000 |     216 | 0.299 |          37008899.76
147 | Debra      | Hall      | 1980-12-31 | Maroon    | 1100037 |     230 | 0.431 |           9000101403
(5 rows)

您可以创建一个省略表中异常值的视图:

=> CREATE VIEW clean_baseball AS
   SELECT * FROM baseball WHERE id NOT IN (SELECT id FROM baseball_hr_hits_salary_outliers);
CREATE VIEW

另请参阅

2.3 - 分类列编码

许多机器学习算法无法处理分类数据。为了适应这种算法,必须在训练之前将分类数据转换为数值数据。将分类值直接映射到索引是不够的。例如,如果您的分类特征具有“红色”、“绿色”和“蓝色”三个不同的值,将它们替换为 1、2 和 3 可能会对训练过程产生负面影响,因为算法通常依赖于值之间的某种数字距离进行区分。在这种情况下,从 1 到 3 的欧几里得距离是从 1 到 2 的距离的两倍,这意味着训练过程会认为“红色”与“蓝色”不同,而与“绿色”更相似。或者,独热编码将每个分类值映射到一个二进制向量以避免这个问题。例如,“红色”可以映射到 [1,0,0],“绿色”可以映射到 [0,1,0],“蓝色”可以映射到 [0,0,1]。现在,这三个类别之间的成对距离都是相同的。独热编码允许您将分类变量转换为二进制值,以便您可以使用不同的机器学习算法来计算您的数据。

以下示例演示如何将独热编码应用于 Titanic 数据集。如果您想了解有关此数据集的详细信息,请参阅 Kaggle 站点

假设您想使用逻辑回归分类器来预测哪些乘客在泰坦尼克号沉没中幸存下来。如果没有一种热编码,则无法将分类特征用于逻辑回归。该数据集有两个可以使用的分类特征。"sex"(性别)特征可以是男性也可以是女性。"embarkation_point"(上船地点)可以是以下几项之一:

  • S 代表南安普顿

  • Q 代表皇后镇

  • C 代表瑟堡

开始示例之前,请加载机器学习示例数据
  1. 对训练数据运行 ONE_HOT_ENCODER_FIT 函数:
=> SELECT ONE_HOT_ENCODER_FIT('titanic_encoder', 'titanic_training', 'sex, embarkation_point');
ONE_HOT_ENCODER_FIT
---------------------
Success

(1 row)

  1. 查看 titanic_encoder 模型摘要:
=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='titanic_encoder');
GET_MODEL_SUMMARY
------------------------------------------------------------------------------------------
===========
call_string
===========
SELECT one_hot_encoder_fit('public.titanic_encoder','titanic_training','sex, embarkation_point'
USING PARAMETERS exclude_columns='', output_view='', extra_levels='{}');
==================
varchar_categories
==================
category_name    |category_level|category_level_index
-----------------+--------------+--------------------
embarkation_point|      C       |         0
embarkation_point|      Q       |         1
embarkation_point|      S       |         2
embarkation_point|              |         3
sex              |    female    |         0
sex              |     male     |         1
(1 row)
  1. 运行 GET_MODEL_ATTRIBUTE 函数。此函数返回其原生数据类型中的分类级别,因此可以轻松地将它们与原始表进行比较:
=> SELECT * FROM (SELECT GET_MODEL_ATTRIBUTE(USING PARAMETERS model_name='titanic_encoder',
attr_name='varchar_categories')) AS attrs INNER JOIN (SELECT passenger_id, name, sex, age,
embarkation_point FROM titanic_training) AS original_data ON attrs.category_level
ILIKE original_data.embarkation_point ORDER BY original_data.passenger_id LIMIT 10;
category_name     | category_level | category_level_index | passenger_id |name
|  sex   | age | embarkation_point
------------------+----------------+----------------------+--------------+-----------------------------
-----------------------+--------+-----+-------------------
embarkation_point | S              |                    2 |            1 | Braund, Mr. Owen Harris
| male   |  22 | S
embarkation_point | C              |                    0 |            2 | Cumings, Mrs. John Bradley
(Florence Briggs Thayer | female |  38 | C
embarkation_point | S              |                    2 |            3 | Heikkinen, Miss. Laina
| female |  26 | S
embarkation_point | S              |                    2 |            4 | Futrelle, Mrs. Jacques Heath
(Lily May Peel)       | female |  35 | S
embarkation_point | S              |                    2 |            5 | Allen, Mr. William Henry
| male   |  35 | S
embarkation_point | Q              |                    1 |            6 | Moran, Mr. James
| male   |     | Q
embarkation_point | S              |                    2 |            7 | McCarthy, Mr. Timothy J
| male   |  54 | S
embarkation_point | S              |                    2 |            8 | Palsson, Master. Gosta Leonard
| male   |   2 | S
embarkation_point | S              |                    2 |            9 | Johnson, Mrs. Oscar W
(Elisabeth Vilhelmina Berg)  | female |  27 | S
embarkation_point | C              |                    0 |           10 | Nasser, Mrs. Nicholas
(Adele Achem)                | female |  14 | C
(10 rows)
  1. 对训练和测试数据运行 APPLY_ONE_HOT_ENCODER 函数:
=> CREATE VIEW titanic_training_encoded AS SELECT passenger_id, survived, pclass, sex_1, age,
sibling_and_spouse_count, parent_and_child_count, fare, embarkation_point_1, embarkation_point_2
FROM (SELECT APPLY_ONE_HOT_ENCODER(* USING PARAMETERS model_name='titanic_encoder')
FROM titanic_training) AS sq;

CREATE VIEW

=> CREATE VIEW titanic_testing_encoded AS SELECT passenger_id, name, pclass, sex_1, age,
sibling_and_spouse_count, parent_and_child_count, fare, embarkation_point_1, embarkation_point_2
FROM (SELECT APPLY_ONE_HOT_ENCODER(* USING PARAMETERS model_name='titanic_encoder')
FROM titanic_testing) AS sq;
CREATE VIEW
  1. 然后,对训练数据训练一个逻辑回归分类器,并对测试数据执行该模型:
=> SELECT LOGISTIC_REG('titanic_log_reg', 'titanic_training_encoded', 'survived', '*'
USING PARAMETERS exclude_columns='passenger_id, survived');
LOGISTIC_REG
---------------------------
Finished in 5 iterations
(1 row)

=> SELECT passenger_id, name, PREDICT_LOGISTIC_REG(pclass, sex_1, age, sibling_and_spouse_count,
parent_and_child_count, fare, embarkation_point_1, embarkation_point_2 USING PARAMETERS
model_name='titanic_log_reg') FROM titanic_testing_encoded ORDER BY passenger_id LIMIT 10;
passenger_id |                     name                     | PREDICT_LOGISTIC_REG
-------------+----------------------------------------------+----------------------
893          | Wilkes, Mrs. James (Ellen Needs)             |                    0
894          | Myles, Mr. Thomas Francis                    |                    0
895          | Wirz, Mr. Albert                             |                    0
896          | Hirvonen, Mrs. Alexander (Helga E Lindqvist) |                    1
897          | Svensson, Mr. Johan Cervin                   |                    0
898          | Connolly, Miss. Kate                         |                    1
899          | Caldwell, Mr. Albert Francis                 |                    0
900          | Abrahim, Mrs. Joseph (Sophie Halaut Easu)    |                    1
901          | Davies, Mr. John Samuel                      |                    0
902          | Ilieff, Mr. Ylio                             |
(10 rows)

2.4 - 估算缺失值

您可以使用 IMPUTE 函数将缺失数据替换为最频繁的值或同一列中的平均值。此估算示例使用 small_input_impute 表。使用该函数,您可以指定均值法或众数法。

这些示例展示了如何对 small_input_impute 表使用 IMPUTE 函数。

开始示例之前,请加载机器学习示例数据

首先,查询表,以便查看缺失值:

=> SELECT * FROM small_input_impute;
pid | pclass | gender |    x1     |    x2     |    x3     | x4 | x5 | x6
----+--------+--------+-----------+-----------+-----------+----+----+----
5   |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | t  | C
7   |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | C
13  |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | C
15  |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | f  | A
16  |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | f  | A
19  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  |
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
2   |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | A
3   |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | B
4   |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | t  | B
6   |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | t  | C
8   |      1 |      1 |  3.273592 |           |  3.477332 | 18 | f  | B
10  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | A
18  |      1 |      1 |  3.273592 |           |  3.477332 | 18 | t  | B
20  |      1 |      1 |           |  3.841606 |  3.754375 | 20 |    | C
9   |      1 |      1 |           |  3.841606 |  3.754375 | 20 | f  | B
11  |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | B
12  |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | C
14  |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | f  | A
17  |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | B
(21 rows)

指定均值法

执行 IMPUTE 函数,指定均值法:

=> SELECT IMPUTE('output_view','small_input_impute', 'pid, x1,x2,x3,x4','mean'
                  USING PARAMETERS exclude_columns='pid');
IMPUTE
--------------------------
Finished in 1 iteration
(1 row)

查看 output_view 以查看估算值:

=> SELECT * FROM output_view;
pid | pclass | gender |        x1         |        x2         |        x3         | x4 | x5 | x6
----+--------+--------+-------------------+-------------------+-------------------+----+----+----
5   |      0 |      1 |         -2.590837 |         -2.892819 |          -2.70296 |  2 | t  | C
7   |      1 |      1 |          3.829239 |           3.08765 | -3.12989705263158 | 11 | f  | C
13  |      0 |      0 |         -9.060605 |         -9.390844 |         -9.559848 |  6 | t  | C
15  |      0 |      1 |         -2.590837 |         -2.892819 |          -2.70296 |  2 | f  | A
16  |      0 |      1 |         -2.264599 |         -2.615146 |          -2.10729 | 11 | f  | A
19  |      1 |      1 | -3.86645035294118 |          3.841606 |          3.754375 | 20 | t  |
9   |      1 |      1 | -3.86645035294118 |          3.841606 |          3.754375 | 20 | f  | B
11  |      0 |      0 |         -9.445818 |         -9.740541 |         -9.786974 |  3 | t  | B
12  |      0 |      0 |         -9.618292 |         -9.308881 |         -9.562255 |  4 | t  | C
14  |      0 |      0 |         -2.264599 |         -2.615146 |          -2.10729 | 15 | f  | A
17  |      1 |      1 |          3.829239 |           3.08765 | -3.12989705263158 | 11 | f  | B
1   |      0 |      0 |         -9.445818 |         -9.740541 |         -9.786974 |  3 | t  | A
1   |      0 |      0 |         -9.445818 |         -9.740541 |         -9.786974 |  3 | t  | A
2   |      0 |      0 |         -9.618292 |         -9.308881 |         -9.562255 |  4 | t  | A
3   |      0 |      0 |         -9.060605 |         -9.390844 |         -9.559848 |  6 | t  | B
4   |      0 |      0 |         -2.264599 |         -2.615146 |          -2.10729 | 15 | t  | B
6   |      0 |      1 |         -2.264599 |         -2.615146 |          -2.10729 | 11 | t  | C
8   |      1 |      1 |          3.273592 | -3.22766163157895 |          3.477332 | 18 | f  | B
10  |      1 |      1 | -3.86645035294118 |          3.841606 |          3.754375 | 20 | t  | A
18  |      1 |      1 |          3.273592 | -3.22766163157895 |          3.477332 | 18 | t  | B
20  |      1 |      1 | -3.86645035294118 |          3.841606 |          3.754375 | 20 |    | C
(21 rows)

您还可以执行 IMPUTE 函数,指定均值法并使用 partition_columns 参数。此参数的工作方式类似于 GROUP_BY 子句:

=> SELECT IMPUTE('output_view_group','small_input_impute', 'pid, x1,x2,x3,x4','mean'
USING PARAMETERS exclude_columns='pid', partition_columns='pclass,gender');
impute
--------------------------
Finished in 1 iteration
(1 row)

查看 output_view_group 以查看估算值:

=> SELECT * FROM output_view_group;
pid | pclass | gender |    x1     |        x2        |        x3        | x4 | x5 | x6
----+--------+--------+-----------+------------------+------------------+----+----+----
5   |      0 |      1 | -2.590837 |        -2.892819 |         -2.70296 |  2 | t  | C
7   |      1 |      1 |  3.829239 |          3.08765 | 3.66202733333333 | 19 | f  | C
13  |      0 |      0 | -9.060605 |        -9.390844 |        -9.559848 |  6 | t  | C
15  |      0 |      1 | -2.590837 |        -2.892819 |         -2.70296 |  2 | f  | A
16  |      0 |      1 | -2.264599 |        -2.615146 |         -2.10729 | 11 | f  | A
19  |      1 |      1 | 3.5514155 |         3.841606 |         3.754375 | 20 | t  |
1   |      0 |      0 | -9.445818 |        -9.740541 |        -9.786974 |  3 | t  | A
1   |      0 |      0 | -9.445818 |        -9.740541 |        -9.786974 |  3 | t  | A
2   |      0 |      0 | -9.618292 |        -9.308881 |        -9.562255 |  4 | t  | A
3   |      0 |      0 | -9.060605 |        -9.390844 |        -9.559848 |  6 | t  | B
4   |      0 |      0 | -2.264599 |        -2.615146 |         -2.10729 | 15 | t  | B
6   |      0 |      1 | -2.264599 |        -2.615146 |         -2.10729 | 11 | t  | C
8   |      1 |      1 |  3.273592 | 3.59028733333333 |         3.477332 | 18 | f  | B
10  |      1 |      1 | 3.5514155 |         3.841606 |         3.754375 | 20 | t  | A
18  |      1 |      1 |  3.273592 | 3.59028733333333 |         3.477332 | 18 | t  | B
20  |      1 |      1 | 3.5514155 |         3.841606 |         3.754375 | 20 |    | C
9   |      1 |      1 | 3.5514155 |         3.841606 |         3.754375 | 20 | f  | B
11  |      0 |      0 | -9.445818 |        -9.740541 |        -9.786974 |  3 | t  | B
12  |      0 |      0 | -9.618292 |        -9.308881 |        -9.562255 |  4 | t  | C
14  |      0 |      0 | -2.264599 |        -2.615146 |         -2.10729 | 15 | f  | A
17  |      1 |      1 |  3.829239 |          3.08765 | 3.66202733333333 | 19 | f  | B
(21 rows)

指定众数法

执行 IMPUTE 函数,指定众数法:

=> SELECT impute('output_view_mode','small_input_impute', 'pid, x5,x6','mode'
                  USING PARAMETERS exclude_columns='pid');
impute
--------------------------
Finished in 1 iteration
(1 row)

查看 output_view_mode 以查看估算值:

=> SELECT * FROM output_view_mode;
pid | pclass | gender |    x1     |    x2     |    x3     | x4 | x5 | x6
----+--------+--------+-----------+-----------+-----------+----+----+----
5   |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | t  | C
7   |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | C
13  |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | C
15  |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | f  | A
16  |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | f  | A
19  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | B
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
2   |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | A
3   |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | B
4   |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | t  | B
6   |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | t  | C
8   |      1 |      1 |  3.273592 |           |  3.477332 | 18 | f  | B
10  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | A
18  |      1 |      1 |  3.273592 |           |  3.477332 | 18 | t  | B
20  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | C
9   |      1 |      1 |           |  3.841606 |  3.754375 | 20 | f  | B
11  |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | B
12  |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | C
14  |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | f  | A
17  |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | B
(21 rows)

您还可以执行 IMPUTE 函数,指定众数法并使用 partition_columns 参数。此参数的工作方式类似于 GROUP_BY 子句:

=> SELECT impute('output_view_mode_group','small_input_impute', 'pid, x5,x6','mode'
                   USING PARAMETERS exclude_columns='pid',partition_columns='pclass,gender');
impute
--------------------------
Finished in 1 iteration
(1 row)

查看 output_view_mode_group 以查看估算值:

=> SELECT * FROM output_view_mode_group;
pid | pclass | gender |    x1     |    x2     |    x3     | x4 | x5 | x6
----+--------+--------+-----------+-----------+-----------+----+----+----
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
1   |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | A
2   |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | A
3   |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | B
4   |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | t  | B
13  |      0 |      0 | -9.060605 | -9.390844 | -9.559848 |  6 | t  | C
11  |      0 |      0 | -9.445818 | -9.740541 | -9.786974 |  3 | t  | B
12  |      0 |      0 | -9.618292 | -9.308881 | -9.562255 |  4 | t  | C
14  |      0 |      0 | -2.264599 | -2.615146 |  -2.10729 | 15 | f  | A
5   |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | t  | C
15  |      0 |      1 | -2.590837 | -2.892819 |  -2.70296 |  2 | f  | A
16  |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | f  | A
6   |      0 |      1 | -2.264599 | -2.615146 |  -2.10729 | 11 | t  | C
7   |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | C
19  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | B
9   |      1 |      1 |           |  3.841606 |  3.754375 | 20 | f  | B
17  |      1 |      1 |  3.829239 |   3.08765 |  Infinity |    | f  | B
8   |      1 |      1 |  3.273592 |           |  3.477332 | 18 | f  | B
10  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | t  | A
18  |      1 |      1 |  3.273592 |           |  3.477332 | 18 | t  | B
20  |      1 |      1 |           |  3.841606 |  3.754375 | 20 | f  | C
(21 rows)

另请参阅

IMPUTE

2.5 - 标准化数据

标准化的目的主要是把来自不同列的数字数据缩小到等效的比例。例如,假设您对具有两个特征列的数据集执行 LINEAR_REG 函数,这两个特征列为 current_salaryyears_worked。您试图预测的输出值是一名工人的未来工资。current_salary 列的值可能具有很大的范围,且数值可能比 years_worked 列的值大很多。因此,current_salary 列的值可能会超过 years_worked 列的值,使模型偏斜。

Vertica 提供以下使用标准化的数据准备方法。这些方法是:

  • MinMax
    使用 MinMax 标准化方法,您可以将这两列的数值全部标准化,使之分布在 0 至 1 的范围之内。使用这种方法,您可以通过减少一列对于另一列的支配控制,比较不同标度的值。

  • Z-score
    使用 Z-score 标准化方法,您可以将这两列中的值标准化为观测值与每列平均值的标准差数。这使您可以将数据与正态分布的随机变量进行比较。

  • 稳健 Z-score
    使用稳健 Z-score 标准化方法,您可以减少异常值对 Z-score 计算的影响。稳健 Z-score 标准化使用中位数,而不是 Z-score 中使用的平均值。通过使用中位数而不是平均值,它有助于消除数据中异常值的一些影响。

标准化数据会导致创建一个保存标准化数据的视图。NORMALIZE 函数中的 output_view 选项确定视图的名称。

使用 MinMax 标准化工资数据

以下示例演示如何使用 MinMax 标准化方法标准化 salary_data 表。

开始示例之前,请加载机器学习示例数据
=> SELECT NORMALIZE('normalized_salary_data', 'salary_data', 'current_salary, years_worked', 'minmax');
        NORMALIZE
--------------------------
 Finished in 1 iteration

(1 row)

=> SELECT * FROM normalized_salary_data;
employee_id | first_name  | last_name  |     years_worked     |    current_salary
------------+-------------+------------+----------------------+----------------------
189         | Shawn       | Moore      | 0.350000000000000000 | 0.437246565765357217
518         | Earl        | Shaw       | 0.100000000000000000 | 0.978867411144492943
1126        | Susan       | Alexander  | 0.250000000000000000 | 0.909048995710749580
1157        | Jack        | Stone      | 0.100000000000000000 | 0.601863084103319918
1277        | Scott       | Wagner     | 0.050000000000000000 | 0.455949209228501786
3188        | Shirley     | Flores     | 0.400000000000000000 | 0.538816771536005140
3196        | Andrew      | Holmes     | 0.900000000000000000 | 0.183954046444834949
3430        | Philip      | Little     | 0.100000000000000000 | 0.735279557092379495
3522        | Jerry       | Ross       | 0.800000000000000000 | 0.671828883472214349
3892        | Barbara     | Flores     | 0.350000000000000000 | 0.092901007123556866

.
.
.
(1000 rows)

使用 Z-score 标准化工资数据

以下示例演示如何使用 Z-score 标准化方法标准化 salary_data 表。

开始示例之前,请加载机器学习示例数据
=> SELECT NORMALIZE('normalized_z_salary_data', 'salary_data', 'current_salary, years_worked',
                     'zscore');
        NORMALIZE
--------------------------
 Finished in 1 iteration

(1 row)

=> SELECT * FROM normalized_z_salary_data;
employee_id | first_name  | last_name  |    years_worked     |    current_salary
------------+-------------+------------+---------------------+----------------------
189         | Shawn       | Moore      |  -0.524447274157005 |   -0.221041249770669
518         | Earl        | Shaw       |   -1.35743214416495 |     1.66054215981221
1126        | Susan       | Alexander  |  -0.857641222160185 |     1.41799393943946
1157        | Jack        | Stone      |   -1.35743214416495 |    0.350834283622416
1277        | Scott       | Wagner     |   -1.52402911816654 |   -0.156068522159045
3188        | Shirley     | Flores     |  -0.357850300155415 |    0.131812255991634
3196        | Andrew      | Holmes     |    1.30811943986048 |    -1.10097599783475
3430        | Philip      | Little     |   -1.35743214416495 |    0.814321286168547
3522        | Jerry       | Ross       |   0.974925491857304 |    0.593894513770248
3892        | Barbara     | Flores     |  -0.524447274157005 |    -1.41729301118583

.
.
.
(1000 rows)

使用稳健 Z-score 标准化工资数据

以下示例演示如何使用稳健 Z-score 标准化方法标准化 salary_data 表。

开始示例之前,请加载机器学习示例数据
=> SELECT NORMALIZE('normalized_robustz_salary_data', 'salary_data', 'current_salary, years_worked', 'robust_zscore');
        NORMALIZE
--------------------------
 Finished in 1 iteration

(1 row)

=> SELECT * FROM normalized_robustz_salary_data;
employee_id | first_name  | last_name  |    years_worked    |    current_salary
------------+-------------+------------+--------------------+-----------------------
189         | Shawn       | Moore      | -0.404694455685957 | -0.158933849655499140
518         | Earl        | Shaw       | -1.079185215162552 |  1.317126172796275889
1126        | Susan       | Alexander  | -0.674490759476595 |  1.126852528914384584
1157        | Jack        | Stone      | -1.079185215162552 |  0.289689691751547422
1277        | Scott       | Wagner     | -1.214083367057871 | -0.107964200747705902
3188        | Shirley     | Flores     | -0.269796303790638 |  0.117871818902746738
3196        | Andrew      | Holmes     |  1.079185215162552 | -0.849222942006447161
3430        | Philip      | Little     | -1.079185215162552 |  0.653284859470426481
3522        | Jerry       | Ross       |  0.809388911371914 |  0.480364995828913355
3892        | Barbara     | Flores     | -0.404694455685957 | -1.097366550974798397
3939        | Anna        | Walker     | -0.944287063267233 |  0.414956177842775781
4165        | Martha      | Reyes      |  0.269796303790638 |  0.773947701782753329
4335        | Phillip     | Wright     | -1.214083367057871 |  1.218843012657445647
4534        | Roger       | Harris     |  1.079185215162552 |  1.155185021164402608
4806        | John        | Robinson   |  0.809388911371914 | -0.494320112876813908
4881        | Kelly       | Welch      |  0.134898151895319 | -0.540778808820045933
4889        | Jennifer    | Arnold     |  1.214083367057871 | -0.299762093576526566
5067        | Martha      | Parker     |  0.000000000000000 |  0.719991348857328239
5523        | John        | Martin     | -0.269796303790638 | -0.411248545269163826
6004        | Nicole      | Sullivan   |  0.269796303790638 |  1.065141044522487821
6013        | Harry       | Woods      | -0.944287063267233 |  1.005664438654129376
6240        | Norma       | Martinez   |  1.214083367057871 |  0.762412844887071691

.
.
.
(1000 rows)

另请参阅

2.6 - PCA(主分量分析)

主分量分析 (PCA) 是一种技术,可以在保留数据中所存在变异的同时降低数据维数。本质上,相当于构建了一个新的坐标系,使数据变化沿第一个轴最强,沿第二个轴减弱,以此类推。然后,数据点转换到这个新的坐标系中。轴的方向称为主分量。

如果输入数据是具有 p 列的表,则可能最多存在 p 个主分量。但是,通常情况下,沿第 k 个主分量方向的数据变化几乎可以忽略不计,这使我们只保留前 k 个分量。因此,新坐标系的轴较少。因此,转换后的数据表只有 k 列而不是 p 列。一定要记住,k 个输出列不仅仅是 p 个输入列的子集。相反,k 个输出列中的每个列都是所有 p 个输入列的组合。

可以使用以下函数来训练和应用 PCA 模型:

有关完整示例,请参阅使用 PCA 降维

2.6.1 - 使用 PCA 降维

该 PCA 示例使用一个包含大量列的名为 world 的数据集。该示例展示了如何将 PCA 应用于数据集中的所有列(HDI 除外)并将它们降为二维。

开始示例之前,请加载机器学习示例数据
  1. 创建名为 pcamodel 的 PCA 模型。

    => SELECT PCA ('pcamodel', 'world','country,HDI,em1970,em1971,em1972,em1973,em1974,em1975,em1976,em1977,
    em1978,em1979,em1980,em1981,em1982,em1983,em1984 ,em1985,em1986,em1987,em1988,em1989,em1990,em1991,em1992,
    em1993,em1994,em1995,em1996,em1997,em1998,em1999,em2000,em2001,em2002,em2003,em2004,em2005,em2006,em2007,
    em2008,em2009,em2010,gdp1970,gdp1971,gdp1972,gdp1973,gdp1974,gdp1975,gdp1976,gdp1977,gdp1978,gdp1979,gdp1980,
    gdp1981,gdp1982,gdp1983,gdp1984,gdp1985,gdp1986,gdp1987,gdp1988,gdp1989,gdp1990,gdp1991,gdp1992,gdp1993,
    gdp1994,gdp1995,gdp1996,gdp1997,gdp1998,gdp1999,gdp2000,gdp2001,gdp2002,gdp2003,gdp2004,gdp2005,gdp2006,
    gdp2007,gdp2008,gdp2009,gdp2010' USING PARAMETERS exclude_columns='HDI, country');
    
    
    PCA
    ---------------------------------------------------------------
    Finished in 1 iterations.
    Accepted Rows: 96  Rejected Rows: 0
    (1 row)
    
  2. 查看 pcamodel 的摘要输出。

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='pcamodel');
    GET_MODEL_SUMMARY
    --------------------------------------------------------------------------------
    
  3. 接下来,将 PCA 应用于选定的几个列(HDI 和 country 列除外)。

    => SELECT APPLY_PCA (HDI,country,em1970,em2010,gdp1970,gdp2010 USING PARAMETERS model_name='pcamodel',
    exclude_columns='HDI,country', key_columns='HDI,country',cutoff=.3) OVER () FROM world;
    HDI   |       country       |       col1
    ------+---------------------+-------------------
    0.886 | Belgium             | -36288.1191849017
    0.699 | Belize              |   -81740.32711562
    0.427 | Benin               | -122666.882708325
    0.805 | Chile               | -161356.484748602
    0.687 | China               | -202634.254216416
    0.744 | Costa Rica          | -242043.080125449
    0.4   | Cote d'Ivoire       | -283330.394428932
    0.776 | Cuba                | -322625.857541772
    0.895 | Denmark             | -356086.311721071
    0.644 | Egypt               | -403634.743992772
    .
    .
    .
    (96 rows)
    
  4. 然后,可以选择应用反函数以将数据转换回其原始状态。此示例显示了仅针对第一条记录的缩小版输出。总共有 96 条记录。

    => SELECT APPLY_INVERSE_PCA (HDI,country,em1970,em2010,gdp1970,gdp2010 USING PARAMETERS model_name='pcamodel',
    exclude_columns='HDI,country', key_columns='HDI,country') OVER () FROM world limit 1;
    -[ RECORD 1 ]--------------
    HDI     | 0.886
    country | Belgium
    em1970  | 3.74891915022521
    em1971  | 26.091852917619
    em1972  | 22.0262860721982
    em1973  | 24.8214492074202
    em1974  | 20.9486650320945
    em1975  | 29.5717692117088
    em1976  | 17.4373459783249
    em1977  | 33.1895610966146
    em1978  | 15.6251407781098
    em1979  | 14.9560299812815
    em1980  | 18.0870223053504
    em1981  | -6.23151505146251
    em1982  | -7.12300504708672
    em1983  | -7.52627957856581
    em1984  | -7.17428622245234
    em1985  | -9.04899186621455
    em1986  | -10.5098581697156
    em1987  | -7.97146984849547
    em1988  | -8.85458031319287
    em1989  | -8.78422101747477
    em1990  | -9.61931854722004
    em1991  | -11.6411235452067
    em1992  | -12.8882752879355
    em1993  | -15.0647523842803
    em1994  | -14.3266175918398
    em1995  | -9.07603254825782
    em1996  | -9.32002671928241
    em1997  | -10.0209028262361
    em1998  | -6.70882735196004
    em1999  | -7.32575918131333
    em2000  | -10.3113551933996
    em2001  | -11.0162573094354
    em2002  | -10.886264397431
    em2003  | -8.96078372850612
    em2004  | -11.5157129257881
    em2005  | -12.5048269019293
    em2006  | -12.2345161132594
    em2007  | -8.92504587601715
    em2008  | -12.1136551375247
    em2009  | -10.1144380511421
    em2010  | -7.72468307053519
    gdp1970 | 10502.1047183969
    gdp1971 | 9259.97560190599
    gdp1972 | 6593.98178532712
    gdp1973 | 5325.33813328068
    gdp1974 | -899.029529832931
    gdp1975 | -3184.93671107899
    gdp1976 | -4517.68204331439
    gdp1977 | -3322.9509067019
    gdp1978 | -33.8221923368737
    gdp1979 | 2882.50573071066
    gdp1980 | 3638.74436577365
    gdp1981 | 2211.77365027338
    gdp1982 | 5811.44631880621
    gdp1983 | 7365.75180165581
    gdp1984 | 10465.1797058904
    gdp1985 | 12312.7219748196
    gdp1986 | 12309.0418293413
    gdp1987 | 13695.5173269466
    gdp1988 | 12531.9995299889
    gdp1989 | 13009.2244205049
    gdp1990 | 10697.6839797576
    gdp1991 | 6835.94651304181
    gdp1992 | 4275.67753277099
    gdp1993 | 3382.29408813394
    gdp1994 | 3703.65406726311
    gdp1995 | 4238.17659535371
    gdp1996 | 4692.48744219914
    gdp1997 | 4539.23538342266
    gdp1998 | 5886.78983381162
    gdp1999 | 7527.72448728762
    gdp2000 | 7646.05563584361
    gdp2001 | 9053.22077886667
    gdp2002 | 9914.82548013531
    gdp2003 | 9201.64413455221
    gdp2004 | 9234.70123279344
    gdp2005 | 9565.5457350936
    gdp2006 | 9569.86316415438
    gdp2007 | 9104.60260145907
    gdp2008 | 8182.8163827425
    gdp2009 | 6279.93197775805
    gdp2010 | 4274.40397281553
    

另请参阅

2.7 - 对数据采样

数据采样的目标是从较大的数据集中获取较小、较易于管理的样本。使用示例数据集,您可以生成预测模型或使用它来帮助您调整数据库。以下示例演示如何使用 TABLESAMPLE 子句创建数据样本。

对表中数据采样

开始示例之前,请加载机器学习示例数据

使用 baseball 表,创建一个名为 baseball_sample 的新表,其中包含 25% 的 baseball 样本。请记住,TABLESAMPLE 不保证可返回子句中定义的记录的确切百分比。

=> CREATE TABLE baseball_sample AS SELECT * FROM baseball TABLESAMPLE(25);
CREATE TABLE
=> SELECT * FROM baseball_sample;
 id  | first_name | last_name  |    dob     |    team    | hr  | hits  |  avg  |   salary
-----+------------+------------+------------+------------+-----+-------+-------+-------------
   4 | Amanda     | Turner     | 1997-12-22 | Maroon     |  58 |   177 | 0.187 |     8047721
  20 | Jesse      | Cooper     | 1983-04-13 | Yellow     |  97 |    39 | 0.523 |     4252837
  22 | Randy      | Peterson   | 1980-05-28 | Orange     |  14 |    16 | 0.141 |  11827728.1
  24 | Carol      | Harris     | 1991-04-02 | Fuscia     |  96 |    12 | 0.456 |  40572253.6
  32 | Rose       | Morrison   | 1977-07-26 | Goldenrod  |  27 |   153 | 0.442 | 14510752.49
  50 | Helen      | Medina     | 1987-12-26 | Maroon     |  12 |   150 |  0.54 | 32169267.91
  70 | Richard    | Gilbert    | 1983-07-13 | Khaki      |   1 |   250 | 0.213 | 40518422.76
  81 | Angela     | Cole       | 1991-08-16 | Violet     |  87 |   136 | 0.706 | 42875181.51
  82 | Elizabeth  | Foster     | 1994-04-30 | Indigo     |  46 |   163 | 0.481 | 33896975.53
  98 | Philip     | Gardner    | 1992-05-06 | Puce       |  39 |   239 | 0.697 | 20967480.67
 102 | Ernest     | Freeman    | 1983-10-05 | Turquoise  |  46 |    77 | 0.564 | 21444463.92
.
.
.
(227 rows)

就您的示例而言,您可以创建预测模型,或调整您的数据库。

另请参阅

  • FROM 子句 (有关 TABLESAMPLE 子句的详细信息)

2.8 - SVD(奇异值分解)

奇异值分解 (SVD) 是一种矩阵分解方法,它允许您将 n×p 维矩阵 X 近似为 3 个矩阵的乘积:X(nxp) = U(nxk).S(kxk).VT(kxp),其中 k 是从 1 到 p 的整数,S 是对角矩阵。其对角线上的值为非负值(称为奇异值),按左上角最大、右下角最小的顺序排序。S 的所有其他元素为零。

在实践中,矩阵 V(pxk)(即 VT 的转置版本)更受欢迎。

如果 k(分解算法的输入参数,也称为要保留在输出中的组件数)等于 p,则分解是精确的。如果 k 小于 p,则分解变为近似值。

SVD 的一个应用是有损数据压缩。例如,存储 X 需要 n.p 个元素,而存储三个矩阵 U、S 和 VT 需要存储 n.k + k + k.p 个元素。如果 n=1000、p=10 和 k=2,存储 X 需要 10,000 个元素,而存储近似值需要 2,000+4+20 = 2,024 个元素。较小的 k 值更加节省存储空间,而较大的 k 值会提供更准确的近似值。

根据您的数据,奇异值可能会迅速减少,从而允许您选择一个远小于 p 值的 k 值。

SVD 的另一个常见应用是执行主分量分析。

可以使用以下函数来训练和应用 SVD 模型:

有关完整示例,请参阅计算 SVD

2.8.1 - 计算 SVD

该 SVD 示例使用名为 small_svd 的小数据集。该示例向您展示了如何使用给定的数据集计算 SVD。该表是一个数字矩阵。奇异值分解是使用 SVD 函数计算的。该示例计算表矩阵的 SVD 并将其赋给一个新对象,该对象包含一个向量以及两个矩阵 U 和 V。向量包含奇异值。第一个矩阵 U 包含左奇异向量,V 包含右奇异向量。

开始示例之前,请加载机器学习示例数据
  1. 创建名为 svdmodel 的 SVD 模型。

    => SELECT SVD ('svdmodel', 'small_svd', 'x1,x2,x3,x4');
    SVD
    --------------------------------------------------------------
    
    Finished in 1 iterations.
    Accepted Rows: 8  Rejected Rows: 0
    (1 row)
    
  2. 查看 svdmodel 的摘要输出。

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='svdmodel');
    GET_MODEL_SUMMARY
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------------------------
    =======
    columns
    =======
    index|name
    -----+----
    1    | x1
    2    | x2
    3    | x3
    4    | x4
    ===============
    singular_values
    ===============
    index| value  |explained_variance|accumulated_explained_variance
    -----+--------+------------------+------------------------------
    1    |22.58748|      0.95542     |            0.95542
    2    | 3.79176|      0.02692     |            0.98234
    3    | 2.55864|      0.01226     |            0.99460
    4    | 1.69756|      0.00540     |            1.00000
    ======================
    right_singular_vectors
    ======================
    index|vector1 |vector2 |vector3 |vector4
    -----+--------+--------+--------+--------
    1    | 0.58736| 0.08033| 0.74288|-0.31094
    2    | 0.26661| 0.78275|-0.06148| 0.55896
    3    | 0.71779|-0.13672|-0.64563|-0.22193
    4    | 0.26211|-0.60179| 0.16587| 0.73596
    ========
    counters
    ========
    counter_name      |counter_value
    ------------------+-------------
    accepted_row_count|      8
    rejected_row_count|      0
    iteration_count   |      1
    ===========
    call_string
    ===========
    SELECT SVD('public.svdmodel', 'small_svd', 'x1,x2,x3,x4');
    (1 row)
    
  3. 创建名为 Umat 的新表以获取 U 的值。

    => CREATE TABLE Umat AS SELECT APPLY_SVD(id, x1, x2, x3, x4 USING PARAMETERS model_name='svdmodel',
    exclude_columns='id', key_columns='id') OVER() FROM small_svd;
    CREATE TABLE
    
  4. Umat 表中查看结果。该表将矩阵转换为新坐标系。

    => SELECT * FROM Umat ORDER BY id;
      id |        col1        |        col2        |        col3         |        col4
    -----+--------------------+--------------------+---------------------+--------------------
    1    | -0.494871802886819 | -0.161721379259287 |  0.0712816417153664 | -0.473145877877408
    2    |  -0.17652411036246 | 0.0753183783382909 |  -0.678196192333598 | 0.0567124770173372
    3    | -0.150974762654569 | -0.589561842046029 | 0.00392654610109522 |  0.360011163271921
    4    |  -0.44849499240202 |  0.347260956311326 |   0.186958376368345 |  0.378561270493651
    5    | -0.494871802886819 | -0.161721379259287 |  0.0712816417153664 | -0.473145877877408
    6    |  -0.17652411036246 | 0.0753183783382909 |  -0.678196192333598 | 0.0567124770173372
    7    | -0.150974762654569 | -0.589561842046029 | 0.00392654610109522 |  0.360011163271921
    8    |  -0.44849499240202 |  0.347260956311326 |   0.186958376368345 |  0.378561270493651
    (8 rows)
    
  5. 然后,我们可以选择将数据从 Umat 转换回 Xmat。首先,我们必须创建 Xmat 表,然后将 APPLY_INVERSE_SVD 函数应用于该表:

    => CREATE TABLE Xmat AS SELECT APPLY_INVERSE_SVD(* USING PARAMETERS model_name='svdmodel',
    exclude_columns='id', key_columns='id') OVER() FROM Umat;
    CREATE TABLE
    
  6. 然后,查看所创建的 Xmat 表中的数据:

    => SELECT id, x1::NUMERIC(5,1), x2::NUMERIC(5,1), x3::NUMERIC(5,1), x4::NUMERIC(5,1) FROM Xmat
    ORDER BY id;
    id | x1  | x2  | x3  | x4
    ---+-----+-----+-----+-----
    1  | 7.0 | 3.0 | 8.0 | 2.0
    2  | 1.0 | 1.0 | 4.0 | 1.0
    3  | 2.0 | 3.0 | 2.0 | 0.0
    4  | 6.0 | 2.0 | 7.0 | 4.0
    5  | 7.0 | 3.0 | 8.0 | 2.0
    6  | 1.0 | 1.0 | 4.0 | 1.0
    7  | 2.0 | 3.0 | 2.0 | 0.0
    8  | 6.0 | 2.0 | 7.0 | 4.0
    (8 rows)
    

另请参阅

3 - 回归算法

回归是一种重要且流行的机器学习工具,它通过学习数据的某些特征与观察值响应之间的关系来根据数据进行预测。回归用于对利润、销售额、温度、库存等项目进行预测。例如,您可以使用回归来根据位置、平方英尺、地块大小等来预测房屋的价格。在此示例中,房屋的价值是响应,其他因素(例如位置)是特征。

为回归方程找到的最佳系数集称为模型。结果与特征之间的关系在模型中进行了总结,然后可以应用于结果值未知的不同数据集。

3.1 - 自回归

请参阅时间序列模型下的自回归模型示例

3.2 - 线性回归

使用线性回归,可以为自变量或特性,以及因变量或结果之间的线性关系进行建模。建立线性回归模型用于:

  • 为自变量和因变量的数据集建立可预测模型。这样做允许您使用特征变量值来预测结果。例如,您可以预测一年中某一天的降雨量。

  • 决定自变量和一些结果变量之间的关系强弱。例如,加入你想要通过降雨量这个结果来决定不同天气变量下的重要性。可通过观察天气和降雨来建立线性回归模型进行求解。

与用来确定二进制分类结果的 逻辑回归 不同的是,线性回归主要用于预测线性关系中的连续数字结果。

可以使用下列函数进行线性回归建模,观察这个模型,并且使用模型对一组测试数据进行预测。

有关如何在 Vertica 表中使用线性回归的完整示例,请参阅构建线性回归模型

3.2.1 - 构建线性回归模型

线性回归示例使用名为 faithful 的小数据集。该数据集包含黄石国家公园老忠实间歇泉的喷发间隔和喷发持续时间。每次喷发的持续时间在 1.5 到 5 分钟之间。喷发之间的间隔长度和每次喷发的间隔长度各不相同。不过,您可以根据上一次喷发的持续时间来估计下一次喷发的时间。该示例展示了如何构建模型来预测 eruptions 的值(给定 waiting 特征的值)。

开始示例之前,请加载机器学习示例数据
  1. 使用 linear_reg_faithful 样本数据创建名为 faithful_training 的线性回归模型。

    => SELECT LINEAR_REG('linear_reg_faithful', 'faithful_training', 'eruptions', 'waiting'
       USING PARAMETERS optimizer='BFGS');
            LINEAR_REG
    ---------------------------
     Finished in 6 iterations
    
    (1 row)
    
  2. 查看 linear_reg_faithful 的摘要输出:

    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='linear_reg_faithful');
    --------------------------------------------------------------------------------
    =======
    details
    =======
    predictor|coefficient|std_err |t_value |p_value
    ---------+-----------+--------+--------+--------
    Intercept| -2.06795  | 0.21063|-9.81782| 0.00000
    waiting  |  0.07876  | 0.00292|26.96925| 0.00000
    
    ==============
    regularization
    ==============
    type| lambda
    ----+--------
    none| 1.00000
    
    ===========
    call_string
    ===========
    linear_reg('public.linear_reg_faithful', 'faithful_training', '"eruptions"', 'waiting'
    USING PARAMETERS optimizer='bfgs', epsilon=1e-06, max_iterations=100,
    regularization='none', lambda=1)
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    iteration_count   |  3
    rejected_row_count|  0
    accepted_row_count| 162
    (1 row)
    
  3. 通过在测试数据中运行 PREDICT_LINEAR_REG 函数,创建包含响应值的表。将该表命名为 pred_faithful_results:在 pred_faithful_results 表中查看结果:

    => CREATE TABLE pred_faithful_results AS
       (SELECT id, eruptions, PREDICT_LINEAR_REG(waiting USING PARAMETERS model_name='linear_reg_faithful')
       AS pred FROM faithful_testing);
    CREATE TABLE
    
    => SELECT * FROM pred_faithful_results ORDER BY id;
     id  | eruptions |       pred
    -----+-----------+------------------
       4 |     2.283 |  2.8151271587036
       5 |     4.533 | 4.62659045686076
       8 |       3.6 | 4.62659045686076
       9 |      1.95 | 1.94877514654148
      11 |     1.833 | 2.18505296804024
      12 |     3.917 | 4.54783118302784
      14 |      1.75 |  1.6337380512098
      20 |      4.25 | 4.15403481386324
      22 |      1.75 |  1.6337380512098
    .
    .
    .
    (110 rows)
    

计算均方误差 (MSE)

您可以使用 MSE 函数计算模型与数据的拟合程度。MSE 返回实际值与预测值之间的平方差的平均值。

=> SELECT MSE (eruptions::float, pred::float) OVER() FROM
   (SELECT eruptions, pred FROM pred_faithful_results) AS prediction_output;
        mse        |                   Comments
-------------------+-----------------------------------------------
 0.252925741352641 | Of 110 rows, 110 were used and 0 were ignored
(1 row)

另请参阅

3.3 - 用于回归的随机森林

回归算法的随机森林创建回归树的集成模型。每棵树都对随机选择的训练数据子集进行训练。该算法预测的值是单个树的平均预测值。

您可以使用下列函数训练随机森林模型,并使用该模型对一组测试数据进行预测:

有关如何在 Vertica 中将随机森林用于回归算法的完整示例,请参阅构建随机森林回归模型

3.3.1 - 构建随机森林回归模型

此示例使用 "mtcars" 数据集创建随机森林模型来预测 carb 的值(化油器的数量)。

开始示例之前,请加载机器学习示例数据
  1. 使用 RF_REGRESSORmtcars 训练数据创建随机森林模型 myRFRegressorModel。使用 GET_MODEL_SUMMARY 查看模型的摘要输出:

    => SELECT RF_REGRESSOR ('myRFRegressorModel', 'mtcars', 'carb', 'mpg, cyl, hp, drat, wt' USING PARAMETERS
    ntree=100, sampling_size=0.3);
    RF_REGRESSOR
    --------------
    Finished
    (1 row)
    
    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='myRFRegressorModel');
    --------------------------------------------------------------------------------
    ===========
    call_string
    ===========
    SELECT rf_regressor('public.myRFRegressorModel', 'mtcars', '"carb"', 'mpg, cyl, hp, drat, wt'
    USING PARAMETERS exclude_columns='', ntree=100, mtry=1, sampling_size=0.3, max_depth=5, max_breadth=32,
    min_leaf_size=5, min_info_gain=0, nbins=32);
    
    
    =======
    details
    =======
    predictor|type
    ---------+-----
    mpg      |float
    cyl      | int
    hp       | int
    drat     |float
    wt       |float
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    tree_count        | 100
    rejected_row_count|  0
    accepted_row_count| 32
    (1 row)
    
  2. 使用 PREDICT_RF_REGRESSOR 预测化油器数量:

    => SELECT PREDICT_RF_REGRESSOR (mpg,cyl,hp,drat,wt
    USING PARAMETERS model_name='myRFRegressorModel') FROM mtcars;
    PREDICT_RF_REGRESSOR
    ----------------------
    2.94774203574204
    2.6954087024087
    2.6954087024087
    2.89906346431346
    2.97688489288489
    2.97688489288489
    2.7086587024087
    2.92078965478965
    2.97688489288489
    2.7086587024087
    2.95621822621823
    2.82255155955156
    2.7086587024087
    2.7086587024087
    2.85650394050394
    2.85650394050394
    2.97688489288489
    2.95621822621823
    2.6954087024087
    2.6954087024087
    2.84493251193251
    2.97688489288489
    2.97688489288489
    2.8856467976468
    2.6954087024087
    2.92078965478965
    2.97688489288489
    2.97688489288489
    2.7934087024087
    2.7934087024087
    2.7086587024087
    2.72469441669442
    (32 rows)
    

3.4 - 用于回归的 SVM(支持向量机)

用于回归的支持向量机 (SVM) 根据训练数据预测连续有序变量。

与用来确定二进制分类结果的 逻辑回归 不同的是,用于回归的 SVM 主要用来预测连续数字结果。

您可以使用下列函数构建用于回归的 SVM 模型、查看模型,并使用该模型对一组测试数据进行预测:

有关如何在 Vertica 中使用 SVM 算法的完整示例,请参阅构建用于回归的 SVM 模型

3.4.1 - 构建用于回归的 SVM 模型

该用于回归的 SVM 示例使用了一个名为 faithful 的小型数据集,该数据集基于黄石国家公园的老忠实间歇泉。该数据集包含有关间歇泉喷发之间的等待时间和喷发持续时间的值。该示例展示了如何构建模型来预测 eruptions 的值(给定 waiting 特征的值)。

开始示例之前,请加载机器学习示例数据
  1. 使用 faithful_training 训练数据创建名为 svm_faithful 的 SVM 模型。

    => SELECT SVM_REGRESSOR('svm_faithful', 'faithful_training', 'eruptions', 'waiting'
                          USING PARAMETERS error_tolerance=0.1, max_iterations=100);
            SVM_REGRESSOR
    ---------------------------
     Finished in 5 iterations
    
    Accepted Rows: 162   Rejected Rows: 0
    (1 row)
    
  2. 查看 svm_faithful 的摘要输出:

    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='svm_faithful');
    
    ------------------------------------------------------------------
    =======
    
    details
    
    =======
    
    
    ===========================
    Predictors and Coefficients
    ===========================
             |Coefficients
    ---------+------------
    Intercept|  -1.59007
    waiting  |   0.07217
    ===========
    call_string
    ===========
    Call string:
    SELECT svm_regressor('public.svm_faithful', 'faithful_training', '"eruptions"',
    'waiting'USING PARAMETERS error_tolerance = 0.1, C=1, max_iterations=100,
    epsilon=0.001);
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    accepted_row_count| 162
    rejected_row_count|  0
    iteration_count  |  5
    (1 row)
    
  3. 在测试数据中运行 PREDICT_SVM_REGRESSOR 函数创建包含响应值的新表。将此表命名为 pred_faithful_results. 。在 pred_faithful_results 表中查看结果:

    => CREATE TABLE pred_faithful AS
           (SELECT id, eruptions, PREDICT_SVM_REGRESSOR(waiting USING PARAMETERS model_name='svm_faithful')
            AS pred FROM faithful_testing);
    CREATE TABLE
    
    => SELECT * FROM pred_faithful ORDER BY id;
     id  | eruptions |       pred
    -----+-----------+------------------
       4 |     2.283 | 2.88444568755189
       5 |     4.533 | 4.54434581879796
       8 |       3.6 | 4.54434581879796
       9 |      1.95 | 2.09058040739072
      11 |     1.833 | 2.30708912016195
      12 |     3.917 | 4.47217624787422
      14 |      1.75 | 1.80190212369576
      20 |      4.25 | 4.11132839325551
      22 |      1.75 | 1.80190212369576
    .
    .
    .
    (110 rows)
    

计算均方误差 (MSE)

您可以使用 MSE 函数计算模型与数据的拟合程度。MSE 返回实际值与预测值之间的平方差的平均值。

=> SELECT MSE(obs::float, prediction::float) OVER()
   FROM (SELECT eruptions AS obs, pred AS prediction
         FROM pred_faithful) AS prediction_output;
        mse        |                   Comments
-------------------+-----------------------------------------------
 0.254499811834235 | Of 110 rows, 110 were used and 0 were ignored
(1 row)

另请参阅

3.5 - 用于回归的 XGBoost

XGBoost (eXtreme Gradient Boosting) 是一种很受欢迎的监督式学习算法,用于对大型数据集进行回归和分类。它使用顺序构建的浅层决策树来提供准确的结果和高度可扩展的定型方法,以避免过度拟合。

以下 XGBoost 函数使用回归模型创建和执行预测:

示例

此示例使用名为 "mtcars" 的小型数据集(其中包含 1973-1974 年 32 辆汽车的设计和性能数据),并创建 XGBoost 回归模型来预测变量 carb 的值(化油器的数量)。

开始示例之前,请加载机器学习示例数据
  1. 使用 XGB_REGRESSORmtcars 数据集创建 XGBoost 回归模型 xgb_cars

    => SELECT XGB_REGRESSOR ('xgb_cars', 'mtcars', 'carb', 'mpg, cyl, hp, drat, wt'
        USING PARAMETERS learning_rate=0.5);
     XGB_REGRESSOR
    ---------------
     Finished
    (1 row)
    

    然后,您可以使用 GET_MODEL_SUMMARY 查看模型的摘要:

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='xgb_cars');
                      GET_MODEL_SUMMARY
    ------------------------------------------------------
    ===========
    call_string
    ===========
    xgb_regressor('public.xgb_cars', 'mtcars', '"carb"', 'mpg, cyl, hp, drat, wt'
    USING PARAMETERS exclude_columns='', max_ntree=10, max_depth=5, nbins=32, objective=squarederror,
    split_proposal_method=global, epsilon=0.001, learning_rate=0.5, min_split_loss=0, weight_reg=0, sampling_size=1)
    
    =======
    details
    =======
    predictor|      type
    ---------+----------------
       mpg   |float or numeric
       cyl   |      int
       hp    |      int
      drat   |float or numeric
       wt    |float or numeric
    
    ===============
    Additional Info
    ===============
           Name       |Value
    ------------------+-----
        tree_count    | 10
    rejected_row_count|  0
    accepted_row_count| 32
    
    (1 row)
    
  2. 使用 PREDICT_XGB_REGRESSOR 预测化油器数量:

    => SELECT carb, PREDICT_XGB_REGRESSOR (mpg,cyl,hp,drat,wt USING PARAMETERS model_name='xgb_cars') FROM mtcars;
     carb | PREDICT_XGB_REGRESSOR
    ------+-----------------------
        4 |      4.00335213618023
        2 |       2.0038188946536
        6 |      5.98866003194438
        1 |      1.01774386191546
        2 |       1.9959801016274
        2 |       2.0038188946536
        4 |      3.99545403625739
        8 |      7.99211056556231
        2 |      1.99291901733151
        3 |       2.9975688946536
        3 |       2.9975688946536
        1 |      1.00320357711227
        2 |       2.0038188946536
        4 |      3.99545403625739
        4 |      4.00124134679445
        1 |      1.00759516721382
        4 |      3.99700517763435
        4 |      3.99580193056138
        4 |      4.00009088187525
        3 |       2.9975688946536
        2 |      1.98625064560888
        1 |      1.00355294416998
        2 |      2.00666247039502
        1 |      1.01682931210169
        4 |      4.00124134679445
        1 |      1.01007809485918
        2 |      1.98438405824605
        4 |      3.99580193056138
        2 |      1.99291901733151
        4 |      4.00009088187525
        2 |       2.0038188946536
        1 |      1.00759516721382
    (32 rows)
    

4 - 分类算法

分类是一种重要且流行的机器学习工具,可将数据集中的项分配给不同的类别。分类用于在欺诈检测、文本分类等方面预测随时间变化的风险。分类函数从具有不同的已知类别的数据集开始。例如,假设您想根据学生进入研究生院的可能性对他们进行分类。除了入学考试分数和等级等因素外,您还可以跟踪工作经验。

二进制分类意味着结果(本例中的结果为“录取情况”)只有两个可能的值:录取或不录取。多类结果有两个以上的值。例如,低、中或高录取机会。在训练过程中,分类算法查找结果和特征之间的关系。这种关系在模型中进行了总结,然后可以应用到类别未知的不同数据集。

4.1 - 逻辑回归

使用逻辑回归,您可以模拟独立变量之间的关系或功能,以及一些相关变量或结果。逻辑回归的结果始终是二进制值。

您可以构建逻辑回归模型:

  • 将预测模型拟合到独立变量和一些二进制变量的训练数据集。通过这种方法,您可以对结果进行预测,例如判断一个电子邮件是否是垃圾邮件。

  • 确定一个独立变量和一些二进制结果变量之间的关系强度。例如,假设您想要确定一个电子邮件是否是垃圾邮件。您可以基于对电子邮件属性的观测值来构建逻辑回归模型。然后,您可以确定电子邮件的各种属性对该结果的重要性。

您可以使用下列函数构建逻辑回归模型、查看模型,并使用该模型对一组测试数据进行预测:

有关如何在 Vertica 表中使用逻辑回归的完整编程实例,请参阅构建逻辑回归模型

4.1.1 - 构建逻辑回归模型

该逻辑回归示例使用了名为 mtcars 的小数据集。该示例展示了如何构建预测 am 值的模型(表示汽车是自动档还是手动档)。使用数据集中所有其他特征给定的值。

在该示例中,使用约 60% 的数据作为样本数据来创建模型。余下 40% 的数据用于针对测试逻辑回归模型的测试数据。

开始示例之前,请加载机器学习示例数据
  1. 使用 mtcars_train 训练数据创建名为 logistic_reg_mtcars 的逻辑回归模型。

    => SELECT LOGISTIC_REG('logistic_reg_mtcars', 'mtcars_train', 'am', 'cyl, wt'
       USING PARAMETERS exclude_columns='hp');
            LOGISTIC_REG
    ----------------------------
     Finished in 15 iterations
    
    (1 row)
    
  2. 查看 logistic_reg_mtcars 的摘要输出。

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='logistic_reg_mtcars');
    --------------------------------------------------------------------------------
    =======
    details
    =======
    predictor|coefficient|  std_err  |z_value |p_value
    ---------+-----------+-----------+--------+--------
    Intercept| 262.39898 |44745.77338| 0.00586| 0.99532
    cyl      | 16.75892  |5987.23236 | 0.00280| 0.99777
    wt       |-119.92116 |17237.03154|-0.00696| 0.99445
    
    ==============
    regularization
    ==============
    type| lambda
    ----+--------
    none| 1.00000
    
    ===========
    call_string
    ===========
    logistic_reg('public.logistic_reg_mtcars', 'mtcars_train', '"am"', 'cyl, wt'
    USING PARAMETERS exclude_columns='hp', optimizer='newton', epsilon=1e-06,
    max_iterations=100, regularization='none', lambda=1)
    
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    iteration_count   | 20
    rejected_row_count|  0
    accepted_row_count| 20
    (1 row)
    
  3. 创建名为 mtcars_predict_results 的表。使用通过在测试数据上运行 PREDICT_LOGISTIC_REG 函数获得的预测结果来填充表。在 mtcars_predict_results 表中查看结果。

    => CREATE TABLE mtcars_predict_results AS
       (SELECT car_model, am, PREDICT_LOGISTIC_REG(cyl, wt
       USING PARAMETERS model_name='logistic_reg_mtcars')
       AS Prediction FROM mtcars_test);
    CREATE TABLE
    
    
    => SELECT * FROM mtcars_predict_results;
       car_model    | am | Prediction
    ----------------+----+------------
     AMC Javelin    |  0 |          0
     Hornet 4 Drive |  0 |          0
     Maserati Bora  |  1 |          0
     Merc 280       |  0 |          0
     Merc 450SL     |  0 |          0
     Toyota Corona  |  0 |          1
     Volvo 142E     |  1 |          1
     Camaro Z28     |  0 |          0
     Datsun 710     |  1 |          1
     Honda Civic    |  1 |          1
     Porsche 914-2  |  1 |          1
     Valiant        |  0 |          0
    (12 rows)
    
  4. 使用 PREDICT_LOGISTIC_REG 评估函数来评估 CONFUSION_MATRIX 函数的准确性。

    => SELECT CONFUSION_MATRIX(obs::int, pred::int USING PARAMETERS num_classes=2) OVER()
       FROM (SELECT am AS obs, Prediction AS pred FROM mtcars_predict_results) AS prediction_output;
     class | 0 | 1 |                   comment
    -------+---+---+---------------------------------------------
         0 | 6 | 1 |
         1 | 1 | 4 | Of 12 rows, 12 were used and 0 were ignored
    (2 rows)
    

    在本例中,PREDICT_LOGISTIC_REG 正确预测在 1 列中值为 am 的五辆汽车中的四辆具有 1 值。在 0 列中值为 am 的七辆汽车中,正确预测了六辆具有值 0。将一辆汽车错误地分类为具有值 1

另请参阅

4.2 - 朴素贝叶斯

当可以假设特征独立时,您可以使用朴素贝叶斯算法对数据进行分类。该算法使用独立的特征来计算特定类的概率。例如,您可能想要预测电子邮件是垃圾邮件的概率。在该例中,您将使用与垃圾邮件相关的词库来计算电子邮件内容是垃圾邮件的概率。

您可以使用下列函数构建朴素贝叶斯模型、查看模型,并使用该模型对一组测试数据进行预测:

有关如何在 Vertica 中使用朴素贝叶斯算法的完整示例,请参阅使用朴素贝叶斯对数据进行分类

4.2.1 - 使用朴素贝叶斯对数据进行分类

该朴素贝叶斯示例使用 HouseVotes84 数据集向您展示如何构建模型。使用此模型,您可以根据投票记录预测美国国会议员隶属于哪个政党。为了帮助对已清理的数据进行分类,替换了所有缺投的投票。已清理的数据将缺投的投票替换为选民所在政党的大多数投票。例如,假设一名民主党成员未对 vote1 投票,而大多数民主党人投了赞成票。此示例将所有民主党人对 vote1 的缺投投票替换为赞成票。

在此示例中,大约 75% 的已清理 HouseVotes84 数据被随机选择并复制到训练表中。剩余的已清理 HouseVotes84 数据用作测试表。

开始示例之前,请加载机器学习示例数据

您还必须加载 naive_bayes_data_prepration.sql 脚本:

$ /opt/vertica/bin/vsql -d <name of your database> -f naive_bayes_data_preparation.sql
  1. 使用 house84_train 训练数据创建名为 naive_house84_model 的朴素贝叶斯模型。

    => SELECT NAIVE_BAYES('naive_house84_model', 'house84_train', 'party',
                          '*' USING PARAMETERS exclude_columns='party, id');
                      NAIVE_BAYES
    ------------------------------------------------
     Finished. Accepted Rows: 315  Rejected Rows: 0
    (1 row)
    
  2. 创建名为 predicted_party_naive 的新表。使用从测试数据上的 PREDICT_NAIVE_BAYES 函数得到的预测结果来填充此表。

    => CREATE TABLE predicted_party_naive
         AS SELECT party,
              PREDICT_NAIVE_BAYES (vote1, vote2, vote3, vote4, vote5,
                                   vote6, vote7, vote8, vote9, vote10,
                                   vote11, vote12, vote13, vote14,
                                   vote15, vote16
                                     USING PARAMETERS model_name = 'naive_house84_model',
                                                      type = 'response') AS Predicted_Party
           FROM house84_test;
    CREATE TABLE
    
  3. 计算模型预测的准确性。

    
    => SELECT  (Predictions.Num_Correct_Predictions / Count.Total_Count) AS Percent_Accuracy
        FROM (  SELECT COUNT(Predicted_Party) AS Num_Correct_Predictions
            FROM predicted_party_naive
            WHERE party = Predicted_Party
             ) AS Predictions,
             (  SELECT COUNT(party) AS Total_Count
                   FROM predicted_party_naive
                ) AS Count;
       Percent_Accuracy
    ----------------------
     0.933333333333333333
    (1 row)
    

该模型根据国会议员的投票模式正确预测了他们的政党,准确率为 93%。

查看每个类别的概率

您还可以查看每个类的概率。使用 PREDICT_NAIVE_BAYES_CLASSES 查看每个类的概率。

=> SELECT PREDICT_NAIVE_BAYES_CLASSES (id, vote1, vote2, vote3, vote4, vote5,
                                       vote6, vote7, vote8, vote9, vote10,
                                       vote11, vote12, vote13, vote14,
                                       vote15, vote16
                                       USING PARAMETERS model_name = 'naive_house84_model',
                                                        key_columns = 'id', exclude_columns = 'id',
                                                        classes = 'democrat, republican')
        OVER() FROM house84_test;
 id  | Predicted  |    Probability    |       democrat       |      republican
-----+------------+-------------------+----------------------+----------------------
 368 | democrat   |                 1 |                    1 |                    0
 372 | democrat   |                 1 |                    1 |                    0
 374 | democrat   |                 1 |                    1 |                    0
 378 | republican | 0.999999962214987 | 3.77850125111219e-08 |    0.999999962214987
 384 | democrat   |                 1 |                    1 |                    0
 387 | democrat   |                 1 |                    1 |                    0
 406 | republican | 0.999999945980143 | 5.40198564592332e-08 |    0.999999945980143
 419 | democrat   |                 1 |                    1 |                    0
 421 | republican | 0.922808855631005 |   0.0771911443689949 |    0.922808855631005
.
.
.
(109 rows)

另请参阅

4.3 - 用于分类的随机森林

随机森林算法创建决策树的集成模型。每棵树都对随机选择的训练数据子集进行训练。

您可以使用下列函数训练随机森林模型,并使用该模型对一组测试数据进行预测:

有关如何在 Vertica 中使用随机森林算法的完整示例,请参阅使用随机森林对数据进行分类

4.3.1 - 使用随机森林对数据进行分类

该随机森林示例使用了一个名为 iris 的数据集。该示例包含四个变量,用于测量 iris 花的各个部分以预测其种属。

在开始该示例之前,请确保您已按照下载机器学习示例数据中的步骤进行操作。

  1. 使用 RF_CLASSIFIERiris 数据创建名为 rf_iris 的随机森林模型。使用 GET_MODEL_SUMMARY 查看模型的摘要输出:

    => SELECT RF_CLASSIFIER ('rf_iris', 'iris', 'Species', 'Sepal_Length, Sepal_Width, Petal_Length, Petal_Width'
    USING PARAMETERS ntree=100, sampling_size=0.5);
    
    
            RF_CLASSIFIER
    ----------------------------
    Finished training
    
    (1 row)
    
    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='rf_iris');
    ------------------------------------------------------------------------
    ===========
    call_string
    ===========
    SELECT rf_classifier('public.rf_iris', 'iris', '"species"', 'Sepal_Length, Sepal_Width, Petal_Length,
    Petal_Width' USING PARAMETERS exclude_columns='', ntree=100, mtry=2, sampling_size=0.5, max_depth=5,
    max_breadth=32, min_leaf_size=1, min_info_gain=0, nbins=32);
    
    =======
    details
    =======
    predictor   |type
    ------------+-----
    sepal_length|float
    sepal_width |float
    petal_length|float
    petal_width |float
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    tree_count        | 100
    rejected_row_count|  0
    accepted_row_count| 150
    (1 row)
    
  2. 使用 PREDICT_RF_CLASSIFIER 将分类器应用于测试数据:

    => SELECT PREDICT_RF_CLASSIFIER (Sepal_Length, Sepal_Width, Petal_Length, Petal_Width
                                      USING PARAMETERS model_name='rf_iris') FROM iris1;
    
    PREDICT_RF_CLASSIFIER
    -----------------------
    setosa
    setosa
    setosa
    .
    .
    .
    versicolor
    versicolor
    versicolor
    .
    .
    .
    virginica
    virginica
    virginica
    .
    .
    .
    (90 rows)
    
  3. 使用 PREDICT_RF_CLASSIFIER_CLASSES 查看每个类的概率:

    => SELECT PREDICT_RF_CLASSIFIER_CLASSES(Sepal_Length, Sepal_Width, Petal_Length, Petal_Width
                                   USING PARAMETERS model_name='rf_iris') OVER () FROM iris1;
    predicted  |    probability
    -----------+-------------------
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |                 1
    setosa     |              0.99
    .
    .
    .
    (90 rows)
    

4.4 - 用于分类的 SVM(支持向量机)

支持向量机 (SVM) 是一种分类算法,它根据训练数据将数据分配到一个类别或另一个类别。该算法实施了可高度扩展的线性 SVM。

您可以使用下列函数训练 SVM 模型,并使用该模型对一组测试数据进行预测:

您还可以使用以下评估函数来获得进一步的见解:

有关如何在 Vertica 中使用 SVM 算法的完整示例,请参阅使用 SVM(支持向量机)对数据进行分类

Vertica 中 SVM 算法的实施基于论文 Distributed Newton Methods for Regularized Logistic Regression(正则逻辑回归的分布式牛顿法)。

4.4.1 - 使用 SVM(支持向量机)对数据进行分类

该 SVM 示例使用名为 mtcars 的小数据集。该示例展示了如何使用 SVM_CLASSIFIER 函数训练模型以使用 PREDICT_SVM_CLASSIFIER 函数预测 am 的值(挡位类型,其中 0 = 自动挡,1 = 手动挡)。

开始示例之前,请加载机器学习示例数据
  1. 使用 mtcars_train 训练数据创建名为 svm_class 的 SVM 模型。

    
    => SELECT SVM_CLASSIFIER('svm_class', 'mtcars_train', 'am', 'cyl, mpg, wt, hp, gear'
                              USING PARAMETERS exclude_columns='gear');
    
    SVM_CLASSIFIER
    
    ----------------------------------------------------------------
    Finished in 12 iterations.
    Accepted Rows: 20  Rejected Rows: 0
    (1 row)
    
  2. 查看 svm_class 的摘要输出。

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='svm_class');
    ------------------------------------------------------------------------
    
    =======
    details
    =======
    predictor|coefficient
    ---------+-----------
    Intercept| -0.02006
    cyl      |  0.15367
    mpg      |  0.15698
    wt       | -1.78157
    hp       |  0.00957
    
    ===========
    call_string
    ===========
    SELECT svm_classifier('public.svm_class', 'mtcars_train', '"am"', 'cyl, mpg, wt, hp, gear'
    USING PARAMETERS exclude_columns='gear', C=1, max_iterations=100, epsilon=0.001);
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    accepted_row_count| 20
    rejected_row_count|  0
    iteration_count   | 12
    (1 row)
    
  3. 创建名为 svm_mtcars_predict 的新表。使用通过在测试数据上运行 PREDICT_SVM_CLASSIFIER 函数获得的预测结果来填充表。

    => CREATE TABLE svm_mtcars_predict AS
       (SELECT car_model, am, PREDICT_SVM_CLASSIFIER(cyl, mpg, wt, hp
                                                USING PARAMETERS model_name='svm_class')
                                                AS Prediction FROM mtcars_test);
    CREATE TABLE
    
  4. svm_mtcars_predict 表中查看结果。

    => SELECT * FROM svm_mtcars_predict;
    car_model     | am | Prediction
    ------------- +----+------------
    
    Toyota Corona |  0 |          1
    Camaro Z28    |  0 |          0
    Datsun 710    |  1 |          1
    Valiant       |  0 |          0
    Volvo 142E    |  1 |          1
    AMC Javelin   |  0 |          0
    Honda Civic   |  1 |          1
    Hornet 4 Drive|  0 |          0
    Maserati Bora |  1 |          1
    Merc 280      |  0 |          0
    Merc 450SL    |  0 |          0
    Porsche 914-2 |  1 |          1
    (12 rows)
    
  5. 使用 PREDICT_SVM_CLASSIFIER 评估函数来评估 CONFUSION_MATRIX 函数的准确性。

    => SELECT CONFUSION_MATRIX(obs::int, pred::int USING PARAMETERS num_classes=2) OVER()
            FROM (SELECT am AS obs, Prediction AS pred FROM svm_mtcars_predict) AS prediction_output;
     class | 0 | 1 |                   comment
    -------+---+---+---------------------------------------------
         0 | 6 | 1 |
         1 | 0 | 5 | Of 12 rows, 12 were used and 0 were ignored
    (2 rows)
    

    在本例中,PREDICT_SVM_CLASSIFIER 正确预测在 am 列中值为 1 的汽车具有 1 值。没有汽车被错误分类。在 0 列中值为 am 的七辆汽车中,正确预测了六辆具有值 0。将一辆汽车错误地分类为具有值 1

另请参阅

4.5 - XGBoost 用于分类

XGBoost (eXtreme Gradient Boosting) 是一种很受欢迎的监督式学习算法,用于对大型数据集进行回归和分类。它使用顺序构建的浅层决策树来提供准确的结果和高度可扩展的定型方法,以避免过度拟合。

以下 XGBoost 函数使用分类模型创建和执行预测:

示例

此示例使用 "iris" 数据集(其中包含对花的各个部分的测量值),可用于预测其种属并创建 XGBoost 分类器模型来对每朵花的种属进行分类。

开始示例之前,请加载机器学习示例数据
  1. 使用 XGB_CLASSIFIERiris 数据集创建名为 xgb_iris 的 XGBoost 分类器模型。

    => SELECT XGB_CLASSIFIER ('xgb_iris', 'iris', 'Species', 'Sepal_Length, Sepal_Width, Petal_Length, Petal_Width'
        USING PARAMETERS max_ntree=10, max_depth=5, weight_reg=0.1, learning_rate=1);
     XGB_CLASSIFIER
    ----------------
     Finished
    (1 row)
    

    然后,您可以使用 GET_MODEL_SUMMARY 查看模型的摘要:

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='xgb_iris');
                                                                                                                                                                           GET_MODEL_SUMMARY
    ------------------------------------------------------
    ===========
    call_string
    ===========
    xgb_classifier('public.xgb_iris', 'iris', '"species"', 'Sepal_Length, Sepal_Width, Petal_Length, Petal_Width'
    USING PARAMETERS exclude_columns='', max_ntree=10, max_depth=5, nbins=32, objective=crossentropy,
    split_proposal_method=global, epsilon=0.001, learning_rate=1, min_split_loss=0, weight_reg=0.1, sampling_size=1)
    
    =======
    details
    =======
     predictor  |      type
    ------------+----------------
    sepal_length|float or numeric
    sepal_width |float or numeric
    petal_length|float or numeric
    petal_width |float or numeric
    
    
    ===============
    Additional Info
    ===============
           Name       |Value
    ------------------+-----
        tree_count    |  10
    rejected_row_count|  0
    accepted_row_count| 150
    
    (1 row)
    
  2. 使用 PREDICT_XGB_CLASSIFIER 将分类器应用于测试数据:

    => SELECT PREDICT_XGB_CLASSIFIER (Sepal_Length, Sepal_Width, Petal_Length, Petal_Width
        USING PARAMETERS model_name='xgb_iris') FROM iris1;
     PREDICT_XGB_CLASSIFIER
    ------------------------
     setosa
     setosa
     setosa
     .
     .
     .
     versicolor
     versicolor
     versicolor
     .
     .
     .
     virginica
     virginica
     virginica
     .
     .
     .
    
    (90 rows)
    
  3. 使用 PREDICT_XGB_CLASSIFIER_CLASSES 查看每个类的概率:

    => SELECT PREDICT_XGB_CLASSIFIER_CLASSES(Sepal_Length, Sepal_Width, Petal_Length, Petal_Width
        USING PARAMETERS model_name='xgb_iris') OVER (PARTITION BEST) FROM iris1;
      predicted  |    probability
    ------------+-------------------
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     | 0.999911552783011
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     setosa     |   0.9999650465368
     versicolor |  0.99991871763563
     .
     .
     .
    (90 rows)
    

5 - 聚类算法

聚类是一种重要且流行的机器学习工具,用于在数据集中查找彼此相似的项目群集。聚类的目标是创建具有大量相似对象的群集。与分类类似,聚类对数据进行分段。不过,在聚类中,不定义分类组。

将数据聚类成相关的组有许多有用的应用场合。如果您已经知道数据包含多少个群集,则 K-均值 算法可能足以训练您的模型并使用该模型来预测新数据点的群集成员资格。

但是,在更常见的情况下,您在分析数据之前不知道它包含多少个群集。在这些情况下,二等分 k-means 算法可以更有效地在您的数据中找到正确的群集。

k-means 和二等分 k-means 都预测给定数据集的群集。然后,可以使用借助于任一算法训练的模型来预测分配新数据点的群集。

聚类可用于发现数据中的异常并找到自然的数据组。例如,您可以使用聚类来分析地理区域并确定该区域中最有可能遭受地震袭击的区域。有关完整示例,请参阅使用 KMeans 方法进行地震群集分析

在 Vertica 中,基于欧几里德距离计算聚类。通过这种计算,数据点被分配到具有最近中心的群集。

5.1 - K-均值

您可以使用聚类算法(k 均值聚类)根据数据点之间的相似性将数据点分为 k 个不同的组。

k 均值的目的在于将 n 个数据对象分为 k 个群集。通过这种分法,将每个数据对象分配给最小距离的聚类。最小距离也被称为聚类中心对象:

有关如何对 Vertica 中的表使用 k 均值的完整示例,请参阅使用 k-means 对数据进行聚类

5.1.1 - 使用 k-means 对数据进行聚类

该 k-means 示例使用了名为 agar_dish_1agar_dish_2 的两个小数据集。使用 agar_dish_1 数据集中的数字数据,可以将数据聚类到 k 群集。然后,可以使用所创建的 k-means 模型,在 agar_dish_2 上运行 APPLY_KMEANS,并将其分配到原始模型中创建的群集。

开始示例之前,请加载机器学习示例数据

将训练数据聚类到 k 群集

  1. 使用 agar_dish_1 表数据创建名为 agar_dish_kmeans 的 k-means 模型。

    => SELECT KMEANS('agar_dish_kmeans', 'agar_dish_1', '*', 5
                      USING PARAMETERS exclude_columns ='id', max_iterations=20, output_view='agar_1_view',
                      key_columns='id');
               KMEANS
    ---------------------------
     Finished in 7 iterations
    
    (1 row)
    

    该示例创建了一个名为 agar_dish_kmeans 的模型和一个包含模型结果的名为 agar_1_view 的视图。运行聚类算法时,您可能会得到不同的结果。这是因为 KMEANS 默认随机选择初始中心。

  2. 查看 agar_1_view 输出。

    => SELECT * FROM agar_1_view;
     id  | cluster_id
    -----+------------
       2 |          4
       5 |          4
       7 |          4
       9 |          4
      13 |          4
    .
    .
    .
    (375 rows)
    
  3. 由于指定了群集的数量为 5,验证函数创建了五个群集。计算每个群集内的数据点数。

    => SELECT cluster_id, COUNT(cluster_id) as Total_count
       FROM agar_1_view
       GROUP BY cluster_id;
     cluster_id | Total_count
    ------------+-------------
              0 |          76
              2 |          80
              1 |          74
              3 |          73
              4 |          72
    (5 rows)
    

    从输出可以看出创建了五个群集:01234

    您现在已成功将 agar_dish_1.csv 中的数据聚类为五个不同的群集。

生成您的模型的摘要

使用 GET_MODEL_SUMMARY 函数查看 agar_dish_means 的摘要输出。

=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='agar_dish_kmeans');
----------------------------------------------------------------------------------
=======
centers
=======
x       |   y
--------+--------
0.49708 | 0.51116
-7.48119|-7.52577
-1.56238|-1.50561
-3.50616|-3.55703
-5.52057|-5.49197

=======
metrics
=======
Evaluation metrics:
  Total Sum of Squares: 6008.4619
  Within-Cluster Sum of Squares:
      Cluster 0: 12.083548
      Cluster 1: 12.389038
      Cluster 2: 12.639238
      Cluster 3: 11.210146
      Cluster 4: 12.994356
  Total Within-Cluster Sum of Squares: 61.316326
  Between-Cluster Sum of Squares: 5947.1456
  Between-Cluster SS / Total SS: 98.98%
Number of iterations performed: 2
Converged: True
Call:
kmeans('public.agar_dish_kmeans', 'agar_dish_1', '*', 5
USING PARAMETERS exclude_columns='id', max_iterations=20, epsilon=0.0001, init_method='kmeanspp',
distance_method='euclidean', output_view='agar_view_1', key_columns='id')
(1 row)

使用 k-means 模型对数据进行聚类

使用刚刚创建的 k-means 模型 agar_dish_kmeans,您可以将 agar_dish_2 中的点分配给群集中心。

使用 agar_dish_2 表作为输入表,使用 agar_dish_kmeans 模型作为初始群集中心,创建一个名为 kmeans_results 的表。

仅向 APPLY_KMEANS 函数中的参数添加相关特征列。

=> CREATE TABLE kmeans_results AS
        (SELECT id,
                APPLY_KMEANS(x, y
                             USING PARAMETERS
                                              model_name='agar_dish_kmeans') AS cluster_id
         FROM agar_dish_2);

kmeans_results 表显示 agar_dish_kmeans 模型对 agar_dish_2 数据进行了正确聚类。

另请参阅

5.2 - 二等分 k-means

“二等分 k-means”聚类算法将 k-means 聚类与划分层次聚类相结合。使用二等分 k-means,您不仅可以获得群集,还可以获得数据点群集的层次结构。

该层次结构比 K-均值 返回的非结构化平面群集集合提供更多信息。该层次结构显示聚类结果如何查看群集二等分过程的每个步骤以查找新群集。利用群集的层次结构,可以更轻松地确定数据集中的群集数量。

给定由二等分 k-means 产生的 k 群集的层次结构,您可以轻松计算以下形式的任何预测:假设数据只包含 k' 个群集,其中 k' 是一个数字,它小于或等于用于训练模型的 k

有关如何使用二等分 k-means 在 Vertica 中分析表的完整示例,请参阅使用二等分 k-means 对数据进行分层聚类

5.2.1 - 使用二等分 k-means 对数据进行分层聚类

此二等分 k-means 示例使用名为 agar_dish_training 和 agar_dish_testing 的两个小数据集。使用 agar_dish_training 数据集中的数字数据,可以将数据聚类到 k 群集。然后,使用生成的二等分 k-means 模型,您可以在 agar_dish_testing 上运行 APPLY_BISECTING_KMEANS,并将数据分配给在您的训练模型中创建的群集。与常规 k-means(Vertica 中也提供)不同,二等分 k-means 允许您使用小于或等于 k 的任意数量的群集进行预测。因此,如果您使用 k=5 训练模型,但后来决定使用 k=2 进行预测,则无需重新训练该模型;只需运行 k=2 的 APPLY_BISECTING_KMEANS。

开始示例之前,请加载机器学习示例数据。 对于这个示例,加载 agar_dish_training.csvagar_dish_testing.csv

将训练数据聚类成 k 个群集来训练模型

  1. 使用 agar_dish_training 表数据创建名为 agar_dish_bkmeans 的二等分 k-means 模型。

    => SELECT BISECTING_KMEANS('agar_dish_bkmeans', 'agar_dish_training', '*', 5 USING PARAMETERS exclude_columns='id', key_columns='id', output_view='agar_1_view');
     BISECTING_KMEANS
    ------------------
     Finished.
    (1 row)
    

    此示例创建一个名为 agar_dish_bkmeans 的模型和一个包含模型结果的名为 agar_1_view 的视图。运行聚类算法时,您可能会得到略有不同的结果。这是因为 BISECTING_KMEANS 使用随机数来生成最佳群集。

  2. 查看 agar_1_view 的输出:

    => SELECT * FROM agar_1_view;
     id  | cluster_id
    -----+------------
       2 |          4
       5 |          4
       7 |          4
       9 |          4
    
    ...
    

    在这里,我们可以看到 agar_dish_training 表中每个点的 ID 以及它被分配到了哪个群集。

  3. 由于我们将群集数量指定为 5,因此通过计算每个群集中的数据点数来验证该函数是否创建了五个群集。

    => SELECT cluster_id, COUNT(cluster_id) as Total_count FROM agar_1_view GROUP BY cluster_id;
     cluster_id | Total_count
    ------------+-------------
              5 |          76
              7 |          73
              8 |          74
              4 |          72
              6 |          80
    (5 rows)
    

    您可能想知道为什么 cluster_id 不从 0 或 1 开始。这是因为二等分 k-means 算法生成的群集比 k-means 多很多,然后输出 k 的指定值所需的群集。我们稍后会看到为什么这很有用。

    您现在已成功将 agar_dish_training.csv 中的数据聚类为五个不同的群集。

生成您的模型的摘要

使用 GET_MODEL_SUMMARY 函数查看 agar_dish_bkmeans 的摘要输出。

```
=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='agar_dish_bkmeans');
======
BKTree
======

```

```
center_id|   x    |   y    | withinss |totWithinss|bisection_level|cluster_size|parent|left_child|right_child
---------+--------+--------+----------+-----------+---------------+------------+------+----------+-----------
    0    |-3.59450|-3.59371|6008.46192|6008.46192 |       0       |    375     |      |    1     |     2
    1    |-6.47574|-6.48280|336.41161 |1561.29110 |       1       |    156     |  0   |    5     |     6
    2    |-1.54210|-1.53574|1224.87949|1561.29110 |       1       |    219     |  0   |    3     |     4
    3    |-2.54088|-2.53830|317.34228 | 665.83744 |       2       |    147     |  2   |    7     |     8
    4    | 0.49708| 0.51116| 12.08355 | 665.83744 |       2       |     72     |  2   |          |
    5    |-7.48119|-7.52577| 12.38904 | 354.80922 |       3       |     76     |  1   |          |
    6    |-5.52057|-5.49197| 12.99436 | 354.80922 |       3       |     80     |  1   |          |
    7    |-1.56238|-1.50561| 12.63924 | 61.31633  |       4       |     73     |  3   |          |
    8    |-3.50616|-3.55703| 11.21015 | 61.31633  |       4       |     74     |  3   |          |
```

```


=======
Metrics
=======
                       Measure                       |  Value
-----------------------------------------------------+----------
                Total sum of squares                 |6008.46192
         Total within-cluster sum of squares         | 61.31633
           Between-cluster sum of squares            |5947.14559
Between-cluster sum of squares / Total sum of squares| 98.97950
      Sum of squares for cluster 1, center_id 5      | 12.38904
      Sum of squares for cluster 2, center_id 6      | 12.99436
      Sum of squares for cluster 3, center_id 7      | 12.63924
      Sum of squares for cluster 4, center_id 8      | 11.21015
      Sum of squares for cluster 5, center_id 4      | 12.08355


===========
call_string
===========
bisecting_kmeans('agar_dish_bkmeans', 'agar_dish_training', '*', 5
USING PARAMETERS exclude_columns='id', bisection_iterations=1, split_method='SUM_SQUARES', min_divisible_cluster_size=2, distance_method='euclidean', kmeans_center_init_method='kmeanspp', kmeans_epsilon=0.0001, kmeans_max_iterations=10, output_view=''agar_1_view'', key_columns=''id'')

===============
Additional Info
===============
        Name         |Value
---------------------+-----
   num_of_clusters   |  5
dimensions_of_dataset|  2
num_of_clusters_found|  5
  height_of_BKTree   |  4

(1 row)
```

在这里,我们可以看到训练过程中通过对 k-means 进行二等分创建的所有中间群集的详细信息、一些用于评估聚类质量的指标(平方和越低越好)、训练算法的具体参数,以及有关数据算法的一些常规信息。

使用二等分 k-means 模型对测试数据进行聚类

使用刚刚创建的二等分 k-means 模型 agar_dish_bkmeans,您可以将 agar_dish_testing 中的点分配给群集中心。

  1. 使用 agar_dish_testing 表作为输入表,使用 agar_dish_bkmeans 模型作为群集中心,创建一个名为 bkmeans_results 的表。仅向 APPLY_BISECTING_KMEANS 函数中的实参添加相关特征列。

    => CREATE TABLE bkmeans_results_k5 AS
            (SELECT id,
                    APPLY_BISECTING_KMEANS(x, y
                                 USING PARAMETERS
                                                  model_name='agar_dish_bkmeans', number_clusters=5) AS cluster_id
             FROM agar_dish_testing);
    => SELECT cluster_id, COUNT(cluster_id) as Total_count FROM bkmeans_results_k5 GROUP BY cluster_id;
     cluster_id | Total_count
    ------------+-------------
              5 |          24
              4 |          28
              6 |          20
              8 |          26
              7 |          27
    (5 rows)
    

    bkmeans_results_k5 表显示 agar_dish_bkmeans 模型对 agar_dish_testing 数据进行了正确聚类。

  2. 使用二等分 k-means 的真正优势在于,它创建的模型可以将数据聚类到小于或等于训练它的 k 的任意数量的群集中。现在,无需重新训练模型,您可以将上述测试数据聚类为 3 个群集而不是 5 个群集:

    => CREATE TABLE bkmeans_results_k3 AS
            (SELECT id,
                    APPLY_BISECTING_KMEANS(x, y
                                 USING PARAMETERS
                                                  model_name='agar_dish_bkmeans', number_clusters=3) AS cluster_id
             FROM agar_dish_testing);
    => SELECT cluster_id, COUNT(cluster_id) as Total_count FROM bkmeans_results_k3 GROUP BY cluster_id;
     cluster_id | Total_count
    ------------+-------------
              4 |          28
              3 |          53
              1 |          44
    (3 rows)
    

使用经过训练的二等分 k-means 模型进行预测

为了使用经过训练的模型对数据进行聚类,二等分 k-means 算法首先将传入数据点与根群集节点的子群集中心进行比较。该算法找出数据点与这些中心中的哪个中心离得最近。然后,将该数据点与离根最近的子节点的子群集中心进行比较。预测过程继续迭代,直到到达叶群集节点。最后,将该点分配给最近的叶群集。下图简单说明了二等分 k-means 算法的训练过程和预测过程。使用二等分 k-means 的一个优点是,您可以使用从 2 到训练模型的最大 k 值范围内的任何 k 值来进行预测。

下图中的模型使用 k=5 训练。中间的图显示如何使用模型预测 k=5 的情况,换句话说,在有 5 个叶群集的层次结构级别中,将传入的数据点匹配到具有最接近值的中心。右图显示如何使用模型预测 k=2 的情况,也就是说,先在只有两个群集的级别将传入的数据点与叶群集进行比较,然后将数据点匹配到这两个群集中心中较近的一个。这种方法比使用 k-means 进行预测快。

另请参阅

6 - 时间序列预测

时间序列模型在具有一致时间步长的随机过程的平稳时间序列(即平均值不随时间变化的时间序列)上进行训练。这些算法通过考虑一些先前时间步长(滞后)的值的影响来预测未来值。

适用数据集的示例包括温度、股票价格、地震、产品销售等数据集。

要标准化时间步长不一致的数据集,请参阅空白填充和插值 (GFI)

6.1 - 自回归模型示例

自动回归模型将根据先前的值来预测时间序列的未来值。更具体地说,用户指定的 lag 决定了该模型在计算过程中要考虑多少个先前的时间段,且预测值为每个 lag 的线性组合。

使用自回归模型进行训练和预测时使用以下函数。请注意,这些函数需要具有一致时间步长的数据集。

要标准化时间步长不一致的数据集,请参阅空白填充和插值 (GFI)

示例

  1. Machine-Learning-Examples 存储库加载数据集。

    此示例使用 daily-min-temperatures 数据集,其中包含 1981 年至 1990 年澳大利亚墨尔本每天的最低气温数据:

    => SELECT * FROM temp_data;
            time         | Temperature
    ---------------------+-------------
     1981-01-01 00:00:00 |        20.7
     1981-01-02 00:00:00 |        17.9
     1981-01-03 00:00:00 |        18.8
     1981-01-04 00:00:00 |        14.6
     1981-01-05 00:00:00 |        15.8
    ...
     1990-12-27 00:00:00 |          14
     1990-12-28 00:00:00 |        13.6
     1990-12-29 00:00:00 |        13.5
     1990-12-30 00:00:00 |        15.7
     1990-12-31 00:00:00 |          13
    (3650 rows)
    
  2. 使用 AUTOREGRESSORtemp_data 数据集创建自回归模型 AR_temperature。在本例中,模型以 p=3 的滞后进行训练,每次估计都要考虑前 3 个条目:

    => SELECT AUTOREGRESSOR('AR_temperature', 'temp_data', 'Temperature', 'time' USING PARAMETERS p=3);
                        AUTOREGRESSOR
    ---------------------------------------------------------
     Finished. 3650 elements accepted, 0 elements rejected.
    (1 row)
    

    您可以使用 GET_MODEL_SUMMARY 查看模型的摘要:

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='AR_temperature');
    
     GET_MODEL_SUMMARY
    -------------------
    
    ============
    coefficients
    ============
    parameter| value
    ---------+--------
      alpha  | 1.88817
    phi_(t-1)| 0.70004
    phi_(t-2)|-0.05940
    phi_(t-3)| 0.19018
    
    
    ==================
    mean_squared_error
    ==================
    not evaluated
    
    ===========
    call_string
    ===========
    autoregressor('public.AR_temperature', 'temp_data', 'temperature', 'time'
    USING PARAMETERS p=3, missing=linear_interpolation, regularization='none', lambda=1, compute_mse=false);
    
    ===============
    Additional Info
    ===============
           Name       |Value
    ------------------+-----
        lag_order     |  3
    rejected_row_count|  0
    accepted_row_count|3650
    (1 row)
    
  3. 使用 PREDICT_AUTOREGRESSOR 预测未来温度。以下查询在数据集末尾start预测,并返回 10 个预测。

    => SELECT PREDICT_AUTOREGRESSOR(Temperature USING PARAMETERS model_name='AR_temperature', npredictions=10) OVER(ORDER BY time) FROM temp_data;
    
        prediction
    ------------------
     12.6235419917807
     12.9387860506032
     12.6683380680058
     12.3886937385419
     12.2689506237424
     12.1503023330142
     12.0211734746741
     11.9150531529328
     11.825870404008
     11.7451846722395
    (10 rows)
    

6.2 - 移动平均模型示例

移动平均值模型使用早期预测误差进行未来预测。更具体地说,用户指定的 lag 决定了它在计算过程中要考虑多少先前的预测和错误。

使用移动平均模型进行训练和预测时使用以下函数。请注意,这些函数需要具有一致时间步长的数据集。

要标准化时间步长不一致的数据集,请参阅空白填充和插值 (GFI)

示例

  1. Machine-Learning-Examples 存储库加载数据集。

    此示例使用 daily-min-temperatures 数据集,其中包含 1981 年至 1990 年澳大利亚墨尔本每天的最低气温数据:

    => SELECT * FROM temp_data;
            time         | Temperature
    ---------------------+-------------
     1981-01-01 00:00:00 |        20.7
     1981-01-02 00:00:00 |        17.9
     1981-01-03 00:00:00 |        18.8
     1981-01-04 00:00:00 |        14.6
     1981-01-05 00:00:00 |        15.8
    ...
     1990-12-27 00:00:00 |          14
     1990-12-28 00:00:00 |        13.6
     1990-12-29 00:00:00 |        13.5
     1990-12-30 00:00:00 |        15.7
     1990-12-31 00:00:00 |          13
    (3650 rows)
    
  2. 使用 MOVING_AVERAGEtemp_data 数据集创建移动平均模型 MA_temperature。在本例中,模型以 p=3 的滞后进行训练,每次估计都要考虑 3 个以前预测的错误:

    => SELECT MOVING_AVERAGE('MA_temperature', 'temp_data', 'temperature', 'time' USING PARAMETERS q=3, missing='linear_interpolation', regularization='none', lambda=1);
                        MOVING_AVERAGE
    ---------------------------------------------------------
     Finished. 3650 elements accepted, 0 elements rejected.
    (1 row)
    

    您可以使用 GET_MODEL_SUMMARY 查看模型的摘要:

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='MA_temperature');
    
     GET_MODEL_SUMMARY
    -------------------
    
    ============
    coefficients
    ============
    parameter| value
    ---------+--------
    phi_(t-0)|-0.90051
    phi_(t-1)|-0.10621
    phi_(t-2)| 0.07173
    
    
    ===============
    timeseries_name
    ===============
    temperature
    
    ==============
    timestamp_name
    ==============
    time
    
    ===========
    call_string
    ===========
    moving_average('public.MA_temperature', 'temp_data', 'temperature', 'time'
    USING PARAMETERS q=3, missing=linear_interpolation, regularization='none', lambda=1);
    
    ===============
    Additional Info
    ===============
           Name       | Value
    ------------------+--------
           mean       |11.17780
        lag_order     |   3
          lambda      | 1.00000
    rejected_row_count|   0
    accepted_row_count|  3650
    
    (1 row)
    
  3. 使用 PREDICT_MOVING_AVERAGE 预测未来温度。以下查询在数据集末尾start预测,并返回 10 个预测。

    => SELECT PREDICT_MOVING_AVERAGE(Temperature USING PARAMETERS model_name='MA_temperature', npredictions=10) OVER(ORDER BY time) FROM temp_data;
    
        prediction
    ------------------
     13.1324365636272
     12.8071086272833
     12.7218966671721
     12.6011086656032
     12.506624729879
     12.4148247026733
     12.3307873804812
     12.2521385975133
     12.1789741993396
     12.1107640076638
    (10 rows)
    

7 - 模型管理

此部分中的主题描述了如何管理模型。

7.1 - 更改模型

您可以使用 ALTER MODEL 修改模型,以响应模型的需要。您可以通过重命名模型、更改所有者和更改架构来更改模型。

您可以删除或更改您创建的任何模型。

7.1.1 - 更改模型所有权

作为超级用户或模型所有者,您可以使用 ALTER MODEL 重新分配模型所有权,如下所示:

ALTER MODEL model-name OWNER TO owner-name

当模型所有者离职或更改职责时,更改模型所有权很有用。由于您可以更改所有者,因此不需要重写模型。

示例

以下示例演示了如何使用 ALTER_MODEL 更改模型所有者:

  1. 查找您要更改的模型。作为 dbadmin,您拥有模型。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mykmeansmodel';
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mykmeansmodel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    
  2. 将模型所有者从 dbadmin 更改为 user1。

    => ALTER MODEL mykmeansmodel OWNER TO user1;
         ALTER MODEL
    
  3. 查看 V_CATALOG.MODELS 以验证所有者是否已更改。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mykmeansmodel';
    
    
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mykmeansmodel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | user1
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    

7.1.2 - 将模型移到另一个架构

您可以使用 ALTER MODEL 将模型从一个架构移动到另一个架构。您可以以超级用户或对当前架构拥有 USAGE 权限且对目标架构拥有 CREATE 权限的用户的身份来移动模型。

示例

以下示例演示了如何使用 ALTER MODEL 更改模型架构:

  1. 查找您要更改的模型。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mykmeansmodel';
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mykmeansmodel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    
  2. 更改模型架构。

    => ALTER MODEL mykmeansmodel SET SCHEMA test;
         ALTER MODEL
    
  3. 查看 V_CATALOG.MODELS 以验证所有者是否已更改。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mykmeansmodel';
    
    
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mykmeansmodel
    schema_id      | 45035996273704978
    schema_name    | test
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    

7.1.3 - 重命名模型

ALTER MODEL 允许您重命名模型。例如:

  1. 查找您要更改的模型。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mymodel';
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mymodel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    
  2. 重命名模型。

    => ALTER MODEL mymodel RENAME TO mykmeansmodel;
         ALTER MODEL
    
  3. 查看 V_CATALOG.MODELS 以验证模型名称是否已更改。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mykmeansmodel';
    
    
    -[ RECORD 1 ]--+------------------------------------------
    model_id       | 45035996273816618
    model_name     | mykmeansmodel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | kmeans
    is_complete    | t
    create_time    | 2017-03-02 11:16:04.990626-05
    size           | 964
    

7.2 - 删除模型

DROP MODEL 从数据库中移除一个或多个模型。例如:

  1. 查找您要删除的模型。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mySvmClassModel';
    -[ RECORD 1 ]--+--------------------------------
    model_id       | 45035996273765414
    model_name     | mySvmClassModel
    schema_id      | 45035996273704978
    schema_name    | public
    owner_id       | 45035996273704962
    owner_name     | dbadmin
    category       | VERTICA_MODELS
    model_type     | SVM_CLASSIFIER
    is_complete    | t
    create_time    | 2017-02-14 10:30:44.903946-05
    size           | 525
    
  2. 删除模型。

    => DROP MODEL mySvmClassModel;
         DROP MODEL
    
  3. 查看 V_CATALOG.MODELS 以验证模型是否已删除。

    => SELECT * FROM V_CATALOG.MODELS WHERE model_name='mySvmClassModel';
    (0 rows)
    

7.3 - 管理模型安全

您可以使用 GRANT 和 REVOKE 语句来管理模型的安全权限。以下示例展示了如何使用 faithful 表和 linearReg 模型更改 user1 和 user2 的权限。

  • 在以下示例中,dbadmin 将 SELECT 权限授予 user1:

    => GRANT SELECT ON TABLE faithful TO user1;
    
    GRANT PRIVILEGE
    
  • 然后,dbadmin 将公共架构的 CREATE 权限授予 user1:

    => GRANT CREATE ON SCHEMA public TO user1;
    GRANT PRIVILEGE
    
  • 以 user1 身份连接到数据库:

    => \c - user1
    
  • 以 user1 身份构建 linearReg 模型:

=> SELECT LINEAR_REG('linearReg', 'faithful', 'waiting', 'eruptions');
LINEAR_REG
---------------------------
Finished in 1 iterations
(1 row)
  • 以 user1 身份将 USAGE 权限授予 user2:
=> GRANT USAGE ON MODEL linearReg TO user2;
GRANT PRIVILEGE
  • 以 user2 身份连接到数据库:
=> \c - user2
  • 要确认权限已授予 user2,请运行 GET_MODEL_SUMMARY 函数。对模型具有 USAGE 权限的用户可以在该模型上运行 GET_MODEL_SUMMARY:
=> SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='linearReg');

=======
details
=======
predictor|coefficient|std_err |t_value |p_value
---------+-----------+--------+--------+--------
Intercept| 33.47440  | 1.15487|28.98533| 0.00000
eruptions| 10.72964  | 0.31475|34.08903| 0.00000

==============
regularization
==============
type| lambda
----+--------
none| 1.00000

===========
call_string
===========
linear_reg('public.linearReg', 'faithful', '"waiting"', 'eruptions'
USING PARAMETERS optimizer='newton', epsilon=1e-06, max_iterations=100, regularization='none', lambda=1)

===============
Additional Info
===============
Name              |Value
------------------+-----
iteration_count   |  1
rejected_row_count|  0
accepted_row_count| 272
(1 row)
  • 以 user1 身份连接到数据库:
=> \c - user1
  • 然后,您可以使用 REVOKE 语句撤销 user2 的权限:
=> REVOKE USAGE ON MODEL linearReg FROM user2;
REVOKE PRIVILEGE
  • 要确认权限已撤销,请以用户 2 身份连接并运行 GET_MODEL_SUMMARY 函数:
=> \c - user2
=>SELECT GET_MODEL_SUMMARY('linearReg');
ERROR 7523:  Problem in get_model_summary.
Detail: Permission denied for model linearReg

另请参阅

7.4 - 查看模型属性

以下主题介绍了 Vertica 机器学习算法的模型属性。这些属性描述了特定模型的内部结构:

7.5 - 总结模型

  1. 查找您要总结的模型。

    => SELECT * FROM v_catalog.models WHERE model_name='svm_class';
    model_id      | model_name |     schema_id   | schema_name |     owner_id      | owner_name |    category    |
    model_type   | is_complete |     create_time          | size
    -------------------+------------+-------------------+-------------+-------------------+------------+--------
    --------+----------------+-------------+-------------------------------+------
    45035996273715226 | svm_class  | 45035996273704980 | public      | 45035996273704962 | dbadmin    | VERTICA_MODELS
    | SVM_CLASSIFIER | t           | 2017-08-28 09:49:00.082166-04 | 1427
    (1 row)
    
  2. 查看模型摘要。

    
    => SELECT GET_MODEL_SUMMARY(USING PARAMETERS model_name='svm_class');
    ------------------------------------------------------------------------
    
    =======
    details
    =======
    predictor|coefficient
    ---------+-----------
    Intercept| -0.02006
    cyl      |  0.15367
    mpg      |  0.15698
    wt       | -1.78157
    hp       |  0.00957
    
    ===========
    call_string
    ===========
    SELECT svm_classifier('public.svm_class', 'mtcars_train', '"am"', 'cyl, mpg, wt, hp, gear'
    USING PARAMETERS exclude_columns='gear', C=1, max_iterations=100, epsilon=0.001);
    
    ===============
    Additional Info
    ===============
    Name              |Value
    ------------------+-----
    accepted_row_count| 20
    rejected_row_count|  0
    iteration_count   | 12
    (1 row)
    

另请参阅

7.6 - 查看模型

Vertica 将您创建的模型存储在 V_CATALOG.MODELS 系统表中。

您可以查询 V_CATALOG.MODELS 来查看您创建的模型的信息:

=> SELECT * FROM V_CATALOG.MODELS;
-[ RECORD 1 ]--+------------------------------------------
model_id       | 45035996273765414
model_name     | mySvmClassModel
schema_id      | 45035996273704978
schema_name    | public
owner_id       | 45035996273704962
owner_name     | dbadmin
category       | VERTICA_MODELS
model_type     | SVM_CLASSIFIER
is_complete    | t
create_time    | 2017-02-14 10:30:44.903946-05
size           | 525
-[ RECORD 2 ]--+------------------------------------------

model_id       | 45035996273711466
model_name     | mtcars_normfit
schema_id      | 45035996273704978
schema_name    | public
owner_id       | 45035996273704962
owner_name     | dbadmin
category       | VERTICA_MODELS
model_type     | SVM_CLASSIFIER
is_complete    | t
create_time    | 2017-02-06 15:03:05.651941-05
size           | 288

另请参阅

8 - 在 Vertica 中使用外部模型

为了让您在机器学习方面获得最大的灵活性和可扩展性,Vertica 支持使用 PMML 和 TensorFlow 模型进行导入、导出和预测。

机器学习配置参数 MaxModelSizeKB 设置可以导入 Vertica 的模型的最大大小。

对 PMML 模型的支持

Vertica 支持以预测模型标记语言 (PMML) 格式导入和导出 K-means、线性回归和逻辑回归机器学习模型。借助对这种独立于平台的模型格式的支持,您可以使用其他平台上训练的模型来预测 Vertica 数据库中存储的数据。您还可以使用 Vertica 作为模型存储库。Vertica 支持 PMML 4.4 版

通过 PREDICT_PMML 函数,您可以使用在 Vertica 中存档的 PMML 模型对 Vertica 数据库中存储的数据运行预测。

有关详细信息,请参阅使用 PMML 模型

有关 Vertica 当前支持和不支持的 PMML 属性的详细信息,请参阅PMML 特征和属性

对 TensorFlow 模型的支持

Vertica 现在支持导入经过训练的 TensorFlow 模型,并使用这些模型在 Vertica 中对 Vertica 数据库中存储的数据进行预测。Vertica 支持在 TensorFlow 1.15 版中训练的 TensorFlow 模型。

PREDICT_TENSORFLOW 函数可让您使用任何 TensorFlow 模型预测 Vertica 中的数据。

有关其他信息,请参阅TensorFlow 模型

支持外部模型的其他函数

以下函数同时支持 PMML 和 TensorFlow 模型:

IMPORT_MODELS EXPORT_MODELS GET_MODEL_ATTRIBUTE GET_MODEL_SUMMARY

8.1 - TensorFlow 模型

Tensorflow 是一个用于创建神经网络的框架。它以可扩展的方式实现基本的线性代数和多变量微积分运算,使用户可以轻松地将这些运算链接到计算图中。

Vertica 支持使用在 Vertica 外部训练的 TensorFlow 1.x 和 2.x 模型导入、导出和进行预测。

数据库内 TensorFlow 与 Vertica 的集成提供了几点好处:

  • 您的模型存在于您的数据库中,因此您无需移动数据来进行预测。

  • 您可以处理的数据量仅受 Vertica 数据库大小的限制,这使得 Vertica 特别适合大数据机器学习。

  • Vertica 提供数据库内模型管理,因此您可以存储任意数量的模型。

  • 导入的模型是便携式的,可以导出以在其他地方使用。

当您运行 TensorFlow 模型以预测数据库中的数据时,Vertica 会调用 TensorFlow 进程来运行模型。这使 Vertica 能够支持您使用 TensorFlow 创建和训练的任何模型。Vertica 仅提供输入(您在 Vertica 数据库中的数据)并存储输出。

8.1.1 - TensorFlow 集成和目录结构

本页介绍如何将 Tensorflow 模型导入 Vertica、对 Vertica 数据库中的数据进行预测、导出模型以使其可在其他 Vertica 群集或第三方平台上使用。

有关每个操作的从头到尾的示例,请参阅 TensorFlow 示例

Vertica 支持借助于 TensorFlow 1.x 和 2.x 创建的模型,但强烈建议使用 2.x 来创建模型。

要将 TensorFlow 与 Vertica 结合使用,请在任何节点上安装 TFIntegration UDX 包。您只需执行一次该操作:

$ /opt/vertica/bin/admintools -t install_package -d database_name -p 'password' --package TFIntegration

TensorFlow 模型的目录和文件结构

在导入模型之前,您应当为每个模型创建一个单独的目录,其中包含以下各项之一。请注意,Vertica 在导入时使用目录名称作为模型名称:

  • model_name.pb:冻结图格式的训练模型

  • tf_model_desc.json:模型的描述

您可以使用 Machine-Learning-Examples/TensorFlow 存储库(或 opt/vertica/packages/TFIntegration/examples)中包含的脚本 freeze_tf2_model.py 来为给定的 TensorFlow 2 模型生成两个文件,但您可能需要根据您的用例以及您希望 Vertica 数据库与模型交互的方式对描述进行修改:

$ python3 Tensorflow/freeze_tf2_model.py your/model/directory

例如,tf_models 目录包含两个模型 tf_mnist_estimatortf_mnist_keras

tf_models/
├── tf_mnist_estimator
│   ├── mnist_estimator.pb
│   └── tf_model_desc.json
└── tf_mnist_keras
    ├── mnist_keras.pb
    └── tf_model_desc.json

tf_model_desc.json

tf_model_desc.json 文件构成了 TensorFlow 和 Vertica 之间的桥梁。它描述了模型的结构,以便 Vertica 可以将其输入和输出正确匹配到输入/输出表。

请注意,freeze_tf2_model.py 脚本会自动为您的模型生成此文件,并且此生成的文件通常可以按原样使用。对于较复杂的模型或用例,您可能必须编辑此文件。有关每个字段的详细分类,请参阅tf_model_desc.json 概述

将 TensorFlow 模型导入 Vertica

要导入 TensorFlow 模型,请使用 IMPORT_MODELS 和类别 'TENSORFLOW'

导入单个模型。请记住,Vertica 数据库使用目录名称作为模型名称:

select IMPORT_MODELS ( '/path/tf_models/tf_mnist_keras' USING PARAMETERS category='TENSORFLOW');
 import_models
---------------
 Success
(1 row)

使用通配符 (*) 导入目录中的所有模型(每个模型都有自己的目录):

select IMPORT_MODELS ('/path/tf_models/*' USING PARAMETERS category='TENSORFLOW');
 import_models
---------------
 Success
(1 row)

使用导入的 TensorFlow 模型进行预测

导入 TensorFlow 模型后,您可以使用该模型来预测 Vertica 表中的数据。

PREDICT_TENSORFLOW 函数与其他预测函数的不同之处在于它不接受任何影响输入列的参数,例如 "exclude_columns" 或 "id_column";相反,该函数总是对提供的所有输入列进行预测。但是,它确实接受 num_passthru_cols 参数,该参数允许用户“跳过”一些输入列,如下所示。

OVER(PARTITION BEST) 子句告知 Vertica 跨多个节点并行化操作。有关详细信息,请参阅窗口分区子句

=> select PREDICT_TENSORFLOW (*
                   USING PARAMETERS model_name='tf_mnist_keras', num_passthru_cols=1)
                   OVER(PARTITION BEST) FROM tf_mnist_test_images;

--example output, the skipped columns are displayed as the first columns of the output
 ID | col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9
----+------+------+------+------+------+------+------+------+------+------
  1 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0
  3 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0
  6 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0
...

导出 TensorFlow 模型

Vertica 将模型导出为冻结图,然后可以随时重新导入。请记住,保存为冻结图的模型无法进一步训练。

使用 EXPORT_MODELS 导出 TensorFlow 模型。例如,要将 tf_mnist_keras 模型导出到 /path/to/export/to 目录:

=> SELECT EXPORT_MODELS ('/path/to/export/to', 'tf_mnist_keras');
 export_models
---------------
 Success
(1 row)

导出 TensorFlow 模型时,Vertica 数据库会创建并使用指定的目录来存储描述模型的文件:

$ ls tf_mnist_keras/
crc.json  metadata.json  mnist_keras.pb  model.json  tf_model_desc.json

.pbtf_model_desc.json 文件描述了模型,其余文件是由 Vertica 数据库创建的组织文件。

另请参阅

8.1.2 - TensorFlow 示例

Vertica 使用 TFIntegration UDX 包与 TensorFlow 集成。您可以在 Vertica 数据库之外训练模型,然后将它们导入 Vertica 并对数据进行预测。

TensorFlow 脚本和数据集包含在 Machine-Learning-Examples/TensorFlow 下的 GitHub 存储库中。

下面的示例创建一个在 MNIST 手写数字分类数据集上训练的 Keras(一种 TensorFlow API)神经网络模型,其各层如下所示。

数据从上到下穿过每一层,每一层在返回分数之前修改输入。在此示例中,传入的数据是一组手写阿拉伯数字图像,输出内容是输入图像为特定数字的概率:

inputs = keras.Input(shape=(28, 28, 1), name="image")
x = layers.Conv2D(32, 5, activation="relu")(inputs)
x = layers.MaxPooling2D(2)(x)
x = layers.Conv2D(64, 5, activation="relu")(x)
x = layers.MaxPooling2D(2)(x)
x = layers.Flatten()(x)
x = layers.Dense(10, activation='softmax', name='OUTPUT')(x)
tfmodel = keras.Model(inputs, x)

有关 TensorFlow 如何与 Vertica 数据库交互以及如何导入更复杂模型的详细信息,请参阅TensorFlow 集成和目录结构

为 Vertica 准备 TensorFlow 模型

以下过程在 Vertica 之外进行。

训练和保存 TensorFlow 模型

  1. 安装 TensorFlow 2

  2. 训练您的模型。对于此特定示例,您可以运行 train_simple_model.py 来训练和保存模型。否则,一般而言,您可以在 Python 中手动训练您的模型,然后保存它

    $ mymodel.save('my_saved_model_dir')
    
  3. 运行 Machine-Learning-Examples 存储库opt/vertica/packages/TFIntegration/examples 中包含的 freeze_tf2_model.py 脚本,指定您的模型和输出目录(可选,默认为 frozen_tfmodel)。

    此脚本将您保存的模型转换为与 Vertica 兼容的冻结图格式并创建 tf_model_desc.json 文件,该文件描述了 Vertica 应如何将其表转换为 TensorFlow 张量:

    $ ./freeze_tf2_model.py path/to/tf/model frozen_model_dir
    

导入 TensorFlow 模型并在 Vertica 中进行预测

  1. 如果您尚未安装 TFIntegration UDX 包,请以 dbadmin 身份在任何节点上安装。您只需执行一次该操作。

    $ /opt/vertica/bin/admintools -t install_package -d database_name -p 'password' --package TFIntegration
    

  2. directory 复制到 Vertica 群集中的任何节点并导入模型:

    => SELECT IMPORT_MODELS('path/to/frozen_model_dir' USING PARAMETERS category='TENSORFLOW');
    
  3. 导入要对其进行预测的数据集。对于此示例:

    1. Machine-Learning-Examples/TensorFlow/data 目录复制到 Vertica 群集中的任何节点。

    2. 从该 data 目录中,运行 SQL 脚本 load_tf_data.sql 以加载 MNIST 数据集:

      $ vsql -f load_tf_data.sql
      
  4. 使用 PREDICT_TENSORFLOW 在数据集上使用您的模型进行预测。在此示例中,该模型用于对 MNIST 数据集中的手写数字图像进行分类:

    => SELECT PREDICT_TENSORFLOW (*
                       USING PARAMETERS model_name='tf_mnist_keras', num_passthru_cols=1)
                       OVER(PARTITION BEST) FROM tf_mnist_test_images;
    
    --example output, the skipped columns are displayed as the first columns of the output
     ID | col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9
    ----+------+------+------+------+------+------+------+------+------+------
      1 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0
      3 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0
      6 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0
    ...
    
  5. 要使用 EXPORT_MODELS 导出模型:

    => SELECT EXPORT_MODELS('/path/to/export/to', 'tf_mnist_keras');
     EXPORT_MODELS
    ---------------
     Success
    (1 row)
    

TensorFlow 1(已弃用)

  1. 使用 Python 3.7 或更低版本安装 TensorFlow 1.15

  2. Machine-Learning-Examples/TensorFlow/tf1 中运行 train_save_model.py 以训练模型并将其保存为 TensorFlow 和冻结图格式。

另请参阅

8.1.3 - tf_model_desc.json 概述

在导入外部训练的 TensorFlow 模型之前,您必须:

  • 将模型保存为冻结图 (.pb) 格式

  • 创建 tf_model_desc.json,向 Vertica 数据库描述如何将其输入和输出映射到输入/输出表

方便的是,Machine-Learning-Examples 存储库的 TensorFlow 目录中(和opt/vertica/packages/TFIntegration/examples中)包含的脚本 freeze_tf2_model.py 会自动完成这两项工作。在大多数情况下,生成的 tf_model_desc.json 可以按原样使用,但对于较复杂的数据集和用例,您可能需要对其进行编辑。

用于示例数据集的 tf_model_desc.json

下面的 tf_model_desc.json 是从 TensorFlow 示例 使用的 MNIST 手写数据集生成的。

{
    "frozen_graph": "mnist_keras.pb",
    "input_desc": [
        {
            "op_name": "image_input",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        1,
                        28,
                        28,
                        1
                    ],
                    "col_start": 0
                }
            ]
        }
    ],
    "output_desc": [
        {
            "op_name": "OUTPUT/Softmax",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        1,
                        10
                    ],
                    "col_start": 0
                }
            ]
        }
    ]
}

该文件描述了模型输入和输出的结构。它必须包含一个与 .pb 模型的文件名匹配的 frozen_graph 字段、一个 input_desc 字段和一个 output_desc 字段。

  • input_descoutput_desc:TensorFlow 图中输入和输出节点的描述。其中每一个都包含以下字段:
    • op_name:创建和训练模型时设置的操作节点名称。您通常可以从 tfmodel.inputstfmodel.outputs 检索这些参数的名称。例如:

      
      $ print({t.name:t for t in tfmodel.inputs})
      {'image_input:0': <tf.Tensor 'image_input:0' shape=(?, 28, 28, 1) dtype=float32>}
      
      $ print({t.name:t for t in tfmodel.outputs})
      {'OUTPUT/Softmax:0': <tf.Tensor 'OUTPUT/Softmax:0' shape=(?, 10) dtype=float32>}
      

      在本例中,op_name 的相应值如下。

      • input_descimage_input

      • output_descOUTPUT/Softmax

      有关此过程的更详细示例,请查看 freeze_tf2_model.py 的代码。

    • tensor_map:如何将张量映射到可通过以下方式指定的 Vertica 列:

      • idx:张量的索引(第一个输入/输出应为 0,第二个输入/输出应为 1,等等)

      • dim:保存张量维度的向量;它提供了列数

      • col_start(仅在未指定 col_idx 时使用):起始列索引。当与 dim 一起使用时,它指定从 col_start 开始、在 col_start+dim 结束的 Vertica 列的索引范围;Vertica 从索引 col_start 指定的列处开始,获取接下来的 dim

      • col_idx:Vertica 列中对应于修整张量的索引。这允许您显式指定 Vertica 列的索引,否则无法使用 col_startdim 将其指定为简单范围(例如 1、3、5、7)

      • data_type(未显示):输入或输出的数据类型,为以下之一:

        • TF_FLOAT(默认值)

        • TF_DOUBLE

        • TF_INT8

        • TF_INT16

        • TF_INT32

        • TF_INT64

复杂 tf_model_desc.json 示例

下面是一个包含多个输入和输出的较复杂示例:

{
    "input_desc": [
        {
            "op_name": "input1",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        4
                    ],
                    "col_idx": [
                        0,
                        1,
                        2,
                        3
                    ]
                },
                {
                    "idx": 1,
                    "dim": [
                        2,
                        2
                    ],
                    "col_start": 4
                }
            ]
        },
        {
            "op_name": "input2",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [],
                    "col_idx": [
                        8
                    ]
                },
                {
                    "idx": 1,
                    "dim": [
                        2
                    ],
                    "col_start": 9
                }
            ]
        }
    ],
    "output_desc": [
        {
            "op_name": "output",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        2
                    ],
                    "col_start": 0
                }
            ]
        }
    ]
}

另请参阅

8.2 - 使用 PMML 模型

Vertica 可以使用 4.4 版及以下版本的 PMML 模型导入、导出和进行预测。

8.2.1 - 以 PMML 格式导出 Vertica 模型

您可以利用 Vertica 中的内置分布式算法来训练机器学习模型。在某些情况下,您可能希望在 Vertica 之外(例如在边缘节点上)使用这些模型进行预测。现在,您可以将模型导出为 PMML 格式,并使用导出后的模型通过一个支持读取和评估 PMML 模型的库或平台进行预测。

这里有一个在 Vertica 中训练模型后以 PMML 格式导出的示例。下图显示了示例的工作流程。我们使用 vsql 来运行该示例。

假设您想在名为“患者”的关系中训练数据的逻辑回归模型,以预测患者在接受治疗后的第二次发作和特质焦虑。

训练后,模型显示在名为 V_CATALOG.MODELS 的系统表中,其中列出了 Vertica 中存档的 ML 模型。

=> -- Training a logistic regression model on a training_data
=> SELECT logistic_reg('myModel', 'patients', 'second_attack', 'treatment, trait_anxiety');
       logistic_reg
---------------------------
 Finished in 5 iterations

(1 row)

=> -- Looking at the models table
=> SELECT model_name, schema_name, category, model_type, create_time, size FROM models;
 model_name | schema_name |    category    |     model_type      |          create_time          | size
------------+-------------+----------------+---------------------+-------------------------------+------
 myModel    | public      | VERTICA_MODELS | LOGISTIC_REGRESSION | 2020-07-28 00:05:18.441958-04 | 1845
(1 row)

可以使用 GET_MODEL_SUMMARY 函数来查看模型摘要。

=> -- Looking at the summary of the model
=> \t
Showing only tuples.
=> SELECT get_model_summary(USING PARAMETERS model_name='myModel');


=======
details
=======
  predictor  |coefficient|std_err |z_value |p_value
-------------+-----------+--------+--------+--------
  Intercept  | -6.36347  | 3.21390|-1.97998| 0.04771
  treatment  | -1.02411  | 1.17108|-0.87450| 0.38185
trait_anxiety|  0.11904  | 0.05498| 2.16527| 0.03037


==============
regularization
==============
type| lambda
----+--------
none| 1.00000


===========
call_string
===========
logistic_reg('public.myModel', 'patients', '"second_attack"', 'treatment, trait_anxiety'
USING PARAMETERS optimizer='newton', epsilon=1e-06, max_iterations=100, regularization='none', lambda=1, alpha=0.5)

===============
Additional Info
===============
       Name       |Value
------------------+-----
 iteration_count  |  5
rejected_row_count|  0
accepted_row_count| 20

您还可以使用 GET_MODEL_ATTRIBUTE 函数检索模型的属性。

=> \t
Tuples only is off.
=> -- The list of the attributes of the model
=> SELECT get_model_attribute(USING PARAMETERS model_name='myModel');
     attr_name      |                    attr_fields                    | #_of_rows
--------------------+---------------------------------------------------+-----------
 details            | predictor, coefficient, std_err, z_value, p_value |         3
 regularization     | type, lambda                                      |         1
 iteration_count    | iteration_count                                   |         1
 rejected_row_count | rejected_row_count                                |         1
 accepted_row_count | accepted_row_count                                |         1
 call_string        | call_string                                       |         1
(6 rows)

=> -- Returning the coefficients of the model in a tabular format
=> SELECT get_model_attribute(USING PARAMETERS model_name='myModel', attr_name='details');
   predictor   |    coefficient    |      std_err       |      z_value       |      p_value
---------------+-------------------+--------------------+--------------------+--------------------
 Intercept     | -6.36346994178182 |   3.21390452471434 |  -1.97998101463435 | 0.0477056620380991
 treatment     | -1.02410605239327 |    1.1710801464903 | -0.874496980810833 |  0.381847663704613
 trait_anxiety | 0.119044916668605 | 0.0549791755747139 |   2.16527285875412 | 0.0303667955962211
(3 rows)

您可以在一个简单的语句中使用 EXPORT_MODELS 函数将模型导出为 PMML 格式,如下所示。


=> -- Exporting the model as PMML
=> SELECT export_models('/data/username/temp', 'myModel' USING PARAMETERS category='PMML');
 export_models
---------------
 Success
(1 row)

另请参阅

8.2.2 - 使用 PMML 模型导入和预测

作为 Vertica 用户,您可以在其他平台上训练 ML 模型,将其转换为标准 PMML 格式,然后将其导入 Vertica 以对存储在 Vertica 关系中的数据进行数据库内预测。

这里有一个如何导入在 Spark 中训练的 PMML 模型的示例。下图显示了示例的工作流程。

您可以在一个简单的语句中使用 IMPORT_MODELS 函数来导入 PMML 模型。导入的模型随后会出现在名为 V_CATALOG.MODELS 的系统表中,其中列出了 Vertica 中存档的 ML 模型。

=> -- importing the PMML model trained and generated in Spark
=> SELECT import_models('/data/username/temp/spark_logistic_reg' USING PARAMETERS category='PMML');
 import_models
---------------
 Success
(1 row)

=> -- Looking at the models table=> SELECT model_name, schema_name, category, model_type, create_time, size FROM models;
     model_name     | schema_name | category |      model_type       |          create_time          | size
--------------------+-------------+----------+-----------------------+-------------------------------+------
 spark_logistic_reg | public      | PMML     | PMML_REGRESSION_MODEL | 2020-07-28 00:12:29.389709-04 | 5831
(1 row)

可以使用 GET_MODEL_SUMMARY 函数来查看模型摘要。

=> \t
Showing only tuples.
=> SELECT get_model_summary(USING PARAMETERS model_name='spark_logistic_reg');

=============
function_name
=============
classification

===========
data_fields
===========
 name  |dataType|  optype
-------+--------+-----------
field_0| double |continuous
field_1| double |continuous
field_2| double |continuous
field_3| double |continuous
field_4| double |continuous
field_5| double |continuous
field_6| double |continuous
field_7| double |continuous
field_8| double |continuous
target | string |categorical


==========
predictors
==========
 name  |exponent|coefficient
-------+--------+-----------
field_0|   1    | -0.23318
field_1|   1    |  0.73623
field_2|   1    |  0.29964
field_3|   1    |  0.12809
field_4|   1    | -0.66857
field_5|   1    |  0.51675
field_6|   1    | -0.41026
field_7|   1    |  0.30829
field_8|   1    | -0.17788


===============
Additional Info
===============
    Name     | Value
-------------+--------
is_supervised|   1
  intercept  |-1.20173

您还可以使用 GET_MODEL_ATTRIBUTE 函数检索模型的属性。

=> \t
Tuples only is off.
=> -- The list of the attributes of the PMML model
=> SELECT get_model_attribute(USING PARAMETERS model_name='spark_logistic_reg');
   attr_name   |         attr_fields         | #_of_rows
---------------+-----------------------------+-----------
 is_supervised | is_supervised               |         1
 function_name | function_name               |         1
 data_fields   | name, dataType, optype      |        10
 intercept     | intercept                   |         1
 predictors    | name, exponent, coefficient |         9
(5 rows)

=> -- The coefficients of the PMML model
=> SELECT get_model_attribute(USING PARAMETERS model_name='spark_logistic_reg', attr_name='predictors');
  name   | exponent |    coefficient
---------+----------+--------------------
 field_0 |        1 |   -0.2331769167607
 field_1 |        1 |  0.736227459496199
 field_2 |        1 |   0.29963728232024
 field_3 |        1 |  0.128085369856188
 field_4 |        1 | -0.668573096260048
 field_5 |        1 |  0.516750679584637
 field_6 |        1 |  -0.41025989394959
 field_7 |        1 |  0.308289533913736
 field_8 |        1 | -0.177878773139411
(9 rows)

然后,您可以使用 PREDICT_PMML 函数将导入的模型应用于关系以进行数据库内预测。模型的内部参数可以通过名称或列出的位置与输入关系的列名匹配。也可以将直接输入值馈送到函数,如下所示。

=> -- Using the imported PMML model for scoring direct input values
=> SELECT predict_pmml(1.5,0.5,2,1,0.75,4.2,3.1,0.9,1.1
username(>                     USING PARAMETERS model_name='spark_logistic_reg', match_by_pos=true);
 predict_pmml
--------------
 1
(1 row)

=> -- Using the imported PMML model for scoring samples in a table
=> SELECT predict_pmml(* USING PARAMETERS model_name='spark_logistic_reg') AS prediction
=>     FROM test_data;
 prediction
------------
 1
 0
(2 rows)

另请参阅

8.2.3 - PMML 特征和属性

在 Vertica 中使用外部模型 概述了 Vertica 支持使用外部模型的功能。本主题提供有关 Vertica 如何支持使用 PMML 模型的限制的更多详细信息。

为了得到 Vertica 的支持,PMML 模型:

  • 不得包含数据预处理步骤。

  • 必须仅编码以下模型类型:k-means、线性回归、逻辑回归、随机森林(分类器和回归器)、XGBoost(分类器和回归器)、GeneralRegressionModel 和 TreeModel。

支持的 PMML 标记和属性

下表列出了支持的 PMML 标记及其属性。