[Spark_mllib]K-Means
来源:互联网 发布:淘宝网音乐芯片 编辑:程序博客网 时间:2024/06/08 17:04
- K-means
- 优缺点
- 步骤
- 使用后处理来提高聚类性能
- 二分K-Means算法
- Spark实现KMeans
- 关键步骤
- 聚类个数K的选择
- 初始聚类中心点的选择
- MLlib的K-means实现
- 参数
- Spark_K-Means_Python
- 关键步骤
K-means
优缺点
优点:容易实现
缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢
步骤
- 选择K个点作为初始聚类中心
- 计算其余所有点到聚类中心的距离,并把每个点划分到离它最近的聚类中心所在的聚类中去。计算距离常用欧几里得距离公式,也叫欧氏距离。查看距离的计算方法
- 重新计算每个聚类中所有点的平均值,并将其作为新的聚类中心点。
- 重复2、3步,直到聚类中心不再发生改变,或者算法达到预定的迭代次数,又或聚类中心的改变小于预先设定的阈值
使用后处理来提高聚类性能
局部最小值指结果还可以但并非最好结果,全局最小值是可能的最好结果
一种用于度量聚类效果的指标是SSE(误差平方和)。SSE值越小表示数据点越接近它们的质心。
后处理方法:将具有最大SSE值的簇划分成为两个簇;合并最近的质心,或者合并两个使得SSE增幅最小的质心。
二分K-Means算法
- 将所有点作为一个簇,然后将该簇一分为二;
- 之后选择其中一个簇继续进行划分,选择哪一个簇进行划分取决于对其划分是否可以最大程度降低SSE的值。
- 不断重复SSE的划分过程,直到得到用户指定的簇数目为止。
Spark实现KMeans
关键步骤
聚类个数K的选择
Spark MLlib 在 KMeansModel 类里提供了 computeCost 方法,该方法通过计算所有数据点到其最近的中心点的平方和来评估聚类的效果。一般来说,同样的迭代次数和算法跑的次数,这个值越小代表聚类的效果越好。但是在实际情况下,我们还要考虑到聚类结果的可解释性,不能一味的选择使 computeCost 结果值最小的那个 K。
初始聚类中心点的选择
Spark MLlib K-means算法的实现在初始聚类点的选择上,借鉴了K-means||的类K-means++实现。K-means++算法在初始点选择上遵循一个基本原则:初始聚类中心点相互之间的距离应该尽可能的远。基本步骤如下:
1. 从数据集中随机选择一个点作为第一个初始点
2. 计算数据集中所有点与最新选择的中心点的距离D(x)
3. 选择下一个中心点,使得
最大
4. 重复2、3步,直到K个初始点选择完成
MLlib的K-means实现
- 读取训练数据,调用KMeans.train方法对数据集进行聚类训练,方法返回KMeansModel实例
- 使用KMeansModel.predict方法对新的数据点进行所属聚类的预测
- 均方差(MSE),就是对各个实际存在评分的项,pow(预测评分-实际评分,2)的值进行累加,再除以项数。而均方根差(RMSE)就是MSE开根号。MSE/RMSE值越小说明预测结果越准确
参数
Spark_K-Means_Python
from __future__ import print_functionfrom numpy import arrayfrom math import sqrtfrom pyspark import SparkContextfrom pyspark.mllib.clustering import KMeans, KMeansModelif __name__ == "__main__": sc = SparkContext(appName="KmeansExample") # Load and parse the data data = sc.textFile("kmeans_data.txt") parsedData = data.map(lambda line:array([float(x) for x in line.split(' ')])) # Build the Model(cluster the data) clusters = KMeans.train(parsedData, 2, maxIterations=10, initializationMode="random") print(clusters.clusterCenters) print(clusters.predict([0.2, 0.2, 0.2])) # Evaluate clustering by computing Within Set Sum of Squared Errors def error(point): center = clusters.centers[clusters.predict(point)] return sqrt(sum([x**2 for x in (point - center)])) WSSSE = parsedData.map(lambda point: error(point)).reduce(lambda x, y: x + y) print("Within Set Sum of Squared Error = " + str(WSSSE))
阅读全文