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

目录

一、聚类

二、机器学习中的距离

三、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 mtx,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.hqwc.cn/news/21201.html

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

相关文章

计算机网络基础

在介绍网络之前,先讲一个概念,一台计算机的内部本质也是一个小型网络结构,CPU、内存、外设都是通过线连接起来的,并且它们之前也有协议,一台计算机各个功能用多台计算机构建起来,用网络及链起来&#xff0c…

聊聊微服务 架构思想

用了好多年微服务架构了,我经常会反思,这个项目为啥用微服务?真的能帮我们解决一些痛点吗?这个项目有必要用微服务吗?这个项目体现出微服务的价值了吗? 我是从2017年开始入手微服务,距今已经五六…

Linux——权限

1.Linux权限的概念 Linux权限是指用于限制对文件和目录的访问的安全机制。文件和目录的权限由三个部分组成:所有者权限、同组用户权限和其他用户权限。每个部分又包括读、写、执行三种权限。这些权限决定了用户能否对文件或目录进行读、写、执行等操作。 2.Linux…

ETHERNET/IP转PROFIBUS-DP网关Profibus DP转EtherNet/IP协议转换网关

大家好,今天要给大家介绍一款非常神奇的通讯网关捷米特JM-DPM-EIP!这款产品可以将各种PROFIBUS-DP从站接入到ETHERNET/IP网络中,真是一款神奇的产品啊!你是否想过,如果没有这款产品,PROFIBUS-DP从站和ETHER…

【Linux后端服务器开发】进程控制与替换

目录 一、进程控制 1. 进程退出 2. 进程等待 2.1 阻塞等待 2.2 status位图结构 2.3 非阻塞等待 二、进程替换 1. exec*系列函数 2. 进程替换高级语言可执行程序 一、进程控制 1. 进程退出 进程退出会进入僵尸态,把自己的退出结果写入到自己的task_struct…

QT打开和保存文件对话框的操作笔记

QT打开和保存文件对话框的操作&#xff0c;需要先包含头文件QFileDialog&#xff0c;一般通过按钮实现打开和保存文件对话框的操作。 代码如下&#xff1a; #include <QDebug> #include <QFileDialog>void Form::on_pushButton_clicked() {QString fileName;fileN…

【尚医通】vue3+ts前端项目开发笔记 2 —— 创建项目、封装网络请求、集成elment-plus 、重置样式、准备状态管理/路由 等开发前准备

尚医通开发记录(Vue3TypeScriptPiniaAxios) 一、接口地址 服务器地址:http://syt.atguigu.cn 医院接口&#xff1a;http://139.198.34.216:8201/swagger-ui.html 公共数据接口&#xff1a;http://139.198.34.216:8202/swagger-ui.html 会员接口&#xff1a;http://139.198.34…

POI下载excel通用方法

POI下载excel通用方法 最近遇到一个业务是需要下载excel&#xff0c;使用POI,这里记录一下实现过程 1、导包 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency>…

Python实现将pdf,docx,xls,doc,wps链接下载并将文件保存到本地

前言 本文是该专栏的第31篇,后面会持续分享python的各种干货知识,值得关注。 在工作上,尤其是在处理爬虫项目中,会遇到这样的需求。访问某个网页或者在采集某个页面的时候,正文部分含有docx,或pdf,或xls,或doc,或wps等链接。需要你使用python自动将页面上含有的这些信…

什么是RPC并实现一个简单的RPC

1. 基本的RPC模型 主要介绍RPC是什么&#xff0c;基本的RPC代码&#xff0c;RPC与REST的区别&#xff0c;gRPC的使用 1.1 基本概念 RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用&#xff0c;简单的理解是一个节点请求另一个节点提供的服务本地过程调用&am…

C++STL:顺序容器之vector

文章目录 1. 概述2. 成员函数3. 创建 vector 容器的几种方式4. 迭代器vector容器迭代器的基本用法vector容器迭代器的独特之处 5. 访问元素5.1 访问vector容器中单个元素5.2 访问vector容器中多个元素 6. 添加元素6.1 push_back()6.2 emplace_back()6.3 emplace_back()和push_b…

【Java/大数据】Kafka简介

Kafka简介 Kafka概念关键功能应用场景 Kafka的原理Kafka 的消息模型早期的队列模型发布-订阅模型Producer、Consumer、Broker、Topic、PartitionPartitionoffsetISR Consumer Groupleader选举Controller leaderPartition leader producer 的写入流程 多副本机制replicas的同步时…