注意:单击此处https://urlify.cn/rQ7fay下载完整的示例代码,或通过Binder在浏览器中运行此示例
本示例演示了不同度量指标对层次聚类的影响(hierarchical clustering)。
该示例旨在展示选择不同度量指标对层次聚类的影响,它应用于波形(waveform),可以看作是高维向量。实际上,度量指标之间的差异通常在高维度上更为明显(尤其是对于欧几里得和cityblock来说)。
我们从三组波形中生成数据,其中两个波形(波形1和波形2)彼此成比例。余弦距离对于数据的缩放是不变的,因此它无法区分这两个波形。即使没有噪声,使用余弦距离进行聚类也不能分离出波形1和波形2。
我们将观察噪声数据添加到这些波形中,产生非常稀疏的噪声:只有6%的时间点包含噪声。结果可得,此噪声的l1范数(即“城市街区(cityblock)”距离)比其l2范数(“欧几里得”距离)要小得多,这可以从类间距离(inter-class distance)矩阵中看出:欧几里得距离上的对角线的值(代表类的扩展)比cityblock距离要大得多。
将聚类应用于数据时,我们发现聚类反映了距离矩阵中的内容。对于欧几里得距离来说,由于噪声,这些聚类结果是不适当的,因此聚类不会分离波形。对于cityblock来说,数据分离得很好,并且恢复了波形类别。最后,余弦距离并没有在所有的波形1和2上分开,因此聚类算法将它们置于同一聚类中。
# 作者: Gael Varoquaux
# 许可证: BSD 3-Clause or CC-0
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import pairwise_distances
np.random.seed(0)
# 生成波形数据
n_features = 2000
t = np.pi * np.linspace(0, 1, n_features)
def sqr(x):
return np.sign(np.cos(x))
X = list()
y = list()
for i, (phi, a) in enumerate([(.5, .15), (.5, .6), (.3, .2)]):
for _ in range(30):
phase_noise = .01 * np.random.normal()
amplitude_noise = .04 * np.random.normal()
additional_noise = 1 - 2 * np.random.rand(n_features)
# Make the noise sparse
additional_noise[np.abs(additional_noise) < .997] = 0
X.append(12 * ((a + amplitude_noise)
* (sqr(6 * (t + phi + phase_noise)))
+ additional_noise))
y.append(i)
X = np.array(X)
y = np.array(y)
n_clusters = 3
labels = ('Waveform 1', 'Waveform 2', 'Waveform 3')
# 绘制真实类(ground-truth)标签
plt.figure()
plt.axes([0, 0, 1, 1])
for l, c, n in zip(range(n_clusters), 'rgb',
labels):
lines = plt.plot(X[y == l].T, c=c, alpha=.5)
lines[0].set_label(n)
plt.legend(loc='best')
plt.axis('tight')
plt.axis('off')
plt.suptitle("Ground truth", size=20)
# 绘制距离
for index, metric in enumerate(["cosine", "euclidean", "cityblock"]):
avg_dist = np.zeros((n_clusters, n_clusters))
plt.figure(figsize=(5, 4.5))
for i in range(n_clusters):
for j in range(n_clusters):
avg_dist[i, j] = pairwise_distances(X[y == i], X[y == j],
metric=metric).mean()
avg_dist /= avg_dist.max()
for i in range(n_clusters):
for j in range(n_clusters):
plt.text(i, j, '%5.3f' % avg_dist[i, j],
verticalalignment='center',
horizontalalignment='center')
plt.imshow(avg_dist, interpolation='nearest', cmap=plt.cm.gnuplot2,
vmin=0)
plt.xticks(range(n_clusters), labels, rotation=45)
plt.yticks(range(n_clusters), labels)
plt.colorbar()
plt.suptitle("Interclass %s distances" % metric, size=18)
plt.tight_layout()
# 绘制聚类结果
for index, metric in enumerate(["cosine", "euclidean", "cityblock"]):
model = AgglomerativeClustering(n_clusters=n_clusters,
linkage="average", affinity=metric)
model.fit(X)
plt.figure()
plt.axes([0, 0, 1, 1])
for l, c in zip(np.arange(model.n_clusters), 'rgbk'):
plt.plot(X[model.labels_ == l].T, c=c, alpha=.5)
plt.axis('tight')
plt.axis('off')
plt.suptitle("AgglomerativeClustering(affinity=%s)" % metric, size=20)
plt.show()
脚本的总运行时间:(0分钟1.512秒)
估计的内存使用量: 9 MB
![2a53bb01d4a27aeebedc89b612da5aa7.png](https://i-blog.csdnimg.cn/blog_migrate/d62849ec0efa5da2e2e243ce0eadf2d5.png)
下载Python源代码: plot_agglomerative_clustering_metrics.py
下载Jupyter notebook源代码: plot_agglomerative_clustering_metrics.ipynb
由Sphinx-Gallery生成的画廊
文壹由“伴编辑器”提供技术支持
☆☆☆为方便大家查阅,小编已将scikit-learn学习路线专栏 文章统一整理到公众号底部菜单栏,同步更新中,关注公众号,点击左下方“系列文章”,如图:欢迎大家和我一起沿着scikit-learn文档这条路线,一起巩固机器学习算法基础。(添加微信:mthler,备注:sklearn学习,一起进【sklearn机器学习进步群】开启打怪升级的学习之旅。)