ax1.scatter(X[:, 0], X[:, 1]
,marker='o' #点的形状
,s=8 #点的大小
)
plt.show()
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210224125637735.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
基于这个分布,我们来使用Kmeans进行聚类。首先,我们要猜测一下,这个数据中有几簇?
* 根据上面画出的图,我们先猜测有 3 簇
from sklearn.cluster import KMeans
n_clusters = 3
cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
y_pred = cluster.labels_ #标签类别
y_pred
pre = cluster.fit_predict(X)
pre == y_pred
cluster_smallsub = KMeans(n_clusters=n_clusters, random_state=0).fit(X[:200])
y_pred_ = cluster_smallsub.predict(X)
y_pred == y_pred_
centroid = cluster.cluster_centers_ # 质心
centroid
“”"
array([[-8.09286791, -3.50997357],
[-1.54234022, 4.43517599],
[-7.0877462 , -8.08923534]])
“”"
centroid.shape
“”"
(3, 2)
“”"
inertia = cluster.inertia_ #簇内平方和
inertia
“”"
1903.5342237665059
“”"
画出 n\_clusters = 3 时的聚类图:
color = [“red”,“pink”,“orange”,“gray”]
fig, ax1 = plt.subplots(1)
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[:,0],centroid[:,1]
,marker="x"
,s=15
,c="black")
plt.show()
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021022413045383.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
调整 n\_clusters 的值,查看对应的**簇内平方和**:
* 发现当 n\_clusters 越大,簇内平方和越小,这能说明聚类效果好吗?(**并不能**)
n_clusters = 4
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
“”"
908.3855684760603
“”"
n_clusters = 5
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
“”"
811.0952123653016
“”"
n_clusters = 6
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
“”"
728.2827697678249z
“”"
**查看点的实际分布**
color = [“red”,“pink”,“orange”,“gray”]
fig, ax1 = plt.subplots(1)
for i in range(4):
ax1.scatter(X[y==i, 0], X[y==i, 1]
,marker='o' #点的形状
,s=8 #点的大小
,c=color[i]
)
plt.show()
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021022412572119.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
[](
)聚类算法的模型评估指标
------------------------------------------------------------------------------
不同于分类模型和回归,聚类算法的模型评估不是一件简单的事。
> 在分类中,有直接结果(标签)的输出,并且分类的结果有正误之分,所以我们使用预测的准确度,混淆矩阵,ROC曲线等等指标来进行评估,但无论如何评估,都是在”模型找到正确答案“的能力。
>
> 而回归中,由于要拟合数据,我们有SSE均方误差,有损失函数来衡量模型的拟合程度。
>
> 但这些衡量指标都不能够使用于聚类。
> **面试高频问题:如何衡量聚类算法的效果?**
> 聚类模型的结果不是某种标签输出,并且聚类的结果是不确定的,其优劣由业务需求或者算法需求来决定,并且没有永远的正确答案。那我们如何衡量聚类的效果呢?
记得我们说过,KMeans的目标是确保“**簇内差异小,簇外差异大**”,我们就可以通过**衡量簇内差异来衡量聚类的效果**。而`Inertia`是用距离来衡量簇内差异的指标,因此,我们是否可以使用Inertia来作为聚类的衡量指标呢?Inertia越小模型越好嘛?
可以,但是这个指标的缺点和极限太大。
* 首先,**它不是有界的**。我们只知道,Inertia是越小越好,是0最好,但我们不知道,一个较小的Inertia究竟有没有达到模型的极限,能否继续提高。
* 第二,**它的计算太容易受到特征数目的影响**,数据维度很大的时候,Inertia的计算量会陷入维度诅咒之中,计算量会爆炸,不适合用来一次次评估模型。
* 第三,**它会受到超参数K的影响**,在我们之前的尝试中其实我们已经发现,随着K越大,Inertia注定会越来越小,但这并不代表模型的效果越来越好了
* 第四,**Inertia对数据的分布有假设**,它假设数据满足凸分布(即数据在二维平面图像上看起来是一个凸函数的样子),并且它假设数据是各向同性的(isotropic),即是说数据的属性在不同方向上代表着相同的含义。但是现实中的数据往往不是这样。所以使用Inertia作为评估指标,会让聚类算法在一些细长簇,环形簇,或者不规则形状的流形时表现不佳:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210224134823743.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
那我们可以使用什么指标呢?分两种情况来看。
* 真实标签已知的时候
* 真实标签未知的时候
### [](
)当真实标签已知的时候
虽然我们在聚类中不输入真实标签,但这不代表我们拥有的数据中一定不具有真实标签,或者一定没有任何参考信息。当然,**在现实中,拥有真实标签的情况非常少见(几乎是不可能的)**。如果拥有真实标签,我们更倾向于使用**分类算法**。但不排除我们依然可能使用聚类算法的可能性。如果我们有样本真实聚类情况的数据,我们可以对于聚类算法的结果和真实结果来衡量聚类的效果。常用的有以下三种方法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021022413533441.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
### [](
)当真实标签未知的时候:轮廓系数
99%的情况下,我们是对没有真实标签的数据进行探索,也就是对不知道真正答案的数据进行聚类。这样的聚类,**完全依赖于评价簇内的稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)来评估聚类的效果**。其中**轮廓系数**是最常用的聚类算法的评价指标。它是对每个样本来定义的,它能够同时衡量:
1. 样本与其自身所在的簇中的其他样本的相似度a
等于样本与同一簇中所有其他点之间的平均距离
2. 样本与其他簇中的样本的相似度b
等于样本与下一个最近的簇中的所有点之间的平均距离
根据聚类的要求”**簇内差异小,簇外差异大**“,我们希望**b永远大于a,并且大得越多越好**。
单个样本的轮廓系数计算为:
s = b − a m a x ( a , b ) s = \\frac {b-a} {max(a,b)} s\=max(a,b)b−a
这个公式可以被解析为:
s = { 1 − a b , i f a < b 0 , i f a = b b a − 1 , i f a > b s = \\left\\{\\begin{matrix} 1- \\frac a b , & if a < b \\\\ 0,& if a = b\\\\ \\frac b a - 1, & if a > b \\end{matrix}\\right. s\=⎩⎨⎧1−ba,0,ab−1,ifab
很容易理解轮廓系数范围是(-1,1)
* 值越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似
* 当样本点与簇外的样本更相似的时候,轮廓系数就为负。
* 当轮廓系数为0时,则代表两个簇中的样本相似度一致,两个簇本应该是一个簇
可以总结为:**轮廓系数越接近于1越好,负数则表示聚类效果非常差**。
如果一个簇中的大多数样本具有比较高的轮廓系数,则簇会有较高的总轮廓系数,则整个数据集的平均轮廓系数越高,则聚类是合适的。如果许多样本点具有低轮廓系数甚至负值,则聚类是不合适的,聚类的超参数K可能设定得太大或者太小。
在sklearn中,我们使用模块`sklearn.metrics`中的`silhouette_score`类来计算轮廓系数,它返回的是一个数据集中所有样本的轮廓系数的均值。
* `silhouette_sample` 的参数与轮廓系数一致,但返回数据集中每个样本自己的轮廓系数
我们来看看轮廓系数在我们自建的数据集上表现如何:
from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples
X
y_pred
silhouette_score(X,y_pred)
silhouette_score(X,cluster_.labels_)
silhouette_samples(X,y_pred)
轮廓系数有很多优点:
* 它在有限空间中取值,使得我们对模型的聚类效果有一个“参考”
* 轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好
但它在每个簇的分割比较清洗时表现最好
但轮廓系数也有缺陷,它在凸型的类上表现会虚高,比如基于密度进行的聚类,或通过DBSCAN获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数。
### [](
)当真实标签未知的时候:Calinski-Harabaz Index
…
[](
)【案例】基于轮廓系数来选择n\_clusters
===========================================================================================
我们通常会绘制轮廓系数分布图和聚类后的数据分布图来选择我们的最佳n\_clusters。
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
n_clusters = 4
fig, (ax1, ax2) = plt.subplots(1, 2)
fig.set_size_inches(18, 7)
ax1.set_xlim([-0.1, 1])
ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])
clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)
cluster_labels = clusterer.labels_
silhouette_avg = silhouette_score(X, cluster_labels)
print(“For n_clusters =”, n_clusters,
"The average silhouette_score is :", silhouette_avg)
sample_silhouette_values = silhouette_samples(X, cluster_labels)
y_lower = 10
for i in range(n_clusters):
ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]
ith_cluster_silhouette_values.sort()
size_cluster_i = ith_cluster_silhouette_values.shape[0]
y_upper = y_lower + size_cluster_i
color = cm.nipy_spectral(float(i)/n_clusters)
ax1.fill_betweenx(np.arange(y_lower, y_upper)
,ith_cluster_silhouette_values
,facecolor=color
,alpha=0.7
)
ax1.text(-0.05
, y_lower + 0.5 * size_cluster_i
, str(i))
y_lower = y_upper + 10
ax1.set_title(“The silhouette plot for the various clusters.”)
ax1.set_xlabel(“The silhouette coefficient values”)
ax1.set_ylabel(“Cluster label”)
ax1.axvline(x=silhouette_avg, color=“red”, linestyle="–")
ax1.set_yticks([])
ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
ax2.scatter(X[:, 0], X[:, 1]
,marker='o'
,s=8
,c=colors
)
centers = clusterer.cluster_centers_
ax2.scatter(centers[:, 0], centers[:, 1], marker=‘x’,
c="red", alpha=1, s=200)
ax2.set_title(“The visualization of the clustered data.”)
ax2.set_xlabel(“Feature space for the 1st feature”)
ax2.set_ylabel(“Feature space for the 2nd feature”)
**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](
)**
以下是我个人的一些做法,希望可以给各位提供一些帮助:
整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!
283页的Java进阶核心pdf文档
Java部分:Java基础,集合,并发,多线程,JVM,设计模式
数据结构算法:Java算法,数据结构
开源框架部分:Spring,MyBatis,MVC,netty,tomcat
分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等
微服务部分:SpringBoot,SpringCloud,Dubbo,Docker
还有源码相关的阅读学习
**
以下是我个人的一些做法,希望可以给各位提供一些帮助:
整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!
[外链图片转存中…(img-mCDWy6ve-1631189734768)]
283页的Java进阶核心pdf文档
Java部分:Java基础,集合,并发,多线程,JVM,设计模式
数据结构算法:Java算法,数据结构
开源框架部分:Spring,MyBatis,MVC,netty,tomcat
分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等
微服务部分:SpringBoot,SpringCloud,Dubbo,Docker
[外链图片转存中…(img-Ij5NUZfZ-1631189734770)]
还有源码相关的阅读学习
[外链图片转存中…(img-dI0KCTMh-1631189734771)]