kmeans优化 spark_spark kmeans - CSDN
  • Spark实现 – Kmeans聚类算法 Kmeans简介 Kmeans是最常用的聚类算法,也是十大经典的数据挖掘算法之一。聚类的思想用一句话概括就是“物以类聚,人以群分”。kmeans算法作为最基础的算法之一,基本上每本数据挖掘的...

    Spark自编程实现Kmeans聚类算法

    Kmeans简介

    Kmeans是最常用的聚类算法,也是十大经典的数据挖掘算法之一。聚类的思想用一句话概括就是“物以类聚,人以群分”。kmeans算法作为最基础的算法之一,基本上每本数据挖掘的书都会讲到,这里就不在啰嗦了。本文主要结合实现原理利用Spark实现一下过程。

    算法实现步骤

    step1 首先随机选取k个样本点最为初始聚类中心
    step2 计算每个样本到聚类中心的距离,将该样本归属到最近的聚类中心
    step3 将每个类的点的均值作为新的聚类中心
    step4 重复2、3步骤直到代价函数不再发生较大大变化或达到迭代次数

    Kmeans动态过程
    Kmeans动态过程  --图片来源维基百科
    图片来源:维基百科

    代码实现

    // 定义一个方法 传入的参数是 数据集、K、最大迭代次数、代价函数变化阈值
    // 其中 最大迭代次数和代价函数变化阈值是设定了默认值,可以根据需要做相应更改
      def train(data: RDD[Seq[Double]], k: Int, maxIter: Int = 40, tol: Double = 1e-4) = {
    
        val sc: SparkContext = data.sparkContext
    
        var i = 0 // 迭代次数
        var cost = 0D //初始的代价函数
        var convergence = false   //判断收敛,即代价函数变化小于阈值tol
        
        // step1 :随机选取 k个初始聚类中心
        var initk: Array[(Seq[Double], Int)] = data.takeSample(false, k, Random.nextLong()).zip(Range(0, k))
    
        var res: RDD[(Seq[Double], Int)] = null
    
        while (i < maxIter && !convergence) {
    
          val bcCenters = sc.broadcast(initk)
    
          val centers: Array[(Seq[Double], Int)] = bcCenters.value
    
          val clustered: RDD[(Int, (Double, Seq[Double], Int))] = data.mapPartitions(points => {
    
            val listBuffer = new ListBuffer[(Int, (Double, Seq[Double], Int))]()
    
    	// 计算每个样本点到各个聚类中心的距离
            points.foreach { point =>
    
              // 计算聚类id以及最小距离平方和、样本点、1
              val cost: (Int, (Double, Seq[Double], Int)) = centers.map(ct => {
    
                ct._2 -> (math.pow(distance.Euclidean(ct._1, point), 2), point, 1)
    
              }).minBy(_._2._1)  // 将该样本归属到最近的聚类中心
              listBuffer.append(cost)
            }
    
            listBuffer.toIterator
    
          })
          //
          val mpartition: Array[(Int, (Double, Seq[Double]))] = clustered
            .reduceByKey((a, b) => {
              val cost = a._1 + b._1   //代价函数
              val count = a._3 + b._3   // 每个类的样本数累加
              val newCenters = a._2.zip(b._2).map(tp => tp._1 + tp._2)    // 新的聚类中心点集
              (cost, newCenters, count)
            })
            .map {
              case (clusterId, (costs, point, count)) =>
                clusterId -> (costs, point.map(_ / count))   // 新的聚类中心 
            }
            .collect()
    
          val newCost = mpartition.map(_._2._1).sum   // 代价函数
    
          convergence =  math.abs(newCost - cost) <= tol    // 判断收敛,即代价函数变化是否小于小于阈值tol
    
    	// 变换新的代价函数
          cost = newCost
          
          // 变换初始聚类中心
          initk = mpartition.map(tp => (tp._2._2, tp._1))
    
    	// 聚类结果 返回样本点以及所属类的id
          res = clustered.map(tp=>(tp._2._2,tp._1))
    
          i += 1
        }
    
        // 返回聚类结果
        res
    
      }
    
    

    算法调用 :为了方便,本案例使用的数据集还是鸢尾花数据集

     val dataset = spark.read.textFile("F:\\DataSource\\iris.csv")
          .rdd.map(_.split(",").filter(NumberUtils.isNumber _).map(_.toDouble))
          .filter(!_.isEmpty).map(_.toSeq)
    
        val kmeans = new Kmeans2()
    
        val res: RDD[(Seq[Double], Int)] = kmeans.train(dataset, 3)
        
        res.sample(false, 0.1, 1234L)
          .map(tp => (tp._1.mkString(","), tp._2))
          .foreach(println)
    

    聚类结果

    (4.8,3.0,1.4,0.3,0)
    (4.6,3.2,1.4,0.2,0)
    (6.0,3.4,4.5,1.6,2)
    (5.6,2.7,4.2,1.3,2)
    (7.1,3.0,5.9,2.1,1)
    (7.2,3.2,6.0,1.8,1)
    ······
    

    根据笔者的检验来看,聚类出来的结果和源数据的分类还是有些许差别。所以通过本案例说明:每个方法都有它自身的使用场景,每个数据集都有自身的属性因此每个都有不同的解决方法,没有最好,只有更好。工具固然可以帮我们解决问题,但是掌握工具能帮我们有效的解决问题。

    不足之处

    因为初始聚类中心是随机选择,因此可能会让结果陷入局部最优,有学者就此问题提出了很多优化方法,例如kmeans++、Kernel K-means等方法。有兴趣的朋友们可以看看 。

    如有不当之处,欢迎指正

    展开全文
  • import sys import numpy as np from pyspark.sql import SparkSession #该函数主要是将文件的string类型转换成float类型 def parseVector(line): return np.array([float(x) for x in line.split(' ')]) ...
    import sys
    
    import numpy as np
    from pyspark.sql import SparkSession
    #该函数主要是将文件的string类型转换成float类型
    def parseVector(line):
        return np.array([float(x) for x in line.split(' ')])
    #该函数将点分配到点集中,返回的是点集的index
    #其中传入的参数p是需分配的点的值(可以看成矢量,假设是m维),centers是目前的中心点的值(可以看成n*m维的矩阵,其中n指的是中心点的个数)
    def closestPoint(p, centers):
        bestIndex = 0
        closest = float("+inf")
        for i in range(len(centers)):
            tempDist = np.sum((p - centers[i]) ** 2)#计算需分配的点与第i个中心点的距离
            if tempDist < closest:
                closest = tempDist
                bestIndex = i
        return bestIndex
    
    
    if __name__ == "__main__":
    
        if len(sys.argv) != 4:
            print("Usage: kmeans <file> <k> <convergeDist>", file=sys.stderr)
            exit(-1)
    
        print("""WARN: This is a naive implementation of KMeans Clustering and is given
           as an example! Please refer to examples/src/main/python/ml/kmeans_example.py for an
           example on how to use ML's KMeans implementation.""", file=sys.stderr)
    
        spark = SparkSession\
            .builder\
            .appName("PythonKMeans")\
            .getOrCreate()
    
        lines = spark.read.text(sys.argv[1]).rdd.map(lambda r: r[0])
        data = lines.map(parseVector).cache()
        K = int(sys.argv[2])  #设置的中心点的个数
        convergeDist = float(sys.argv[3])  #设置的阈值
    
        kPoints = data.takeSample(False, K, 1)  #在data点集中随机选取K个点作为中心点
        tempDist = 1.0
    
        while tempDist > convergeDist:
            closest = data.map(
                lambda p: (closestPoint(p, kPoints), (p, 1)))#返回的结果是(p点所分配的集合的index值,(p点的值,1))
            pointStats = closest.reduceByKey(   #reduceByKey针对具有相同键(在这里指的是p点被分配到相同的点集)的二元组
    #则p1_c1和p2_c2指的都是二元组的value值,也就是(p,1)。所以,该句子表示将在同一个点集上的点的(p,1)分别求和,其中别忘了p是一个矢量
    lambda p1_c1, p2_c2: (p1_c1[0] + p2_c2[0], p1_c1[1] + p2_c2[1])) #得到的是(点集的index,(点值的求和,该点集的点的个数)) newPoints = pointStats.map( # 返回(点集的index,点值求和/点的个数(矢量除法)),作为新的中心点 lambda st: (st[0], st[1][0] / st[1][1])).collect()        #计算新旧中心点的距离差 tempDist = sum(np.sum((kPoints[iK] - p) ** 2) for (iK, p) in newPoints) for (iK, p) in newPoints: kPoints[iK] = p #设置新的中心点的值 print("Final centers: " + str(kPoints)) spark.stop()

    有可能表述不是很准确,但是能看懂就行。(随机可能学多了,喜欢用矩阵看问题)

    展开全文
  • kmeans算法spark实战

    2018-07-23 16:28:01
    1.标准kmeans算法 kmeans算法是实际中最常用的聚类算法,没有之一。kmeans算法的原理简单,实现起来不是很复杂,实际中使用的效果一般也不错,所以深受广大人民群众的喜爱。  kmeans算法的原理介绍方面的paper...

    1.标准kmeans算法

    kmeans算法是实际中最常用的聚类算法,没有之一。kmeans算法的原理简单,实现起来不是很复杂,实际中使用的效果一般也不错,所以深受广大人民群众的喜爱。 
    kmeans算法的原理介绍方面的paper多如牛毛,而且理解起来确实也不是很复杂,这里使用wiki上的版本: 
    已知观测集(x1,x2,⋯,xn)(x1,x2,⋯,xn),其中每个观测都是一个dd维实矢量,kmeans聚类要把这nn个观测值划分到kk个集合中(k≤nk≤n),使得组内平方和(WCSS within-cluster sum of squares)最小。换句话说,它的目标是找到使得下式满足的聚类SiSi, 

    argminS∑i=1k∑x∈Si∥x−μi∥2argminS∑i=1k∑x∈Si‖x−μi‖2


    其中μiμi是SiSi中所有点的均值。

     

    标准kmeans算法的步骤一般如下: 
    1.先随机挑选k个初始聚类中心。 
    2.计算数据集中每个点到每个聚类中心的距离,然后将这个点分配到离该点最近的聚类中心。 
    3.重新计算每个类中所有点的坐标的平均值,并将得到的这个新的点作为新的聚类中心。 
    重复上面第2、3步,知道聚类中心点不再大范围移动(精度自己定义)或者迭代的总次数达到最大。

    2.标准kmeans算法的优缺点

    标准的kmeans算法的优缺点都很突出。这里挑几个最重要的点总结一下。

    主要优点:

    1.原理简单,易于理解。 
    2.实现简单 
    3.计算速度较快 
    4.聚类效果还不错。

    主要缺点:

    1.需要确定k值。 
    2.对初始中心点的选择敏感。 
    3.对异常值敏感,因为异常值很很大程度影响聚类中心的位置。 
    4.无法增量计算。这点在数据量大的时候尤为突出。

    3.spark中对kmeans的优化

    作为经典的聚类算法,一般的机器学习框架里都实现由kmeans,spark自然也不例外。前面我们已经讲了标准kmeans的流程以及优缺点,那么针对标准kmeans中的不足,spark里主要做了如下的优化:

    1.选择合适的K值。

    k的选择是kmeans算法的关键。Spark MLlib在KMeansModel里实现了computeCost方法,这个方法通过计算数据集中所有的点到最近中心点的平方和来衡量聚类的效果。一般来说,同样的迭代次数,这个cost值越小,说明聚类的效果越好。但在实际使用过程中,必须还要考虑聚类结果的可解释性,不能一味地选择cost值最小的那个k。比如我们如果考虑极限情况,如果数据集有n个点,如果令k=n,每个点都是聚类中心,每个类都只有一个点,此时cost值最小为0。但是这样的聚类结果显然是没有实际意义的。

    2.选择合适的初始中心点

    大部分迭代算法都对初始值很敏感,kmeans也是如此。spark MLlib在初始中心点的选择上,使用了k-means++的算法。想要详细了解k-means++的同学们,可以参考k-means++在wiki上的介绍:https://en.wikipedia.org/wiki/K-means%2B%2B。 
    kmeans++的基本思想是是初始中心店的相互距离尽可能远。为了实现这个初衷,采取如下步骤: 
    1.从初始数据集中随机选择一个点作为第一个聚类中心点。 
    2.计算数据集中所有点到最近一个中心点的距离D(x)并存在一个数组里,然后将所有这些距离加起来得到Sum(D(x))。 
    3.然后再取一个随机值,用权重的方式计算下一个中心点。具体的实现方法:先取一个在Sum(D(x))范围内的随机值,然后领Random -= D(x),直至Random <= 0,此时这个D(x)对应的点为下一个中心点。 
    4.重复2、3步直到k个聚类中心点被找出。 
    5.利用找出的k个聚类中心点,执行标准的kmeans算法。

    算法的关键是在第三步。有两个小点需要说明: 
    1.不能直接取距离最大的那个点当中心店。因为这个点很可能是离群点。 
    2.这种取随机值的方法能保证距离最大的那个点被选中的概率最大。给大家举个很简单的例子:假设有四个点A、B、C、D,分别离最近中心的距离D(x)为1、2、3、4,那么Sum(D(x))=10。然后在[0,10]之间取一随机数假设为random,然后用random与D(x)依次相减,直至random<0为止。应该不难发现,D被选中的概率最大。

    4.spark实战kmeans算法

    前面讲了这么多理论,照例咱们需要实践一把。talk is cheap,show me the code!

    1.准备数据

    首先准备数据集。这里采用的数据集是UCI的一个数据集。数据地址http://archive.ics.uci.edu/ml/datasets/Wholesale+customers?cm_mc_uid=70889544450214522232748&cm_mc_sid_50200000=1469871598。UCI是一个常用的标准测试数据集,是搞ML与DM同学经常使用的数据集。关于该数据集的介绍,同学们可以去网页上查看。

    将数据下载下来以后查看一把,第一行相当于是表头,是对数据的相关说明。将此行去掉,还剩440行。将前400行作为训练集,后40行作为测试集。

    2.将代码run起来

    import org.apache.spark.{SparkContext, SparkConf}
    import org.apache.spark.mllib.clustering.{KMeans, KMeansModel}
    import org.apache.spark.mllib.linalg.Vectors
    
    object KmeansTest {
      def main(args: Array[String]) {
    
        val conf = new
            SparkConf().setAppName("K-Means Clustering").setMaster("spark://your host:7077").setJars(List("your jar file"))
        val sc = new SparkContext(conf)
    
        val rawTrainingData = sc.textFile("file:///Users/lei.wang/data/data_training")
        val parsedTrainingData =
          rawTrainingData.filter(!isColumnNameLine(_)).map(line => {
            Vectors.dense(line.split(",").map(_.trim).filter(!"".equals(_)).map(_.toDouble))
          }).cache()
    
        // Cluster the data into two classes using KMeans
    
        val numClusters = 8
        val numIterations = 30
        val runTimes = 3
        var clusterIndex: Int = 0
        val clusters: KMeansModel =
          KMeans.train(parsedTrainingData, numClusters, numIterations, runTimes)
    
        println("Cluster Number:" + clusters.clusterCenters.length)
    
        println("Cluster Centers Information Overview:")
        clusters.clusterCenters.foreach(
          x => {
            println("Center Point of Cluster " + clusterIndex + ":")
            println(x)
            clusterIndex += 1
          })
    
        //begin to check which cluster each test data belongs to based on the clustering result
    
        val rawTestData = sc.textFile("file:///Users/lei.wang/data/data_test")
        val parsedTestData = rawTestData.map(line => {
          Vectors.dense(line.split(",").map(_.trim).filter(!"".equals(_)).map(_.toDouble))
    
        })
        parsedTestData.collect().foreach(testDataLine => {
          val predictedClusterIndex:
          Int = clusters.predict(testDataLine)
          println("The data " + testDataLine.toString + " belongs to cluster " +
            predictedClusterIndex)
        })
    
        println("Spark MLlib K-means clustering test finished.")
      }
    
      private def isColumnNameLine(line: String): Boolean = {
        if (line != null && line.contains("Channel")) true
        else false
      }
    }

    5.后续工作

    本次测试是在单机上做的demo测试,数据集比较小,运算过程也比较快。其实当数据量增大以后,基本过程跟这是类似的,只需要将input改为集群的数据路径,然后再写个简单的shell脚本,调用spark-submit,将任务提交到集群即可。

     

    原文网址:https://blog.csdn.net/bitcarmanlee/article/details/52092288

    展开全文
  • 1. 聚类 1.1 什么是聚类? 所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用算法将集合D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高,...

    1. 聚类
    1.1 什么是聚类?


    所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用算法将集合D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高,其中每个子集叫做一个簇。

    K-means算法简介

    k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。聚类与分类最大的区别在于,聚类过程为无监督过程,即待处理数据对象没有任何先验知识,而分类过程为有监督过程,即存在有先验知识的训练数据集。

    K-means算法原理

    k-means算法中的k代表类簇个数,means代表类簇内数据对象的均值(这种均值是一种对类簇中心的描述),因此,k-means算法又称为k-均值算法。k-means算法是一种基于划分的聚类算法,以距离作为数据对象间相似性度量的标准,即数据对象间的距离越小,则它们的相似性越高,则它们越有可能在同一个类簇。数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离

    k-means算法优缺点分析

    - 优点: 算法简单易实现;

     - 缺点: 需要用户事先指定类簇个数; 聚类结果对初始类簇中心的选取较为敏感; 容易陷入局部最优; 只能发现球形类簇;


    1.2 KMeans 聚类算法


    K-Means聚类算法主要分为如下几个步骤:

    1. 从D中随机取k个元素,作为k个簇的各自的中心
    2. 分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇
    3. 根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数
    4. 将D中全部元素按照新的中心重新聚类。 
    5. 重复第4步,直到聚类结果不再变化。 

    1.2.1 什么是相异度


    设 X={x1,x2.....,xn},Y={y1,y2......yn}其中X,Y是两个元素项,各自具有n个可度量特征属性
    X和Y的相异度定义为: d(X,Y)=f(X,Y)->R,其中R为实数域,也就是两个元素的相异度。


    1.2.2 相异度的算法


    因为每个纬度的数字都是无方向意义的标度变量,可以通过距离来标示相异度
    常见的几个距离计算公式:

    1. 欧几里得距离: 
    2. 曼哈顿距离:
    3. 闵可夫斯基距离:

    1.2.3 数据的规格化


    在计算距离的时候,会发现取值范围大的属性对距离的影响高于取值范围小的属性,为了解决这个问题,一般要对属性值进行规格化。
    规格化就是将各个属性值按比例映射到相同的取值区间,这样是为了平衡各个属性对距离的影响。

    最典型的规格化就是数据的归一化:将各个属性均映射到[0,1]区间
    映射公式为:其中max(ai)和min(ai)表示所有元素项中第i个属性的最大值和最小值


    2. Spark Kmeans的实现


    2.1 Kmeans 初始化的几个参数

    class KMeans private (
        private var k: Int,
        private var maxIterations: Int,
        private var initializationMode: String,
        private var initializationSteps: Int,
        private var epsilon: Double,
        private var seed: Long) extends Serializable 
    参数 定义
    K 聚的总类
    maxIterations 迭代的次数
    initializationMode 有 random 和 k-means||两种
    initializationSteps 初始化的步长
    epsilon 最小中心距离的筏值
    seed 随机数的种子

     

    2.2 步骤1:Kmeans 的初始化中心的选择


    Kmeans 在数据集初始化的时候中选K个中心点有两种算法

    • 随机选择:依据给的种子seed,随机生成K个随机中心点
    • k-means||:默认的算法
    1.  随机生成一个中心点,基于这个中心点,找出一批距离这个中心点较远的点作为集合(分布式查找)
    2.  以这些找到的点的集合为新的中心点,依据initializationSteps作为重复查找步骤1,2的次数(分布式查找)
    3.  如果找到的这些点的数量小于k,那么就以这些点为中心点
    4.  不如2步骤找到的这些点大于k,那么将基于这些点作为样本进行k-means++的中心点查找,找到K个中心点。k-means++的查找是在有限的点上查找(driver端的本地权重查找)
    if (initializationMode == KMeans.RANDOM) {
              initRandom(data)
            } else {
              initKMeansParallel(data)
            }

    2.3  步骤2: 计算每个点的特征向量的norm

    // Compute squared norms and cache them.
        val norms = data.map(Vectors.norm(_, 2.0))
        norms.persist()

    我们来看一下norm的算法

    else if (p == 2) {
          var sum = 0.0
          var i = 0
          while (i < size) {
            sum += values(i) * values(i)
            i += 1
          }
          math.sqrt(sum)

    假如:一个点的A(a1,b1) 那么norm的计算就是 sqrt(a1^2+b1^2),这也是向量的L2范数


    2.4 步骤3:计算每个点距离其他点的距离


    在Spark使用的距离算法是欧式距离算法,我们先来看这个距离算法:对两个点 x(x1,x2....xn)和y(y1,y2....yn)


    将方程式解开

    sqrt(x1^2+x2^2+x3^2+.....+xn^2 + y1^2+y2^2+...+yn^2 -2(x1y1+x2*y2.....+xn*yn))

    对x1^2+x2^2+x3^2+.....+xn^2 这部分可以提前算,但是-2(x1y1+x2*y2.....+xn*yn))这部分的计算是需要时时计算的
     

    注意:

    在我们前面的文章中,Spark做了一些算法的优化而这些优化是基于欧式距离的,Spark mllib里提供的Kmeans算法不支持其它的距离算法。

    3. Kmeans的训练模型


    Kmeans本身也提供了训练模型,模型的目的为了对新输入的向量进行判定到哪个类别,聚类的模型最终的目的是为了分类。

    @Since("0.8.0")
    class KMeansModel @Since("1.1.0") (@Since("1.0.0") val clusterCenters: Array[Vector])
      extends Saveable with Serializable with PMMLExportable {
     
      /**
       * A Java-friendly constructor that takes an Iterable of Vectors.
       */
      @Since("1.4.0")
      def this(centers: java.lang.Iterable[Vector]) = this(centers.asScala.toArray)
     
      /**
       * Total number of clusters.
       */
      @Since("0.8.0")
      def k: Int = clusterCenters.length
     
      /**
       * Returns the cluster index that a given point belongs to.
       */
      @Since("0.8.0")
      def predict(point: Vector): Int = {
        KMeans.findClosest(clusterCentersWithNorm, new VectorWithNorm(point))._1
      }
     
      /**
       * Maps given points to their cluster indices.
       */
      @Since("1.0.0")
      def predict(points: RDD[Vector]): RDD[Int] = {
        val centersWithNorm = clusterCentersWithNorm
        val bcCentersWithNorm = points.context.broadcast(centersWithNorm)
        points.map(p => KMeans.findClosest(bcCentersWithNorm.value, new VectorWithNorm(p))._1)
      }
     
      /**
       * Maps given points to their cluster indices.
       */
      @Since("1.0.0")
      def predict(points: JavaRDD[Vector]): JavaRDD[java.lang.Integer] =
        predict(points.rdd).toJavaRDD().asInstanceOf[JavaRDD[java.lang.Integer]]
     
      /**
       * Return the K-means cost (sum of squared distances of points to their nearest center) for this
       * model on the given data.
       */
      @Since("0.8.0")
      def computeCost(data: RDD[Vector]): Double = {
        val centersWithNorm = clusterCentersWithNorm
        val bcCentersWithNorm = data.context.broadcast(centersWithNorm)
        data.map(p => KMeans.pointCost(bcCentersWithNorm.value, new VectorWithNorm(p))).sum()
      }
     
      private def clusterCentersWithNorm: Iterable[VectorWithNorm] =
        clusterCenters.map(new VectorWithNorm(_))
     
      @Since("1.4.0")
      override def save(sc: SparkContext, path: String): Unit = {
        KMeansModel.SaveLoadV1_0.save(sc, this, path)
      }
     
      override protected def formatVersion: String = "1.0"
    }

     

    通过KMeansModel的训练模型,predict输入的向量所距离最近的中心点

      @Since("0.8.0")
      def predict(point: Vector): Int = {
        KMeans.findClosest(clusterCentersWithNorm, new VectorWithNorm(point))._1
      }


    看了熟悉的函数findClosest,那些中心点是在聚类结束创建中心点

    new KMeansModel(centers.map(_.vector))

    4. Spark Kmeans的评估
    如何评估KMeans的聚类K的效果?可以通过computeCost函数来计算cost

      @Since("0.8.0")
      def computeCost(data: RDD[Vector]): Double = {
        val centersWithNorm = clusterCentersWithNorm
        val bcCentersWithNorm = data.context.broadcast(centersWithNorm)
        data.map(p => KMeans.pointCost(bcCentersWithNorm.value, new VectorWithNorm(p))).sum()
      }


    函数的算法:
    通过计算所有数据点到其最近的中心点的距离平方和 (a1-c1)^2+(a2-c2)^2 +...... 

    使用不同的K,相同的迭代次数,理论上值越小,聚类效果越好,但是这是需要可解释性,如果聚类K等于总数据点,当然聚类效果最好,cost是0,但没有意义。
     

    展开全文
  • sparkML之kmeans聚类

    2017-12-06 20:42:52
    1.标准kmeans算法 kmeans算法是实际中最常用的聚类算法,没有之一。kmeans算法的原理简单,实现起来不是很复杂,实际中使用的效果一般也不错,所以深受广大人民群众的喜爱。  kmeans算法的原理介绍方面的paper...
  • Spark MLlib 源代码解读之Kmeans(上)PS:第一次写博客,希望大家支持,谢谢。基本原理:Kmeans算法的基本思想是:初始随机给定k个簇中心,按照最近邻的点将数据集中所包含的点分给不同的中心点,进而得到数据的分类。...
  • ------------------------------目录-------------------------------------------...Kmeans理论 Matlab实现 Spark源码分析 Spark源码 Spark实验 -------------------------------------------------------------------
  • 引言 提起机器学习 (Machine ...然而学习并使用机器学习算法来处理数据却是一项复杂的工作,需要充足的知识储备,如概率论,数理统计,数值逼近,最优化理论等。机器学习旨在使计算机具有人类一样的学习能力和模...
  • Spark-KMeans文本聚类

    2016-01-07 11:37:05
    1 实验环境部署 1.1 主机环境  处理器 Intel(R) Core(TM)2 Duo CPU 2.80GHz 内存 8.00GB 操作系统 WIN7SP1 64bit ...VMware® Workstation 10.0.2 build-1744117 ...操作系统 Ubuntu12.04 LTS Desktop...
  • 1.标准kmeans算法kmeans算法是实际中最常用的聚类算法,没有之一。kmeans算法的原理简单,实现起来不是很复杂,实际中使用的效果一般也不错,所以深受广大人民群众的喜爱。 kmeans算法的原理介绍方面的paper...
  • 摘要: MLlib 是 Spark 生态系统里用来解决大数据机器学习问题的模块。本文将以聚类分析这个典型的机器学习问题为基础,向读者介绍如何使用 MLlib 提供的 K-means 算法对数据做聚类分析,我们还将通过分析源码,...
  • 基于sparkkmeans算法

    2019-07-31 02:36:24
    from __future__ import print_function import sys import numpy as np from pyspark.sql import SparkSession def parseVector(line): ... return np.array([float(x) for x in line.split(' ')]) ...
  • 聚类算法是机器学习中的一种无监督学习算法,它在数据科学领域应用场景很广泛,比如基于用户购买行为、兴趣等来构建推荐系统。核心思想可以理解为,在给定的数据集中(数据集中的每个元素有可被观察...
  • 1. 聚类1.1 什么是聚类?所谓聚类问题,就是给定一个...1.2 KMeans 聚类算法K-Means聚类算法主要分为如下几个步骤:从D中随机取k个元素,作为k个簇的各自的中心分别计算剩下的元素到k个簇中心的相异度,将这些元素分
  • 【[2020.6] 数据挖掘:基于Spark框架的K-Means聚类2】在Iris数据集上借助pyspark实现K-Means聚类Iris(鸢尾花)数据集Iris数据集简介Iris数据集下载和处理基于pypark的K-Means 聚类实验与参数分析Spark组件MLlib[^2]...
  • 1.取英文文章数据,训练成模型,就是特征向量,用word2Vec。  2.然后用这个模型,去将新数据,或者老数据...中间可以自己加一些去除停用词,结果优化,格式化输出等。 val conf = new SparkConf().setMaster...
  • 本博客是【Spark-Python-机器学习】系列的文章。 该系列的文章主要讲解【机器学习】的一些通用算法的原理,并且使用【Python+Spark】来实现。 文章通常分为上下篇(理论篇 与 实践篇)。 如需转载,请附上...
  • Spark

    2018-11-21 01:23:42
    1.Spark 的四大组件下面哪个不是 (D ) A.Spark Streaming B Mlib C Graphx D Spark R2.下面哪个端口不是 spark 自带服务的端口 (C ) A.8080 B.4040 C.8090 D.180803.spark 1.4 版本的最大变化 (B ) A spark ...
1 2 3 4 5 ... 20
收藏数 1,368
精华内容 547
关键字:

kmeans优化 spark