聚类算法之k-means算法的数据集分析:
1. K均值聚类的步骤:
K均值算法首先随机的指定K个簇中心。然后:
1)将每个实例分配到距它最近的簇中心,得到K个簇;
2)计分别计算各簇中所有实例的均值,把它们作为各簇新的簇中心。重复1)和2)不断迭代,直到K个簇中心的位置都固定,簇的分配也固定。
2.用weka对给定的数据集进行测试和分析:
2.1数据预处理:
由于聚类算法是无监督的学习算法,不需要对数据进行训练,因此将训练集和测试集合并成为一个新的数据集,即将TEST中的数据合并到TRAIN中去。
2.1 Plane数据集:
运行weka,用“Explorer”打开”Plane_TRAIN.arff文件”,并切换到“Cluster”。点“Choose”按钮选择“SimpleKMeans”,这是WEKA中实现K均值的算法。点击旁边的文本框,修改“numClusters”为3,说明我们希望把这210条实例聚成3类,即K=3。下面的“seed”参数是要设置一个随机种子,依此产生一个随机数,用来得到K均值算法中第一次给出的K个簇中心的位置。我们不妨暂时让它就为10。
选中“Cluster Mode”的“Usetraining set”,点击“Start”按钮,观察右边“Clusterer output”给出的聚类结果。也可以在左下角“Result list”中这次产生的结果上点右键,“View in separate window”在新窗口中浏览结果:
**由于数据量比较大,在此只截取部分数据。
下面对输出结果进行分析:
我们看到有这么一行数据:
Within cluster sumof squared errors: 1005.6637836953896,这是评价聚类好坏的标准,数值越小说明同一簇实例之间的距离越小,我们可以更改seed和numClusters的值,使我们的聚类达到最优, 经过不同的尝试,得到了下表:
NumCluster | seed | Within cluster sum of squared errors |
3 | 10 | 1005 |
7 | 10 | 371 |
10 | 10 | 365 |
14 | 10 | 258 |
20 | 10 | 126 |
25 | 10 | 94 |
30 | 10 | 88 |
35 | 10 | 71 |
40 | 10 | 67 |
200 | 10 | 2 |
,从表中我们可以看出,当我们设置的NumCluster越大的时候, 我们的Within cluster sum of squared errors就越小,也就是说我们聚类的结果也就越好,但是真的就好了吗?下图是当numCluster=200,seed=10群集所占实例的比例:
我们可以看到,我们所聚类的几乎每个群集都只占一个或者两个实例,虽然Within cluster sum of squared errors的值变小了,但很明显这样的聚类就失去意义了,因此,我们NumCluster的值应该在类标数目的附近徘徊,而不是过大或者过小,也可以说我们的NumCluster的设定是与我们的实例数目息息相关的,平均每个簇应该分配多少个实例才能让我们聚类的效果达到最优。因此为了得到更好的聚类结果,在之后我所进行的数据集测试中我的NumCluster参数的值将始终与相应数据集的类标数目保持一致。
当然,除了NumCluster的值对我们的聚类的好坏产生影响,参数seed的值也会对我们的聚类的结果产生影响,再进行与上个表进行相同的测试得到了下表:
7 | 20 | 555 |
7 | 50 | 260 |
7 | 70 | 364 |
7 | 100 | 346 |
7 | 200 | 134 |
7 | 300 | 367.5 |
7 | 350 | 296.1 |
7 | 400 | 316.8 |
从表中可以看出,我们在numCluster不变的情况下,动态改变seed值的大小,Within cluster sum of squared errors的值呈现不规则变化,因此在求聚类算法的正确率时,需要随机对seed值的大小进行调整,以求达到最优的正确率。
接下来“Cluster centroids:”之后列出了各个簇中心的位置。对于数值型的属性,簇中心就是它的均值(Mean);分类型的就是它的众数(Mode),也就是说这个属性上取值为众数值的实例最多。对于数值型的属性,还给出了它在各个簇里的标准差(Std Devs)。
最后的“Clustered Instances”是各个簇中实例的数目及百分比。
为了观察可视化的聚类结果,我们在左下方“Result list”列出的结果上右击,点“Visualize cluster assignments”。弹出的窗口给出了各实例的散点图。最上方的两个框是选择横坐标和纵坐标,第二行的“colour”是散点图着色的依据,默认是根据不同的簇“Cluster”给实例标上不同的颜色。如下图:
由图可知,数据集的结果最后被聚成了7类,每一类占有相应比例的实例。图中的x代表实例,比如cluster0有30个,也就是说这一类中有30个实例。
下面对我们的聚类结果进行评估,检查一下产生的clusters与原数据集类别的吻合程度。此时numCluster=7,seed=10选中“ClusterMode”的“classes to clusters evaluation”,点击“Start”按钮,得到如下结果:
根据图片显示的信息,我们可以看到:聚类结果的不正确的实例为43个,聚类的评估结果有20.4762 %的错误率,也就是说聚类算法的正确率大概为80%。对照图中的两个矩阵可以清晰的看到我们的类别6被聚成了cluster0,有30个实例聚类正确,有0个错误,类别3被聚成了cluster1,有30个实例聚类正确,0个错误,然后依次类推。将所有正确聚类的实例数除以总的实例数目最后得到结果,即正确率为大约为80%。
接着我们在可视化聚类评估结果,如下图:
我们可以看到,与上一个根据训练集得到的聚类可视化的图有些许差别,图中除了之前的x点集外多了一些小方形点集,于是我们点击小方形就会得到下面的信息:
****由于数据量太大,中间部分省略
可以看到,这是我们的第108条实例,它是属于类别5的实例,最后被聚类成了第2簇,即Cluster2。但从上面的聚类结果的矩阵来看,我们的5这个类别应该是被聚类为Cluster3的,但在这里却被聚类成了Cluster2,也就是说这个聚类的实例是错误的。所以,图中的小方框代表的是我们错误的聚类实例。到此,对于一个数据集的聚类算法分析就基本算完成了。
但此时的正确率仍然不是得到的最佳结果,此时numCluster=7,seed=10,正确率大约为20%,经过多次对NumCluster和seed的值进行修改得到了下表:
**测试结果较多,只选取正确率较高的几个。
Numcluster | seed | 正确率 |
7 | 100 | 84% |
7 | 400 | 92% |
7 | 410 | 93.4% |
7 | 500 | 83.3% |
7 | 600 | 83.3% |
10 | 100 | 89% |
13 | 100 | 81.5% |
分析表格中的数据可以看到,正确率的高低与我们NumCluster和seed的值的变化并没有什么直接的联系,因此要想达到比较高的正确率需要对参数的值进行多次修改。至此,一个完整的数据集分析就完成了。
总结算法优缺点:
优点:首先,算法能根据较少的已知聚类样本的类别对树进行剪枝确定部分样本的分类;其次,为克服少量样本聚类的不准确性,该算法本身具有优化迭代功能,在已经求得的聚类上再次进行迭代修正剪枝确定部分样本的聚类,优化了初始监督学习样本分类不合理的地方;第三,由于只是针对部分小样本可以降低总的聚类时间复杂度。
缺点是:首先,在K-means 算法中K 是事先给定的,这个K 值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适;其次,在K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果;最后,该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。比如下面的有一个数据集达到17M,用weka基本上几个小时都不一定跑的出来。
问题:在利用训练集进行训练的时候,侧边栏有一行参数:Within cluster sum of squared errors 根据网上的相关资料,解释为这个参数时衡量聚类的好坏的,数值越小就代表聚类的情况越好,但是我发现,该数值的大小对我们聚类的正确率的高低并没有直接的联系,而且在进行聚类评估的时候该数值会发生轻微的变动,那其数值跟聚类的正确率到底有没有关系呢?这一点是我无法理解的。
下面,根据上面的相应操作步骤,对我们的剩下每个数据集进行分析,最后得到最终的正确率,在此只给出了各数据集测试的相应参数以及正确率,相关过程不再赘述:
数据集 | NumCluster | seed | 正确率 |
Plane_TRAIN | 7 | 410 | 93.4% |
OliveOil_TRAIN | 4 | 50 | 80% |
OSULeaf_TRAIN | 6 | 50 | 40% |
PhalangesOutlinesCorrect_TRAIN | 2 | 10 | 57% |
Phoneme_TRAIN | 39 | 10 | 50% |
ProximalPhalanxOutlineAgeGroup_TRAIN | 3 | 50 | 80% |
ProximalPhalanxOutlineCorrect_TRAIN | 2 | 10 | 63% |
ProximalPhalanxTW_TRAIN | 4 | 100 | 73% |
RefrigerationDevices_TRAIN | 3 | 10 | 36% |
ScreenType_TRAIN | 3 | 10 | 40% |