【版权声明】本文为原创,转载请注明原地址 https://www.jianshu.com/p/f78722762fc4
同步更新在个人网站:http://www.wangpengcufe.com/machinelearning/ml-ml10/
一、概念
1.1、定义
按照某一个特定的标准(比如距离),把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不再同一个簇内的数据对象的差异性也尽可能的大。
聚类属于典型的无监督学习(Unsupervised Learning) 方法。与监督学习(如分类器)相比,无监督学习的训练集没有人为标注的结果。在非监督式学习中,数据并不被特别标识,学习模型是为了推断出数据的一些内在结构。
1.2、主要方法
层次聚类(Hierarchical Clustering):合并法、分解法、树状图
非层次聚类:划分聚类、谱聚类
1.3、主要特征
- 聚类变量的测量尺度不同,需要事先对变量标准化;
- 聚类变量中如果有些变量非常相关,意味着这个变量的权重会更大
- 欧式距离的平方是最常用的距离测量方法;
- 聚类算法要比距离测量方法对聚类结果影响更大;
- 标准化方法影响聚类模式:
- 变量标准化倾向产生基于数量的聚类;
- 样本标准化倾向产生基于模式的聚类;
- 一般聚类个数在4-6类,不易太多,或太少
二、KMeans原理
KMeans 是一个迭代求解的聚类算法,其属于 划分(Partitioning) 型的聚类方法,即首先创建K个划分,然后迭代地将样本从一个划分转移到另一个划分来改善最终聚类的质量,KMeans 的过程大致如下:
1.根据给定的k值,选取k个样本点作为初始划分中心;
2.计算所有样本点到每一个划分中心的距离,并将所有样本点划分到距离最近的划分中心;
3.计算每个划分中样本点的平均值,将其作为新的中心;
4.用计算出的中心位置重新进行聚类,如此反复循环,直到达到最大迭代次数,或划分中心的变化小于某一预定义阈值
方法的特点:
- 通常要求已知类别数
- 可人为指定初始位置
- 节省运算时间
- 样本量大于100时有必要考虑
- 只能使用连续性变量
三、代码实现
3.1、数据集的读取
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.mllib.clustering.KMeans;
import org.apache.spark.mllib.clustering.KMeansModel;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
//1、获取Spark
SparkConf conf = new SparkConf().setAppName("ClusteringModel").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
//2、读取数据
JavaRDD<String> rawData = sc.textFile("data/mllib/iris.data");
JavaRDD<Vector> trainingData = rawData.map(line->{
String[] parts = line.split(",");
return Vectors.dense(Double.parseDouble(parts[0]),
Double.parseDouble(parts[1]),
Double.parseDouble(parts[2]),
Double.parseDouble(parts[3]));
});
本文使用模式识别领域广泛使用的UCI数据集中的鸢尾花数据Iris进行实验,Iris数据的样本容量为150,有四个实数值的特征,分别代表花朵四个部位的尺寸,以及该样本对应鸢尾花的亚种类型(共有3种亚种类型),如下所示:
5.1,3.5,1.4,0.2,setosa
...
5.4,3.0,4.5,1.5,versicolor
...
7.1,3.0,5.9,2.1,virginica
...
3.2、模型训练与分析
可以通过创建一个KMeans类并调用其run(RDD[Vector])方法来训练一个KMeans模型KMeansModel,在该方法调用前需要设置一系列参数,如下表所示:
| 参数 | 含义 |
| ——————- | :———————: |
| K | 聚类数目,默认为2 |
| maxIterations | 最大迭代次数,默认为20 |
| initializationMode | 初始化模式,默认为”k-means||” |
| runs | 运行次数,默认为:1 |
| initializationSteps | 初始化步数,用于KMeans||,默认为5 |
| epsilon | 迭代停止的阈值,默认为1e-4 |
其中,每一个参数均可通过名为setXXX(…)(如maxIterations即为setMaxIterations())的方法进行设置。
由于KMeans类只有无参的构造函数,其对象创建、参数设置需要分别进行,且往往使用的只有存放模型的KMeansModel类对象,花功夫创建出的KMeans类自象本身却并未使用。故MLlib也提供了包装好的高层次方法KMeans.train(…),传入训练样本和相应的参数,即返回一个训练好的KMeansModel对象,十分方便。
该方法有4个重载形式,分别可以指定不同的输入参数,具体可以查阅MLlib的API文档,这里我们使用KMeans.train(data, k, maxIterations, runs)形式,只需要输入k值、最大迭代次数和运行次数,其他参数使用默认值,如下所示:
KMeansModel model = KMeans.train(trainingData.rdd(),3,100,5);
//通过KMeansModel类自带的clusterCenters属性获取到模型的所有聚类中心情况
这样,模型即创建成功了。可以通过KMeansModel类自带的clusterCenters属性获取到模型的所有聚类中心情况:
Vector[] vectors = model.clusterCenters();
for(Vector vector : vectors) {
System.out.println(vector);
}
/**
*控制台输出结果:
----------------------------------------------------------------------------
[5.901612903225807,2.748387096774194,4.393548387096774,1.4338709677419355]2
[5.005999999999999,3.4180000000000006,1.4640000000000002,0.2439999999999999]
[6.85,3.0736842105263147,5.742105263157893,2.071052631578947]
----------------------------------------------------------------------------
**/
也可以通过predict()方法来确定每个样本所属的聚类:
//通过predict()方法来确定每个样本所属的聚类:
trainingData.collect().forEach(sample->{
int predictedClustre = model.predict(sample);
System.out.println(sample.toString()+" belongs to cluster "+predictedClustre);
});
/**
*控制台输出结果:
---------------------------------------
[5.1,3.5,1.4,0.2] belongs to cluster 1
[4.9,3.0,1.4,0.2] belongs to cluster 1
[4.7,3.2,1.3,0.2] belongs to cluster 1
[4.6,3.1,1.5,0.2] belongs to cluster 1
[5.0,3.6,1.4,0.2] belongs to cluster 1
[5.4,3.9,1.7,0.4] belongs to cluster 1
[4.6,3.4,1.4,0.3] belongs to cluster 1
.....
--------------------------------------
**/
同时,KMeansModel类还提供了计算 集合内误差平方和(Within Set Sum of Squared Error, WSSSE) 的方法来度量聚类的有效性:
double wssse = model.computeCost(trainingData.rdd());
System.out.println("集合内误差平方和:"+wssse);
/**
*控制台输出结果:
----------------------------------
集合内误差平方和:78.94084142614648
----------------------------------
**/
四、主要应用
4.1、商业
聚类分析被用来发现不同的客户群,并且通过购买模式刻画不同的客户群的特征。
聚类分析是细分市场的有效工具,同时也可用于研究消费者行为,寻找新的潜在市场、选择实验的市场,并作为多元分析的预处理。
4.2、生物
聚类分析被用来动植物分类和对基因进行分类,获取对种群固有结构的认识
4.3、地理
聚类能够帮助在地球中被观察的数据库商趋于的相似性
4.4、保险行业
聚类分析通过一个高的平均消费来鉴定汽车保险单持有者的分组,同时根据住宅类型,价值,地理位置来鉴定一个城市的房产分组
4.5、因特网
聚类分析被用来在网上进行文档归类来修复信息
4.6、电子商务
聚类分析在电子商务中网站建设数据挖掘中也是很重要的一个方面,通过分组聚类出具有相似浏览行为的客户,并分析客户的共同特征,可以更好的帮助电子商务的用户了解自己的客户,向客户提供更合适的服务。
参考资料:http://spark.apache.org/docs/latest/mllib-clustering.html