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 ‘’)’’
。輸入表欄位格式說明:參與訓練的資料列支援INT和DOUBLE資料類型。如果輸入為稀疏格式的表,則支援STRING類型的資料列。
組件配置
您可以使用以下任意一種方式,配置K均值聚類組件參數。
方式一:可視化方式
在Designer工作流程頁面配置組件參數。
頁簽 | 參數 | 描述 |
欄位設定 | 特徵列 | 輸入資料表中,參與訓練的列。列名以半形逗號(,)分隔,支援INT和DOUBLE類型。如果輸入為稀疏格式,則支援STRING類型的列。 |
附加列 | 附加輸出至聚類結果表的輸入列,列名以半形逗號(,)分隔。 | |
輸入為疏鬆陣列 | 使用KV格式表示稀疏資料。 | |
kv鍵間分隔字元 | 預設為半形逗號(,)。 | |
kv鍵內分隔字元 | 預設為半形冒號(:)。 | |
參數設定 | 聚類數 | 取值範圍為1~1000。 |
距離度量方式 | 支援Euclidean、Cosine及Cityblock方式。 | |
質心初始化方法 | 支援Random、First K、Uniform、K-Means++及使用初始質心表方法。 | |
最大迭代次數 | 取值範圍為1~1000。 | |
收斂標準 | 迭代終止條件。 | |
初始隨機種子 | 預設值為目前時間。如果seed為固定值,則聚類結果穩定。 | |
執行調優 | 核心數 | 預設為系統自動分配。 |
每個核的記憶體大小 | 預設為系統自動分配,單位為MB。 |
方式二:PAI命令方式
使用PAI命令方式,配置該組件參數。您可以使用SQL指令碼組件進行PAI命令調用,詳情請參見SQL指令碼。
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 | 否 | 輸入表中,參與訓練的分區。支援以下格式:
說明 如果指定多個分區,則使用半形逗號(,)分隔。 | 所有分區 |
appendColNames | 否 | 附加輸出至聚類結果表的輸入列,列名以半形逗號(,)分隔。 | 無 |
enableSparse | 否 | 輸入表是否為疏鬆陣列,取值為true或false。 | false |
itemDelimiter | 否 | KV對之間的分隔字元。 | 半形逗號(,) |
kvDelimiter | 否 | key和value之間的分隔字元。 | 半形冒號(:) |
centerCount | 是 | 聚類數,取值範圍為1~1000。 | 10 |
distanceType | 否 | 距離度量方式,支援以下類型:
| euclidean |
initCenterMethod | 否 | 質心初始化的方法,支援以下方法:
| random |
initCenterTableName | 否 | 初始質心表的名稱。如果initCenterMethod為external,則該參數生效。 | 無 |
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
訓練表中,參與訓練的列。
樣本
以稠密格式資料作為輸入:
您可以通過以下任何一種方式,產生測試資料:
使用初始質心表的方式
create table pai_kmeans_test_init_center as select * from ( select 1 as f0,2 as f1 union all select 1 as f0,3 as f1 union all select 1 as f0,4 as f1 )tmp;
使用其他初始質心的方式
create table pai_kmeans_test_input as select * from ( select 'id1' as id,1 as f0,2 as f1 union all select 'id2' as id,1 as f0,3 as f1 union all select 'id3' as id,1 as f0,4 as f1 union all select 'id4' as id,0 as f0,3 as f1 union all select 'id5' as id,0 as f0,4 as f1 )tmp;
使用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;
查看聚類結果表、聚類統計表及聚類中心表:
聚類結果表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 | +---------------+------------+------------+
以稀疏格式資料作為輸入:
產生測試資料。
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 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 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 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 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 )tmp;
稀疏格式資料作為輸入時,使用0填充缺失的列。如果多個列同時作為輸入,則會被合并。例如,kvs0和kvs1同時作為輸入,則第一行的實際資料如下。
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中存在異常列編號的未經處理資料,建議重新進行列編號以減小矩陣規模。使用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;
查看聚類結果表、聚類統計表及聚類中心表:
聚類結果表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 | +---------------+------------+------------+