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)
私の質問は:最初に、なぜmat
と1-mat
ここに同一のクラスタリングを与えますか?次に、ノードのペア間の距離を比較できるように、dendrogram
を使用してツリーの各ブランチに沿った距離に注釈を付けるにはどうすればよいですか?
最後に、show_leaf_counts
フラグは無視されますが、各クラスのオブジェクトの数が表示されるようにオンにする方法はありますか?ありがとう。
linkage()
への入力は、m次元空間のn点を表すnxm配列、または condensed距離行列 。この例では、mat
は3 x 3であるため、3つの3次元ポイントをクラスタリングしています。クラスタリングは、これらのポイント間の距離に基づいています。
なぜmatと1-matは同一のクラスタリングを提供するのですか?
クラスタリングはポイント間の距離に基づいており、反射(1-mat
)も変換(-mat
)も使用しないため、配列mat
とmat + offset
は同じクラスタリングを生成しますデータセット全体で、ポイント間の相対距離を変更します。
ノードのペア間の距離を比較できるように、樹形図を使用してツリーの各ブランチに沿った距離に注釈を付けるにはどうすればよいですか?
以下のコードでは、樹状図によって返されたデータを使用して、ダイアグラムの水平セグメントに対応する距離をラベル付けする方法を示します。キーicoord
およびdcoord
に関連付けられた値は、図の各3セグメント逆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
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()
これらは、データセットのポイントです。
p=6
およびtrunc_mode="lastp"
を使用すると、dendrogram
は樹状図の「上部」のみを表示します。以下は、show_leaf_counts
の効果を示しています。
使用しようとしている関数の使用に関して、いくつかの誤解があると思います。以下に、私のポイントを説明するための完全に機能するコードスニペットを示します。
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()
まず、計算m-> m-1は、基本的にすべての一意のペア間の相対距離を記述する距離行列が特定のケースで変化しなかったため、結果を実際に変更しませんでした。 (上の私の例のコードでは、すべての距離はユークリッドであるため、すべては2d平面上の点から正で一貫しています。)
2番目の質問については、おそらくdendromgramがネイティブにサポートしているとは思わないので、あなたが望むことをするために独自の注釈ルーチンを展開する必要があります...
最後の質問では、show_leaf_countsは、truncate_mode = 'lastp'オプションでシングルトン以外のリーフノードを表示しようとした場合にのみ機能するようです。基本的に、葉は非常に密集しているため、見づらいです。そのため、葉を表示するだけのオプションがありますが、その葉にいくつが束ねられているかを(括弧内に)表示するオプションがあります。
お役に立てれば。