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

返回本页常规视图.

聚类算法

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

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

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

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

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

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

1 - K-均值

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

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

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

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 数据进行了正确聚类。

另请参阅

2 - 二等分 k-means

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

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

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

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

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 进行预测快。

另请参阅