《机器学习算法与实现 —— Python编程与应用实例》评估聚性能的方法
<div class='showpostmsg'> 本帖最后由 lospring 于 2024-8-4 19:23 编辑<p>k-Means是无监督学习的算法之一。k-means就是将n个数据点进行聚类分析,得到 k 个聚类,使得每个数据点到聚类中心的距离最小。</p>
<p>k-Means的相关过程很容易获得,整体的推导过程实在是没什么意义再复制出来,下面就看看评估聚性能的方法:</p>
<h3>方法1 - ARI</h3>
<p>如果被用来评估的数据本身带有正确的类别信息,则利用Adjusted Rand Index(ARI)对聚类结果进行评估,ARI与分类问题中计算准确性的方法类似,兼顾了类簇无法和分类标记一一对应的问题。</p>
<h4>1、RI</h4>
<p>为了方便理解ARI,先讨论一下RI,也就是rand index,是ARI的基础方法。</p>
<p>假如有两类,那么针对这两类的的RI评价指标为:</p>
<p> </p>
<p>a,b,c,d分别代表的含义为:</p>
<ul>
<li>a : 应该在一类,最后聚类到一类的数量,</li>
<li>b : 不应该在一类,最后聚类结果也没把他们聚类在一起的数量。</li>
<li>c和d那么就是应该在一起而被分开的和不应该在一起而被迫在一起的。毕竟强扭的瓜不甜,c和d固然是错误的。</li>
</ul>
<p>所以从R的表达式中可以看出,a和b是对的,这样能够保证R在0到1之间,而且,聚类越准确,指标越接近于1.</p>
<p>这里有一个关键性的问题,就是什么叫数量?怎么去计算?准确的说,是配对的数量。比如说a是应该在一起而真的幸福的在一起了的数量,这显然就应该像人类一样按照小夫妻数量计算,但是我们的样本可不管一夫一妻制,任意选两个就是一个配对,所以,就是 n(n−1)/2这样来计算,也就是组合数,n个当中选两个的选法。同时我们看到,分母其实是所有配对的总和,所以,我们最后可以写成这样:</p>
<p> </p>
<h4>2、ARI</h4>
<p>有了先前RI的感性理解之后,接下来解释一下ARI。</p>
<p>RI有一个缺点,就是惩罚力度不够,换句话说,大家普遍得分比较高,没什么区分度,普遍80分以上。这样的话,往往是评价区分性不是特别好,于是就诞生出了ARI,这个指标相对于RI就很有区分度了。</p>
<p></p>
<p>具体的公式是:</p>
<p> </p>
<p>ARI取值范围为[-1,1],值越大越好,反映两种划分的重叠程度,使用该度量指标需要数据本身有类别标记。</p>
<p>关联表(contingency table)的定义:</p>
<p> </p>
<p>表中:</p>
<p> </p>
<p>公式中:</p>
<p> </p>
<p>假设配对矩阵是这样的,共有 n(n−1)/2 个配对方法。在行方向计算出可能取到的配对数,在列方向计算可能取到的配对数,相乘以后,除以总的配对数,这就是a的期望了。</p>
<pre>
<code class="language-python">from sklearn.metrics import adjusted_rand_score
ari_train = adjusted_rand_score(y_train, kmeans.labels_)
print("ari_train = %f" % ari_train)</code></pre>
<h3>方法2 - 轮廓系数</h3>
<p>如果被用来评估的数据没有所属类别,则使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量,评估聚类的效果。<strong>轮廓系数同时兼顾了聚类的凝聚度和分离度,取值范围是[-1,1],轮廓系数越大,表示聚类效果越好。</strong></p>
<p>轮廓系数的具体计算步骤:</p>
<p> </p>
<pre>
<code class="language-python">import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize']=(10,10)
plt.subplot(3,2,1)
x1=np.array() #初始化原始数据
x2=np.array()
X=np.array(list(zip(x1,x2))).reshape(len(x1),2)
plt.xlim()
plt.ylim()
plt.title('Instances')
plt.scatter(x1,x2)
colors=['b','g','r','c','m','y','k','b']
markers=['o','s','D','v','^','p','*','+']
clusters=
subplot_counter=1
sc_scores=[]
for t in clusters:
subplot_counter +=1
plt.subplot(3,2,subplot_counter)
kmeans_model=KMeans(n_clusters=t).fit(X) #KMeans建模
for i,l in enumerate(kmeans_model.labels_):
plt.plot(x1,x2,color=colors,marker=markers,ls='None')
plt.xlim()
plt.ylim()
sc_score=silhouette_score(X,kmeans_model.labels_,metric='euclidean') #计算轮廓系数
sc_scores.append(sc_score)
plt.title('k=%s,silhouette coefficient=%0.03f'%(t,sc_score))
plt.figure()
plt.plot(clusters,sc_scores,'*-') #绘制类簇数量与对应轮廓系数关系
plt.xlabel('Number of Clusters')
plt.ylabel('Silhouette Coefficient Score')
plt.savefig('fig-res-k-means_silhouette_coef.pdf')
plt.show() </code></pre>
<p> </p>
<p> </p>
<p> </p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页:
[1]