聚类算法(2)--- ISODATA算法

       本篇文章是博主在人工智能等领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在AI学习笔记

      AI学习笔记(8)---聚类算法(2)--- ISODATA算法》

聚类算法(2)--- ISODATA算法

目录

一、 ISODATA算法

1.1算法原理

1.2实验应用

二、 ISODATA算法python实现

2.1 算法流程

2.2 算法python程序

2.3 算法注意事项

三、 ISODATA算法实验结果

四、小结


一、 ISODATA算法

        ISODATA算法(Iterative Self-Organizing Data Analysis Technique Algorithm)是一种经典的聚类算法,结合了K-均值和层次聚类的特点。该算法通过动态调整簇的数量和簇的中心点,能够根据数据特点自适应地调整聚类情况。

其他聚类算法见:

聚类算法(1)---最大最小距离、C-均值算法

1.1算法原理

        SODATA算法采用迭代的方式动态地更新簇的数目和簇的中心,根据设定的参数来调整簇的数量以及样本点与簇之间的距离等。算法首先初始化聚类中心并对样本进行初步的分组,然后根据一定

1.2实验应用

        ISODATA算法在实际应用中有着广泛的应用,特别是在数据挖掘、图像处理和生物信息学等领域。例如在地理信息系统(GIS)领域,ISODATA算法可以用于空间数据的聚类分析,对地理位置数据进行聚类,以实现地理空间上的模式识别和区域划分。


二、 ISODATA算法python实现

        ISODATA(Iterative Self-Organizing Data Analysis Technique)算法是一种自组织数据分析技术,主要用于聚类分析。其算法流程如下:

2.1 算法流程

(1)初始化参数:选择初始的簇中心数量K、设定其他参数(如每个簇的最小样本数、簇内样本方差阈值等),并随机选择K个点作为初始的簇中心。

(2)分配样本:对于数据集中的每个样本点,计算它与各个簇中心的距离,并将其分配到距离最近的簇中。

(3)簇合并:检查每个簇的样本方差是否大于预设的阈值,如果是,则将该簇进行分裂,生成新的簇中心。

(4)簇分裂:重复执行步骤2和步骤3,直至满足终止条件(如簇中心不再发生大的变化、达到最大迭代次数等)。

(5)更新簇中心:根据当前的簇分配情况,重新计算每个簇中所有样本点的均值,以此更新簇中心的位置。

(6)重复迭代:重复执行步骤2至步骤5,直至满足终止条件(如簇中心不再发生大的变化、达到最大迭代次数等)。

(7)输出结果:得到K个簇,每个簇包含若干个样本点,完成聚类过程。

2.2 算法python程序

导入需要的python库

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import euclidean_distances
import copy

ISODATA聚类算法

class ISODATA():def __init__(self, designCenterNum, Nc, LeastSampleNum, StdThred, LeastCenterDist, L, iterationNum):#  指定预期的聚类数、初始聚类中心个数、每类的最小样本数、标准差阈值、最小中心距离、每次可合并的最多对数、迭代次数self.K = designCenterNumself.centerNum = Ncself.thetaN = LeastSampleNumself.thetaS = StdThredself.thetaC = LeastCenterDistself.L = Lself.iteration = iterationNumself.data = np.stack([[0, 0], [0, 1], [4, 4], [4, 5], [5, 4], [5, 5], [1, 0]], dtype=np.float64)self.label = np.stack([0, 0, 0, 0, 0, 0, 0])# 随机选取NC个初始聚类中心center_ind = np.random.choice(np.arange(len(self.data), dtype=np.int32), Nc, replace=False)self.center = np.stack([copy.deepcopy(self.data[center_ind[i], :]) for i in range(Nc)])self.centerMeanDist = 0# 更新def updateLabel(self):# 计算样本到中心的距离distance = euclidean_distances(self.data, self.center.reshape((self.centerNum, -1)))# 选出每个模式到各个中心的最小距离,并为样本重新分配标签self.label = np.argmin(distance, 1)for i in range(self.centerNum):# 找出同一类样本index = np.argwhere(self.label == i).squeeze()sameClassSample = self.data[index, :]# 更新中心if len(sameClassSample.shape) >= 2:self.center[i, :] = np.mean(sameClassSample, 0)# 计算所有类到各自中心的平均距离之和for i in range(self.centerNum):# 找出同一类样本index = np.argwhere(self.label == i).squeeze()sameClassSample = self.data[index, :]if len(sameClassSample.shape) < 2:sameClassSample = sameClassSample.reshape((1,-1))# 计算样本到中心距离的平均值distance = np.mean(euclidean_distances(sameClassSample, self.center[i, :].reshape((1, -1))))# 更新中心self.centerMeanDist += distanceself.centerMeanDist /= self.centerNumdef divide(self):# 临时保存更新后的中心集合,否则在删除和添加的过程中顺序会乱newCenterSet = self.center# 计算每个类的样本在每个维度的标准差for i in range(self.centerNum):# 找出同一类样本index = np.argwhere(self.label == i).squeeze()sameClassSample = self.data[index, :]# 计算样本到中心每个维度的标准差stdEachDim = np.mean((sameClassSample - self.center[i, :])**2, axis=0)if type(stdEachDim) is not np.ndarray:maxStd = stdEachDimsameClassSample = sameClassSample.reshape(1,-1)# 找出其中维度的最大标准差else:maxIndex = np.argmax(stdEachDim)maxStd = stdEachDim[maxIndex]# 计算样本到本类中心的距离distance = np.mean(euclidean_distances(sameClassSample, self.center[i, :].reshape((1, -1))))# 如果最大标准差超过了阈值if maxStd > self.thetaS:# 还需要该类的样本数大于于阈值很多 且 太分散才进行分裂if self.centerNum <= self.K//2 or \sameClassSample.shape[0] > 2 * (self.thetaN+1) and distance >= self.centerMeanDist:newCenterFirst = self.center[i, :].copy()newCenterSecond = self.center[i, :].copy()newCenterFirst[maxIndex] += 0.5 * maxStdnewCenterSecond[maxIndex] -= 0.5 * maxStd# 删除原始中心newCenterSet = np.delete(newCenterSet, i, axis=0)# 添加新中心newCenterSet = np.vstack((newCenterSet, newCenterFirst))newCenterSet = np.vstack((newCenterSet, newCenterSecond))else:continue# 更新中心集合self.center = newCenterSetself.centerNum = self.center.shape[0]def combine(self):# 临时保存更新后的中心集合,否则在删除和添加的过程中顺序会乱delIndexList = []# 计算中心之间的距离centerDist = euclidean_distances(self.center, self.center)centerDist += (np.eye(self.centerNum)) * 10**10# 把中心距离小于阈值的中心对找出来,每次和并数量少于L对for i in range(self.L):# 如果最小的中心距离都大于阈值的话,则不再进行合并minDist = np.min(centerDist)if minDist >= self.thetaC:break# 否则合并(两个中心距离太近合并)index = np.argmin(centerDist)row = index // self.centerNumcol = index % self.centerNum# 找出合并的两个类别index = np.argwhere(self.label == row)classNumFirst = len(index)index = np.argwhere(self.label == col)classNumSecond = len(index)newCenter = self.center[row, :] * (classNumFirst / (classNumFirst+ classNumSecond)) + \self.center[col, :] * (classNumSecond / (classNumFirst+ classNumSecond))# 记录被合并的中心delIndexList.append(row)delIndexList.append(col)# 增加合并后的中心self.center = np.vstack((self.center, newCenter))self.centerNum -= 1# 标记,以防下次选中centerDist[row, :] = float("inf")centerDist[col, :] = float("inf")centerDist[:, col] = float("inf")centerDist[:, row] = float("inf")# 更新中心self.center = np.delete(self.center, delIndexList, axis=0)self.centerNum = self.center.shape[0]def drawResult(self):color = ['r', 'b', 'g', 'c', 'm', 'y']ax = plt.gca()ax.clear()for i in range(self.centerNum):index = np.argwhere(self.label == i).squeeze()ax.scatter(self.data[index, 0], self.data[index, 1], c=color[i], label=f'Cluster { i}')ax.scatter(self.center[i,0], self.center[i,1], c=color[i], marker='x',label=f'Centroid { i}')# ax.set_aspect(1)# 坐标信息plt.title('ISODATA Clustering')plt.xlabel('X')plt.ylabel('Y')plt.legend()plt.show()def start(self):# 初始化中心和labelself.updateLabel()self.drawResult()# 到设定的次数自动退出for i in range(self.iteration):# 如果是偶数次迭代或者中心的数量太多,那么进行合并if self.centerNum < self.K //2:self.divide()# 偶数次迭代或者中心数大于预期的一半,进行合并elif (i > 0 and i % 2 == 0) or self.centerNum > 2 * self.K:self.combine()else:self.divide()# 更新中心self.updateLabel()print("中心数量:{}".format(self.centerNum))self.drawResult()

主函数

if __name__ == "__main__":isoData = ISODATA(designCenterNum=2, Nc=3, LeastSampleNum=1, StdThred=0.1, LeastCenterDist=2, L=3, iterationNum=5)isoData.start()

2.3 算法注意事项

        ISODATA算法相比于传统的K-means算法增加了簇合并和簇分裂的步骤,这使得算法能够动态地调整簇的数量和形状,适应数据的复杂性。在实际应用中,还可以根据具体情况对参数进行调整,以获得更好的聚类效果。


三、 ISODATA算法实验结果

相关参数设置:

参数类型

数值

预期的聚类数

2

初始聚类中心个数

3

每类的最小样本数

3

标准差阈值

0.1

最小中心距离

2

每次可合并的最多对数

3

迭代次数

5

(1)数据可视化聚类单步输出结果:

第一步                                                 第二步

第三步                                                 第四步

第五步 

        由多次实验结果可知,一般运行到五步以内即可达到聚类目的,合理设置相关参数可以达到满足聚类的要求。

(1)调整预期聚类数:

预期的聚类数=3时,

第一步运行结果                                 最终运行结果

预期的聚类数=5时,

第一步运行结果                                    最终运行结果

        由此实验可知,设置预期的聚类数为3或者5,聚类的最终结果分类为2类。后续经过多次其他预期的聚类数设置,得到结果聚类分类为2类,初步推算,预期聚类数的设置不影响最终聚类的结果。若修改其他参数,也可分析相应的实验输出结果。


四、小结

        ISODATA算法是基于C-均值算法的改进,增加了簇的合并和分裂机制,使其能够动态地调整簇的数量和形状,适应数据的复杂性。这使得ISODATA算法更适用于数据集具有复杂形状、密度不均匀、簇的数量变化较大的情况。然而,对于该算法来说,需要合理设置参数,并且算法复杂度较高,需要更多的计算资源和时间。

        通过合理选择算法、优化参数和评估结果,可以实现对提供的数据成功的进行聚类。在实际应用中,通常会根据具体情况综合考虑算法的优缺点,选择合适的算法,并不断优化参数,以获得满足实际需求的聚类效果。


     文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者私信联系作者。

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

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

相关文章

Vue02-第一个Vue程序

第一个Vue程序 1、什么是MVVM MVVM&#xff08;Model-View-ViewModel&#xff09;是一种软件设计模式&#xff0c;由微软WPF&#xff08;用于替代WinForm&#xff0c;以前就是用这个技术开发桌面应用程序的&#xff09;和Silverlight&#xff08;类似于Java Applet&#xff0…

新手(初学者)学R语言第一课,从学正确导入数据开始

初看题目好像我在教你怎么导入数据&#xff0c;不不不&#xff0c;我是在教你正确的导入数据&#xff0c;不是说数据导入R就叫正确导入数据了。本章为新手教程&#xff0c;老手可以跳过。 这个内容早就想写了&#xff0c;今天有点空和大家聊一下。为什么R语言对于新手而言不太友…

nginx启动之后任务管理器里面没有nginx进程

原因1&#xff1a;确保你的nginx文件夹里面只包含英文路径&#xff01;绝对不能有中文&#xff01; 原因2&#xff1a; 到conf\nginx.conf里面查看端口和IP地址是否正确设置&#xff0c;ip地址有无正确输入

【MATLAB】(高数)

参考文章 函数极限 导数与偏导 极值和最值 局部范围的最值 局部范围内的最值&#xff0c;相当于函数的极值 离散数据的最值 多元函数的极值 fminunc [x, fval] fminunc(fun, x0)fun为代求极值的函数&#xff1b;x0为起始点&#xff0c;即从这个点开始寻找极值&#xff0c;…

4、MFC:菜单栏、工具栏与状态栏

菜单栏、工具栏与状态栏 1、菜单栏1.1 简介1.2 创建属性设置菜单消息成员函数 1.3 实例 2、工具栏2.1 简介工具栏属性2.2 创建消息CToolBar类的主要成员函数 2.3 实例 3、状态栏3.1 简介3.2 创建CStatusBar类状态栏创建 3.3 实例 1、菜单栏 1.1 简介 菜单在界面设计中是经常使…

渗透测试-若依框架的杀猪交易所系统管理后台

前言 这次是带着摸鱼的情况下简单的写一篇文章&#xff0c;由于我喜欢探究黑灰产业&#xff0c;所以偶尔机遇下找到了一个加密H币的交易所S猪盘&#xff0c;我记得印象是上年的时候就打过这一个同样的站&#xff0c;然后我是通过指纹查找其它的一些站&#xff0c;那个站已经关…

海外短剧系统如何征服观众心

海外短剧系统要征服观众的心&#xff0c;需要综合考虑多个方面。 1、紧凑的剧情设计&#xff1a; 短小精悍&#xff1a;海外短剧通常每集时长不超过半小时&#xff0c;甚至有的仅有几分钟。这种紧凑的剧情设计让观众能够在短时间内迅速沉浸在故事中&#xff0c;无需花费大量时间…

STM32驱动-ads1112

汇总一系列AD/DA的驱动程序 ads1112.c #include "ads1112.h" #include "common.h"void AD5726_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE );//PORTA、D时钟使能 G…

大脑临界状态:探索思维背后的物理机制

在深度思考或创造性灵感的涌现时刻&#xff0c;个体常体验到一种介于混乱与有序之间的特殊心理状态。这种感受实则反映了大脑在认知过程中的临界状态&#xff0c;这是一种涉及复杂物理现象的心理活动表现。近期研究表明&#xff0c;大脑结构中存在着与临界性密切相关的物理特性…

为什么挂牌量是跟踪楼市情况的核心指标?

通过挂牌量&#xff0c;可以跟踪被动卖出者的数量&#xff0c;从而理解楼市的进展。 引子 楼市的“5.17”新政落地有一个多月了&#xff0c;然而&#xff0c;资本市场对“楼市的复苏预期”却在不断地下修。 以房地产开发的龙头企业保利发展为例&#xff0c;市场在“5.17”新…

学习笔记——路由网络基础——动态路由

五、动态路由 1、动态路由概述 动态路由&#xff1a;通过在设备上运行某种协议&#xff0c;通过该协议自动交互路由信息的过程。 动态路由协议有自己的路由算法&#xff0c;能够自动适应网络拓扑的变化&#xff0c;适用于具有一定数量三“层设备的网络。 动态路由协议适用场…

Python发送Email的性能怎么样?如何配置?

Python发送Email怎么配置SMTP&#xff1f;批发邮件的方法技巧&#xff1f; Python是一种广泛使用的编程语言&#xff0c;因其简洁和强大的功能深受开发者喜爱。在许多应用场景中&#xff0c;Python发送Email是一个常见需求。那么&#xff0c;Python发送Email的性能怎么样呢&am…

基于Java的农机电招平台系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果你对农机电招平台系统感兴趣或有相关开发需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 B/S结构&#xff0c;SpringBoot框架 工具 Eclipse&#xff0c;Navicat&#xff0c;Tomcat8.0 系…

代理的匿名级别有哪些?为什么匿名性很重要?

在互联网时代&#xff0c;代理服务器在许多领域都扮演着重要的角色。无论是个人用户还是企业&#xff0c;都可能需要使用代理来保护自己的隐私和数据安全。在选择代理服务时&#xff0c;匿名级别是一个重要的考虑因素。本文将介绍代理的匿名级别&#xff0c;并解释为什么匿名性…

华为RH2288 V3安装 Linux 系统,安装过程心得

带着U盘&#xff0c;怀着激动的心情进入机房安装操作系统&#xff0c;结果没有显示器和键盘鼠标&#xff0c;傻眼了。 作为过来人&#xff0c;温馨提醒&#xff0c;进入机房前记得先打听&#xff0c;准备好这些&#xff1a;机房房间号、机柜编号、物理机编号、键盘、鼠标、显示…

ShareX,屏幕截图、屏幕录制和文件共享,还提供了丰富的高级功能和自定义选项

ShareX是一个免费开源的Windows应用程序&#xff0c;用于屏幕截图、屏幕录制和文件共享。它不仅支持基本的屏幕截图功能&#xff0c;还提供了丰富的高级功能和自定义选项&#xff0c;使其成为提高工作效率和截图体验的利器。以下是ShareX v16.1.0便携版的主要功能和特色&#x…

别再滥用std::async了,strace命令暴露了一个乱开线程问题

用strace查看进程的系统调用后&#xff0c;发现一个std::async滥用问题 问题现象 进程的系统调用clone次数持续增加 使用工具strace发现进程clone系统调用过多且一直在增加 strace -c -p PID问题分析 clone在做什么&#xff1a;创建进程&#xff08;线程&#xff09; 查看…

【吊打面试官系列-Mysql面试题】什么是存储过程?用什么来调用?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是存储过程&#xff1f;用什么来调用&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是存储过程&#xff1f;用什么来调用&#xff1f; 答&#xff1a;存储过程是一个预编译的 SQL 语句&#xff0c;优点是…

昇思25天学习打卡营第4天|数据变换(Transforms)

一、简介&#xff1a; 数据变换是指将已有的数据转换成可以提供给模型直接训练和验证的数据格式&#xff0c;在深度学习中一般被称为数据预处理&#xff0c;之前在昇思25天学习打卡营第3天|数据集Dataset-CSDN博客 介绍数据集的时候已经有了一个简单的使用&#xff0c;下面将具…

docker 基本用法及跨平台使用

一、Docker的优点 docker 主要解决的问题就是程序开发过程中编译和部署中遇到的环境配置的问题。 1.1 Docker与其他虚拟机层次结构的区别** 运行程序重点关注点在于环境。 VM虚拟机是基于Hypervisor虚拟化服务运行的。 Docker是基于内核的虚拟化技术实现的。 1.2 Docker的技…