【Spark ML系列】 Kmeans聚类算法由来原理方法示例源码分析

基于Spark MLib的鸢尾花数据聚类项目实战案例 目录背景KMeans原理实训操作一、准备数据二、对数据进行聚类 背景 聚类(Cluster analysis)有时也被翻译为簇类,其核心任务是:将一组目标object划分为若干个簇,每个簇之间的object尽可能相似,簇与簇之间的object尽可能相异。聚类算法是机器学习(或者说是数据挖掘更合适)中重要的一部分,除了最为简单的K-Means聚类算法外,比较常见的还有层次法(CURE、CHAMELEON等)、网格算法(STING、WaveCluster等),等等。 较权威的聚类问题定义:所谓聚类问题,就是给定 阅读详情

Spark Kmeans聚类算法由来原理方法示例源码分析 点击这里免费看全文


K-means++ 是一种改进的 K-means 聚类算法,旨在选择更好的初始聚类中心点。以下是 Spark 中 K-means++ 的全面介绍

由来

传统的 K-means 算法是通过随机选择初始聚类中心点来开始聚类过程。然而,随机选择的初始中心可能导致收敛到局部最优解的风险增加,即结果聚类质量较差。

为了解决这个问题,Arthur 和 Vassilvitskii 在 2007 年提出了 K-means++ 算法。它使用一种概率性的方法来选择初始聚类中心,从而使得初始中心能够更好地代表数据集,减少陷入局部最优解的可能性。

原理

K-means++ 的初始化过程如下:

  1. 从数据集中随机选择一个样本作为第一个聚类中心。
  2. 对于每个样本,计算它与已选择的聚类中心的最短距离(即到最近的聚类中心的距离)。
  3. 根据每个样本与已选择的聚类中心的最短距离,以概率分布的方式选择下一个聚类中心。距离较远的样本被选择为下一个聚类中心的概率较大。
  4. 重复步骤 2 和 3,直到选择出 k 个聚类中心。

K-means++ 的核心思想是通过引入概率选择机制,使得选择的初始聚类中心在整个数据集中分布更加均匀。这样做的好处是能够更好地代表数据集,从而改善最终聚类结果的质量。

在 Spark 中,K-means++ 算法被用作默认的初始化算法,它可以通过设置 initMode 参数为 "k-means||" 来启用。通过使用 K-means++ 初始化算法,Spark 能够提供更可靠和高质量的聚类结果。

示例RDD版

import org.apache.spark.mllib.clustering.{
   
   KMeans, KMeansModel}
import org.apache.spark.mllib.linalg.Vectors

// Load and parse the data
val data = sc.textFile("data/mllib/kmeans_data.txt")
val parsedData = data.map(s => Vectors.dense(s.split(' ').map(_.toDouble))).cache()

// Cluster the data into two classes using KMeans
val numClusters = 2
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(s"Within Set Sum of Squared Errors = $WSSSE")

// Save and load model
clusters.save(sc, "target/org/apache/spark/KMeansExample/KMeansModel")
val sameModel = KMeansModel.load(sc, "target/org/apache/spark/KMeansExample/KMeansModel")

示例DataFrame版本

import org.apache.spark.ml.clustering.KMeans
import org.apache.spark.ml.evaluation.ClusteringEvaluator

// Loads data.
val dataset = spark.read.format("libsvm").load("data/mllib/sample_kmeans_data.txt")

// Trains a k-means model.
val kmeans = new KMeans().setK(2).setSeed(1L)
val model = kmeans.fit(dataset)

// Make predictions
val predictions = model.transform(dataset)

// Evaluate clustering by computing Silhouette score
val evaluator = new ClusteringEvaluator()

val silhouette = evaluator.evaluate(predictions)
println(s"Silhouette with squared euclidean distance = $silhouette")

// Shows the result.
println("Cluster Centers: ")
model.clusterCenters.foreach(println)

方法详细说明

  • load:从指定路径加载 KMeans 模型。

    • load(path: String): KMeansModel
    • 从指定路径加载保存的 KMeans 模型。
    • 参数:
      • path:模型的保存路径。
    • 返回值:KMeansModel 对象,表示加载的 KMeans 模型。
  • read:返回一个用于读取 KMeans 模型的 MLReader 对象。

    • read(): MLReader[KMeansModel]
    • 返回一个用于读取 KMeans 模型的 MLReader 对象。
    • 返回值:MLReader[KMeansModel] 对象,用于读取 KMeans 模型。
  • k:获取聚类数目(k)的参数。

    • k: IntParam
    • 获取聚类数目(k)的参数。注意,实际返回的聚类数目可能少于 k,例如如果数据集中的不同点数量少于 k。
    • 返回值:IntParam 对象,表示聚类数目。
  • initMode:获取初始化算法的参数。

    • initMode: Param[String]
    • 获取初始化算法的参数。可以选择 “random” 以随机选择初始聚类中心,或选择 “k-means||” 使用 k-means++ 的并行变种算法。
    • 返回值:Param[String] 对象,表示初始化算法。
  • initSteps:获取 k-means|| 初始化模式的步数参数。

    • initSteps: IntParam
    • 获取 k-means|| 初始化模式的步数参数。这是一个高级设置,通常默认值 2 已经足够。
    • 返回值:IntParam 对象,表示初始化步数。
  • solver:获取优化方法的参数。

    • solver: Param[String]
    • 获取用于优化的方法的参数。支持的选项有:“auto”、“row” 和 “block”。默认为 “auto”。
    • 返回值:Param[String] 对象,表示优化方法。
  • maxBlockSizeInMB:获取将输入数据堆叠到块中的最大内存限制的参数。

    • maxBlockSizeInMB: DoubleParam
    • 获取将输入数据堆叠到块中的最大内存限制的参数。默认值为 0.0,表示自动选择最佳值。
    • 返回值:DoubleParam 对象,表示最大内存限制。
  • weightCol:获取权重列名的参数。

    • weightCol: Param[String]
    • 获取权重列名的参数。如果未设置或为空,则将所有实例权重视为 1.0。
    • 返回值:Param[String] 对象,表示权重列名。
  • distanceMeasure:获取距离度量的参数。

    • distanceMeasure: Param[String]
    • 获取距离度量的参数。支持的选项有:“euclidean” 和 “cosine”。
    • 返回值:Param[String] 对象,表示距离度量。
  • tol:获取迭代算法的收敛容忍度的参数。

    • tol: DoubleParam
    • 获取迭代算法的收敛容忍度的参数。必须大于等于 0。
    • 返回值:DoubleParam 对象,表示容忍度。
  • predictionCol:获取预测结果列名的参数。

    • predictionCol: Param[String]
    • 获取预测结果列名的参数。
    • 返回值:Param[String] 对象,表示预测结果列名。
  • seed:获取随机种子的参数。

    • seed: LongParam
    • 获取随机种子的参数。
    • 返回值:LongParam 对象,表示随机种子。
  • featuresCol:获取特征列名的参数。

    • featuresCol: Param[String]
    • 获取特征列名的参数。
    • 返回值:Param[String] 对象,表示特征列名。
  • maxIter:获取最大迭代次数的参数。

    • maxIter: IntParam
    • 获取最大迭代次数的参数。必须大于等于 0。
    • 返回值:IntParam 对象,表示最大迭代次数。
  • uid:获取对象的唯一 ID。

    • uid: String
    • 获取对象及其派生对象的不可变唯一 ID。
    • 返回值:String,表示对象的唯一 ID。
  • copy:创建一个具有相同 UID 和额外参数的当前实例的副本。

    • copy(extra: ParamMap): KMeans
    • 创建当前实例的副本,并带有相同的 UID 和额外的参数。
    • 参数:
      • extra:ParamMap 对象,用于指定额外的参数。
    • 返回值:KMeans 对象的副本。
  • fit:将模型应用于输入数据,拟合出一个模型。

    • fit(dataset: Dataset[_]): KMeansModel
    • 将模型应用于输入数据,并拟合出一个 KMeansModel 模型。
    • 参数:
      • dataset:要拟合的输入数据集。
    • 返回值:KMeansModel 对象,表示拟合得到的 KMeans 模型。
  • transformSchema:检查转换的有效性,并根据输入模式推导出输出模式。

    • transformSchema(schema: StructType): StructType
    • 检查转换的有效性,并根据输入模式推导出输出模式。
    • 参数:
      • schema:输入数据的模式。
    • 返回值:StructType 对象,表示输出数据的模式。

中文源码

object KMeans

/**
 * 用于调用K-means聚类的顶层方法。
 */
@Since("0.8.0")
object KMeans {
   
   

  // 初始化模式名称
  @Since("0.8.0")
  val RANDOM = "随机"
  @Since("0.8.0")
  val K_MEANS_PARALLEL = "k-means||"

  /**
   * 使用给定的参数训练一个K-means模型。
   *
   * @param data 训练数据点,作为`Vector`类型的RDD。
   * @param k 要创建的簇的数量。
   * @param maxIterations 允许的最大迭代次数。
   * @param initializationMode 初始化算法。可以是"random"或"k-means||"。(默认值:"k-means||")
   * @param seed 随机种子用于簇初始化。默认是基于系统时间生成种子。
   */
  @Since("2.1.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int,
      initializationMode: String,
      seed: Long): KMeansModel = {
   
   
    new KMeans().setK(k)
      .setMaxIterations(maxIterations)
      .setInitializationMode(initializationMode)
      .setSeed(seed)
      .run(data)
  }

  /**
   * 使用给定的参数训练一个K-means模型。
   *
   * @param data 训练数据点,作为`Vector`类型的RDD。
   * @param k 要创建的簇的数量。
   * @param maxIterations 允许的最大迭代次数。
   * @param initializationMode 初始化算法。可以是"random"或"k-means||"。(默认值:"k-means||")
   */
  @Since("2.1.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int,
      initializationMode: String): KMeansModel = {
   
   
    new KMeans().setK(k)
      .setMaxIterations(maxIterations)
      .setInitializationMode(initializationMode)
      .run(data)
  }

  /**
   * 使用给定的参数训练一个K-means模型。
   *
   * @param data 训练数据点,作为`Vector`类型的RDD。
   * @param k 要创建的簇的数量。
   * @param maxIterations 允许的最大迭代次数。
   * @param runs 从Spark 2.0.0开始,此参数不起作用。
   * @param initializationMode 初始化算法。可以是"random"或"k-means||"。(默认值:"k-means||")
   * @param seed 随机种子用于簇初始化。默认是基于系统时间生成种子。
   */
  @Since("1.3.0")
  @deprecated("使用不带'runs'参数的train方法", "2.1.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int,
      runs: Int,
      initializationMode: String,
      seed: Long): KMeansModel = {
   
   
    new KMeans().setK(k)
      .setMaxIterations(maxIterations)
      .setInitializationMode(initializationMode)
      .setSeed(seed)
      .run(data)
  }

  /**
   * 使用给定的参数训练一个K-means模型。
   *
   * @param data 训练数据点,作为`Vector`类型的RDD。
   * @param k 要创建的簇的数量。
   * @param maxIterations 允许的最大迭代次数。
   * @param runs 从Spark 2.0.0开始,此参数不起作用。
   * @param initializationMode 初始化算法。可以是"random"或"k-means||"。(默认值:"k-means||")
   */
  @Since("0.8.0")
  @deprecated("使用不带'runs'参数的train方法", "2.1.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int,
      runs: Int,
      initializationMode: String): KMeansModel = {
   
   
    new KMeans().setK(k)
      .setMaxIterations(maxIterations)
      .setInitializationMode(initializationMode)
      .run(data)
  }

  /**
   * 使用指定的参数和未指定参数的默认值训练一个K-means模型。
   */
  @Since("0.8.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int): KMeansModel = {
   
   
    new KMeans().setK(k)
      .setMaxIterations(maxIterations)
      .run(data)
  }

  /**
   * 使用指定的参数和未指定参数的默认值训练一个K-means模型。
   */
  @Since("0.8.0")
  @deprecated("使用不带'runs'参数的train方法", "2.1.0")
  def train(
      data: RDD[Vector],
      k: Int,
      maxIterations: Int,
    
K-Means及Spark实现Kmeans算法 K-means 步骤 关键步骤 聚类个数K的选择 初始聚类中心点的选择 MLlib的K-means实现 参数 Spark_K-Means_PythonK-means步骤 选择K个点作为初始聚类中心 计算其余所有点到聚类中心的距离,并把每个点划分到离它最近的聚类中心所在的聚类中去。计算距离常用欧几里得距离公式,也叫欧氏距离。查看距离的计算方法 重新计算每个聚类中所有点的平均值,并将其作为新的聚类中心点 阅读详情

相关推荐

Spark实现K-means

Q:无监督学习和有监督学习定义和区别 A:有监督学习:提供数据并提供数据对应结果的机器学习过程。追要包括分类和回归。 无监督学习:提供数据但是不提供数据对应结果的机器学习过程。主要应用在统计学中的密度估计和聚类分析。 Q:K-means的聚类过程 A: step1:首先选择k个类别的中心点 step2:对任意一个样本,求其到各类中心的距离,将该样本归到距离最短的中心所在的类 step3:聚好类后,重新计算每个聚类的中心点位置 step4:重复2,3步骤迭代,直到k个类中心点的位置不变,或者达到一定的迭代次数

xiaozhaoshigedasb的博客 721

Spark 聚类算法 ---- kmeans 简介,源码分析

文章大纲KMeans 算法简介 KMeans 算法简介 KMeans 算法的基本思想是初始随机给定K 个簇中心,按照最近邻原则把待分类样本点分到各个簇。然后按平均法重新计算各个簇的质心,从而确定新的簇心。一直迭代,直到簇心的移动距离小于某个给定的值。 KMeans 聚类算法主要分为3个步骤: 第一步,是为 ...

shiter编写程序的艺术 897

Spark实现K-Means算法代码示例

K-Means算法是一种基于距离的聚类算法,采用迭代的方法,计算出K个聚类中心,把若干个点聚成K类。 MLlib实现K-Means算法的原理是,运行多个K-Means算法,每个称为run,返回最好的那个聚类的类簇中心。初始的类簇中心,可以是随机的,也可以是KMean||得来的,迭代达到一定的次数,或者所有run都收敛时,算法就结束。 用Spark实现K-Means算法,首先修改pom文件,引入机器学习MLlib包: <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-mllib_2.10</

Crossbar RRAM技术解析:从1TnR架构到存储革命

非易失性存储器(NVM)是数据存储的核心技术,其原理基于物理状态的稳定改变以实现数据持久化。阻变存储器(RRAM)作为一种新兴NVM,利用导电细丝在介质层中的形成与断裂实现数据存储,具有高速、低功耗和结构简单的优势。在工程实践中,RRAM面临潜行路径电流等挑战,而Crossbar提出的1TnR架构通过引入共享晶体管有效解决了这一问题,在保证性能的同时提升了集成密度。该技术与CMOS工艺兼容,支持后端集成与多层堆叠,为高密度存储和嵌入式应用提供了新的解决方案。结合当前行业对高能效、高密度存储的需求,RRAM在

weixin_42523104的博客 320

用python提取PDF中各类文本内容的方法

用python提取PDF中各类文本内容的方法

安静的软件工程师 6086

10.2 在新能源、储能及电网节点的应用实践

构网型变流器技术在电力系统中的应用进展 构网型变流器技术正从理论研究走向规模化工程应用,为新能源并网提供主动支撑能力。该技术在光伏电站采用"部分构网"混合架构,由构网单元实现黑启动和弱网稳定;在风电场利用叶轮动能提供惯量响应。储能系统是理想的构网载体,可提供快速调频和动态电压支撑。在电网节点,构网型STATCOM可增强弱电网电压稳定性,大容量变流器可替代传统调相机。当前面临标准滞后、宽频振荡风险等共性挑战,需在可靠性、经济性间取得平衡。系统级协调控制和精确阻抗建模是应用成功的关键。

技术工作者 1110

第一章 初识SpringBoot

提供大量的自动配置Spring和第三方库,开发者可以根据项目需求选择相关的starters依赖,而无需手动配置大量的Spring配置文件,开箱即用,无需配置XML,无代码生成。Spring Boot与Spring Cloud等框架集成,为构建微服务提供了强大的支持,并通过Spring Cloud实现服务注册、负载均衡、熔断等功能。本质上讲,Spring Boot就是Spring,它做了那些本应我们去做的Spring Bean配置等工作。以上就是一个简单的Spring Boot应用的创建和运行过程。

Calvin的博客 1581

ADS负载牵引仿真避坑指南:从零开始搞定Loadpull模板设置

本文是一份针对ADS负载牵引仿真的深度避坑指南,详细解析了Loadpull模板从初始化配置到结果解读的全过程。文章重点阐述了如何根据设计目标灵活设置扫描圆、采样点等关键参数,以解决仿真不收敛、结果不完整等常见问题,并指导读者在功率与效率之间做出理性权衡,最终提取出用于匹配网络设计的最优负载阻抗。

weixin_29234423的博客 597

AgentScope Java 2.0 项目实战:从零构建企业级自主Coding Agent

本文基于 AgentScope Java 框架,完整拆解两个生产级 AI Agent 项目的从零开发全过程。其一是企业级自主编码机器人(agentscope-codingagent),支持 Issue→PR 自动实现、PR Code Review、Docker 沙箱隔离执行与多通道接入;其二是个人 AI 助手管理平台(agentscope-paw),采用 Spring Boot + React 全栈架构,支持多 Agent、技能市场与多 IM 通道。

program哲学 838

Happycapy深度解析:AI智能体的“iPhone时刻“来了?

从理论到实践深度解析了融合OpenClaw和ClaudeCode优点的超强智能体工具Happycapy

program哲学 457

Allegro如何进行四层板板层设计

板层的设计

weixin_42499230的博客 3189

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: 【Java原理系列】 scala JavaConverters原理用法示例源码详解
下一篇: Spark LogicalPlan源码分析
BigDataMLApplication
博客等级 码龄11年 7363粉丝 565原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值