前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【技术分享】快速迭代聚类

【技术分享】快速迭代聚类

原创
作者头像
腾讯云TI平台
发布于 2019-07-04 03:04:08
发布于 2019-07-04 03:04:08
89800
代码可运行
举报
文章被收录于专栏:腾讯云TI平台腾讯云TI平台
运行总次数:0
代码可运行

本文原作者:尹迪,经授权发布。

1 谱聚类算法的原理

  在分析快速迭代聚类之前,我们先来了解一下谱聚类算法。谱聚类算法是建立在谱图理论的基础上的算法,与传统的聚类算法相比,它能在任意形状的样本空间上聚类且能够收敛到全局最优解。 谱聚类算法的主要思想是将聚类问题转换为无向图的划分问题。

  • 首先,数据点被看做一个图的顶点v,两数据的相似度看做图的边,边的集合由E=AijE=Aij表示,由此构造样本数据集的相似度矩阵A,并求出拉普拉斯矩阵L
  • 其次,根据划分准则使子图内部相似度尽量大,子图之间的相似度尽量小,计算出L的特征值和特征向量
  • 最后,选择k个不同的特征向量对数据点聚类

  那么如何求拉普拉斯矩阵呢?

  将相似度矩阵A的每行元素相加就可以得到该顶点的度,我们定义以度为对角元素的对角矩阵称为度矩阵D。可以通过AD来确定拉普拉斯矩阵。拉普拉斯矩阵分为规范和非规范两种,规范的拉普拉斯矩阵 表示为L=D-A,非规范的拉普拉斯矩阵表示为L=I−D−1AL=I−D−1A 。

  谱聚类算法的一般过程如下:

  • (1)输入待聚类的数据点集以及聚类数k
  • (2)根据相似性度量构造数据点集的拉普拉斯矩阵L
  • (3)选取L的前k个(默认从小到大,这里的k和聚类数可以不一样)特征值和特征向量,构造特征向量空间(这实际上是一个降维的过程);
  • (4)使用传统方法对特征向量聚类,并对应于原始数据的聚类。

  谱聚类算法和传统的聚类方法(例如K-means)比起来有不少优点:

  • K-medoids类似,谱聚类只需要数据之间的相似度矩阵就可以了,而不必像K-means那样要求数据必须是N维欧氏空间中的向量。
  • 由于抓住了主要矛盾,忽略了次要的东西,因此比传统的聚类算法更加健壮一些,对于不规则的误差数据不是那么敏感,而且性能也要好一些。
  • 计算复杂度比K-means要小,特别是在像文本数据或者平凡的图像数据这样维度非常高的数据上运行的时候。

  快速迭代算法和谱聚类算法都是将数据点嵌入到由相似矩阵推导出来的低维子空间中,然后直接或者通过k-means算法产生聚类结果,但是快速迭代算法有不同的地方。下面重点了解快速迭代算法的原理。

2 快速迭代算法的原理

  在快速迭代算法中,我们构造另外一个矩阵W=D−1AW=D−1A ,同第一章做比对,我们可以知道W的最大特征向量就是拉普拉斯矩阵L的最小特征向量。 我们知道拉普拉斯矩阵有一个特性:第二小特征向量(即第二小特征值对应的特征向量)定义了图最佳划分的一个解,它可以近似最大化划分准则。更一般的,k个最小的特征向量所定义的子空间很适合去划分图。 因此拉普拉斯矩阵第二小、第三小直到第k小的特征向量可以很好的将图W划分为k个部分。

  注意,矩阵Lk个最小特征向量也是矩阵Wk个最大特征向量。计算一个矩阵最大的特征向量可以通过一个简单的方法来求得,那就是快速迭代(即PI)。 PI是一个迭代方法,它以任意的向量v0v0作为起始,依照下面的公式循环进行更新。

  在上面的公式中,c是标准化常量,是为了避免vtvt产生过大的值,这里c=||Wvt||1c=||Wvt||1 。在大多数情况下,我们只关心第k(k不为1)大的特征向量,而不关注最大的特征向量。 这是因为最大的特征向量是一个常向量:因为W每一行的和都为1。

  快速迭代的收敛性在文献【1】中有详细的证明,这里不再推导。

  快速迭代算法的一般步骤如下:

  在上面的公式中,输入矩阵W根据W=D−1AW=D−1A来计算。

3 快速迭代算法的源码实现

  在spark中,文件org.apache.spark.mllib.clustering.PowerIterationClustering实现了快速迭代算法。我们从官方给出的例子出发来分析快速迭代算法的实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import org.apache.spark.mllib.clustering.{PowerIterationClustering, PowerIterationClusteringModel}
import org.apache.spark.mllib.linalg.Vectors
// 加载和切分数据
val data = sc.textFile("data/mllib/pic_data.txt")
val similarities = data.map { line =>
  val parts = line.split(' ')
  (parts(0).toLong, parts(1).toLong, parts(2).toDouble)
}
// 使用快速迭代算法将数据分为两类
val pic = new PowerIterationClustering()
  .setK(2)
  .setMaxIterations(10)
val model = pic.run(similarities)
//打印出所有的簇
model.assignments.foreach { a =>
  println(s"${a.id} -> ${a.cluster}")
}

  在上面的例子中,我们知道数据分为三列,分别是起始id,目标id,以及两者的相似度,这里的similarities代表前面章节提到的矩阵A。有了数据之后,我们通过PowerIterationClusteringrun方法来训练模型。 PowerIterationClustering类有三个参数:

  • k:聚类数
  • maxIterations:最大迭代数
  • initMode:初始化模式。初始化模式分为RandomDegree两种,针对不同的模式对数据做不同的初始化操作

  下面分步骤介绍run方法的实现。

  • (1)标准化相似度矩阵A到矩阵W
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def normalize(similarities: RDD[(Long, Long, Double)]): Graph[Double, Double] = {
    //获得所有的边
    val edges = similarities.flatMap { case (i, j, s) =>
      //相似度值必须非负
      if (s < 0.0) {
        throw new SparkException("Similarity must be nonnegative but found s($i, $j) = $s.")
      }
      if (i != j) {
        Seq(Edge(i, j, s), Edge(j, i, s))
      } else {
        None
      }
    }
    //根据edges信息构造图,顶点的特征值默认为0
    val gA = Graph.fromEdges(edges, 0.0)
    //计算从顶点的出发的边的相似度之和,在这里称为度
    val vD = gA.aggregateMessages[Double](
      sendMsg = ctx => {
        ctx.sendToSrc(ctx.attr)
      },
      mergeMsg = _ + _,
      TripletFields.EdgeOnly)
    //计算得到W , W=A/D
    GraphImpl.fromExistingRDDs(vD, gA.edges)
      .mapTriplets(
        //gAi/vDi
        //使用边的权重除以起始点的度
        e => e.attr / math.max(e.srcAttr, MLUtils.EPSILON),
        TripletFields.Src)
  }

  上面的代码首先通过边集合构造图gA,然后使用aggregateMessages计算每个顶点的度(即所有从该顶点出发的边的相似度之和),构造出VertexRDD。最后使用现有的VertexRDDEdgeRDD, 相继通过fromExistingRDDsmapTriplets方法计算得到最终的图W。在mapTriplets方法中,对每一个EdgeTriplet,使用相似度除以出发顶点的度(为什么相除?对角矩阵的逆矩阵是各元素取倒数,W=D−1AW=D−1A就可以通过元素相除得到)。

  下面举个例子来说明这个步骤。假设有v1,v2,v3,v4四个点,它们之间的关系如下图所示,并且假设点与点之间的相似度均设为1。

  通过该图,我们可以得到相似度矩阵A和度矩阵D,他们分别如下所示。

  通过mapTriplets的计算,我们可以得到从点v1v2,v3,v4的边的权重分别为1/3,1/3,1/3;从点v2v1,v3,v4的权重分别为1/3,1/3,1/3;从点v3v1,v2的权重分别为1/2,1/2;从点v4v1,v2的权重分别为1/2,1/2。 将这个图转换为矩阵的形式,可以得到如下矩阵W

  通过代码计算的结果和通过矩阵运算得到的结果一致。因此该代码实现了W=D−1AW=D−1A 。

  • (2)初始化v0v0

  根据选择的初始化模式的不同,我们可以使用不同的方法初始化v0v0 。一种方式是随机初始化,一种方式是度(degree)初始化,下面分别来介绍这两种方式。

  • 随机初始化
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 def randomInit(g: Graph[Double, Double]): Graph[Double, Double] = {
    //给每个顶点指定一个随机数
    val r = g.vertices.mapPartitionsWithIndex(
      (part, iter) => {
        val random = new XORShiftRandom(part)
        iter.map { case (id, _) =>
          (id, random.nextGaussian())
        }
      }, preservesPartitioning = true).cache()
    //所有顶点的随机值的绝对值之和
    val sum = r.values.map(math.abs).sum()
    //取平均值
    val v0 = r.mapValues(x => x / sum)
    GraphImpl.fromExistingRDDs(VertexRDD(v0), g.edges)
  }
  • 度初始化
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 def initDegreeVector(g: Graph[Double, Double]): Graph[Double, Double] = {
    //所有顶点的度之和
    val sum = g.vertices.values.sum()
    //取度的平均值
    val v0 = g.vertices.mapValues(_ / sum)
    GraphImpl.fromExistingRDDs(VertexRDD(v0), g.edges)
  }

  通过初始化之后,我们获得了向量v0v0 。它包含所有的顶点,但是顶点特征值发生了改变。随机初始化后,特征值为随机值;度初始化后,特征为度的平均值。

  在这里,度初始化的向量我们称为“度向量”。度向量会给图中度大的节点分配更多的初始化权重,使其值可以更平均和快速的分布,从而更快的局部收敛。详细情况请参考文献【1】。

  • (3)快速迭代求最终的v
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (iter <- 0 until maxIterations if math.abs(diffDelta) > tol) {
      val msgPrefix = s"Iteration $iter"
      // 计算w*vt
      val v = curG.aggregateMessages[Double](
        //相似度与目标点的度相乘
        sendMsg = ctx => ctx.sendToSrc(ctx.attr * ctx.dstAttr),
        mergeMsg = _ + _,
        TripletFields.Dst).cache()
      // 计算||Wvt||_1,即第二章公式中的c
      val norm = v.values.map(math.abs).sum()
      val v1 = v.mapValues(x => x / norm)
      // 计算v_t+1和v_t的不同
      val delta = curG.joinVertices(v1) { case (_, x, y) =>
        math.abs(x - y)
      }.vertices.values.sum()
      diffDelta = math.abs(delta - prevDelta)
      // 更新v
      curG = GraphImpl.fromExistingRDDs(VertexRDD(v1), g.edges)
      prevDelta = delta
    }

  在上述代码中,我们通过aggregateMessages方法计算WvtWvt 。我们仍然以第(1)步的举例来说明这个方法。假设我们以度来初始化v0v0 , 在第一次迭代中,我们可以得到v1(注意这里的v1是上面举例的顶点)的特征值为(1/3)*(3/10)+(1/3)*(1/5)+(1/3)*(1/5)=7/30v2的特征值为7/30v3的特征值为3/10,v4的特征值为3/10。即满足下面的公式。

  • (4)使用k-means算法对v进行聚类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def kMeans(v: VertexRDD[Double], k: Int): VertexRDD[Int] = {
    val points = v.mapValues(x => Vectors.dense(x)).cache()
    val model = new KMeans()
      .setK(k)
      .setRuns(5)
      .setSeed(0L)
      .run(points.values)
    points.mapValues(p => model.predict(p)).cache()
  }

  如果对graphX不太了解,可以阅读spark graph使用和源码解析

4 参考文献

【1】Frank Lin,William W. Cohen.Power Iteration Clustering

【2】漫谈 Clustering (4): Spectral Clustering

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入机器学习系列之:快速迭代聚类
今日头条丨一点资讯丨腾讯丨搜狐丨网易丨凤凰丨阿里UC大鱼丨新浪微博丨新浪看点丨百度百家丨博客中国丨趣头条丨腾讯云·云+社区
数据猿
2019/11/20
8370
深入机器学习系列之:快速迭代聚类
使用谱聚类(spectral clustering)进行特征选择
谱聚类是一种基于图论的聚类方法,通过对样本数据的拉普拉斯矩阵的特征向量进行聚类,从而达到对样本数据聚类的目的。谱聚类可以理解为将高维空间的数据映射到低维,然后在低维空间用其它聚类算法(如KMeans)进行聚类
数据STUDIO
2023/02/24
1.2K0
使用谱聚类(spectral clustering)进行特征选择
谱聚类(spectral clustering)原理总结
    谱聚类(spectral clustering)是广泛使用的聚类算法,比起传统的K-Means算法,谱聚类对数据分布的适应性更强,聚类效果也很优秀,同时聚类的计算量也小很多,更加难能可贵的是实现起来也不复杂。在处理实际的聚类问题时,个人认为谱聚类是应该首先考虑的几种算法之一。下面我们就对谱聚类的算法原理做一个总结。
刘建平Pinard
2018/08/14
1.3K0
谱聚类(spectral clustering)原理总结
详解谱聚类原理
作者 | 荔枝boy 编辑 | 磐石 出品 | 磐创AI技术团队 【磐创AI导读】:本文详细介绍了谱聚类的原理。欢迎大家点击上方蓝字关注我们的公众号:磐创AI。 目录 一. 拉普拉斯矩阵性质 二.拉普拉斯矩阵与图分割的联系 三.Ratiocut 四.总结 一.拉普拉斯矩阵性质 这篇文章可能会有些枯燥,着重分享了谱聚类的原理中的一些思想,以及自己本人对谱聚类的一些理解。如果在看完这篇文章后,也能解决你对谱聚类的一些疑问,想必是对你我都是极好的。在之前查阅了很多关于谱聚类的资料,
磐创AI
2018/07/03
1.3K0
斯坦福CS224W 图与机器学习5】Spectral Clustering
第五节主要介绍了谱聚类,也可用于上一节提到的社区划分,另外还扩展了基于motif的谱聚类,主要分成两个部分:
Houye
2020/05/21
1K0
R语言谱聚类社会化推荐挖掘协同过滤电影社交网站Flixster数据集应用研究
本课题着眼于谱聚类在社会化推荐挖掘中的应用研究。谱聚类算法是基于图论的数据聚类算法,与其他聚类方法相比具有明显的优势:建立在谱图理论的基础之上;操作简单,易于实现;具有识别非高斯分布的能力,非常适用于许多实际应用问题。所以,谱聚类算法成为近几年来机器学习领域的一个新的研究热点,处理方法以及机器学习本身算法理论的学习和代码实现在各领域具有相同性,之后同学可以在其他感兴趣的领域结合数据进行分析,利用此课题所学知识举一反三。
拓端
2023/02/04
6460
理解图的拉普拉斯矩阵
谱图理论是图论与线性代数相结合的产物,它通过分析图的某些矩阵的特征值与特征向量而研究图的性质。拉普拉斯矩阵是谱图理论中的核心与基本概念,在机器学习与深度学习中有重要的应用。包括但不仅限于:流形学习数据降维算法中的拉普拉斯特征映射、局部保持投影,无监督学习中的谱聚类算法,半监督学习中基于图的算法,以及目前炙手可热的图神经网络等。还有在图像处理、计算机图形学以及其他工程领域应用广泛的图切割问题。理解拉普拉斯矩阵的定义与性质是掌握这些算法的基础。在今天的文章中,我们将系统地介绍拉普拉斯矩阵的来龙去脉。
SIGAI学习与实践平台
2021/04/09
4.6K0
理解图的拉普拉斯矩阵
谱聚类概述
作者 | 荔枝boy 编辑 | 磐石 出品 | 磐创AI技术团队 【磐创AI导读】:本文主要介绍了谱聚类的相关概念。欢迎大家点击上方蓝字关注我们的公众号:磐创AI。 目录: 一.简述 二.图相关的符号符号 三.相似度矩阵S 四.拉普拉斯矩阵L性质 五.谱聚类算法 六.总结 一.简述 聚类是对探索性数据分析最广泛使用的技术,在现在各个科学领域中处理没有类标的数据时,人们总是想通过确定数据中不同样本的归类,来获取对数据的直观印象。传统的聚类方法有很多,像K-me
磐创AI
2018/07/03
6460
拉普拉斯矩阵及谱聚类
拉普拉斯矩阵及谱聚类(Laplacian Matrix and Spectral Clustering)
AIHGF
2019/02/18
1.9K0
白话什么是谱聚类算法
谱聚类(Spectral Clustering, SC), 是一种基于图论的聚类方法——将带权无向图划分为两个或两个以上的最优子图,使子图内部尽量相似,而子图间距离尽量距离较远
杨熹
2018/12/25
1K0
理解谱聚类
聚类是典型的无监督学习问题,其目标是将样本集划分成多个类,保证同一类的样本之间尽量相似,不同类的样本之间尽量不同,这些类称为簇(cluster)。与有监督的分类算法不同,聚类算法没有训练过程,直接完成对一组样本的划分。
SIGAI学习与实践平台
2019/03/08
1.5K0
谱聚类算法(Spectral Clustering)
谱聚类(Spectral Clustering, SC)是一种基于图论的聚类方法——将带权无向图划分为两个或两个以上的最优子图,使子图内部尽量相似,而子图间距离尽量距离较远,以达到常见的聚类的目的。其中的最优是指最优目标函数不同,可以是割边最小分割——如图1的Smallest cut(如后文的Min cut), 也可以是分割规模差不多且割边最小的分割——如图1的Best cut(如后文的Normalized cut)。
AIHGF
2019/02/18
1.8K0
【机器学习】谱聚类
本文介绍了一种定义在图上聚类算法-谱聚类。首先介绍谱聚类其实是保持图上节点之间的相似性对节点进行向量表示。然后介绍了谱聚类的目标函数-最小化原始相似性矩阵与样本向量表示,相似性的乘积,由此导出谱聚类与拉普拉斯矩阵的关系。最后介绍了谱聚类算法特点,其实际为成对相似性保持(pair-wise)算法。
yuquanle
2020/04/20
8250
谱聚类
谱聚类是一种基于图论的聚类算法,他的思想是将数据集转化称为无向带权图,然后将在各图划分成为两个或两个以上的最优子图,这些最优图的内部尽量相似,子图间的距离尽量远。
opprash
2019/08/30
8610
通透!十大聚类算法全总结!!
这些聚类算法各有优缺点,适用于不同类型的数据和不同的应用场景。选择合适的聚类算法通常取决于具体的需求、数据的特性和计算资源。
Python编程爱好者
2023/11/28
4.3K0
通透!十大聚类算法全总结!!
听说比K-means厉害多了:谱聚类
地址:https://www.cnblogs.com/pinard/p/6221564.html
机器学习算法工程师
2018/08/17
5.6K0
听说比K-means厉害多了:谱聚类
简单易学的机器学习算法——谱聚类(Spectal Clustering)
    网络簇结构(network cluster structure)也称为网络社团结构(network community structure),是复杂网络中最普遍和最重要的拓扑属性之一。网络簇是整个网络中的稠密连接分支,具有同簇内部节点之间相互连接密集,不同簇的节点之间相互连接稀疏的特征。
felixzhao
2019/02/13
1.5K0
论文 | 半监督学习下的高维图构建
磐创AI 专注分享原创AI技术文章 翻译 | 荔枝boy 编辑 | 磐石 出品 | 磐创AI技术团队 【磐创AI导读】:本文主要介绍了半监督下的高纬图重建。欢迎大家点击上方蓝字关注我们的公众号:磐创AI。 目录 一.简述 二.介绍 三.概述 四.总结 一.简述 本次翻译一篇Liu Wei的一篇论文,之前介绍谱聚类的时候大家都知道,用谱聚类对样本进行分割,大概的流程就是先将原始数据通过不同的规则构建出相似度矩阵,然后再用相似度矩阵表示拉普拉斯矩阵,再对拉普拉斯矩阵进行特征分解,
磐创AI
2018/07/03
7320
Python 谱聚类算法从零开始
谱聚类算法是一种常用的无监督机器学习算法,其性能优于其他聚类方法。 此外,谱聚类实现起来非常简单,并且可以通过标准线性代数方法有效地求解。 在谱聚类算法中,根据数据点之间的相似性而不是k-均值中的绝对位置来确定数据点属于哪个类别下。具体区别可通过下图直观看出:
深度学习与Python
2019/07/19
3.3K0
Python 谱聚类算法从零开始
谱聚类
基于无向加权图G=(V,E),其中每个顶点vi对应一个xi,顶点vi和vj间的边有权值wij≥0
AIHGF
2019/02/18
6260
相关推荐
深入机器学习系列之:快速迭代聚类
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文