C#,无监督的K-Medoid聚类算法(K-Medoid Algorithm)与源代码

1 K-Medoid算法

K-Medoid(也称为围绕Medoid的划分)算法是由Kaufman和Rousseeuw于1987年提出的。中间点可以定义为簇中的点,其与簇中所有其他点的相似度最小。

K-medoids聚类是一种无监督的聚类算法,它对未标记数据中的对象进行聚类。

在本文中,我们将了解什么是K-medoids聚类?为什么我们需要它?首先,得出第二个问题的答案:我们需要它,因为K-means聚类有一些缺点,即在这方面,具有极大值的对象可能会严重扭曲对象在簇/组中的分布。因此,它对异常值很敏感。它通过K-medoids聚类(也称为K-means聚类的临时版本)来解决。


在K-medoids聚类中,我们将medoid作为参考点,而不是像K-means聚类那样将簇中对象的质心作为参考点。中间体是群集中位置最集中的对象,或其与所有对象的平均相异性最小。因此,K-medoids算法比K-means算法对噪声更具鲁棒性。

2 K-medoids聚类有三种算法:

PAM(围绕medoid分区)

CLARA(群集大型应用程序)

CLARANS(“随机化”克拉拉)。

在这些PAM中,PAM被认为是最强大的,并被广泛使用。然而,PAM有一个缺点,因为它的时间复杂性(我们将在后面讨论)。因此,在本文中,我们将详细了解PAM算法。

算法

现在我们来看看k-medoids算法内部的情况,如下所示:

步骤1:在给定的数据空间D中初始化k个集群。

步骤2:从数据中的n个对象中随机选择k个对象,并将k个对象分配给k个簇,这样每个对象都被分配给一个且仅一个簇。因此,它成为每个集群的初始中间层。


步骤3:对于所有剩余的非medoid对象,计算所有medoid的成本(通过欧几里德、曼哈顿或切比雪夫方法计算的距离)。

步骤4:现在,将每个剩余的非中间层对象指定给该簇,该簇的中间层到该对象的距离与其他簇的中间层相比是最小的。

步骤5:计算总成本,即,它是所有非medoid对象与其群集medoid之间距离的总和,并将其分配给dj。

第六步:随机选择一个非中间体对象i。

步骤7:现在,暂时将对象i与medoid j交换,然后重复步骤5以重新计算总成本并将其分配给di。

步骤8:如果di<dj,则将步骤7中的临时交换永久化,以形成新的k medoid集。否则撤消步骤7中完成的临时交换。

步骤9:重复步骤4、步骤5、步骤6、步骤7、步骤8。直到没有变化;

3 PAM、CLARA、CLARANS之间的差异

3.1 PAM

与k-means算法相比,它有效地处理了数据中存在的噪声和异常值;因为它使用medoid将对象划分为簇,而不是k-means中的质心。

因为它对整体数据执行聚类,而不是仅对数据集中选定的样本执行聚类。因此,对于大型数据集,它不能有效地工作。

PAM的计算成本很高,因为它在整个数据集上执行集群。

其每次迭代的时间复杂度为O(k*(n-k)^2);其中n是数据中对象的数量,k是簇的数量。

3.2 CLARA

在CLARA中,它首先从数据集中选择数据样本,对这些样本应用PAM,然后从这些样本中输出最佳聚类。

因为它通过从数据中选择样本来应用聚类,所以它处理的是较大的数据集。

随着样本量的增加,其有效性也会增加,反之亦然。

假设它绘制了多个较小的样本,并在其上进行了良好的聚类。如果所选样本有偏差,则不能很好地对总体数据进行聚类。

3.3 CLARANS

在每一步中,它都会选择一个邻居样本进行检查。因此,它不会将搜索限制在特定区域。它给出了基于总体数据的结果。

现在,因为它在每一步都会检查邻居。因此,当集群和对象数量很大时,这很耗时。

在CLARANS中,有一个参数表示局部最优值的数量。就像找到了局部最优值一样,它再次开始随机选取一个节点来找到新的局部最优值。要限制此过程,请在启动时指定上述参数。

因为,它的时间复杂度是O(n^2)。因此,它是其他k-medoids算法中最有效的算法;返回更高质量的群集。

3.4 K-medoids算法的优点

与其他分割算法相比,它有效地处理了数据中存在的噪声和异常值;因为它使用medoid将对象划分为集群。

易于实现且易于理解。

与其他分割算法相比,K-Medoid算法速度相对较快。

它以固定的迭代次数输出最终的对象簇。

3.5 K-medoids算法的缺点

对于同一数据集上的不同运行,可能会产生不同的聚类,因为最初,我们从所有数据对象中随机选择k个medoid,并将它们逐个分配给每个聚类,使其成为该聚类的初始medoid。

它在开始时固定了k(簇/组的数量)的值,因此我们不知道k的值是多少,结果是准确和可区分的。

它的总体计算时间和对象在簇或组中的最终分布取决于初始划分。

因为在这里,我们根据对象与质心的最小距离(而不是k-means中的质心)将对象分布在簇中。因此,在任意形状的聚类中对数据进行聚类是没有用的。

源程序

using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public class K_Medoids{public static List<Crows> Pam(List<Indivaduls> indivadulses, List<Indivaduls> centerPoints){List<Crows> firstCrows = K_medoids(indivadulses, centerPoints);List<Indivaduls> resultCenterPoints = new List<Indivaduls>();for (int i = 0; i < firstCrows.Count; i++){resultCenterPoints.Add(firstCrows[i].CenterPoint);List<Crows> oldOtherCrows = new List<Crows>();oldOtherCrows.AddRange(firstCrows);oldOtherCrows.RemoveAt(i);double oldDiff = AbsoluteDiff(firstCrows[i], oldOtherCrows);int count = firstCrows[i].CrowsPoint.Count;for (int j = 0; j < count; j++){List<Indivaduls> newCenterPoints = new List<Indivaduls>();newCenterPoints.AddRange(centerPoints);newCenterPoints.RemoveAt(i);newCenterPoints.Add(firstCrows[i].CrowsPoint[j]);List<Indivaduls> newOtherCrowsCenterPoints = new List<Indivaduls>();newOtherCrowsCenterPoints.AddRange(centerPoints);newOtherCrowsCenterPoints.RemoveAt(i);List<Crows> newCrows = K_medoids(indivadulses, newCenterPoints);List<Crows> newOtherCrows = new List<Crows>();Crows newCrow = new Crows();foreach (Crows crow in newCrows){if (newOtherCrowsCenterPoints.MyContains(crow.CenterPoint)){newOtherCrows.Add(crow);}else{newCrow = crow;}}double newDiff = AbsoluteDiff(newCrow, newOtherCrows);if (newDiff < oldDiff){resultCenterPoints[i] = newCrow.CenterPoint;oldDiff = newDiff;}}}List<Crows> resultCrows = K_medoids(indivadulses, resultCenterPoints);return resultCrows;}public static List<Crows> K_medoids(List<Indivaduls> indivadulses, List<Indivaduls> centerPoints){List<Crows> resultCrows = new List<Crows>();int indivadulsCount = indivadulses.Count;for (var i = 0; i < centerPoints.Count; i++){resultCrows.Add(new Crows() { CenterPoint = centerPoints[i] });}for (int i = 0; i < indivadulsCount; i++){if (!centerPoints.MyContains(indivadulses[i])){int myNumber = 0;double firstDic = P2PDistance(indivadulses[i], resultCrows[0].CenterPoint);//该点与第一个中心的距离for (int j = 1; j < resultCrows.Count; j++){double otherDic = P2PDistance(indivadulses[i], resultCrows[j].CenterPoint);if (otherDic < firstDic){firstDic = otherDic;myNumber = j;}}resultCrows[myNumber].CrowsPoint.Add(indivadulses[i]);}}return resultCrows;}public static double AbsoluteDiff(Crows centerCrow, List<Crows> otherPoints){int countCrows = otherPoints.Count;double distance = Distance(centerCrow);for (var i = 0; i < countCrows; i++){distance += Distance(otherPoints[i]);}return distance;}public static double Distance(Crows crow){int pointCount = crow.CrowsPoint.Count;double distance = 0.0;for (var i = 0; i < pointCount; i++){distance += P2PDistance(crow.CenterPoint, crow.CrowsPoint[i]);}return distance;}public static double P2PDistance(Indivaduls p1, Indivaduls p2){if (p1.Numbers.Count != p2.Numbers.Count || p1.Numbers.Count == 0){throw new Exception();}int dimension = p1.Numbers.Count;double result = 0.0;for (int i = 0; i < dimension; i++){result += (p1.Numbers[i] - p2.Numbers[i]) * (p1.Numbers[i] - p2.Numbers[i]);}return Math.Sqrt(result);}}public class Indivaduls{public List<double> Numbers { get; set; } = new List<double>();public Indivaduls(){}public bool MyEquals(Indivaduls obj){if (obj.Numbers.Count != Numbers.Count){return false;}for (int i = 0; i < Numbers.Count; i++){if (Numbers[i] != obj.Numbers[i]){return false;}}return true;}}public class Crows{public List<Indivaduls> CrowsPoint { get; set; } = new List<Indivaduls>();public Indivaduls CenterPoint { get; set; } = new Indivaduls();public Crows(){}}public static class ExpandList{public static bool MyContains(this List<Indivaduls> indivadulses, Indivaduls point){foreach (var indivadulse in indivadulses){if (point.MyEquals(indivadulse)){return true;}}return false;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/508524.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【DIY】超重低音耳机放大器的制作

这不是一款普通的耳机放大器&#xff0c;我在它前级加入低音提升电路后&#xff0c;可以让你使用耳机听到高保真的音响效果&#xff0c;特别是重低音效果&#xff0c;逼真感很强以至于用它听的时间长了会让人感到头晕&#xff0c;使用它必须得注意&#xff1a;你的耳机要能经得…

文心一言 VS 讯飞星火 VS chatgpt (207)-- 算法导论15.4 4题

四、说明如何只使用表 c 中 2*min(m&#xff0c;n) 个表项及O(1)的额外空间来计算LCS的长度。然后说明如何只用 min(m&#xff0c;n) 个表项及O(1)的额外空间完成相同的工作。要写代码的时候&#xff0c;请用go语言。 文心一言&#xff1a; 在只使用 2 * min(m, n) 个表项和 …

MySQL高可用性攻略:快速搭建MySQL主从复制集群 !

MySQL高可用性攻略&#xff1a;快速搭建MySQL主从复制集群 &#xff01; MySQL基础知识&#xff1a;介绍MySQL数据库的基本概念和常用命令&#xff0c;如何创建数据库、表、用户和权限管理等。 MySQL安装教程&#xff1a;Centos7 安装MySQL5.7.29详细安装手册 MySQL数据类型&…

页面布局与样式设计:从基础到进阶

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一. 基础布局技巧 1.使用CSS Grid布局设计网页布局 1.1 创建网格容器 1.2. 定义…

Unity 常用的4种灯光、制作镜子、灯光的调用修改数值、

创建灯光时&#xff0c;一般用4种&#xff1a;定向光、点光源、聚光、区域光、 定向光&#xff1a;太阳 点光源&#xff1a;灯泡 聚光灯&#xff1a;手电筒 区域光&#xff1a;烘焙-贴图 灯光选择已烘焙 需要先选择被烘焙的物体&#xff0c;然后再选择Contribute GI 等待进…

Spring框架精髓:带你手写IoC

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

Elasticsearch:如何创建搜索引擎

作者&#xff1a;Jessica Taylor 搜索引擎是生活中我们认为理所当然的事情之一。 每当我们寻找某些东西时&#xff0c;我们都会将一个单词或短语放入搜索引擎&#xff0c;就像魔术一样&#xff0c;它会为我们提供一个匹配结果列表。 现在可能感觉不那么神奇了&#xff0c;因为这…

将编译好的FFmpeg导入iOS项目使用(swift)

1. 将ffmpeg 拖入工程并添加search Paths路径 2.添加所需的framework和lib AudioToolbox.framework&#xff0c;CoreMedia.framework&#xff0c;libbz2&#xff0c;libbz&#xff0c;libiconv&#xff0c;VideoToolbox.framework 3.使用 在桥接header中引入头文件

rt thread stdio如何同时生成bin和hex

一、rt thread stdio默认生成bin文件&#xff1a; rt thread stdio 软件编译时&#xff0c;默认生成bin文件&#xff1b; 二、rt thread stdio如何同时生成bin和hex 右键单击-->项目-->属性-->C/C构建-->设置-->构建步骤-->(构建后步骤)命令&#xff1a; …

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+辗转相除法)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列&#xff0c;只记得其中 N N N 个整数。 现在给出这 N N N 个整数&#xff0c;小明想知道包含这 N N N 个整数的最短的等差数列有几项&#xff1f; 输…

Go-zero中分布式事务的实现(DTM分布式事务管理器,在一个APi中如何调用两个不同服务的rpc层,并保证两个不同服务之间的业务逻辑同时成功)

涉及到的相关技术 1.DTM分布式事务管理器,解决跨数据库、跨服务、跨语言栈更新数据的一致性问题。 2.SAGA事务模式,SAGA事务模式是DTM中常用的一种模式,简单易上手.(当然还有其它更多的事务模式,这里采用的SAGA只不过是其中一种较为简单的方法) 3.Go-zero框架,ETCD服务注册... …

14-RPC-自研微服务框架

RPC RPC 框架是分布式领域核心组件&#xff0c;也是微服务的基础。 RPC &#xff08;Remote Procedure Call&#xff09;全称是远程过程调用&#xff0c;相对于本地方法调用&#xff0c;在同一内存空间可以直接通过方法栈实现调用&#xff0c;远程调用则跨了不同的服务终端&a…