【Python与机器学习】5.K-Means聚类

2023-05-16

聚类(clustering)

什么是聚类

聚类属于无监督学习(unsupervised learning),即无类别标记。
是数据挖掘经典算法之一。
算法接收参数k;然后将样本点划分为k个聚类;同一聚类中的样本相似度较高;不同聚类中的样本相似度较小
也就是说它不能自动识别类的个数(因为k要提前指定),随机挑选初始点为中心点计算。

算法描述

聚类的算法思想就是以空间中k个样本点为中心进行聚类,对最靠近它们的样本点归类通过迭代的方法,逐步更新各聚类中心,直至达到最好的聚类效果。

具体的算法步骤如下:
1. 选择k个聚类的初始中心
随机取k个中心点
2. 在第n次迭代中,对任意一个样本点,求其到k个聚类中心的距离,将该样本点归类到距离最小的中心所在的聚类
就是算一下样本点到这k个中心点的距离,到哪个中心点的距离最小则属于这一类。
3. 利用均值等方法更新各类的中心值
即在第2此迭代的时候来算各类的均值,将新的值作为下一次迭代的中心点
4. 对所有的k个聚类中心,如果利用2,3步的迭代更新后,达到稳定,则迭代结束。

如下图,为一个2-means的例子。也就是k=2,把样本分成2类。
(a)原始数据
(b)随机取两个中心点
(c)计算每个点到这两个中心点的距离,蓝色的点表示到蓝色点近的那些样本,红色点表示到红色点距离近的那些样本。
(d)求蓝色类中的均值,作为新的蓝色类的中心点。求红色类中的均值,作为新的红色类的中心点。
(e)继续算这些点到新的中心点的距离。
(f)达到平衡状态,迭代结束,即聚好类。
也就是再继续迭代的时候,分类不再有变化即达到了平衡状态或者收敛状态,就迭代结束了。
这里写图片描述

优缺点

优点

速度快,简单

缺点

①最终结果和初始点的选择相关,容易陷入局部最优
②需要给定k值

用k-means对图像压缩

什么是图像压缩

我们知道每个像素包含的字节影响图像占用内存的大小,图中能够表示的颜色越多则意味着每个像素包含的字节越多。
这里写图片描述

因此图像压缩就是将一些相近的颜色用一种颜色来替代掉
所以只要用k-means把图片中的颜色分成几个类,然后用分好的这几个类代替她原来的颜色即可做到图像的压缩

用sklearn中的k-means进行图片压缩

从sklearn导入聚类包

from sklearn.cluster import KMeans

进行聚类

kmeans = KMeans(n_clusters=k, random_state=0)

训练模型

kmeans.fit(pixel_sample)

参数:
pixel_sample为训练的数据

找到每个样本对应的聚类中心

cluster_assignments = kmeans.predict(pixel_sample)

输出找到的k个聚类中心的值

kmeans.cluster_centers_

用k-means进行图片压缩的例子

①导入包

import numpy as np
import cv2
import matplotlib.pyplot as plt 

%matplotlib inline

②输入图片

original_img = cv2.imread('./images/ColorfulBird.jpg')
print('图像维度:', original_img.shape) #输出结果图像维度: (592, 900, 3),因为是RGB图所以有3个通道

cv2.imshow('original_img', original_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

③进行数据预处理,把图片表示成3列数据,分别为RGB三个通道上的像素值

height, width, depth = original_img.shape
# 将图像数据点平铺
# 每个数据点为一个3维的样本
pixel_sample = np.reshape(original_img, (height * width, depth))
#也就是把原来(592, 900, 3)形式的图片表示成592乘900行,3列的矩阵 
print('前10个像素点:')
print(pixel_sample[:10, :])
pixel_sample.shape #结果(532800, 3)

结果:
前10个像素点:
[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]
[2 2 2]
[2 2 2]
[2 2 2]
[2 2 2]
[2 2 2]]
④进行聚类

from sklearn.cluster import KMeans

# 压缩后图片包含的颜色个数,即为聚类的个数
k = 5
kmeans = KMeans(n_clusters=k, random_state=0) #指定k-means的k为5,random_state即每次取得的初始随机中心点为一样的
# 训练模型
kmeans.fit(pixel_sample)

# 找到每个3维像素点对应的聚类中心
cluster_assignments = kmeans.predict(pixel_sample)
kmeans.cluster_centers_ #输出找到的5个聚类中心的值
print(set(cluster_assignments)) # 每个样本聚类的结果是对应的聚类中心的 索引,结果是{0, 1, 2, 3, 4},也就是说0代表第1个中心值以此类推

kmeans.cluster_centers_结果:
array([[ 68.11107251, 89.03672639, 80.03241565],
[ 38.54080044, 66.45019455, 233.13219381],
[205.9955164 , 100.0450495 , 78.74751379],
[ 50.24563672, 26.83740713, 29.50156917],
[ 89.67301041, 204.39409162, 224.8703557 ]])
⑤ 输出压缩后的图片

在第四步已经通过k-means找到了5个中心值,接下来就用这五个颜色来表示其对应类中的其他颜色。这样就起到了压缩图片的作用。

compressed_img = np.zeros( (height, width, depth), dtype=np.uint8)

# 遍历每个像素点,找到聚类中心对应的像素值
pixel_count = 0
for i in range(height):
    for j in range(width):
        # 获取像素点的聚类中心的索引
        cluster_idx = cluster_assignments[pixel_count]

        # 获取聚类中心索引位置上的像素值
        cluster_value = cluster_centers[cluster_idx]

        # 赋值
        compressed_img[i][j] = cluster_value
        pixel_count += 1

cv2.imwrite('./images/compressed_image.jpg', compressed_img, [cv2.IMWRITE_JPEG_QUALITY, 50])# 特别注意的是如果直接输出压缩后的图片,因为OPenCV默认的输出为90,反而通过聚类后输出的图片占用的内存更大,我们需要把值的清晰度改成50

cv2.imshow('original_img', original_img)
cv2.imshow('compressed_img', compressed_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果对比
这里写图片描述

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

【Python与机器学习】5.K-Means聚类 的相关文章

  • 如何传递架构以从现有数据帧创建新数据帧?

    要将 schema 传递到 json 文件 我们这样做 from pyspark sql types import StructField StringType StructType IntegerType data schema Stru
  • 类的 IPython 表示

    我正在使用我创建的模块尝试 IPython 但它没有显示类对象的实际表示 相反 它显示类似的内容 TheClass module TheClass name I heavily在这个模块中使用元类 我有真正有意义的类表示 应该向用户显示 是
  • 如何在 Matplotlib 饼图周围绘制箭头以将每个标签指向圆圈中各自的部分?

    我一直在用 Matplotlib 绘制一些图表 我有一个饼图 想要在图表周围绘制箭头 使每个标签都指向图表 我有一个例子 这是我当前的代码 import matplotlib pyplot as plt plt rcParams font
  • 如何在 __init__ 中使用await设置类属性

    我如何定义一个类await在构造函数或类体中 例如我想要的 import asyncio some code class Foo object async def init self settings self settings setti
  • 使用主题交换运行多个 Celery 任务

    我正在用 Celery 替换一些自制代码 但很难复制当前的行为 我期望的行为如下 创建新用户时 应向tasks与交换user created路由键 该消息应该触发两个 Celery 任务 即send user activate email
  • python multiprocessing 设置生成进程等待

    是否可以生成一些进程并将生成进程设置为等待生成的进程完成 下面是我用过的一个例子 import multiprocessing import time import sys def daemon p multiprocessing curr
  • 在 Django Admin 中调整字段大小

    在管理上添加或编辑条目时 Django 倾向于填充水平空间 但在某些情况下 当编辑 8 个字符宽的日期字段或 6 或 8 个字符的 CharField 时 这确实是一种空间浪费 字符宽 然后编辑框最多可容纳 15 或 20 个字符 我如何告
  • 为什么 web2py 在启动时崩溃?

    我正在尝试让 web2py 在 Ubuntu 机器上运行 所有文档似乎都表明要在 nix 系统上运行它 您需要下载源代码并执行以下操作 蟒蛇 web2py py 我抓住了source http www web2py com examples
  • MongoEngine 查询具有以列表中指定的前缀开头的属性的对象的列表

    我需要在 Mongo 数据库中查询具有以列表中任何前缀开头的特定属性的元素 现在我有一段这样的代码 query mymodel terms term in query terms 并且这会匹配在列表 term 上有一个项目的对象 该列表中的
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • python的shutil.move()在linux上是原子的吗?

    我想知道python的shutil move在linux上是否是原子的 如果源文件和目标文件位于两个不同的分区上 行为是否不同 或者与它们存在于同一分区上时的行为相同吗 我更关心的是如果源文件和目标文件位于同一分区上 shutil move
  • 通过Python连接到Bigquery:ProjectId和DatasetId必须非空

    我编写了以下脚本来通过 SDK 将 Big Query 连接到 Python 如下所示 from google cloud import bigquery client bigquery Client project My First Pr
  • pandas - 包含时间序列数据的堆积条形图

    我正在尝试使用时间序列数据在 pandas 中创建堆积条形图 DATE TYPE VOL 0 2010 01 01 Heavy 932 612903 1 2010 01 01 Light 370 612903 2 2010 01 01 Me
  • Python GTK+ 画布

    我目前正在通过 PyGobject 学习 GTK 需要画布之类的东西 我已经搜索了文档 发现两个小部件似乎可以完成这项工作 GtkDrawingArea 和 GtkLayout 我需要一些基本函数 如 fillrect 或 drawline
  • 在 Google App Engine 中,如何避免创建具有相同属性的重复实体?

    我正在尝试添加一个事务 以避免创建具有相同属性的两个实体 在我的应用程序中 每次看到新的 Google 用户登录时 我都会创建一个新的播放器 当新的 Google 用户在几毫秒内进行多个 json 调用时 我当前的实现偶尔会创建重复的播放器
  • Spider 必须返回 Request、BaseItem、dict 或 None,已“设置”

    我正在尝试从以下位置下载所有产品的图像 我的蜘蛛看起来像 from shopclues items import ImgData import scrapy class multipleImages scrapy Spider name m
  • 在virtualenv中下载sqlite3

    我正在尝试使用命令创建应用程序python3 manage py startapp webapp但我收到一条错误消息 django core exceptions ImproperlyConfigured 加载时出错 pysqlite2 或
  • 如何在 Flask 中的视图函数/会话之间传递复杂对象

    我正在编写一个 Web 应用程序 当 且仅当 用户登录时 该应用程序从第三方服务器接收大量数据 这些数据被解析为自定义对象并存储在list 现在 用户在应用程序中使用这些数据 调用不同的视图 例如发送不同的请求 我不确定什么是最好的模式在视
  • pytest找不到模块[重复]

    这个问题在这里已经有答案了 我正在关注pytest 良好实践 https docs pytest org en latest explanation goodpractices html test discovery或者至少我认为我是 但是
  • python 对浮点数进行不正确的舍入

    gt gt gt a 0 3135 gt gt gt print 3f a 0 314 gt gt gt a 0 3125 gt gt gt print 3f a 0 312 gt gt gt 我期待 0 313 而不是 0 312 有没有

随机推荐

  • STM32F401 I2S(full duplex)全双工示例代码

    USER CODE BEGIN Header 64 file main c 64 brief Main program body This notice applies to any and all portions of this fil
  • 一、认识与学习Linux中的BASH 之 1.1 什么是bash

    1 1 什么是bash 1 1 1 什么是bash bash全称为The Bourne Again shell xff0c 是Bourne Shell的扩展 xff0c 是基于GUN构架发展出来的语言 xff0c 有很灵活和强大的编程接口
  • 阿里云ECS服务器环境搭建(1) —— ubuntu 16.04 图形界面的安装

    阿里云ECS服务器环境搭建 xff08 1 xff09 ubuntu 16 04 图形界面的安装 1 背景 在我们购买阿里云ECS服务器之后 xff0c 默认的系统环境是很干净的 xff0c 我购买的是ubuntu16 04 xff0c 远
  • Python+pandas+每天股票涨了多少

    第一步 xff1a 得到某支股票历年来的交易数据 方法见 xff1a https blog csdn net zwy 0309 article details 108217342 在此 xff0c 我使用以下脚本得到股票 xff08 代码
  • 2021-06-02

    在ROS中仿真模型中添加gps传感器 获取gps传感器模型包为自己的机器人添加gps传感器将gps之中的经度纬度坐标转化为自己地图中的坐标 1 获取gps传感器模型包 link http wiki ros org hector gazebo
  • Dockerfile如何编写(指令详解)

    本文个人博客地址 xff1a https www leafage top posts detail 21525V8AP Dockerfile Dockerfile 描述了组装镜像的步骤 xff0c 其中每条指令都是单独执行的 除了FROM指
  • 关于Home Lab的搭建——硬件选择篇(迷你主机)(一)

    关于Home Lab 这个名词出自哪里 xff0c 我也不清楚 不过 xff0c 可以这样来理解Home Lab xff0c Home Lab是一台作为实验使用的电脑 xff0c 试验的内容多数是关于计算机网络的搭建 系统安装 测试 xff
  • Adaboost基本二分类算法

    最早类型的Adaboost是由Yoav Freund和Robert E Schapire提出的 xff0c 一种用于二分类的boosting集成学习方法 也是李航 统计学习方法 中所介绍的Adaboost 它将一系列弱分类器的线性组合 xf
  • Springboot 项目金蝶中间件AAS-9.0启动报错 javax.persistence.Table.indexes()[Ljavax/persistence/Index 问题解决

    Springboot 项目金蝶中间件AAS 9 0启动报错 java lang NoSuchMethodError javax persistence Table indexes Ljavax persistence Index问题解决方法
  • CMakeLists配置(常用的)

    一 xff1a 最小组成 cmake 最小版本需求 cmake minimum required VERSION 2 8 project 名字 project MyEsp32AllCode 可执行文件生成 add executable PR
  • SLAM学习笔记(四)定位

    原创博客 xff1a http blog csdn net renshengrumenglibing viewmode 61 contents 机器人定位的目的是为了知道 自己在什么地方 xff0c 目前 xff0c 机器人定位的方法可以分
  • SLAM实习岗位面经

    一 地平线 一面主要是在问关于SLAM岗位的技术问题 xff0c 然后还问了一些比较简单的C 43 43 基础知识 其实总体而言 xff0c 面试的问题都比较基础 xff0c 比较考验SLAM基本功 xff0c 如果只知道一些SLAM皮毛的
  • Canal数据库监听

    1 什么是canal canal是用java开发的基于数据库增量日志解析 xff0c 提供增量数据订阅 amp 消费的中间件 目前 xff0c canal主要支持了MySQL的binlog解析 xff0c 解析完成后才利用canal cli
  • linux下安裝mitmproxy 详解傻瓜式文档

    前言 xff1a mitmproxy 就是用于 MITM 的 proxy xff0c MITM 即中间人攻击 xff08 Man in the middle attack xff09 用于中间人攻击的代理首先会向正常的代理一样转发请求 xf
  • ROS学习笔记(2)——ROS架构

    ROS学习笔记 xff08 2 xff09 ROS架构 0 学习来源1 ROS架构2 文件系统级2 1 工作空间 3 计算图级4 ROS开源社区级4 1 发行版 xff08 Distribution xff09 4 2 软件库 xff08
  • STM32_中断

    STM32 中断 一 介绍 1 1解释 打断CPU执行正常的程序 xff0c 转而处理紧急程序 xff0c 然后返回原暂停的程序继续运行 xff0c 就叫中断 1 2作用和意义 作用 xff1a 实时控制 xff1a 在确定时间内对相应事件
  • Oracle创建用户并授权

    很多时候 xff0c 我们不需要用系统原始的sys xff0c sysdba等系统账户 xff0c 需要创建个性化的用户并授权 xff0c 那就需要我们首先登录到dba账户 xff0c 然后通过dba账户进行用户创建并授权 1 用dba权限
  • 【Linux】vim 中批量添加注释

    本期主题 xff1a vim 中批量添加注释博客主页 xff1a 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限 xff0c 出现错误希望大家不吝赐 此文主要介绍两种方法 xff1a 方法一 xff1a 块选择模式
  • 对gazebo启动后黑屏或者没有模型的解决

    1 问题 卡在加载模型界面 xff1b 加载太慢或者黑屏 xff1a 报错信息如下 xff1a 图1 打开界面 xff1a 图2 2 解决办法 直接下载所有模型到用户的根目录下的 gazebo models 下 xff1a 方法1 xff1
  • 【Python与机器学习】5.K-Means聚类

    聚类 xff08 clustering xff09 什么是聚类 聚类属于无监督学习 xff08 unsupervised learning xff09 xff0c 即无类别标记 是数据挖掘经典算法之一 算法接收参数k xff1b 然后将样本