【Python机器学习】无监督学习——K-均值聚类算法

news2024/9/23 21:31:33

聚类是一种无监督的学习,它将相似的对象归到同一簇中,它有点像全自动分类。聚类方法几乎可以应用于所有的对象,簇内的对象越相似,聚类的效果越好。

K-均值聚类算法就是一种典型的聚类算法,之所以称之为K-均值是因为它可以发现k个不同的簇,且每个簇的中心采用簇中所含值的均值计算而成。

簇识别给出聚类结果的含义,假定有一些数据,现在将相似数据归到一起,簇识别会告诉我们这些簇到底都是些什么。聚类与分类的最大不同在于,分类的目标事先已知,而聚类则不同。因为其产生的结果与分类相同,而只是类别没有预先定义,聚类有时也被称为无监督分类

聚类分析试图将相似对象归入同一簇,将不相似对象归到不同簇。相似这一概念取决于所选择的相似度计算方法。

K-均值聚类的优缺点:

优点:容易实现

缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢

适用数据类型:数值型数据。

K-均值是发现给定数据集的k个簇的算法。簇个数k是用户给定的,每一个簇通过其质心,即簇中所有点的中心描述。

K-均值算法的工作流程是这样的:首先,随机确定k个初始点作为质心;然后将数据集中的每个点分配到一个簇中,具体来讲,为每个点找距其最近的质心,并将其分配给该质心所对应的簇;这一步完成之后,每个簇的质心更新为该簇所有点的平均值。

上述过程的伪代码表示如下:

创建k个点作为起始质心(经常是随机选择)

当任意一个点的簇分配结果发生改变时:

    对数据集中的每个数据点:

        对每个质心:

            计算质心与数据点之间的距离

        将数据点分配到距其最近的簇

    对每一个簇,计算簇中所有点的均值并将均值作为质心

K-均值聚类的一般流程:

1、收集数据:使用任意方法

2、准备数据:需要数值型数据来计算距离,也可以将标称型数据映射为二值型数据再用于距离计算

3、分析数据:使用任意方法

4、训练算法:不适用于无监督学习,即无监督学习没有训练过程

5、测试算法:应用聚类算法,观察结果。可以使用量化的误差指标,如误差平方和来评价算法的结果

6、使用算法:可以用于所希望的任何应用。通常情况下,簇质心可以代表整个簇的数据来做出决策。

“最近”质心意味着需要进行某种距离计算。数据集上K-均值算法的性能会受到所选距离计算方法的影响。

K-均值聚类支持函数的实现:

from numpy import *

def loadDataSet(fileName):
    dataMat=[]
    fr=open(fileName)
    for line in fr.readlines():
        curLine=line.strip().split('\t')
        fltLine=list(map(float,curLine))
        dataMat.append(fltLine)
    return dataMat

def distEclud(vecA,vecB):
    return sqrt(sum(power(vecA-vecB,2)))

def randCent(dataSet,k):
    n=shape(dataSet)[1]
    centroids=mat(zeros((k,n)))
    for j in range(n):
        minJ=min(dataSet[:,j])
        rangeJ=float(max(dataSet[:,j])-minJ)
        centroids[:,j]=minJ+rangeJ*random.rand(k,1)
    return centroids

上述代码中包含了几个K-均值算法中要用到的辅助函数。

loadDataSet()将文本文件导入到一个列表中,文本文件每一行为tab分隔的浮点数。每一个列表会被添加到dataMat中,最后返回dataMat,该返回值是一个包含许多其他列表的列表。这种格式可以很容易将很多只封装到矩阵中。

distEclud()计算两个向量的欧式距离。

randCent()为给定数据集构建一个包含k个随机质心的集合。随机质心必须要在整个数据集的边界之内,这可以通过找到数据集每一维的最小和最大值来完成。然后生成0到1.0之间的随机数并通过取值范围和最小值,以便确保随机点在数据的边界之内。

运行效果:

dataMat=mat(loadDataSet('test/testSet.txt'))
print(min(dataMat[:,0]))
print(min(dataMat[:,1]))
print(max(dataMat[:,0]))
print(max(dataMat[:,1]))
print(randCent(dataMat,2))
print(distEclud(dataMat[0],dataMat[1]))

下面实现完整的K-均值算法,该算法会创建k个质心,然后将每个点分配到最近的质心,再重新计算质心。这个过程重复多次,直到数据点的簇分配结果不再改变为止:

def kMeans(dataSet,k,distMeas=distEclud,createCent=randCent):
    m=shape(dataSet)[0]
    clusterAssment=mat(zeros((m,2)))
    centroids=createCent(dataSet,k)
    clusterChanges=True
    while clusterChanges:
        clusterChanges=False
        for i in range(m):
            minDist=inf
            minIndex=-1
            for j in range(k):
                distJI=distMeas(centroids[j,:],dataSet[i,:])
                if distJI<minDist:
                    minDist=distJI
                    minIndex=j
            if clusterAssment[i,0]!=minIndex:
                clusterChanges=True
            clusterAssment[i,:]=minIndex,minDist**2
        print(centroids)
        for cent in range(k):
            ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
            centroids[cent,:]=mean(ptsInClust,axis=0)
    return centroids,clusterAssment

kMeans()函数接受4个输入参数。只有数据集及簇的数目是必选参数,而用来计算距离和创建初始质心的函数都是可选的。kMeans()函数一开始确定数据集中数据点的总数,然后创建一个矩阵来存储每个点的分配结果。簇分配结果矩阵clusterAssment包含两列:一列记录簇索引值,第二列存储误差。这里的误差指的是当前点到簇质心的距离。

按照计算质心-分配-重新计算的方式反复迭代,直到所有数据点的簇分配结果不再改变为止。程序中创建了一个标志变量clusterChanges,如果该值为True,则继续迭代。上述迭代使用while循环来实现。接下来遍历所有数据找到距离每个点最近的质心,这可以通过对每个点遍历所有质心并计算点到每个质心的距离来完成。计算距离是使用distMeas参数给出的距离函数,默认距离函数是distEclud()。如果任一点的簇分配结果发生改变,则更新clusterChanges标志。

最后,遍历所有质心并更新它们的取值。具体实现步骤:首先通过数组过滤来获得给定簇的所有点;然后计算所有点的均值,选项axis=0表示沿矩阵的列方向计算均值计算;最后,程序返回所有的类质心与点的分配结果。

运行效果:

dataMat=mat(loadDataSet('test/testSet.txt'))
myCentroids,clustAssing=kMeans(dataMat,4)
print('质心:',myCentroids)
print('分配结果:',clustAssing)

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

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

相关文章

【qt】QMainWindow下实现一个记事本

之前我们学过QWidget&#xff0c;QMainWindow会在ui界面多一个菜单 先实现ui界面 1.添加文本编辑&#xff0c;实现可以写多行 2.将文本编辑放大&#xff0c;拖动即可 3.编辑菜单栏 4.然后我们要实现对应子列表的功能&#xff0c;但是在这里不能转到槽&#xff0c;所以我们…

【Vue3】Pinia store 组合式写法

【Vue3】Pinia store 组合式写法 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗…

Java EE基础知识点

前言&#x1f440;~ 上一章我们介绍了性能测试工具LoadRunner&#xff0c;今天开启新的篇章Java EE进阶相关的内容 框架 Maven 项目构建 依赖管理 依赖传递 依赖排除 Maven概念 Maven仓库 Maven 设置国内源 创建Spring Boot项目 Web服务器 如果各位对文章的内容感兴…

Flutter 3.24 对普通开发者有哪些影响?

哈喽&#xff0c;我是老刘 Flutter 3.24刚刚发布了。突然觉得时间过得好快。六年前刚开始使用Flutter 1.0的场景还在眼前。 随着Flutter团队老成员的回归和新成员的加入。 前段时间Flutter团队裁员的影响似乎也逐步消退了。 新版本发布的功能逐步回到了该有的状态。 这里盘点…

解决域名加别名后再代理或者映射到fastadmin项目

如果遇到微应用不想再添加或者不方便添加单独的二级域名时&#xff0c;就需要用到代理或者映射来进入到我们的微应用项目中。 可以修改route.php路由文件的下面这个参数 __alias__ > [别名 > 模块/控制器] 如图 然后再修改config.php文件里面的view_replace_str参数…

C++入门基础知识11

C 关键字 下表列出了 C 中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。 &#xff01;&#xff01;&#xff01;完整关键字介绍 &#xff08;下一篇博文中将详细罗列介绍&#xff09;

内网穿透:打破网络边界的神奇钥匙

在数字化时代&#xff0c;我们每天都在使用各种网络设备&#xff0c;但你是否曾想过&#xff0c;家里的智能摄像头、私人服务器或是游戏主机&#xff0c;如何能够在远离家的地方也能轻松访问&#xff1f; 这就需要涉及到内网穿透技术了。今天&#xff0c;我们就用简单的例子来揭…

coze 工作流使用

什么是工作流 工作流就是将一系列的逻辑节点串起来的流程&#xff0c;例如我们做一个爬虫&#xff0c;第一步先爬取网页内容&#xff0c;第二步数据清洗&#xff0c;得到我们想要的数据&#xff0c;第三步存到数据库。这里每步就是一个逻辑节点&#xff0c;她们之间有先后或是…

如何用不到一分钟的时间将Excel电子表格转换为应用程序

我们大多数人对电子表格又爱又恨。当企业需要分析数据、为决策过程提供信息并可视化信息时&#xff0c;Excel和Google Sheets是首选。这些文档非常容易创建&#xff0c;它们帮助我们以直接的方式构建相关的想法和适用的数据。除此之外&#xff0c;事情可能会变得一团糟。 对于…

服务注册中心--Eureka

一.Eureka概述 Eureka是一个基于REST的服务&#xff0c;主要用于AWS(Amazon Web Services 亚马逊云计算服务)云中的定位服务&#xff0c;以实现中间层服务器的负载平衡和故障转移在 Spring Cloud 微服务架构中通常用作注册中心, 我们称这个服务为 Eureka Server&#xff0c;还…

springboot学生作业管理系统---附源码14916

摘 要 在信息化社会中&#xff0c;人们需要针对性的信息获取途径。然而&#xff0c;由于不同角度和偏好的存在&#xff0c;人们经常只能获得特定类型的信息&#xff0c;这也是技术攻克难题之一。为了解决学生作业管理系统等问题&#xff0c;本研究通过分析和研究&#xff0c;设…

汽车免拆诊断案例 | 2011 款进口现代新胜达车智能钥匙系统有时失效

故障现象  一辆2011款进口现代新胜达车&#xff0c;搭载G4KE发动机&#xff0c;累计行驶里程约为26.3万km。车主进厂反映&#xff0c;有时进入车内按下起动按钮&#xff0c;发动机无法起动&#xff0c;且组合仪表黑屏。 故障诊断  接车后试车&#xff0c;车辆使用一切正常。…

Windows创建定时任务触发bat脚本 实现oracle数据库备份

Windows中的计划任务程序来触发oracle数据库备份脚本 任务计划程序 创建基本任务 填写名称、描述&#xff0c;下一步 触发任务&#xff1a;填写定时周期 操作&#xff1a;启动程序&#xff0c;选择要执行的bat脚本 点击完成&#xff0c;就能在任务列表中查看到我们刚才创…

【Linux】MySQL安装教程

Linux中MySQL安装教程 Step1&#xff1a;卸载系统自带的mysqlStep2&#xff1a;下载mysql8安装包Step3&#xff1a;上传mysql压缩包到 /opt 然后解压Step4&#xff1a;解压后按照如下顺序安装Step5&#xff1a;对mysql进行初始化Step6&#xff1a;修改mysql安装目录的所有用户和…

算法的学习笔记—在 O(1) 时间内删除链表节点

&#x1f600;前言 在链表操作中&#xff0c;删除节点是一个常见的操作。然而&#xff0c;如何在最短的时间内完成删除节点的操作是一个值得探讨的问题。通常情况下&#xff0c;删除链表节点需要遍历链表来找到目标节点及其前驱节点&#xff0c;时间复杂度为 O(N)。但是&#x…

【Pyspark-驯化】一文搞懂Pyspark中对json数据处理使用技巧:get_json_object

【Pyspark-驯化】一文搞懂Pyspark中对json数据处理使用技巧&#xff1a;get_json_object 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; …

stm32入门学习13-时钟RTC

&#xff08;一&#xff09;时钟RTC stm32内部集成了一个秒计数器RTC&#xff0c;用于显示我们日常的时间&#xff0c;如日期年月日&#xff0c;时分秒等&#xff0c;RTC的主要原理就是进行每秒自增&#xff0c;如果我们知道开始记秒的开始时间&#xff0c;就可以计算现在的日…

Redis操作--RedisTemplate(二)StringRedisTemplate

一、介绍 1、简介 由于存储在 Redis 中的 key 和 value 通常是很常见的 String 类型&#xff0c;Redis模块提供了 RedisConnection 和 RedisTemplate 的扩展&#xff0c;分是 StringRedisConnection 和 StringRedisTemplate&#xff0c;作为字符串操作的解决方案。 通过源码…

JVM二:JVM类加载机制

目录 前言 1.什么是类加载? 2.类加载整体流程 3.一个类什么时候被加载? 4.双亲委派模型 4.1 JVM默认提供了三个类加载器 4.1.1 BootstrapClassLoader 4.1.2 ExtensionClassLoader 4.1.3 ApplicationClassLoader 4.2 破坏双亲委派模型 前言 在上一篇文章中&#xf…

江科大/江协科技 STM32学习笔记P21

文章目录 ADC模数转换器ADC简介逐次逼近型ADCSTM32的ADCADC基本结构输入通道转换模式单次转换&#xff0c;非扫描模式连续转换&#xff0c;非扫描模式单次转换&#xff0c;扫描模式连续转换&#xff0c;扫描模式 触发控制数据对齐转换时间校准硬件电路电位器产生可调电压的电路…