在我的上一篇里我写的那个只是个人对KMeans聚类在这个项目中的一部分,今天花了很长时间写完和完整的运行测试完这个代码,篇幅很长,都是结合我前面写的加上自己完善的异常检测部分,废话不多说,直接代码实战:
package internet import org.apache.spark.mllib.clustering.{KMeansModel, KMeans} import org.apache.spark.mllib.linalg.{Vectors,Vector} import org.apache.spark.rdd.RDD import org.apache.spark.{SparkContext, SparkConf} /** * Created by 汪本成 on 2016/7/24. */ object CheckAll { def main(args: Array[String]) { //创建入口对象 val conf = new SparkConf().setAppName("CheckAll").setMaster("local") val sc= new SparkContext(conf) val HDFS_DATA_PATH = "hdfs://node1:9000/user/spark/sparkLearning/cluster/kddcup.data" val rawData = sc.textFile(HDFS_DATA_PATH) /** 分类统计样本,降序排序 **/ // clusteringTake1(rawData) /** 评价k值 **/ // clusteringTake2(rawData) // clusteringTake3(rawData) // clusteringTake4(rawData) // clusteringTake5(rawData) /** R数据可视化 **/ /** 异常检测 **/ var beg = System.currentTimeMillis() anomalies(rawData) var end = System.currentTimeMillis() println("用时:" + (end - beg) / 1000 + "s") } //Clustering,Task1 def clusteringTake1(rawData: RDD[String]) = { //分类统计样本个数,降序排序 rawData.map(_.split(",").last).countByValue().toSeq.sortBy(_._2).reverse.foreach(println) val labelsAndData = rawData.map { line => //将csv格式的行拆分成列,创建一个buffer,是一个可变列表 val buffer = line.split(",").toBuffer //删除下标从1开始的三个类别型列 buffer.remove(1, 3) //删除下标最后的标号列 val label = buffer.remove(buffer.length - 1) //保留其他值并将其转换成一个数值型(Double型对象)数组 val vector = Vectors.dense(buffer.map(_.toDouble).toArray) //将数组和标号组成一个元祖 (label, vector) } /** * 为啥要进行labelsAndData => data转化? * 1、k均值在运行过程中只用到特征向量(即没有用到数据集的目标标号列) * 2、使data这个RDD只包含元祖的只包含元组的第二个元素 * 3、实现2可以通过元组类型RDD的values属性得到,在放入缓存中,减少落地 */ //提取出元组的特征向量 val data = labelsAndData.values.cache() //实例化Kmeans类对象 val kmeans = new KMeans() //建立KMeansModel val model = kmeans.run(data) //输出每个簇的质心 model.clusterCenters.foreach(println) val clusterLabelCount = labelsAndData.map { case (label, datum) => //预测样本datum的分类cluster val cluster = model.predict(datum) //返回类别-簇的元组 (cluster, label) }.countByValue() //对簇-类别对分别进行计数,并以可读方式输出 clusterLabelCount.toSeq.sorted.foreach { case ((clus |