1

我正在尝试在 PL/R 中使用 kmeans 函数。我创建了下表

CREATE TABLE EMP (NAME1 TEXT, AGE SMALLINT, SALARY NUMERIC );

INSERT INTO EMP VALUES 
('Joe', 41, 55000),
('Jill', 27, 25000),
('Jack', 31, 45000),
('Joker', 65, 20000),
('Joy', 22, 31000),
('Jane', 72, 35000),
('Jackson', 42, 65000),
('Jessica', 23, 37000);

我的聚类功能如下

CREATE OR REPLACE FUNCTION CLUS(sal NUMERIC[])
RETURNS INTEGER[] AS
$BODY$

a <- NA
a = kmeans(sal, 3)$cluster
return(a)

$BODY$
LANGUAGE 'plr' ;

当我执行以下查询时

SELECT * , CLUS(ARRAY (SELECT SALARY FROM EMP ORDER BY SALARY)) AS CLUSTER_ID from emp order by salary;

我的输出是

name1   age salary  cluster_id
Joker   65  20000   {3,3,2,2,2,2,1,1}
Jill    27  25000   {2,2,2,2,2,3,3,1}
Joy     22  31000   {3,3,2,2,2,2,1,1}
Jane    72  35000   {1,1,1,1,1,2,2,3}
Jessica 23  37000   {1,1,2,2,2,2,3,3}
Jack    31  45000   {2,2,3,3,3,3,1,1}
Joe     41  55000   {1,1,3,3,3,3,2,2}
Jackson 42  65000   {2,2,3,3,3,3,1,1}

我面临的问题是,每次评估一行时,集群都会发生变化,我想要以下输出......

name1   age salary  cluster_id
Joker   65  20000   3
Jill    27  25000   3
Joy     22  31000   2
Jane    72  35000   2
Jessica 23  37000   2
Jack    31  45000   2
Joe     41  55000   1
Jackson 42  65000   1

请让我知道是否可以以更好和简单的方式完成

4

1 回答 1

1

请先阅读K-means 文档

您会注意到 K-means 包含一个随机元素 - 这就是导致您的输出按行显示不同集群 ID 的原因。

请参阅此处以了解如何set.seed在给定相同输入的情况下在每次执行时复制相同的集群结果。

你做错的第二件事是你实现你的CLUS功能的方式和你调用它的方式。

让我通过扩展您正在运行的查询来强调这个问题:

SELECT 
* 
,CLUS(ARRAY (SELECT SALARY FROM EMP ORDER BY SALARY)) AS CLUSTER_ID 
from emp 
order by salary;

name    age salary  inputForClus                                         cluster_id
Joker   65  20000   {20000,25000,31000,35000,37000,45000,55000,65000}   {3,3,2,2,2,2,1,1}
Jill    27  25000   {20000,25000,31000,35000,37000,45000,55000,65000}   {2,2,2,2,2,3,3,1}
Joy     22  31000   {20000,25000,31000,35000,37000,45000,55000,65000}   {3,3,2,2,2,2,1,1}
Jane    72  35000   {20000,25000,31000,35000,37000,45000,55000,65000}   {1,1,1,1,1,2,2,3}
Jess    23  37000   {20000,25000,31000,35000,37000,45000,55000,65000}   {1,1,2,2,2,2,3,3}
Jack    31  45000   {20000,25000,31000,35000,37000,45000,55000,65000}   {2,2,3,3,3,3,1,1}
Joe     41  55000   {20000,25000,31000,35000,37000,45000,55000,65000}   {1,1,3,3,3,3,2,2}
Jack    42  65000   {20000,25000,31000,35000,37000,45000,55000,65000}   {2,2,3,3,3,3,1,1}

请注意每一行的 inputForClus 列是如何相同的。由于前面提到的随机元素,簇 id 逐行变化。

在您的情况下应用 k-means 的正确方法是编写一个函数,该函数采用一id列和一个 numeric array。然后该函数将返回一个包含两列id&的表cluster-id。您可以将您的功能实现为 which retruns table。然后,您可以将 cluster-ids 加入到您的表中id

首先搜索 Postgresql 文档以了解如何编写表返回函数。

另一种方法可能是将 k-means 函数指定为aggregate函数。

于 2014-02-10T13:29:29.777 回答