K-means T-SQL

在这里插入图片描述

在这里插入图片描述

--预备步骤
SELECT t1.X
      ,t1.Y
  ,CASE WHEN t1.A<t1.B AND t1.A<t1.C THEN 'A'
        WHEN t1.B<t1.A AND t1.B<t1.C THEN 'B'
        WHEN t1.C<t1.A AND t1.C<t1.B THEN 'C' END Distance
  ,1 AS Ver
  from
(SELECT X
      ,Y
  ,SQRT(power(x-1,2)+POWER(y-1,2)) A
  ,SQRT(power(x-4,2)+POWER(y-4,2)) B
  ,SQRT(power(x-7,2)+POWER(y-7,2)) C
 FROM dbo.[K-means]) t1;


--存储过程
alter PROC proc_KMeans
  AS
DECLARE @AvgX DEC(10,6),@AvgY DEC(10,6);
DECLARE @AvgX2 DEC(10,6),@AvgY2 DEC(10,6);
DECLARE @AvgX3 DEC(10,6),@AvgY3 DEC(10,6);
DECLARE @i INT=2;
WHILE @i<=30 
BEGIN  
	SELECT @AvgX=AVG(k.X),@AvgY=AVG(k.Y) FROM dbo.[K-means] k WHERE Ver=@i-1 AND k.Distance='A';
  SELECT @AvgX2=AVG(k.X),@AvgY2=AVG(k.Y) FROM dbo.[K-means] k WHERE Ver=@i-1 AND k.Distance='B';
  SELECT @AvgX3=AVG(k.X),@AvgY3=AVG(k.Y) FROM dbo.[K-means] k WHERE Ver=@i-1 AND k.Distance='C';
  
  INSERT INTO dbo.[K-means]
  SELECT t1.X
      ,t1.Y
  ,CASE WHEN t1.A<t1.B AND t1.A<t1.C THEN 'A'
        WHEN t1.B<t1.A AND t1.B<t1.C THEN 'B'
        WHEN t1.C<t1.A AND t1.C<t1.B THEN 'C' END Distance
  ,@i AS Ver
  from
 (SELECT X
      ,Y
  ,SQRT(power(x-@AvgX,2)+POWER(y-@AvgY,2)) A
  ,SQRT(power(x-@AvgX2,2)+POWER(y-@AvgY2,2)) B
  ,SQRT(power(x-@AvgX3,2)+POWER(y-@AvgY3,2)) C
  FROM dbo.[K-means] WHERE Ver=@i-1) t1;
  
  SET @i=@i+1;
END
  SELECT * FROM dbo.[K-means] WHERE Ver=30;

大约在22代的时候收敛。
在这里插入图片描述

--这个是查看收敛情况的
SELECT k.Ver,k.Distance,COUNT(*) c,AVG(k.X) X,AVG(k.Y) Y FROM dbo.[K-means] k
GROUP BY k.Ver,k.Distance
ORDER BY k.Ver,k.Distance;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有一个包含经纬度信息的数据集,可以使用Oracle数据库中的Sdo_Geometry类型来存储经纬度信息。假设我们已经将数据集存储到了一个名为mytable的表中,其中经度和纬度信息存储在名为longitude和latitude的列中。 下面是使用k-means聚类算法对该数据集进行聚类的步骤: 1. 创建一个存储聚类结果的表: ``` CREATE TABLE clusters ( cluster_id NUMBER, longitude NUMBER, latitude NUMBER ); ``` 2. 定义聚类的参数,如聚类的数量K、迭代次数等: ``` DECLARE k NUMBER := 5; max_iterations NUMBER := 10; threshold NUMBER := 0.01; BEGIN ... END; ``` 3. 随机选择K个中心点,并将其存储到一个临时表中: ``` CREATE GLOBAL TEMPORARY TABLE temp_centers ( center_id NUMBER, longitude NUMBER, latitude NUMBER ) ON COMMIT PRESERVE ROWS; INSERT INTO temp_centers SELECT ROWNUM, longitude, latitude FROM mytable SAMPLE(5); ``` 4. 迭代计算每个数据点到最近的中心点,并将其划分到对应的簇中: ``` FOR i IN 1..max_iterations LOOP -- 计算每个数据点到每个中心点的距离 INSERT INTO clusters (cluster_id, longitude, latitude) SELECT t.center_id, m.longitude, m.latitude FROM mytable m, temp_centers t WHERE SDO_GEOM.SDO_DISTANCE( SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(m.longitude, m.latitude, NULL), NULL, NULL), SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(t.longitude, t.latitude, NULL), NULL, NULL), 0.005, 'unit=M') < threshold ORDER BY t.center_id, m.longitude, m.latitude; -- 更新每个簇的中心点 DELETE FROM temp_centers; INSERT INTO temp_centers (center_id, longitude, latitude) SELECT cluster_id, AVG(longitude), AVG(latitude) FROM clusters GROUP BY cluster_id; -- 如果中心点没有发生变化,则停止迭代 IF SQL%ROWCOUNT = 0 THEN EXIT; END IF; -- 清空聚类结果表 DELETE FROM clusters; END LOOP; ``` 5. 查看聚类结果: ``` SELECT cluster_id, COUNT(*) AS num_points FROM clusters GROUP BY cluster_id; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值