你的聚类模型靠谱吗?5大外部指标彻底揭秘
<p>在聚类分析中,我们常常需要评估聚类结果的质量。</p><p><strong>外部指标</strong>是一种通过与已知的“真实标签”进行比较来评估聚类性能的方法。</p>
<p>这些指标可以帮助我们判断聚类算法是否能够准确地将数据划分为有意义的类别。</p>
<p>本文将介绍几种常见的外部指标,包括 <strong>Jaccard 系数</strong>、<strong>FM 指数</strong>、<strong>Rand 指数</strong>、<strong>DB 指数</strong>和 <strong>Dunn 指数</strong>,并通过代码示例展示如何基于<code>scikit-learn</code>库来计算它们。</p>
<h1 id="1-jaccard系数">1. Jaccard系数</h1>
<p><strong>Jaccard 系数</strong>是一种衡量两个集合<strong>相似度</strong>的指标,在聚类评估中,它用于比较聚类结果与真实标签之间的相似性。</p>
<p>具体来说,<strong>Jaccard 系数</strong>定义为两个集合的交集大小与并集大小的比值。</p>
<p>对于聚类结果,它关注的是每个类别内部的样本是否正确划分。</p>
<p>假设我们有两个集合$ A <span class="math inline">\(和\)</span> B <span class="math inline">\(,**Jaccard 系数**\)</span> J $可以表示为:</p>
<p>$ J(A,B)=\frac{|A\cap B|}{|A\cup B|} $</p>
<p>在聚类评估中,我们通常计算所有类别对的** Jaccard 系数<strong>的</strong>平均值**,以得到整体的相似度。</p>
<p><strong>Jaccard 系数</strong>在<code>scikit-learn</code>库中已经封装好,使用方式如下:</p>
<pre><code class="language-python">from sklearn.metrics import jaccard_score
import numpy as np
# 真实标签和聚类结果
true_labels = np.array()
predicted_labels = np.array()
# 计算 Jaccard 系数
jaccard = jaccard_score(true_labels, predicted_labels, average="macro")
print("Jaccard 系数:", jaccard)
</code></pre>
<p>可以调节上面的<code>true_labels</code>和<code>predicted_labels</code>,试试不同的计算结果。</p>
<h1 id="2-fmfowlkes-mallows指数">2. FM(Fowlkes-Mallows)指数</h1>
<p><strong>FM 指数</strong>是一种综合考虑了<strong>真正例</strong>(<code>TP</code>)、<strong>假正例</strong>(<code>FP</code>)和<strong>假负例</strong>(<code>FN</code>)的指标。</p>
<p>它通过计算<strong>精确率</strong>(<code>Precision</code>)和<strong>召回率</strong>(<code>Recall</code>)的几何平均值来衡量聚类结果的质量。</p>
<p>具体公式如下:</p>
<p>$ \text{FM}=\sqrt{\frac{TP}{TP+FP}\times\frac{TP}{TP+FN}} $</p>
<p>其中:</p>
<ul>
<li>$ TP $是正确分类的样本对数。</li>
<li>$ FP $是错误分类为同一类的样本对数。</li>
<li>$ FN $是应该在同一类但被分类到不同类的样本对数。</li>
</ul>
<p><strong>FM 系数</strong>在<code>scikit-learn</code>库中已经封装好,使用方式如下:</p>
<pre><code class="language-python">from sklearn.metrics import fowlkes_mallows_score
# 真实标签和聚类结果
true_labels = np.array()
predicted_labels = np.array()
# 计算 FM 指数
fm = fowlkes_mallows_score(true_labels, predicted_labels)
print("FM 指数:", fm)
</code></pre>
<h1 id="3-rand指数">3. Rand指数</h1>
<p><strong>Rand 指数</strong>是一种衡量聚类结果与真实标签一致性的指标,它通过计算样本对的分类一致性来评估聚类质量。</p>
<p>具体来说,<strong>Rand 指数</strong>定义为:</p>
<p>$ \text{Rand}=\frac{TP+TN}{TP+TN+FP+FN} $</p>
<p>其中:</p>
<ul>
<li>$ TP $是正确分类为同一类的样本对数。</li>
<li>$ TN $是正确分类为不同类的样本对数。</li>
<li>$ FP $是错误分类为同一类的样本对数。</li>
<li>$ FN $是应该在同一类但被分类到不同类的样本对数。</li>
</ul>
<p><strong>Rand 指数</strong>在<code>scikit-learn</code>库中已经封装好,使用方式如下:</p>
<pre><code class="language-python">from sklearn.metrics import rand_score
# 真实标签和聚类结果
true_labels = np.array()
predicted_labels = np.array()
# 计算 Rand 指数
rand = rand_score(true_labels, predicted_labels)
print("Rand 指数:", rand)
</code></pre>
<h1 id="4-dbdavies-bouldin指数">4. DB(Davies-Bouldin)指数</h1>
<p><strong>DB 指数</strong>是一种衡量聚类结果内部一致性的指标,但它也可以用于外部评估。</p>
<p>DB 指数通过比较每个类别的紧致性和分离性来评估聚类质量。</p>
<p>具体来说,<strong>DB 指数</strong>定义为:</p>
<p>$ \text{DB}=\frac{1}{k}\sum_{i=1}^{k}\max_{j\neq i}\left(\frac{\sigma_i+\sigma_j}{d(c_i,c_j)}\right) $</p>
<p>其中:</p>
<ul>
<li>$ k $是类别数量。</li>
<li>$ \sigma_i <span class="math inline">\(是类别\)</span> i $的平均距离。</li>
<li>$ c_i <span class="math inline">\(是类别\)</span> i $的中心。</li>
<li>$ d(c_i,c_j) <span class="math inline">\(是类别\)</span> i <span class="math inline">\(和类别\)</span> j $中心之间的距离。</li>
</ul>
<p><strong>DB 指数</strong>越小,表示聚类结果越好。</p>
<hr>
<p><strong>DB 指数</strong>在<code>scikit-learn</code>库中已经封装好,使用方式如下:</p>
<pre><code class="language-python">from sklearn.metrics import davies_bouldin_score
from sklearn.cluster import KMeans
import numpy as np
# 生成数据
X = np.array([, , , , , ])
# 使用 KMeans 进行聚类
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
predicted_labels = kmeans.labels_
# 计算 DB 指数
db = davies_bouldin_score(X, predicted_labels)
print("DB 指数:", db)
</code></pre>
<h1 id="5-dunn指数">5. Dunn指数</h1>
<p><strong>Dunn 指数</strong>是一种衡量聚类结果分离性和紧致性的指标。</p>
<p>它通过计算类内距离的最小值与类间距离的最大值的比值来评估聚类质量。</p>
<p>具体来说,<strong>Dunn 指数</strong>定义为:</p>
<p>$ \text{Dunn}=\frac{\min_{i\neq j}d(c_i,c_j)}{\max_i\delta(c_i)} $</p>
<p>其中:</p>
<ul>
<li>$ d(c_i,c_j) <span class="math inline">\(是类别\)</span> i <span class="math inline">\(和类别\)</span> j $中心之间的距离。</li>
<li>$ \delta(c_i) <span class="math inline">\(是类别\)</span> i $内部的最大距离。</li>
</ul>
<p><strong>Dunn 指数</strong>越大,表示聚类结果越好。</p>
<p><strong>Dunn 指数</strong>在<code>scikit-learn</code>库中没有现成的函数,不过,根据它的公式封装一个也很简单:</p>
<pre><code class="language-python">from sklearn.cluster import KMeans
import numpy as np
# 生成数据
X = np.array([, , , , , ])
# 使用 KMeans 进行聚类
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
predicted_labels = kmeans.labels_
# 计算 Dunn 指数
def dunn_index(X, labels):
n_clusters = len(set(labels))
inter_cluster_distances = []
intra_cluster_distances = []
for i in range(n_clusters):
cluster_points = X
intra_cluster_distances.append(
np.max(
np.linalg.norm(cluster_points - np.mean(cluster_points, axis=0), axis=1)
)
)
for j in range(i + 1, n_clusters):
other_cluster_points = X
inter_cluster_distances.append(
np.min(
np.linalg.norm(
cluster_points[:, np.newaxis] - other_cluster_points, axis=2
)
)
)
return np.min(inter_cluster_distances) / np.max(intra_cluster_distances)
# 计算 Dunn 指数
dunn = dunn_index(X, predicted_labels)
print("Dunn 指数:", dunn)
</code></pre>
<h1 id="6-总结">6. 总结</h1>
<p>本文介绍了几种常见的聚类性能外部评估指标,包括 <strong>Jaccard 系数</strong>、<strong>FM 指数</strong>、<strong>Rand 指数</strong>、<strong>DB 指数</strong>和 <strong>Dunn 指数</strong>。</p>
<p>这些指标各有优缺点,适用于不同的场景,使用时,建议:</p>
<ol>
<li><strong>有真实标签时</strong>:优先使用<code>Adjusted Rand</code>(平衡随机性)</li>
<li><strong>无真实标签时</strong>:使用<code>DB</code>或<code>Dunn</code></li>
<li><strong>小规模数据</strong>:可计算所有指标综合判断</li>
</ol>
<p>通过灵活组合这些指标,可以全面评估聚类模型的表现!</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/18883894
頁:
[1]