41 python numpy matplotlib dendrogram scipy
我使用的是dendrogram
从scipy
使用绘制层次聚类matplotlib
如下:
mat = array([[1, 0.5, 0.9],
[0.5, 1, -0.5],
[0.9, -0.5, 1]])
plt.subplot(1,2,1)
plt.title("mat")
dist_mat = mat
linkage_matrix = linkage(dist_mat,
"single")
print "linkage2:"
print linkage(1-dist_mat, "single")
dendrogram(linkage_matrix,
color_threshold=1,
labels=["a", "b", "c"],
show_leaf_counts=True)
plt.subplot(1,2,2)
plt.title("1 - mat")
dist_mat = 1 - mat
linkage_matrix = linkage(dist_mat,
"single")
dendrogram(linkage_matrix,
color_threshold=1,
labels=["a", "b", "c"],
show_leaf_counts=True)
Run Code Online (Sandbox Code Playgroud)
我的问题是:第一,为什么mat
和1-mat
在这里给同一聚类?第二,如何使用树的每个分支来注释距离,dendrogram
以便可以比较节点对之间的距离?
最后似乎show_leaf_counts
忽略了标志,有没有办法打开它,以便显示每个类中的对象数量?谢谢.
War*_*ser 69
输入to linkage()
是nxm数组,表示m维空间中的n个点,或者是包含压缩距离矩阵的一维数组.在你的例子中,mat
是3 x 3,所以你正在聚集三个三维点.聚类基于这些点之间的距离.
为什么mat和1-mat在这里给出相同的聚类?
数组mat
并1-mat
产生相同的聚类,因为聚类基于点之间的距离,并且整个数据集的reflection(-mat
)和translate(mat + offset
)都不会改变点之间的相对距离.
如何使用树状图注释树的每个分支的距离,以便可以比较节点对之间的距离?
在下面的代码中,我将展示如何使用树形图返回的数据来标记图表中具有相应距离的水平线段.与键相关联的值,icoord
并dcoord
给出图中每个三段倒U的x和y坐标.在augmented_dendrogram
该数据中,用于在树形图中添加每个水平线段的距离(即y值)的标签.
from scipy.cluster.hierarchy import dendrogram
import matplotlib.pyplot as plt
def augmented_dendrogram(*args, **kwargs):
ddata = dendrogram(*args, **kwargs)
if not kwargs.get('no_plot', False):
for i, d in zip(ddata['icoord'], ddata['dcoord']):
x = 0.5 * sum(i[1:3])
y = d[1]
plt.plot(x, y, 'ro')
plt.annotate("%.3g" % y, (x, y), xytext=(0, -8),
textcoords='offset points',
va='top', ha='center')
return ddata
Run Code Online (Sandbox Code Playgroud)
对于你的mat
数组,增强的树形图是
所以点'a'和'c'相距1.01个单位,点'b'是簇['a','c']的1.57个单位.
似乎show_leaf_counts
忽略了标志,有没有办法打开它,以便显示每个类中的对象数量?
该标志show_leaf_counts
仅适用于并非所有原始数据点都显示为叶子的情况.例如,当trunc_mode = "lastp"
只显示最后一个p
节点时.
以下是100分的示例:
import numpy as np
from scipy.cluster.hierarchy import linkage
import matplotlib.pyplot as plt
from augmented_dendrogram import augmented_dendrogram
# Generate a random sample of `n` points in 2-d.
np.random.seed(12312)
n = 100
x = np.random.multivariate_normal([0, 0], np.array([[4.0, 2.5], [2.5, 1.4]]),
size=(n,))
plt.figure(1, figsize=(6, 5))
plt.clf()
plt.scatter(x[:, 0], x[:, 1])
plt.axis('equal')
plt.grid(True)
linkage_matrix = linkage(x, "single")
plt.figure(2, figsize=(10, 4))
plt.clf()
plt.subplot(1, 2, 1)
show_leaf_counts = False
ddata = augmented_dendrogram(linkage_matrix,
color_threshold=1,
p=6,
truncate_mode='lastp',
show_leaf_counts=show_leaf_counts,
)
plt.title("show_leaf_counts = %s" % show_leaf_counts)
plt.subplot(1, 2, 2)
show_leaf_counts = True
ddata = augmented_dendrogram(linkage_matrix,
color_threshold=1,
p=6,
truncate_mode='lastp',
show_leaf_counts=show_leaf_counts,
)
plt.title("show_leaf_counts = %s" % show_leaf_counts)
plt.show()
Run Code Online (Sandbox Code Playgroud)
这些是数据集中的点:
使用p=6
和trunc_mode="lastp"
, dendrogram
仅显示树形图的"顶部".以下显示了效果show_leaf_counts
.
Tar*_*ato 14
我认为对于您尝试使用的功能有一些误解.这是一个完整工作的代码片段,用于说明我的观点:
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
from numpy import array
import numpy as np
mat = array([184, 222, 177, 216, 231,
45, 123, 128, 200,
129, 121, 203,
46, 83,
83])
dist_mat = mat
linkage_matrix = linkage(dist_mat, 'single')
print linkage_matrix
plt.figure(101)
plt.subplot(1, 2, 1)
plt.title("ascending")
dendrogram(linkage_matrix,
color_threshold=1,
truncate_mode='lastp',
labels=array(['a', 'b', 'c', 'd', 'e', 'f']),
distance_sort='ascending')
plt.subplot(1, 2, 2)
plt.title("descending")
dendrogram(linkage_matrix,
color_threshold=1,
truncate_mode='lastp',
labels=array(['a', 'b', 'c', 'd', 'e', 'f']),
distance_sort='descending')
def make_fake_data():
amp = 1000.
x = []
y = []
for i in range(0, 10):
s = 20
x.append(np.random.normal(30, s))
y.append(np.random.normal(30, s))
for i in range(0, 20):
s = 2
x.append(np.random.normal(150, s))
y.append(np.random.normal(150, s))
for i in range(0, 10):
s = 5
x.append(np.random.normal(-20, s))
y.append(np.random.normal(50, s))
plt.figure(1)
plt.title('fake data')
plt.scatter(x, y)
d = []
for i in range(len(x) - 1):
for j in range(i+1, len(x) - 1):
d.append(np.sqrt(((x[i]-x[j])**2 + (y[i]-y[j])**2)))
return d
mat = make_fake_data()
plt.figure(102)
plt.title("Three Clusters")
linkage_matrix = linkage(mat, 'single')
print "three clusters"
print linkage_matrix
dendrogram(linkage_matrix,
truncate_mode='lastp',
color_threshold=1,
show_leaf_counts=True)
plt.show()
Run Code Online (Sandbox Code Playgroud)
首先,计算m - > m - 1并没有真正改变你的结果,因为距离矩阵基本上描述了所有唯一对之间的相对距离,在你的具体情况下并没有改变.(在我上面的示例代码中,所有距离都是欧几里德,所以从2d平面上的点都是正的和一致的.)
对于你的第二个问题,你可能需要推出自己的注释例程来做你想做的事,因为我不认为dendromgram本身支持它...
对于最后一个问题,show_leaf_counts似乎仅在您尝试使用truncate_mode ='lastp'选项显示非单例叶节点时才起作用.基本上,一片叶子紧密地聚在一起,不容易看到.因此,您可以选择仅显示一片叶子,但可以选择显示(在括号中)在该叶子中聚集了多少叶子.
希望这可以帮助.
归档时间: |
|
查看次数: |
44427 次 |
最近记录: |