3次元点集合データ(ポイントクラウド)の解析

この文章で解説するのは

  1. 3次元の点データからパーシステント図を計算する
  2. その図をパラメータを変えながら可視化する
  3. テキストデータにbirth-death pairを出力する
  4. 基本的な逆解析(birth simplex, death simplexの出力)を行う

の4つです。ここまではおよそどのようなポイントクラウドデータでも 共通ですので、ここまでできるようになると良いでしょう。

version 3.0 以降に関する注意

推奨される出力ファイルの識別子が .idiagram から .pdgm に変更になりました.内部フォーマットも変更されています.

パーシステント図の計算

対称となるデータは pointcloud.txt というファイルです。これは 3次元標準正規分布に従うランダムな点を 5000個撒き散らしたものです。これを解析してみましょう。

まずこれを表示します。最初の10行を見てみましょう

このようにデータが3列で並んでいます

データからパーシステント図を計算します。 python3 -m homcloud.pc_alpha というコマンドを使います。 利便性のため、homcloud-pc-alphaというコマンドもあり、これも同じ動作をします。

とします。すると pointcloud.pdgm というファイルが生成されます。これが パーシステント図の情報を収めたファイルです。-d 3というのが入力データの次元 (ここでは3)で、pointcloud.txt で入力データを、pointcloud.pdgmで出力データを 指定します。

パーシステント図の可視化

次に、ここからパーシステント図をプロットしてみましょう。

とします。ここで-d 1というのは1次のパーシステント図(つまりリングの情報)を 可視化することを意味します。-d 2とすると2次のパーシステント図(つまり空隙の情報)を 可視化します。-o pointcloud-pd1.pngは画像を出力先のファイル名を指定します。すると以下のような画像が出力されます。

ここで使っている display は jupyter notebookでbashを使うときに画像を表示するためのインターフェースです。 jupyter notebookと組み合わせると便利なのでこのチュートリアルでは使っていきます。

左下のほうに何かちょっと見えてあとは何も見えません。というのは このデータは左下のほうにデータ(birth-death pair)が偏っているからです。 そこで色付けを log scale にしましょう。-l オプションを使います。あとX軸とY軸のスケールが違うのはかっこ悪いのでそれも直します。 こちらは --aspect equal です。

基本的にはパーシステント図の点は対角線から離れるほど「意味のある」リング構造と対応し、 またY軸が大きい値になるほど大きなリング構造を表しています。 つまり(0.5, 0.7)のあたりにある点がこのランダムな点がなすリング構造のなかで最も ちゃんとしたリング構造を持っているものと対応していると言えそうです。

ここで注意しておくと、パーシステント図のX、Y軸は点に貼り付ける球の半径と対応していると よくある教科書には書かれています。HomCloudでは実はこれは半径の2乗が使われています。 つまり√0.5≒0.7と√0.7≒0.84が実際の半径になります。これは主には内部のアルゴリズムの都合に よるものですが、各点に重みづけをしたときにはこのほうが自然に見えるという事情もあり、 HomCloudでは2乗の値が使われます。これを止めたいときはパーシステント図を homcloud.pc_alpha で計算するときに --no-square オプションを付けると 半径パラメータそのものがX、Y軸に現れます。

さて、次にbirth-death pairが集中している 左下の 0.0〜0.1 のあたりを拡大して調べてみましょう。デフォルトでは すべてのbirth-death pairが含まれるような範囲でプロットするので、これを変更します。 このときは以下のようなコマンドを使います。-xオプションで範囲を指定します。

もちろんランダムデータですので意味のあるリング構造があるわけでは ないのですが、ランダムだとこういうヒストグラムの分布が見えるんだなあ、というのは 知っておくと役に立ちます。

-Xオプションで解像度を変えることができます。デフォルトでは 128x128でヒストグラムを描きますが、もっと細かく256x256にしてみましょう。 以下のコマンドです。

ここでは画像を保存してdisplayで表示していましたが、matplotlib (pythonのプロットライブラリ)のインタラクティブインターフェスも 使えることを覚えておくと良いです。-o ...による出力ファイル指定を削るとウィンドウが表示されます。 これは右上に x=... y=... というのが表示されていてマウスカーソルがパーシステント図のどの座標の位置にあるのかを 表示してくれたりします。

また、plot_PD_guiというモジュールもあり、これはより高度なインタラクティブGUIを提供します。ここで説明したような プロットのパラメータ変更などがインタラクティブにできます。以下のようにして起動します。

テキストデータでの解析

次にパーシステント図をテキストデータとして出力してみましょう。 計算したパーシステント図をさらに統計処理したい、といった場合には テキスト出力をしてそれを使うのが手軽です。以下のコマンドです。

すると2列の数値データが出力されます。これは1次のbirth-death pairすべてを列挙していて、 左側の数値がbirth time、右側の数値がdeath timeです。これも 半径の2乗の値が出力されます。-d 1の所を-d 2にすると2次のbirth death pairが 出力されます。-S noは後で説明します

さて、実際に利用するときにはファイルに保存したいでしょうから、-oオプションを使って以下のように やってみましょう。すると pointcloud-pd1.txt に1次のbirth-death pairの情報がテキストで保存されます。

簡単な逆解析について

パーシステント図の個々の点は何らかの意味で元のポイントクラウドのリング構造、空隙構造と 対応しているはずです。しかしそれがどのようなものであるのかを特定するのは実は そんなに簡単ではないです。このような解析を逆解析と呼びます。HomCloudの 基本的な逆解析のツールであるbirth simplex、death simplexというものを使ってみましょう。birth/death simplexについては 大林のサーベイ論文が理解に有用です。 これには-Sオプションにyesを渡すと表示されます。

これの最初の2列はbirth time、death timeです。次の2つの列 (よく見ると、{...} {...}という形をしています) がそれぞれbirth simplex、death simplexです。 これの最初の行は(0.0005037159143533377, 0.0005579705552885796)というbirth death pairに 対応するリング構造は、

(0.950995498828,-1.00684503611,0.544429148124)
(0.957826751985,-1.02576376749,0.584557432918)

の2つの点を結んだ辺が「現れた」タイミングで生じ、

(0.950995498828,-1.00684503611,0.544429148124)
(0.949185316562,-1.0446271794,0.553072016288)
(0.957826751985,-1.02576376749,0.584557432918)

の3つの点を頂点とする3角形が「現れた」タイミングで消えたことを意味します。 上で上げたサーベイ論文が理解の助けになるでしょう。特に実際的なデータ解析では death simplexのほうが重要です。death simplexの重心あたりがリング構造の 中心になることが多いと考えられるためです。この出力結果は ファイルpointcloud-pd1.txtに保存されていますのででそれをさらに解析することでリングの空間分布を調べる ようなこともできます。

高度な逆解析機能について(Optimal Volume)

次は HomCloud の強力な逆解析ツールである、optimal volumeを使いましょう。 optimal volume について詳しくは、大林の論文を参考にしてください。 とりあえずさきほど表示したパーシステント図をもう一度見てみましょう

(0.5, 0.7) 付近に birth-death pair があります。これは 対角線から離れているため、他のリングに比べて重要度が高そうです。これ の optimal volume を調べましょう。homcloud.optimal_volume モジュールを使います。 以下のようなコマンドを実行します。-d 1で次数を、-x 0.5 -y 0.7でbirth-death pairの位置を 指定します。位置を精密に指定しなくとも、指定した点に一番近いpairを探索してそのpairのoptimal volumeを計算します。 -Pは内部的にparaviewコマンドを使って可視化をすることを指定します。

するとparaviewのウィンウドウが表示されたはずです。左側のパネルの「Apply」ボタンを押すと表示がされます。 緑のリングが対象となるリングです。それ以外にも様々な情報が表示されています。

この情報は ファイルに保存することもできます。以下のようにします。

optimal_volume.jsonにoptimal volumeの情報が保存されています。 これはjson formatになっていて様々な情報が保存されています。 このファイルの中身については現在ドキュメントを準備中です。 とりあえずは大林に質問してください。

optimal volumeとbirth/death simplexの使い分けですが、optimal volumeのほうが情報量が多いので普段はこちらを使えばよいでしょう。 ただ、optimal volumeは計算コストが大きいので、入力データのサイズが大きい場合や多くのbirth-death pairで計算したい場合で 計算時間がどうしようもなくなったら birth/death simplexの利用を検討すると良いでしょう。

以上でこのチュートリアルは終わりです。お疲れさまでした。