机器学习实战笔记8(kmeans)

2023-11-13

       前面的7次笔记介绍的都是分类问题,本次开始介绍聚类问题。分类和聚类的区别在于前者属于监督学习算法,已知样本的标签;后者属于无监督的学习,不知道样本的标签。下面我们来讲解最常用的kmeans算法。

1:kmeans算法

       算法过程:Kmeans中文称为k-均值,步骤为:(1)它事先选定k个聚类中心,(2)然后看每个样本点距离那个聚类中心最近,则该样本就属于该聚类中心。(3)求每个聚类中心的样本的均值来替换该聚类中心(更新聚类中心)。(4)不断迭代(2)和(3), 直到收敛。

       复杂度:Kmeans算法的时间复杂度为O(m*n*k*d),其中m为样本的个数,n为维数,k为迭代的次数,d为聚类中心的个数。空间复杂度为O(m*n)。

       Costfunction: kmeans聚类是使得SSE(sum of squared error)达到最小,SSE公式表示为:

由于SSE为非凸函数,因此每次聚类并不一定能使SSE达到全局最小值,只能使其达到局部最优解。但是可以重复执行几次kmeans,选取SSE最小的一次作为最终的聚类结果。


2:python代码的实现  

from numpy import *
#加载数据
def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float, curLine)    #变成float类型
        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])
        maxJ = max(dataSet[:,j])
        rangeJ = float(maxJ - minJ)
        centroids[:,j] = minJ + rangeJ * random.rand(k, 1)
    return centroids

#k-means 聚类算法
def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent):
    m = shape(dataSet)[0]
    clusterAssment = mat(zeros((m,2)))    #用于存放该样本属于哪类及质心距离
    centroids = createCent(dataSet, k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False;
        for i in range(m):
            minDist = inf; minIndex = -1;
            for j in range(k):
                distJI = distMeans(centroids[j,:], dataSet[i,:])
                if distJI < minDist:
                    minDist = distJI; minIndex = j
            if clusterAssment[i,0] != minIndex: clusterChanged = True;
            clusterAssment[i,:] = minIndex,minDist**2
        print centroids
        for cent in range(k):
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]]   # 去第一列等于cent的所有列
            centroids[cent,:] = mean(ptsInClust, axis = 0)
    return centroids, clusterAssment



注意:度量聚类效果的指标是SSE(Sum of Squared Error, 误差平方和),即属于同一聚类中心的所有样本点到该聚类中心的距离和。通常有以下两种后处理的方法来提高算法的聚类性能。

(1)   将具有最大SSE值的簇划分成两个簇。

(2)   合并最近的质心或者合并两个使得SSE增幅最小的质心。

3:二分k-均值算法

为了克服k-均值算法收敛于局部最小值的问题,有人提出了另外一种称为二分k-均值的算法。该算法首先将所有点作为一个簇,然后将该簇一分为二。之后选择其中一个簇继续进行划分,选择哪一个簇进行划分有两种方法。(1)该划分是否可以最大程度地降低SSE的值。(2)选择SSE最大的簇进行划分。划分过程不断重复,直到簇的数目达到用户指定数目为止。

#2分kMeans算法    #两种方法:(1)是否可以最大程度的降低SSE的值   (2)选择SSE最大的簇进行划分
def bitKmeans(dataSet, k, distMeas=distEclud):
    m = shape(dataSet)[0]
    clusterAssment = mat(zeros((m,2)))
    centroid0 = mean(dataSet, axis=0).tolist()[0]
    centList =[centroid0] 
    for j in range(m):
        clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2
    while (len(centList) < k):
        lowestSSE = inf             #无穷大
        for i in range(len(centList)):
            ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:]
            centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas)
            sseSplit = sum(splitClustAss[:,1])
            sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])
            print "sseSplit, and notSplit: ",sseSplit,sseNotSplit
            if (sseSplit + sseNotSplit) < lowestSSE:
                bestCentToSplit = i
                bestNewCents = centroidMat
                bestClustAss = splitClustAss.copy()
                lowestSSE = sseSplit + sseNotSplit
        bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList)          #二分后标签更新
        bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit
        print 'the bestCentToSplit is: ',bestCentToSplit
        print 'the len of bestClustAss is: ', len(bestClustAss)
        centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]           #加入聚类中心
        centList.append(bestNewCents[1,:].tolist()[0])
        clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss      #更新SSE的值(sum of squared errors)
    return mat(centList), clusterAssment


此外:还有层次聚类算法和密度聚类算法

层次聚类算法有两种,一种是凝聚的聚类算法,另外一种是层次的聚类算法


密度聚类算法用的比较少,这里不做详细讲解

DBSCAN是一个比较有代表性的密度聚类算法。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习实战笔记8(kmeans) 的相关文章

随机推荐

  • IDEA打不开(找不到)RunDashBoard问题

    我的IDEA版本是2022版 最近学习微服务发现打不开RunDashBoard 可能是更改了名称叫做Services 点击下方的Services 再点击加号 选择Run Configuration Type 之后选择springboot 就
  • vulnhub靶机Me-and-My-Girlfriend-1打靶记录

    准备环境 kali linux ip 172 16 10 149 Me and My Girlfriend 1 虚拟机n 渗透工具 kali虚拟机 nmap 端口扫描工具 pker后台扫描工具 谷歌xff伪造插件 X Forwarded F
  • 基于SpringBoot+微信小程序的失物招领小程序

    基于SpringBoot 微信小程序的失物招领小程序 全网粉丝20W csdn特邀作者 博客专家 CSDN新星计划导师 java领域优质创作者 博客之星 掘金 华为云 阿里云 InfoQ等平台优质作者 专注于Java技术领域和毕业项目实战
  • uiautomator2实例

    from pytestreport import TestRunner import uiautomator2 as u2 import email import os import smtplib import random import
  • 以太坊燃烧第一个24小时,中文社区在关心什么?

    8月5日 在区块高度 12965000 北京时间8月5日20 33 备受瞩目的以太坊伦敦升级完成 伦敦升级涉及众多提案 其中最令人关注的是EIP 1559 该提案引入销毁机制 让链上费用更合理 同时也一定程度缓解了以太坊的通胀 截至8月6日
  • JDK Self-Extracting Installation for Linux (64-bit)

    http www oracle com technetwork java javase install linux 64 self extracting 142068 html JDK Documentation System Requir
  • nodejs剪切视频,提取音频,上传播放

    简单说说实现方案 首先要有演唱会的链接 使用ibili 这个库下载视频 也可以自己抓取视频链接请求下载 这里有很多方法 将视频保存在本地后 整理出每一首歌曲对应的时分秒 我找的这个视频在某站评论中已经有人整理过了 所以我用 ibili 这个
  • netty在xxl-job中的使用分析

    xxl job版本 2 3 0 netty版本 netty all 4 1 63 final 一 基于spring容器 客户端启动流程 客户端如springboot应用引入xxl core的jar包后 启动springboot过程中会调用x
  • Mysql8.0 安装手册(linux)

    目录 添加Mysql的 yum 仓库 安装mysql 开启远程访问 添加Mysql的 yum 仓库 访问 https dev mysql com downloads repo yum 下载 yum 源 点击 download 复制下载链接使
  • 00.JavaScript基础

    0o 参考资料 js https codeofli github io 2019 11 js note javaScript javaScript vue https codeofli github io 2019 11 js note v
  • @ConfigurationProperties灵活的映射配置信息

    介绍 在用 ConfigurationProperties最常用的功能是用此注解对类进行修饰 设置好prefix前缀 这样在springboot的配置文件中 配置信息的key和value就会对应的配置到类中的属性上 以设置eureka信息为
  • nas挂载windows_【群晖系统】群晖下直接挂载WINDOWS的NTFS格式硬盘

    群晖的硬盘格式是EXT4 相对于WINDOWS下的NTFS格式 大家较不熟悉 在数据管理 使用 恢复等都不如NTFS方便 如果群晖能支持NTFS格式就好了 相信每一位装黑群晖的朋友当时都会有这样的想法 其实 群晖是支持外部设备的NTFS格式
  • c++实现引用计数

    概述 当有指针指向同一块内存空间时 计数器加1 没增加一个指向该内存空间的指针 计数器加1 同理 当原本指向该内存空间的指针指向另一块内存 计数器减1 被指向的另一个内存的计数器加1 下面是一个引用计数的一种实现 示例 直接上代码 总共分为
  • uni-app项目中如何使用scss less

    前言 由于公司业务调整 特意学习下uni项目框架 其实根据官方api就是实现很多功能 其实都是一些小坑要走 下面来说一下uni项目中如何使用scss vue编写中我们可以直接使用下面这样方法 多方便
  • Eclispse中Run on Server窗口让选择Server,但已经存在的选择不了

    对于这种问题 通常是因为版本不匹配造成的 jdk版本 Dynamic Web Modules版本 只要改到相应版本就好了 jdk7 时Dynamic Web Modules应设为2 5 如果无法修改 可以新建一个工程 在新建工程时选择Dyn
  • 记忆深处有尘埃——Memory Compiler

    Memory是大家Floorplan中经常使用到一个器件 而且需要花费不少时间去摆放它 Memory的种类很多 各种类型还分别具有不同的参数 那大家有没有想过 对一个设计来说 我们是如何去选择合适的memory类型 不同的类型有什么区别 在
  • 作为一名程序员,如何开展自己的副业?月赚三万的真实故事

    作为一名程序员 除了敲代码之外还应该有一些副业 我们都是程序员 大多数都是普通人 都在替别人打工 虽然收入在别人眼中挺高 但是连个首付都付不起 这时 首先得要发展副业 与其拿着死工资 还不如做些啥 今天 我所说的不是教大家如何去挣很多钱 而
  • mavon-editor 页面回显使用turndown将HTML转为markdown

    1 安装npm install turndown npm install turndown 2页面使用 v model markdowntext
  • 后端接口返回近万条数据,前端渲染缓慢,content Download 时间长的优化方案

    前言 性能优化 是前端绕过不去的一道门槛 甚是重要 最近一年 也很少有机会在项目中进行前端性能优化 一直在忙于业务开发 最近终于是来了机会 遇到了这样的场景 心里也甚是激动 写个随笔记录下性能优化的过程及逻辑 有需要的可以参考下 场景 后端
  • 机器学习实战笔记8(kmeans)

    前面的7次笔记介绍的都是分类问题 本次开始介绍聚类问题 分类和聚类的区别在于前者属于监督学习算法 已知样本的标签 后者属于无监督的学习 不知道样本的标签 下面我们来讲解最常用的kmeans算法 1 kmeans算法 算法过程 Kmeans中