聚类属于无监督学习,以往的回归、朴素贝叶斯、SVM等都是有类别标签y的,
也就是说样例中已经给出了样例的分类。而聚类的样本中却没有给定y,只有特征x,
比如假设宇宙中的星星可以表示成三维空间中的点集
聚类的目的是找到每个样本x潜在的类别y,并将同类别y的样本x放在一起。
比如上面的星星,聚类后结果是一个个星团,星团里面的点相互距离比较近,星团间的星星距离就比较远了。
对算法原理的理解:
http://wenku.baidu.com/view/7761432e647d27284b7351f7.html
其实算法中所说的k族就是将目标数据分组成几类,开始的时候随机选择
中心,通过计算得到第一次分类,然后再次计算选定中心,循环以上步骤,
一般是目标函数达到最优或者达到最大的迭代次数即可终止。对于不同的距离度量,
目标函数往往不同。
K-means算法是硬聚类算法,是典型的基于原型的目标函数聚类方法的代表,
它是数据点到原型的某种距离作为优化的目标函数,利用函数求极值的方法
得到迭代运算的调整规则。K-means算法以欧式距离作为相似度测度,
它是求对应某一初始聚类中心向量V最优分类,使得评价指标J最小。
算法采用误差平方和准则函数作为聚类准则函数。
处理流程
(1) 从 n个数据对象任意选择 k 个对象作为初始聚类中心;
(2) 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;
并根据最小距离重新对相应对象进行划分;
(3) 重新计算每个(有变化)聚类的均值(中心对象)
(4) 循环(2)到(3)直到每个聚类不再发生变化为止
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:
同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中
对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
工作过程k-means 算法的工作过程
说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;
而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),
分别将它们分配给与其最相似的(聚类中心所代表的)聚类;
然 后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);
不断重复这一过程直到标准测度函数开始收敛为止。
一般都采用均方差作为标准测度函数。
k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
K-Means聚类算法的优点主要集中在:
1.算法快速、简单;
2.对大数据集有较高的效率并且是可伸缩性的;
3.时间复杂度近于线性,而且适合挖掘大规模数据集。
K-Means聚类算法的时间复杂度是O(nkt) ,其中n代表数据集中对象的数量,
t代表着算法迭代的次数,k代表着簇的数目。
k-means 算法缺点
① 在 K-means 算法中 K 是事先给定的,这个 K 值的选定是非常难以估计的。
很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。
这也是 K-means 算法的一个不足。有的算法是通过类的自动合并和分裂,
得到较为合理的类型数目 K,例如 ISODATA 算法。关于 K-means 算法中
聚类数目K 值的确定在文献中,是根据方差分析理论,应用混合 F统计量来
确定最佳分类数,并应用了模糊划分熵来验证最佳分类数的正确性。
在文献中,使用了一种结合全协方差矩阵的 RPCL 算法,并逐步删除那些
只包含少量训练数据的类。而文献中使用的是一种称为次胜者受罚的竞争学习规则,
来自动决定类的适当数目。它的思想是:对每个输入而言,不仅竞争获胜单元的权值被修正以适应输入值,
而且对次胜单元采用惩罚的方法使之远离输入值。
② 在 K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,
然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,
一旦初始值选择的不好,可能无法得到有效的聚类结果,
这也成为 K-means算法的一个主要问题。对于该问题的解决,许多算法采用遗传算法(GA),
例如文献 中采用遗传算法(GA)进行初始化,以内部聚类准则作为评价指标。
③ 从 K-means 算法框架可以看出,该算法需要不断地进行样本分类调整,
不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。
Scala实现:
一,训练数据:
1,1,1
1,1,1
0,1,0
0,0,1
1,0,1
1,1,0
0,0,0
0,0,0
1,0,0
1,1,1
1,1,1
0,1,0
0,0,1
1,0,1
1,1,0
0,0,0
0,0,0
1,0,0
这些数据都是代表某个事物的特征。
二,需要分类的数据也是同上
三,Scala代码:
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.{SparkContext, SparkConf}
/**
* Created by Administrator on 2016/8/10.
*/
object mykmeans {
def main(args: Array[String]) {
kmeans("file///F:/1/newtest3.txt","file///F:/1/newtest4.txt")
}
def kmeans(trianurl:String,forecasturl:String)={
val conf =new SparkConf().setAppName("k-means").setMaster("local");
val sc = new SparkContext(conf)
val data = sc.textFile(trianurl)
val parsedData = data.map(s => Vectors.dense(s.split(',').map(_.toDouble))).cache()
val numClusters = 3 //将目标数据分成几类
val numIterations = 20//迭代的次数
//将参数,和训练数据传入,形成模型
val clusters = KMeans.train(parsedData, numClusters, numIterations)
// Evaluate clustering by computing Within Set Sum of Squared Errors
val WSSSE = clusters.computeCost(parsedData)
println("Within Set Sum of Squared Errors = " + WSSSE)
//输入需要分类处理的数据
val forecastdata = sc.textFile(forecasturl)
val forecastdata1=forecastdata.map{line=>
val parts=line.split(",")
Vectors.dense(parts.map(_.toDouble))
}
val result=clusters.predict(forecastdata1)
//打印分类结果
result.foreach(println)
}
}