[Python] sklearn.AgglomerativeClusteringを使って樹形図をプロットする


Answers

ここでは、sklearnから階層的クラスタリングモデルを取り出し、scipy dendrogram関数を使ってそれをプロットする単純な関数を示します。 グラフ関数のようなものはsklearnで直接サポートされていないことが多いようです。 このplot_dendrogramコードスニペットのプルリクエストに関連する興味深い議論をここで見つけることができます。

scipyのlinkageを使って階層的なクラスタリングを実行した後は、クラスターの数をfclusterしてfclusterを使用して、任意の数のクラスターに階層をカットすることができます(クラスターの数を定義するユースケースはscipyで利用可能です)。 t引数で指定し、 criterion='maxclust'引数で指定します。

Question

AgglomerativeClusteringで提供されているchildren_属性を使用して樹形図を作成しようとしてchildren_ますが、これまでのところ私は不運です。 私はscipy.cluster使うことができませんscipy.cluster提供されている凝集クラスタリングには、重要なオプションがいくつかありません(クラスタの量を指定するオプションなど)。 私は本当にそこに任意のアドバイスのために感謝しています。

    import sklearn.cluster
    clstr = cluster.AgglomerativeClustering(n_clusters=2)
    clusterer.children_



Pythonから抜け出し、堅牢なD3ライブラリを使用しd3.cluster()場合は、 d3.cluster() (またはd3.tree() )API)を使用して、すばらしいカスタマイズ可能な結果を​​得ることはd3.cluster()難しいことではありません。

jsfiddleでデモをご覧ください。

children_配列は幸いなことにJS配列として簡単に機能し、唯一の中間ステップはd3.stratify()を使って階層表現にすることです。 具体的には、各ノードにidparentIdが必要です。

var N = 272;  // Your n_samples/corpus size.
var root = d3.stratify()
  .id((d,i) => i + N)
  .parentId((d, i) => {
    var parIndex = data.findIndex(e => e.includes(i + N));
    if (parIndex < 0) {
      return; // The root should have an undefined parentId.
    }
    return parIndex + N;
  })(data); // Your children_

あなたはfindIndex行のためにここで少なくともO(n ^ 2)の動作にfindIndexますが、n_samplesが巨大になるまではおそらく問題ありません。その場合は、より効率的なインデックスをあらかじめ計算することができます。

それ以外にも、 d3.cluster()プラグアンドd3.cluster()使用がかなりあります。 mbostockのカノニカルブロックまたはJSFiddleを参照してください。

NB私の使用事例では、単に非リーフノードを表示するだけで十分でした。 サンプル/リーフをすべて明示的にchildren_配列に入れるわけではないので、サンプル/リーフを視覚化するのはややこしいことです。