Kmeans算是是聚类中的经典算法。步骤例如以下:

选择K个点作为初始质心

repeat

将每一个点指派到近期的质心,形成K个簇

又一次计算每一个簇的质心

until 簇不发生变化或达到最大迭代次数

算法中的K须要人为的指定。确定K的做法有非常多,比方多次进行试探。计算误差。得出最好的K。这样须要比較长的时间。我们能够依据Canopy算法来粗略确定K值(能够觉得相等)。看一下Canopy算法的过程:

(1)设样本集合为S。确定两个阈值t1和t2,且t1>t2。

(2)任取一个样本点p。作为一个Canopy,记为C,从S中移除p。

(3)计算S中全部点到p的距离dist

(4)若dist<t1。则将对应点归到C,作为弱关联。

(5)若dist<t2。则将对应点移出S,作为强关联。

(6)反复(2)~(5),直至S为空。

Canopy 个数全然能够作为这个K值,一定程度上降低了选择K的盲目性。

以下通过Canopy算法对一些点进行计算Canopy的个数。假设只计算K值,则T1没有不论什么作用,之用指定T2就可以。这里使用全部点的平均距离的一半来作为T2.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153
package cn.edu.ustc.dm.cluster;



import java.util.ArrayList;

import java.util.List;



import cn.edu.ustc.dm.bean.Point;



/**

 * Canopy算法 借助canopy算法计算相应的Kmeans中的K值大小

 * 当中对于计算K值来说。canopy算法中的T1没有意义,仅仅用设定T2(T1>T2) 我们这里将T2设置为平均距离

 * 

 * @author YD

 *

 */

public class Canopy {

    private List<Point> points = new ArrayList<Point>(); // 进行聚类的点

    private List<List<Point>> clusters = new ArrayList<List<Point>>(); // 存储簇

    private double T2 = -1; // 阈值



    public Canopy(List<Point> points) {

        for (Point point : points)

            // 进行深拷贝

            this.points.add(point);

    }



    /**

     * 进行聚类,依照Canopy算法进行计算,将全部点进行聚类

     */

    public void cluster() {

        T2 = getAverageDistance(points);

        while (points.size() != 0) {

            List<Point> cluster = new ArrayList<Point>();

            Point basePoint = points.get(0); // 基准点

            cluster.add(basePoint);

            points.remove(0);

            int index = 0;

            while (index < points.size()) {

                Point anotherPoint = points.get(index);

                double distance = Math.sqrt((basePoint.x - anotherPoint.x)

                        * (basePoint.x - anotherPoint.x)

                        + (basePoint.y - anotherPoint.y)

                        * (basePoint.y - anotherPoint.y));

                if (distance <= T2) {

                    cluster.add(anotherPoint);

                    points.remove(index);

                } else {

                    index++;

                }

            }

            clusters.add(cluster);

        }

    }



    /**

     * 得到Cluster的数目

     * 

     * @return 数目

     */

    public int getClusterNumber() {

        return clusters.size();

    }



    /**

     * 获取Cluster相应的中心点(各点相加求平均)

     * 

     * @return

     */

    public List<Point> getClusterCenterPoints() {

        List<Point> centerPoints = new ArrayList<Point>();

        for (List<Point> cluster : clusters) {

            centerPoints.add(getCenterPoint(cluster));

        }

        return centerPoints;

    }



    /**

     * 得到的中心点(各点相加求平均)

     * 

     * @return 返回中心点

     */

    private double getAverageDistance(List<Point> points) {

        double sum = 0;

        int pointSize = points.size();

        for (int i = 0; i < pointSize; i++) {

            for (int j = 0; j < pointSize; j++) {

                if (i == j)

                    continue;

                Point pointA = points.get(i);

                Point pointB = points.get(j);

                sum += Math.sqrt((pointA.x - pointB.x) * (pointA.x - pointB.x)

                        + (pointA.y - pointB.y) * (pointA.y - pointB.y));

            }

        }

        int distanceNumber = pointSize * (pointSize + 1) / 2;

        double T2 = sum / distanceNumber / 2; // 平均距离的一半

        return T2;

    }



    /**

     * 得到的中心点(各点相加求平均)

     * 

     * @return 返回中心点

     */

    private Point getCenterPoint(List<Point> points) {

        double sumX = 0;

        double sumY = 0;

        for (Point point : points) {

            sumX += point.x;

            sumY += point.y;

        }

        int clusterSize = points.size();

        Point centerPoint = new Point(sumX / clusterSize, sumY / clusterSize);

        return centerPoint;

    }



    /**

     * 获取阈值T2

     * 

     * @return 阈值T2

     */

    public double getThreshold() {

        return T2;

    }

    

    /**

     * 測试9个点。进行操作

     * @param args

     */

    public static void main(String[] args) {

        List<Point> points = new ArrayList<Point>();

        points.add(new Point(0, 0));

        points.add(new Point(0, 1));

        points.add(new Point(1, 0));



        points.add(new Point(5, 5));

        points.add(new Point(5, 6));

        points.add(new Point(6, 5));



        points.add(new Point(10, 2));

        points.add(new Point(10, 3));

        points.add(new Point(11, 3));



        Canopy canopy = new Canopy(points);

        canopy.cluster();



                //获取canopy数目

        int clusterNumber = canopy.getClusterNumber();

        System.out.println(clusterNumber);



                //获取canopy中T2的值

        System.out.println(canopy.getThreshold());

    }

}

以上代码是对9个点使用Canopy算法进行计算,获取Canopy数目,也即K。

很多其它文章请前往小胖轩.

Canopy算法计算聚类的簇数的更多相关文章

  1. R数据挖掘 第三篇:聚类的评估(簇数确定和轮廓系数)和可视化

    在实际的聚类应用中,通常使用k-均值和k-中心化算法来进行聚类分析,这两种算法都需要输入簇数,为了保证聚类的质量,应该首先确定最佳的簇数,并使用轮廓系数来评估聚类的结果. 一,k-均值法确定最佳的簇数 ...

  2. mahout中kmeans算法和Canopy算法实现原理

    本文讲一下mahout中kmeans算法和Canopy算法实现原理. 一. Kmeans是一个很经典的聚类算法,我想大家都非常熟悉.虽然算法较为简单,在实际应用中却可以有不错的效果:其算法原理也决定了 ...

  3. Canopy算法聚类

    Canopy一般用在Kmeans之前的粗聚类.考虑到Kmeans在使用上必须要确定K的大小,而往往数据集预先不能确定K的值大小的,这样如果 K取的不合理会带来K均值的误差很大(也就是说K均值对噪声的抗 ...

  4. 机器学习算法-K-means聚类

    引文: k均值算法是一种聚类算法.所谓聚类.他是一种无监督学习,将类似的对象归到同一个蔟中.蔟内的对象越类似,聚类的效果越好. 聚类和分类最大的不同在于.分类的目标事先已知.而聚类则不一样. 由于其产 ...

  5. Mahout 系列之--canopy 算法

    Canopy 算法,流程简单,容易实现,一下是算法 (1)设样本集合为S,确定两个阈值t1和t2,且t1>t2. (2)任取一个样本点p属于S,作为一个Canopy,记为C,从S中移除p. (3 ...

  6. Python机器学习算法 — K-Means聚类

    K-Means简介 步,直到每个簇的中心基本不再变化: 6)将结果输出. K-Means的说明 如图所示,数据样本用圆点表示,每个簇的中心点用叉叉表示:       (a)刚开始时是原始数据,杂乱无章 ...

  7. Spark MLlib架构解析(含分类算法、回归算法、聚类算法和协同过滤)

    Spark MLlib架构解析 MLlib的底层基础解析 MLlib的算法库分析 分类算法 回归算法 聚类算法 协同过滤 MLlib的实用程序分析 从架构图可以看出MLlib主要包含三个部分: 底层基 ...

  8. mahout之canopy算法简单理解

    canopy是聚类算法的一种实现 它是一种快速,简单,但是不太准确的聚类算法 canopy通过两个人为确定的阈值t1,t2来对数据进行计算,可以达到将一堆混乱的数据分类成有一定规则的n个数据堆 由于c ...

  9. 数据挖掘算法之聚类分析(二)canopy算法

    canopy是聚类算法的一种实现 它是一种快速,简单,但是不太准确的聚类算法 canopy通过两个人为确定的阈值t1,t2来对数据进行计算,可以达到将一堆混乱的数据分类成有一定规则的n个数据堆 由于c ...

随机推荐

  1. [转]windows 7 下快速搭建php环境(windows7+IIS7+php+mysql)

    转贴:http://apps.hi.baidu.com/share/detail/10406992 (1).采用理由: 优点:最大化的桌面图形化操作系统,可维护性优秀.基于IIS v6.0/v7.0( ...

  2. BZOJ1499: [NOI2005]瑰丽华尔兹(dp)

    Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在 ...

  3. Elasticsearch--扩展索引结构

    目录 索引树形数据 索引非扁平数据 索引关系型数据 使用嵌套对象 评分与嵌套查询 使用主从关系 索引树形数据 使用path_analyzer分析树形数据字段 索引非扁平数据 数据如下: { " ...

  4. Selenium示例集锦--常见元素识别方法、下拉框、文本域及富文本框、鼠标操作、一组元素定位、弹窗、多窗口处理、JS、frame、文件上传和下载

    元素定位及其他操作 0.常见的识别元素的方法是什么? driver.find_element_by_id() driver.find_element_by_name() driver.find_ele ...

  5. selenium学习第三天,新建一个测试用例(运行失败)。

    今天的意外收获,在找SELENIUM实例的时候,发现一个JS实例,功能各类非常全演示及代码都有,谢谢大神的分享:http://www.miniui.com/demo/#src=datagrid/pag ...

  6. CAD得到多行文本(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::Mx_GetMTextContent 得到多行文本的,不包括格式控制符中的字符串值,详细说明如下: 参数 说明 LONG lId 多行 ...

  7. 浅谈:nodejs在cmd提示不是内部或外部命令

    今天用cmd安装个库,结果发现node不是内部命令,检查后发现上次重装nodejs换了个安装位置,path环境变量忘改了. 找到变量值中node的安装地址,比如C:develop\nodejs,如果不 ...

  8. Oracle XE WM_CONCAT undifine

    用docker 跑了个oracle XE 报错 没有WM_CONCAT    下载三个sql文件然后按顺序执行后可以正常使用 一:下载三个文件 解压到 oracle 目录下面 (要能找到,注意权限要o ...

  9. 服务器 获取用户 真实ip

    在有代理的情况下,因为要代替客户端去访问服务器,所以,当请求包经过反向代理后,在代理服务器这里这个IP数据包的IP包头做了修改,最终后端WEB服务器得到的数据包的头部源IP地址是代理服务器的IP地址. ...

  10. 荷兰国旗问题、快排以及BFPRT算法

    荷兰国旗问题 给定一个数组arr,和一个数num,请把小于num的数放数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边.要求额外空间复杂度O(1),时间复杂度O(N). 这个问题 ...