九 机器学习之k均值聚类二

272 阅读5分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。 接上篇 在实现k-mean聚类算法时,有以下几点需要特别注意:

  • ·设置统一的操作对象result_set
  • 为了调用和使用的方便,此处将clusterAssment容易转换为了DataFrame并与输入DataFrame合并,组成的对象可作为后续调用的统一对象,该对象内即保存了原始数据,也保存了迭代运算的中间结果,包括数据所属簇标记和数据质心距离等,该对象同时也作为最终函数的返回结果;
  • 判断质心发生是否发生改变条件
  • 注意,在K-Means中判断质心是否发生改变,即判断是否继续进行下一步迭代的依据并不是某点距离新的质心距离变短,而是某点新的距离向量(到各质心的距离)中最短的分量位置是否发生变化,即质心变化后某点是否应归属另外的簇。在质心变化导致各点所属簇发生变化的过程中,点到质心的距离不一定会变短,即判断条件不能用下述语句表示
  • if not (result_set.iloc[:,-1] == result_set.iloc[:,-2]).a11()
  • ·合并DataFrame后索引值为n的列
  • 这里有个小技巧,能够帮助迅速定位DataFrame合并后列的索引,即两个DF合并后后者的第一列在合并后的DF索引值为n,第二列索引值为n+1
  • 质心和类别一—对应
  • 即在最后生成的结果中,centroids的行标即为result_set中各点所属类别

一 算法验证

数编写完成后,先以testSet数据集测试模型运行效果(为了可以直观看出聚类效果,此处采用一个二维数据集进行验证)。testSet数据集是一个二维数据集,每个观测值都只有两个特征,且数据之间采用空格进行分隔,因此可采用pd.read_table()函数进行读取

testSet = pd.read_table('testSet.txt', header=None)
plt.scatter(testSet.iloc[:,0].values,testSet.iloc[:,1].values);

image.png 可以大概看出数据大概分布在空间的四个角上,后续我们将对此进行验证。然后利用我们刚才编写的K-Means算法对其进行聚类,在执行算法之前需要添加一列虚拟标签列(算法是从倒数第二列开始计算特征值)

label = pd.DataFrame(np.zeros(testSet.shape[0]).reshape(-1, 1))
test_set = pd.concat([testSet, label], axis=1, ignore_index = True)

然后带入算法进行计算,根据二维平面坐标点的分布特征,我们可考虑设置四个质心,即将其分为四个簇,并简单查看运算结果

test_cent, test_cluster = kMeans(test_set, 4)
test_cent

image.png 将分类结果进行可视化展示,使用scatterf函数绘制不同分类点不同颜色的散点图,同时将质心也放入同一张图中进行观察

plt.scatter(test_cluster.iloc[:,0], test_cluster.iloc[:, 1], c=test_cluster.iloc[:, -1])
plt.scatter(test_cent[:, 0], test_cent[:, 1], color='red',marker='x',s=100);

image.png

二 误差平方和SSE计算

误差平方和(SSE)是聚类算法模型最重要评估指标,接下来,在手动编写的K-Means快速聚类函数基础上计算结果集中的误差平方和。在kMeans函数生成的结果result_set中,第n列,也就是我们定义的clusterAssment容器中的第一列就保留了最近一次分类结果的某点到对应所属簇质心的距离平方和,因此我们只需要对result_set中的第n列进行简单求和汇总,即可得聚类模型误差平方和。 当然,对于聚类算法而言,误差平方和仍然有一定的局限性,主要体现在以下几点:

  • 对于任意数据集而言,聚类误差平方和和质心数量高度相关,随着质心增加误差平方和将逐渐下降,虽然下降过程偶尔会有小幅起伏,不是严格递减,极限情况是质心数量和数据集行数保持一致,此时误差平方和将趋于零(思考为何不为0);
  • 同时,误差平方和还与数据集本身数据量大小、量纲大小、数据维度高度相关,数据量越大、量纲越大、维度越高则在相同质心数量情况下误差平方和也将更大; 因此,模型误差平方和没有绝对意义,比较不同数据集聚类结果的误差平方和没有任何意义,误差平方和在聚类分析中主要作用有以下两点:
  • 确定模型最优化目标,结合距离计算方法进而推导质心选取方法;
  • 对于确定数据集可绘制横轴为质心数量、纵轴为误差平方和的曲线,可以判断,曲线整体将呈现下降趋势,我们可从中找到"骤然下降"的某个拐点,则该点可作为聚类分类数量的参考值,即可利用SSE绘制聚类数量学习曲线。当然,由于聚类分析本身属于探索性质的算法,曲线拐点给出的值只是当前数据维度和数据量的情况,数据在高维空间内的分布可能呈现的集中分布趋势,并不一定代表客观事物的自然规律,也不是所有数据集的聚类分类数量学习曲线都存在拐点;