我正在尝试在 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
请告诉我是否可以用更好更简单的方式完成
最佳答案
请阅读K-means documentation首先。
您会注意到 K-means 涉及一个随机元素 - 这就是导致您的输出按行显示不同 cluster-id 的原因。
参见 here了解如何使用 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
列和一个数字 array
。然后该函数将返回一个包含两列 id
和 cluster-id
的表。您可以将您的函数实现为一个retruns table
。然后,您可以将 cluster-ids 加入到 id
上的表中。
首先搜索 Postgresql 文档以了解如何编写表返回函数。
另一种方法可能是将 k-means 函数指定为 aggregate
函数。
关于r - 在 postgresql 中使用 PL/R 进行 kmeans 聚类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21676153/