机器学习(12)--K-Means

news2024/11/25 1:04:25

目录

一、聚类

二、机器学习中的距离

三、sklearn中的聚类算法

四、KMeans簇内平方和和时间复杂度

五、sklearn中的KMeans

1、建立一个数据集

2、使用K-Means进行聚类操作

3、根据上面的模型绘散点图观察分类效果。

4、评估指标

4.1对于真实标签已知情况

4.2当真实标签未知时:轮廓系数

4.3当真实标签未知时的其他指标

六、使用K-Means进行压缩图片 

1、使用sklearn库自带的图片来压缩

2、将图片降维至二维

3、聚类

4、还原三维图片

5、采取随机选取64个数据来压缩进行对比

6、输出图片


一、聚类

        聚类算法又叫做“无监督分类”,其目的是将数据划分成有意义或有用的组(或簇)。组内的对象之间是相关的,不同组之间是不相关的,组内的相关性越大,组间差异性越大,聚类特征越好。 聚类的中心称为簇心,表达簇内样本点的距离均值(欧式距离)

二、机器学习中的距离

1、欧氏距离:计算欧式空间中两点之间的距离,即直线距离.

欧氏距离计算公式

d(x,y)=\sqrt{\sum_{i=1}^{n}(x_{i}-y_{i})^2}

2、曼哈顿距离:表明两个点在标准坐标系上的绝对轴距总和,就是离散的欧式空间。

曼哈顿距离计算公式: 

d(x,y)=\sum_{i=1}^{n}|x_{i}-y_{i}|

3、闵可夫斯基距离:是对多个距离度量公式的概括性表述,是一组距离的定义,当公式中参数p=1时,为曼哈顿距离,当p=2时为欧几里得距离。

闵可夫斯基距离计算公式:

d(x,y)=(\sum_{i=1}^{n}|x_{i}-y_{i}|^{p})^{\frac{1}{p}}

4、切比雪夫距离:L∞度量,是向量空间中的一种度量,表示两个点之间的距离定义是其各坐标数值差绝对值的最大值。可以参考国际象棋中王从一个位子移动至另一个位置可以有八个方向,距离均为1,而所有距离王的位置就是切比雪夫距离。

切比雪夫距离计算公式: 

d(x,y)=max(|x_i-y_i|)

5、余弦距离:也称余弦相似度,机器学习中常用这一概念来衡量样本向量之间的差异,先比于上面的距离度量,余弦距离更注重两个向量在方向上的差异。

余弦距离计算公式:

cos(x,y)=\frac{x\cdot y}{|x|\cdot |y|}=\frac{\sum_{i=1}^{n}x_{i}y_{i}}{\sqrt{\sum_{i=1}^{n}x_i^2}\sqrt{\sum_{i=1}^{n}y_i^2}}

三、sklearn中的聚类算法

        聚类算法在sklearn中有类和函数两种表示方式,下面是类有关的部分聚类算法。

含义
cluster.AffinityPropagation      执行亲和传播数据聚类        
cluster.AgglomerativeClustering       凝聚聚类
cluster.BirchBirch聚类
cluster.DBSCANDBSCAN聚类
cluster.FeatureAgglomeration凝聚特征
cluster.KMeansK均值聚类
cluster.MiniBatchKMeans小批量K均值聚类
cluster.MeanShift平坦核函数平均移位聚类
cluster.SpectralClustering光谱聚类

KMeans:

        聚类原则:以空间中k个点位中心进行聚类,对最靠近他们的对象进行归类,计算各簇中心的值为新的质心,并进行迭代更新,直至簇心位置不在改变,或达到最大迭代次数。

        优点:速度快,且实现简单

        缺点:对于混合度高的,非球状类簇聚类效果差。

                   容易陷入局部最优解,算法结果不稳定。

                   对于噪声或离群点较为敏感,难以区分噪声和离群点,导致聚类紧密程度降低。

DBSCAN:

        聚类原则:基于密度可达关系,聚类距离簇边界最近的点。

        优点:能够识别任意形状的样本,将具有足够密度的区域划分为簇。

        缺点:需要指定最少点个数。

光谱聚类

        聚类原则:从图论中衍生出来的算法,吧所有数据看做空间中的点,将这些点用边连接起来,距离较远的两个点的边权重值较低,而距离较近的两个点之间的边权重值较高。并通过对所有数据点组成的图进行切图,对切图后不同的子图间边权重和尽可能的第,而子图内的边权重和尽可能的高,从而达到聚类。

四、KMeans簇内平方和和时间复杂度

        KMeans使用的簇内平方和,是将一个数据集中所有簇的簇内平方和相加,又称total inertia。簇内平方和越小,聚类效果越好,但是由于这个评估指标没有边界,所以很难判断效果是否好。

KMeans有损失函数吗?

        inertia更像是KMeans的模型评估指标,而非损失函数。由于KMeans不去求解参数,所以模型的本质也没有在拟合数据,更像是在探索数据本身。

        KMeans的平均复杂度为O(k*n*T),其中k为输入的簇数,n为整个数据集的样本量,T为迭代次数。(相比于KNN的平均复杂度为O(n))。在最坏复杂度上可以达到O(n^{(k+2)/p}),可以看到KMeans算法的计算速度非常之慢,所以在KMeans聚类的参数选择时会将训练策略默认为k-means++,而不会选取random。

五、sklearn中的KMeans

1、建立一个数据集

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import sklearn.metrics as mt

x,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)   #建立一个500个样本的,特征数为2,4个簇的数据集
fig,ax1=plt.subplots(1)
color=["red",'pink',"orange","blue"]
for i in range(4):
    ax1.scatter(x[y==i,0],x[y==i,1],marker='o',s=8,c=color[i])        #使用不同颜色标注4个种类绘制散点图
plt.show()

2、使用K-Means进行聚类操作

        首先假设有三个簇,由于聚类K-Means算法需要指定簇数,所以需要去找寻最优的簇数。

from sklearn.cluster import KMeans
n_clusters=3                #先假设有3簇,进行统计聚类
cluster=KMeans(n_clusters=n_clusters,init='random',random_state=0).fit(x)
print(cluster.n_iter_)

cluster=KMeans(n_clusters=n_clusters,random_state=0).fit(x)     #init默认为kmeans++,迭代次数更少
print(cluster.n_iter_)      #输出迭代次数

#print(cluster.labels_)     #输出预测500个点聚类后的标签
pre=cluster.fit_predict(x)  #由于预测也是输出标签所以与上面输出一致
#print(pre)

           输出KMeans模型的三个质心和簇内平方和 。

centroid=cluster.cluster_centers_
print(centroid)   #质心
inertia=cluster.inertia_
print(inertia)    #输出簇内平方和

3、根据上面的模型绘散点图观察分类效果。

#画聚类训练后的图
y_pred=cluster.predict(x)
fig,ax1=plt.subplots(1)
color=["red",'pink',"orange","gray"]
for i in range(n_clusters):
    ax1.scatter(x[y_pred==i,0],x[y_pred==i,1],marker='o',s=8,c=color[i])
    ax1.scatter(centroid[i,0],centroid[i,1],marker='x',s=20,c='b')
plt.show()

        可以看到在分成3簇时,模型将中间两个靠的较近的分成了一个类,而距离较远的一组样本,可以很好地分成一个类。

4、评估指标

如何衡量聚类算法的效果?

        对于KMeans的目标是簇内差异小,簇外差异大,可以通过衡量簇内差异来衡量聚类效果。

Inertia簇内平方和,为什么不能作为评估指标?

        1、无界,不能进行比较

        2、容易受到特征数目的影响,数据维度过大,容易陷入维度诅咒,计算量爆炸

        3、容易收到超参数K的影响,即簇数影响,簇数越大Inertia会逐渐减小,趋于0

        4、Inertia对于数据分布必须满足凸分布,且数据各向同性,但现实中的数据可能存在细长簇,环形簇,不规则形状流形,在这种分布下表现不佳。

4.1对于真实标签已知情况

        y_pred就是指经过模型预测的标签,y_true就是真实标签,x是数据

模型评估指标说明
互信息分析

普通互信息分析

metrics.adjusted_mutual_info_score(y_pred,y_true)

取值在(0,1)之间,越接近1,聚类效果越好

调整互信息分析

metrics.mutual_info_score(y_pred,y_true)

标准化互信息分析

metrics.normalized_mutual_info_score(y_pred,y_true)

V-measure

同质性:是否每个簇仅包含单个类的样本

metrics.homogeneity_score(y_true,y_pred)

取值范围(0,1)之中,越接近1,聚类效果越好。

对样本分布没有假设,在任何分布都有不错表现

完整性:是否给定类的所有样本都分配给同一个簇中

metrics.completeness_score(y_true,y_pred)

同质性和完整性的调和平均,叫做V-measure

metrics.v_measure_score(labels_true,labels_pred)

三者一次性计算出来

metrics.homogeneity_completeness_v_measure(labels

_true,labels_pred)

调整兰德系数

调整兰德系数

metrics_adjusted_rand_score(y_true,y_pred)

取值在(-1,1)之间,负值象征着簇内的点差异巨大,甚至相互独立,正类的兰德系数比较优秀,越接近1越好。

对样本分布没有假设,在具有“折叠”形状的数据表现优秀。

4.2当真实标签未知时:轮廓系数

        在现实中的数据来说,基本都是没有真实标签的数据进行探索,所以完全依赖于评价簇内的稠密程度和簇间的离散程度来评估聚类的效果好坏。轮廓系数作为最常用的评价指标,轮廓系数中有两个参数a和b。

        a:样本与其自身所在的簇中其他样本的相似度为a,等于样本与同一簇中所有其他点之间的平均距离。

        b:样本与其他簇中的样本的相似度为b,等于样本与下一个最近的簇中所有点之间的平均距离。

轮廓系数计算公式:

s=\frac{b-a}{max(a,b)}

         轮廓系数范围为(-1,1),s值趋近1,表示与自己所在的簇中样本很相似,并且与其他簇中的样本不相似。s值越趋近-1,则表示样本点与簇外的样本更加相似。若s值接近0,则表示两个簇中的样本基本相似,两个簇应为一个簇。

print(mt.silhouette_score(x,y_pred))    #注意是x和y_pred,轮廓系数(对每一个样本进行计算轮廓系数)输出为平均数,为一个数
print(mt.silhouette_samples(x,y_pred))  #输出对每一个样本计算轮廓系数的值

         轮廓系数也有缺陷,在凸型类上表现会呈现虚高,在基于密度进行的聚类和DBSCAN获得的聚类结果,也会产生虚高。

4.3当真实标签未知时的其他指标

卡林斯基-哈拉巴斯指数

metrics.calinski_harabaz_score(x,y_pred)

戴维斯-布尔丁指数

metrics.davies_bouldin_score(x,y_pred)

权变矩阵

metrics.cluster.contingency_matrix(x,y_pred)

        卡林斯基-哈拉巴斯指数没有范围,越高越好,计算公式如下:

s(k)=\frac{Tr(B_{k})}{Tr(W_{k})}*\frac{N-k}{k-1}

        其中N为数据集中的样本量,k为簇数,Bk为组间离散矩阵,即不同簇间的协方差矩阵,Wk是簇内离散矩阵,即一个簇内数据的协方差矩阵,Tr为矩阵的迹。

        卡林斯基-哈拉巴斯指数,也会在凸型数据中产生虚高,但是时间要比轮廓系数快很多。

六、使用K-Means进行压缩图片 

1、使用sklearn库自带的图片来压缩

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans                      #聚类
from sklearn.metrics import pairwise_distances_argmin   #对两个序列中的点进行距离匹配的函数
from sklearn.datasets import load_sample_image          #导入图片数据所用的类
from sklearn.utils import shuffle                       #打乱为什么要用sklearn啊

china=load_sample_image('china.jpg')        #数据集中有china和flower两个图片
print(china.dtype)                          #uint8图片类型
print(china.shape)                          #(427,640,3)
newimage=china.reshape((427*640,3))
import pandas as pd
print(pd.DataFrame(newimage).drop_duplicates().shape)   #减少重复,可以看到有9w多个像素构成图片

2、将图片降维至二维

        由于KMeans输入只有两个参数,所以将图片的长宽参数糅合为一维,保留颜色的维度

n_cluster=64
china = np.array(china,dtype=np.float64)/china.max()   #归一化到0-1
w,h,d = original_shape = tuple(china.shape)    #这种等号!!!
assert d==3                                    #防止d维度被改变,可以立即暂停
image_array = np.reshape(china,(w*h,d))        #reshape到二维
print(image_array.shape)   #(273280,3)

3、聚类

        随机取出1000个数据来训练模型,用局部的结果来作为全部训练的结果,减少时间消耗,但一定是要花费一定的聚类效果的。

image_array_sample=shuffle(image_array,random_state=0)[:1000]     #取出1000个来进行kmeans计算质心,生成64个质心
kmeans=KMeans(n_clusters=n_cluster,random_state=0).fit(image_array_sample)   #kmeans
print(kmeans.cluster_centers_)                                    #输出质心

4、还原三维图片

labels=kmeans.predict(image_array)                           #用1000个点训练好的64簇的模型预测27w个点,输出labels为0-63的索引
print(labels.shape)

image_kmeans=image_array.copy()
for i in range(w*h):
    image_kmeans[i]=kmeans.cluster_centers_[labels[i]]       #将这27w个点中的上一行映射的索引,转换为这64个簇所对应的值

image_kmeans = image_kmeans.reshape(w,h,d)                   #reshape回到3个维度

5、采取随机选取64个数据来压缩进行对比

#使用随机质心进行降维
centroid_random=shuffle(image_array,random_state=0)[:n_cluster]             #随机找64个质心
labels_random=pairwise_distances_argmin(centroid_random,image_array,axis=0)
print(labels_random)         #生成随机方式生成的不同数据与64个标签的映射关系

image_random=image_array.copy()
for i in range(w*h):
    image_random[i]=centroid_random[labels_random[i]]

image_random=image_random.reshape(w,h,d)

6、输出图片

#画出原图,随机质心,kmeans三个图
plt.figure(figsize=(10,10))
plt.axis('off')
plt.title('original image')
plt.imshow(china)
plt.savefig('origin.png')

plt.figure(figsize=(10,10))
plt.axis('off')
plt.title('k-means,64 colors')
plt.imshow(image_kmeans)
plt.savefig('k-means.png')

plt.figure(figsize=(10,10))
plt.axis('off')
plt.title('random,64 colors')
plt.imshow(image_random)
plt.savefig('random.png')

plt.show()

        通过聚类算法压缩图片后,相比于随机选取数据进行压缩,图片颜色上影响不会特别大。

参考视频:【sklearn机器学习】菜菜的sklearn机器学习完整版(中)_哔哩哔哩_bilibili

参考书籍:《机器学习》周志华

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

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

相关文章

[RocketMQ] Broker 消息重放服务源码解析 (十三)

构建消息文件ConsumeQueue和IndexFile。 ConsumeQueue: 看作是CommitLog的消息偏移量索引文件, 存储了它所属Topic的消息在Commit Log中的偏移量。消费者拉取消息的时候, 可以从Consume Queue中快速的根据偏移量定位消息在Commit Log中的位置。IndexFile索引文件: 看作是Commi…

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】 1、概述2、实验环境3、问题描述:bash:xxx:command not found问题4、我的努力第一种方式:加入指令方式第二种方式:使用echo $PATH命令查…

设计模式(七)-----桥接模式(Bridge Pattern)

目录 什么是桥接模式优点缺点应用场景 基本结构业务场景不使用模式的解决方案实现发送普通消息实现发送加急消息实现发送特急消息添加发送手机消息的处理方式 使用桥梁模式来解决问题 什么是桥接模式 将抽象部分与他的实现部分分离,这样抽象化与实现化解耦,使他们可以独立的变…

Es直方图聚合--date_histogram

文章目录 1、背景2、bucket_key如何计算3、前置知识4、日历和固定时间间隔 4.1 Calendar intervals 日历间隔4.2 Fixed intervals 固定间隔 5、数据准备 5.1 准备mapping5.2 准备数据 6、聚合案例 6.1 dsl6.2 java代码6.3 聚合结果 7、完整代码8、参考文档 1、背景 此处来简单学…

云计算UPS监控,怎么办?

在大型数据机房中,UPS系统扮演着关键的角色,为计算机和网络设备提供可靠的电力备份。由于数据机房的规模庞大且关键性强,监控UPS系统的可靠性和效率至关重要。 UPS监控可以提供实时的电池状态、负载信息、电网电压等监测数据,并能…

c++中assert

参考:https://blog.csdn.net/bitcarmanlee/article/details/124283683 1.什么是assert assert,中文翻译为断言,注意是一个宏定义,不是函数。 c中,要使用assert,可以将cassert头文件include进来,而cassert最…

路径规划算法:基于孔雀优化的路径规划算法- 附代码

路径规划算法:基于孔雀优化的路径规划算法- 附代码 文章目录 路径规划算法:基于孔雀优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法孔雀…

【HCIA】09.STP

STP的选举之发波原理 设备启动之后,经过选举会分别显示出它们的等级(最强,次强,最弱)选出等级之后,两两设备开始互相发波,等级强的设备会将弱的设备的光顶回去此时两两设备之间的波就是单方向的…

家政服务小程序软件解决方案

家政服务小程序软件是近年来随着人们对家政服务需求的增长而逐渐兴起的一种数字化服务解决方案。通过小程序软件,用户可以轻松预约家政服务,包括保姆、月嫂、钟点工等,而且价格透明、服务规范,大大提高了用户对家政服务的满意度。…

神经网络结构可视化-netron

网址:https://netron.app/ 点选择模型,将oonx文件拉到netron界面,即可 输出; 如何将pytorch模型转换为onnx的格式? 在测试(训练好的模型)里输入代码 to_onnx(model, 3, 28, 28, output/params.onnx)其…

【Linux】十分钟理解动静态库

目录 一 前置概念二 静态库2.12.22.3放入指定路径2.4 第三方库的使用 四 动态库3.1 环境变量3.2 软链接方案3.3 配置文件方案 一 前置概念 我们在VS2022下安装开发环境实际上就是安装编译器软件、安装要开发的语言配套的库和头文件。我们使用编译器有语法的自动提醒功能&#…

python常用库之colorama (python命令行界面打印怎么加颜色)

文章目录 python常用库之colorama (python命令行界面打印怎么加颜色)背景colorama介绍colorama使用colorama打印红色闪烁打印颜色组合 python常用库之colorama (python命令行界面打印怎么加颜色) 背景 在Python开发项目过程中,为了方便调试代码,经常会…

Java中Map中10w条数据用什么循环性能最好呢?

加油,新时代打工人! 1、java中List集合三种获取集合元素方式 2、Java中Map使用增强for循环和迭代器获取key和value 选择合适的循环方式,让性能最优! public class Test2 {public static void main(String[] args) {//初始化 10w…

vue upload 上传下载

目录 上传 下载 对象/文件流 download处理返回 文件流 axios.post 封装axios 1.请求设置类型responseType: blob 2.若有请求拦截(直接返回即可) 3.download 4.请求下载 相关基础 blob MIME vue 实现文件上传、下载的方法 - 掘金 上传 submitAddFile(){var form…

基础算法-【离散化】

离散化的本质:是建立了一段数列到自然数之间的映射关系(value -> index),通过建立新索引,来缩小目标区间,使得可以进行一系列连续数组可以进行的操作比如二分,前缀和等… 相应的算法模板: v…

【Linux】—— 进程地址空间

序言: 在上篇中,我们讲解了关于进程优先级的概念。本期,我将给大家介绍的是关于进程地址空间的话题。 目录 (一)程序地址空间回顾 (二)代码演示 (三)进程地址空间的引…

【力扣算法08】之 5. 最长回文子串 python

文章目录 问题描述示例1示例2提示 思路分析代码分析完整代码详细分析 运行效果截图调用示例运行结果 完结 问题描述 给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例1 输入:s…

【网络编程】Linux服务器程序规范相关内容

文章目录 1、日志1.1、syslog()函数 2、用户信息2.1、UID、EUID、GID、EGID 3、进程间关系3.1、进程组3.2、会话 4、服务器程序后台化(守护进程) 1、日志 Linux提供一个守护进程rsyslogd来处理系统日志,系统日志中包括用户进程产生的日志以及…

VUE2基础-Vue实例

Vue 实例 创建一个 Vue 实例 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: var vm new Vue({// 选项 }) 虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名…

交换:交换机相关技术(二层技术)

目录 VLAN:虚拟局域网 VLAN种类: 接口分配链路类型 接口划分VLAN 跨网段的通讯 VLAN:虚拟局域网 LAN :局域网 MAN:城域网 WAN:广域网 1.一个VLAN相当于一个广播域 VLAN:通过路由器和交换机…