具体例で学ぶ!情報可視化のテクニック

第3回 ツリーマップによる木構造の可視化(前編)

この記事を読むのに必要な時間:およそ 3 分

二分木のツリーマップ

前回解説した階層的クラスタリングでは,各々のノードがそれぞれ2つの子ノードを持つ「二分木」のクラスタツリー構造が出力されたことを憶えているでしょうか。今回からは,この二分木を入力として,長方形型のツリーマップを描画することを目標にします。

それでは早速,二分木からツリーマップを作成する手順を見ていきましょう。

1. ツリーマップの各領域の面積を決めるため,二分木の各末端ノードにあらかじめ「サイズ」の数値属性を持たせておく図3⁠。

図3

図3 treemap_process1

2. ツリー全体を格納する大きな長方形を用意する。

3. 長方形を,ルートノードが持つ2つの子ノードのサイズ比率に従って分割する図4⁠。

図4

図4 treemap_process2

このとき,長方形のアスペクト比(縦横比)ができるだけ1:1に近づくように,以下の方針で分割する。

  • 現在の長方形が横長ならば,左右に分割する
  • 現在の長方形が縦長ならば,上下に分割する

4. 分割後の長方形と対応する子ノードについて,同様の処理を再帰的に実行する図5⁠。

図5

図5 treemap_process3

処理対象のツリー構造を二分木に限定した場合,このように単純なロジックで領域を分割していくことができます。したがって,階層的クラスタリングとツリーマップの相性は非常に良いと言えるでしょう。

階層的クラスタリングの手直し

ツリーマップの描画に先立って,前回作成した階層的クラスタリングのプログラムに機能追加を行います。機能追加の内容は,ノードインターフェイスの拡張と,新しい距離関数の導入です。以下,順に見ていきましょう。

ノードサイズの導入

クラスタリングのノードを示すNodeインターフェイスに,ノードサイズを返すgetArea()メソッドを追加します。

リスト1 Node.java

public interface Node {
    List getVectors();
    double getArea();
}

このgetArea()メソッドを,ItemクラスとClusterクラスでそれぞれ実装します。まずItemクラスでは,double型のarea変数をフィールドに用意し,値をそのまま返すようにします。

リスト2 Item.java(部分)

public class Item {
    private String name;
    private MultiVector vector;
    private double area;

    public Item(String name, MultiVector vector, double area) {
        this.name = name;
        this.vector = vector;
        this.area = area;
    }

    public double getArea() { return area; }
    ...
}

次にClusterクラスでは,左右の子ノードのgetArea()メソッドを呼び出し,その戻り値の合計を返すようにします。

リスト3 Cluster.java(部分)

public class Cluster {
    private Node left;
    private Node right;

    public double getArea() {
        return left.getArea() + right.getArea();
    }

   ...
}

著者プロフィール

浜本階生(はまもとかいせい)

1981年生まれ。栃木県出身。東京工業大学情報工学科卒業。技術やアイデアの組み合わせから面白いソフトウェアを生み出したいと日々考えている。現在,ブログの解析および視覚化の試みとして「TopHatenar」「Blogopolis」を開発,運用中。

URLhttp://d.hatena.ne.jp/kaiseh/