K均值聚类首先随机选择K个对象作为每个簇的初始聚类中心,然后计算剩余对象与各簇中心的距离,将其分配至距离最近的簇,再重新计算每个簇的聚类中心。该算法假设聚类对象为空间向量,且以各聚类内部的均方误差和最小为目标,不断地进行计算迭代,直到准则函数收敛。

注意事项

使用K均值聚类组件时,您需要注意以下事宜:
  • 如果使用夹角余玹距离,则某些聚类可能为空,即聚类数量小于K。因为初始化的K个中心点(向量)可能是平行向量,所以按顺序遍历中心点时,样本不会被分配至后面的中心点(平行向量)。建议通过外部输入中心表的方式,使用线下准备好的K个中心点。
  • 如果输入表中存在NULL或空值,则系统报错Algo Job Failed-System Error-Null feature value found。建议使用缺省值进行填充。
  • 使用稀疏格式数据作输入时,如果最大列编号超过2,000,000,则系统报错Algo Job Failed-System Error-Feature count can’t be more than 2000000。建议从0或1开始,重新对列进行编号。
  • 如果中心点模型过大导致写失败,则系统报错Algo Job Failed-System Error-kIOError:Write failed for message: comparison_measure。建议将稀疏矩阵的列从0或1开始,重新编号。如果模型规模col*centerCount>27,0000,000,则只能通过命令行的方式,去除modelName参数,再重新执行聚类。
  • 如果输入表的列名存在SQL关键字,则系统报错FAILED: Failed Task createCenterTable:kOtherError:ODPS-0130161:[1,558] Parse exception - invalid token ‘,’, expect ‘’)’’

组件配置

PAI-Studio支持通过可视化或PAI命令方式,配置K均值聚类组件的参数:
  • 可视化方式
    页签 参数 描述
    字段设置 特征列 支持DOUBLE及INT数据类型。
    附加列 附加输出至聚类结果表的输入列,列名以英文逗号(,)分隔。
    输入为稀疏矩阵 使用KV格式表示稀疏数据。
    kv键间分隔符 默认为英文逗号(,)。
    kv键内分隔符 默认为英文冒号(:)。
    参数设置 聚类数 取值范围为1~1000。
    距离度量方式 支持EuclideanCosineCityblock方式。
    质心初始化方法 支持RandomFirst KUniformK-Means++使用初始质心表方法。
    最大迭代次数 取值范围为1~1000。
    收敛标准 迭代终止条件。
    初始随机种子 默认值为当前时间。如果seed为固定值,则聚类结果稳定。
    执行调优 核心数 默认为系统自动分配。
    每个核的内存大小 默认为系统自动分配。
  • PAI命令方式
    pai -name kmeans
        -project algo_public
        -DinputTableName=pai_kmeans_test_input
        -DselectedColNames=f0,f1
        -DappendColNames=f0,f1
        -DcenterCount=3
        -Dloop=10
        -Daccuracy=0.01
        -DdistanceType=euclidean
        -DinitCenterMethod=random
        -Dseed=1
        -DmodelName=pai_kmeans_test_output_model_
        -DidxTableName=pai_kmeans_test_output_idx
        -DclusterCountTableName=pai_kmeans_test_output_couter
        -DcenterTableName=pai_kmeans_test_output_center;
    参数 是否必选 描述 默认值
    inputTableName 输入表的表名。
    selectedColNames 输入表中,参与训练的列。列名以英文逗号(,)分隔,支持INT和DOUBLE类型。如果输入为稀疏格式,则支持STRING类型的列。 所有列
    inputTablePartitions 输入表中,参与训练的分区。支持以下格式:
    • Partition_name=value
    • name1=value1/name2=value2:多级格式
    说明 如果指定多个分区,则使用英文逗号(,)分隔。
    所有分区
    appendColNames 附加输出至聚类结果表的输入列,列名以英文逗号(,)分隔。
    enableSparse 输入表是否为稀疏矩阵,取值范围为{true,false} false
    itemDelimiter KV对之间的分隔符。 英文逗号(,)
    kvDelimiter keyvalue之间的分隔符。 英文冒号(:)
    centerCount 聚类数,取值范围为1~1000。 10
    distanceType 距离度量方式,支持以下类型:
    • euclidean:欧式距离d(x-c)=(x-c)(x-c)'
    • cosine:夹角余弦的计算方式如下。夹角余玹
    • cityblock:曼哈顿距离d(x-c)=|x-c|
    euclidean
    initCenterMethod 质心初始化的方法,支持以下方法:
    • random:从输入数据表中,随机采样K个初始中心点,初始随机种子由参数seed指定。
    • topk:从输入数据表,读取前K行作为初始中心点。
    • uniform:从最小值到最大值,均匀地计算K个初始中心点。
    • kmpp:通过K-Means++算法,获得K个初始中心点。
    • external:指定额外的初始质心表。
    random
    initCenterTableName 初始质心表的名称。如果initCenterMethodexternal,则该参数生效。
    loop 最大迭代次数,取值范围为1~1000。 100
    accuracy 算法终止条件。如果两次迭代的目标差小于该值,则算法终止。 0.1
    seed 初始随机种子。 当前时间
    modelName 输出模型的名称。
    idxTableName 输出聚类结果表,包括聚类后每条记录所属的类号。
    idxTablePartition 聚类结果表的分区。
    clusterCountTableName 聚类统计表,统计各聚类包含的点数量。
    centerTableName 聚类中心表。
    coreNum 节点数量,与memSizePerCore搭配使用。取值范围为1~9999。 系统自动分配
    memSizePerCore 每个节点的内存大小,取值范围为1024 MB~64*1024 MB。 系统自动分配
    lifecycle 输出表的生命周期。

组件输出

K均值聚类输出聚类结果表、聚类统计表及聚类中心表。输出格式如下:
  • 聚类结果表
    列名 描述
    appendColNames 附加列。
    cluster_index 训练表中,每个样本被分配到的簇。
    distance 训练表中,每个样本到簇中心的距离。
  • 聚类统计表
    列名 描述
    cluster_index 簇编号。
    cluster_count 每个簇中的样本数量。
  • 聚类中心表
    列名 描述
    cluster_index 簇编号。
    selectedColNames 训练表中,参与训练的列。

示例

以稠密格式数据作为输入:
  1. 您可以通过以下任何一种方式,生成测试数据:
    • 使用初始质心表的方式
      create table pai_kmeans_test_init_center as
      select * from
      (
      select 1 as f0,2 as f1 from dual
      union all
      select 1 as f0,3 as f1 from dual
      union all
      select 1 as f0,4 as f1 from dual
      )tmp;
    • 使用其他初始质心的方式
      create table pai_kmeans_test_input as
      select * from
      (
        select 'id1' as id,1 as f0,2 as f1 from dual
        union all
        select 'id2' as id,1 as f0,3 as f1 from dual
        union all
        select 'id3' as id,1 as f0,4 as f1 from dual
        union all
        select 'id4' as id,0 as f0,3 as f1 from dual
        union all
        select 'id5' as id,0 as f0,4 as f1 from dual
      )tmp;
  2. 使用PAI命令,提交K均值聚类算法组件参数:
    • 使用初始质心表的方式
      drop table if exists pai_kmeans_test_output_idx;
      yes
      drop table if exists pai_kmeans_test_output_couter;
      yes
      drop table if exists pai_kmeans_test_output_center;
      yes
      drop offlinemodel if exists pai_kmeans_test_output_model_;
      yes
      pai -name kmeans
          -project algo_public
          -DinputTableName=pai_kmeans_test_input
          -DinitCenterTableName=pai_kmeans_test_init_center
          -DselectedColNames=f0,f1
          -DappendColNames=f0,f1
          -DcenterCount=3
          -Dloop=10
          -Daccuracy=0.01
          -DdistanceType=euclidean
          -DinitCenterMethod=external
          -Dseed=1
          -DmodelName=pai_kmeans_test_output_model_
          -DidxTableName=pai_kmeans_test_output_idx
          -DclusterCountTableName=pai_kmeans_test_output_couter
          -DcenterTableName=pai_kmeans_test_output_center;
    • 使用随机初始质心的方式
      drop table if exists pai_kmeans_test_output_idx;
      yes
      drop table if exists pai_kmeans_test_output_couter;
      yes
      drop table if exists pai_kmeans_test_output_center;
      yes
      drop offlinemodel if exists pai_kmeans_test_output_model_;
      yes
      pai -name kmeans
          -project algo_public
          -DinputTableName=pai_kmeans_test_input
          -DselectedColNames=f0,f1
          -DappendColNames=f0,f1
          -DcenterCount=3
          -Dloop=10
          -Daccuracy=0.01
          -DdistanceType=euclidean
          -DinitCenterMethod=random
          -Dseed=1
          -DmodelName=pai_kmeans_test_output_model_
          -DidxTableName=pai_kmeans_test_output_idx
          -DclusterCountTableName=pai_kmeans_test_output_couter
          -DcenterTableName=pai_kmeans_test_output_center;
  3. 查看聚类结果表、聚类统计表及聚类中心表:
    • 聚类结果表idxTableName
      +------------+------------+---------------+------------+
      | f0         | f1         | cluster_index | distance   |
      +------------+------------+---------------+------------+
      | 1          | 2          | 0             | 0.0        |
      | 1          | 3          | 1             | 0.5        |
      | 1          | 4          | 2             | 0.5        |
      | 0          | 3          | 1             | 0.5        |
      | 0          | 4          | 2             | 0.5        |
      +------------+------------+---------------+------------+
    • 聚类统计表clusterCountTableName
      +---------------+---------------+
      | cluster_index | cluster_count |
      +---------------+---------------+
      | 0             | 1             |
      | 1             | 2             |
      | 2             | 2             |
      +---------------+---------------+
    • 聚类中心表centerTableName
      +---------------+------------+------------+
      | cluster_index | f0         | f1         |
      +---------------+------------+------------+
      | 0             | 1.0        | 2.0        |
      | 1             | 0.5        | 3.0        |
      | 2             | 0.5        | 4.0        |
      +---------------+------------+------------+
以稀疏格式数据作为输入:
  1. 生成测试数据。
    create table pai_kmeans_test_sparse_input as
    select * from
    (
      select 1 as id,"s1" as id_s,"0:0.1,1:0.2" as kvs0,"2:0.3,3:0.4" as kvs1 from dual
      union all
      select 2 as id,"s2" as id_s,"0:1.1,2:1.2" as kvs0,"4:1.3,5:1.4" as kvs1 from dual
      union all
      select 3 as id,"s3" as id_s,"0:2.1,3:2.2" as kvs0,"6:2.3,7:2.4" as kvs1 from dual
      union all
      select 4 as id,"s4" as id_s,"0:3.1,4:3.2" as kvs0,"8:3.3,9:3.4" as kvs1 from dual
      union all
      select 5 as id,"s5" as id_s,"0:5.1,5:5.2" as kvs0,"10:5.3,6:5.4" as kvs1 from dual
    )tmp;
    稀疏格式数据作为输入时,使用 0填充缺失的列。如果多个列同时作为输入,则会被合并。例如, kvs0kvs1同时作为输入,则第一行的实际数据如下。
    0:0.1,1:0.2,2:0.3,3:0.4,4:0,5:0,6:0,7:0,8:0,9:0,10:0
    示例中的稀疏矩阵列从0开始编号,矩阵共5行11列。如果 kvs中的某列包含 123456789:0.1,则稀疏矩阵变为5行123456789列,该矩会消耗大量CPU和内存。对于 kvs中存在异常列编号的原始数据,建议重新进行列编号以减小矩阵规模。
  2. 使用PAI命令,提交K均值聚类组件的参数。
    pai -name kmeans
      -project algo_public
      -DinputTableName=pai_kmeans_test_sparse_input
      -DenableSparse=true
      -DselectedColNames=kvs0,kvs1
      -DappendColNames=id,id_s
      -DitemDelimiter=,
      -DkvDelimiter=:
      -DcenterCount=3
      -Dloop=100
      -Daccuracy=0.01
      -DdistanceType=euclidean
      -DinitCenterMethod=topk
      -Dseed=1
      -DmodelName=pai_kmeans_test_input_sparse_output_model
      -DidxTableName=pai_kmeans_test_sparse_output_idx
      -DclusterCountTableName=pai_kmeans_test_sparse_output_couter
      -DcenterTableName=pai_kmeans_test_sparse_output_center;
  3. 查看聚类结果表、聚类统计表及聚类中心表:
    • 聚类结果表idxTableName
      +------------+------------+---------------+------------+
      | id         | id_s       | cluster_index | distance   |
      +------------+------------+---------------+------------+
      | 4          | s4         | 0             | 2.90215437218629 |
      | 5          | s5         | 1             | 0.0        |
      | 1          | s1         | 2             | 0.7088723439378913 |
      | 2          | s2         | 2             | 1.1683321445547923 |
      | 3          | s3         | 0             | 2.0548722588034516 |
      +------------+------------+---------------+------------+
    • 聚类统计表clusterCountTableName
      +---------------+---------------+
      | cluster_index | cluster_count |
      +---------------+---------------+
      | 0             | 2             |
      | 1             | 1             |
      | 2             | 2             |
      +---------------+---------------+
    • 聚类中心表centerTableName
      +---------------+------------+------------+
      | cluster_index | kvs0       | kvs1       |
      +---------------+------------+------------+
      | 0             | 0:2.6,1:0,2:0,3:1.1,4:1.6,5:0 | 6:1.15,7:1.2,8:1.65,9:1.7,10:0 |
      | 1             | 0:5.1,1:0,2:0,3:0,4:0,5:5.2 | 6:5.4,7:0,8:0,9:0,10:5.3 |
      | 2             | 0:0.6,1:0.1,2:0.75,3:0.2,4:0.65,5:0.7 | 6:0,7:0,8:0,9:0,10:0 |
      +---------------+------------+------------+