第36集 python机器学习:聚类算法的对比与评价
作者头像
  • 2019-10-23 17:00:08 1

在使用聚类算法时,一个主要挑战是难以评估算法的效果好坏以及比较不同算法的结果。接下来,我们将对已学习的K均值、凝聚聚类、DBSCAN等算法进行评价。

使用真实值评价聚类

在评价聚类算法时,我们可以利用一些指标来衡量其相对于真实聚类的效果。其中最重要的指标是调整兰德指数(Adjusted Rand Index,简称ARI)和归一化互信息(Normalized Mutual Information,简称NMI)。这些指标都可以提供定量的评价,其最佳值为1,而0表示没有相关性。

为了具体说明这一点,我们使用ARI指标对K均值、凝聚聚类和DBSCAN算法进行比较。为了对比,我们还加入了随机分配的数据。

```python from sklearn.cluster import AgglomerativeClustering, DBSCAN from sklearn.preprocessing import StandardScaler from sklearn.metrics.cluster import adjustedrandscore from sklearn.datasets import make_moons import numpy as np import matplotlib.pyplot as plt

x, y = makemoons(nsamples=200, noise=0.05, randomstate=0) scaler = StandardScaler() scaler.fit(x) xscaled = scaler.transform(x)

fig, axes = plt.subplots(1, 4, figsize=(15, 3), subplotkw={'xticks': (), 'yticks': ()}) algorithms = [KMeans(nclusters=2), AgglomerativeClustering(n_clusters=2), DBSCAN()]

randomstate = np.random.RandomState(seed=0) randomclusters = random_state.randint(low=0, high=2, size=len(x))

axes[0].scatter(xscaled[:, 0], x[:, 1], c=randomclusters, cmap='viridis', s=60) axes[0].settitle("随机分配 - ARI: {:.2f}".format(adjustedrandscore(y, randomclusters)))

for ax, algorithm in zip(axes[1:], algorithms): clusters = algorithm.fitpredict(xscaled) ax.scatter(xscaled[:, 0], x[:, 1], c=clusters, cmap='plasma', s=60) ax.settitle("{} - ARI: {:.2f}".format(algorithm.class.name, adjustedrandscore(y, clusters))) ```

运行结果如下:

应用监督API分数在two_moons数据集上比较随机分配,K均值、凝聚聚类及DBSCAN

从图中可以看到,随机分配的ARI为0,而DBSCAN的ARI达到了1,表明DBSCAN完美地找到了预期的聚类。

常见错误

在评价聚类时,一个常见的错误是使用准确性(accuracy)分数而不是ARI或NMI等指标。准确性要求分配的标签与真实值完全匹配,但这在聚类中并不适用,因为簇标签本身没有意义,唯一重要的是哪些点被分到了同一个簇中。

```python from sklearn.metrics import accuracy_score

cluster1 = [0, 0, 1, 1, 0] cluster2 = [1, 1, 0, 0, 1]

print("准确性:{:.2f}".format(accuracyscore(cluster1, cluster2))) print("ARI:{:.2f}".format(adjustedrand_score(cluster1, cluster2))) ```

运行结果为:

准确性:0.00 ARI:1.00

从这个例子可以看出,ARI比准确性更能准确反映聚类的效果。

在没有真实值的情况下评价聚类

在实际应用中,通常没有真实值来比较聚类结果。在这种情况下,可以使用一些不需要真实值的指标,如轮廓系数(Silhouette Coefficient)。轮廓系数衡量一个簇内的紧密度和与其他簇之间的分离度,其值越大越好,最高值为1。

下面是在two_moons数据集上使用轮廓系数比较K均值、凝聚聚类和DBSCAN。

```python from sklearn.metrics.cluster import silhouette_score

x, y = makemoons(nsamples=200, noise=0.05, randomstate=0) scaler = StandardScaler() scaler.fit(x) xscaled = scaler.transform(x)

fig, axes = plt.subplots(1, 4, figsize=(15, 3), subplotkw={'xticks': (), 'yticks': ()}) algorithms = [KMeans(nclusters=2), AgglomerativeClustering(n_clusters=2), DBSCAN()]

randomstate = np.random.RandomState(seed=0) randomclusters = random_state.randint(low=0, high=2, size=len(x))

axes[0].scatter(xscaled[:, 0], x[:, 1], c=randomclusters, cmap='viridis', s=60) axes[0].settitle("随机分配 - 轮廓系数:{:.2f}".format(silhouettescore(xscaled, randomclusters)))

for ax, algorithm in zip(axes[1:], algorithms): clusters = algorithm.fitpredict(xscaled) ax.scatter(xscaled[:, 0], x[:, 1], c=clusters, cmap='plasma', s=60) ax.settitle("{} - 轮廓系数:{:.2f}".format(algorithm.class.name, silhouettescore(xscaled, clusters))) ```

运行结果如下:

应用轮廓系数在two_moons数据集上比较随机分配,K均值、凝聚聚类及DBSCAN

从图中可以看出,随机分配的轮廓系数为0,KMeans的得分为0.49,凝聚聚类的得分为0.46,DBSCAN的得分为0.38。通过这些比较,我们可以看出,在没有真实值的情况下,KMeans在轮廓系数上表现最好。

更好的策略

一种更好的策略是使用基于鲁棒性的聚类评价指标。这种指标通过向数据中添加噪声或使用不同的参数设置,多次运行算法并比较结果,从而评估算法的稳定性。如果多个算法参数和多种数据扰动都能得到一致的结果,那么该算法可能更可靠。

在下一节中,我们将继续探讨这几种聚类算法在人脸数据集上的效果。

    本文来源:图灵汇
责任编辑: :
声明:本文系图灵汇原创稿件,版权属图灵汇所有,未经授权不得转载,已经协议授权的媒体下载使用时须注明"稿件来源:图灵汇",违者将依法追究责任。
    分享
算法对比机器评价python学习
    下一篇