トピック分類確率からポスター間距離を算出&Gvizでグラフ作成
LDAトピックモデルにより、各ポスターについてどのトピックに分類されると考えられるのか、その分類確率が算出されます。なので今回は、各ポスターごとにその分類確率をベクトルにまとめて、それらのユークリッド距離を算出することを考えました。
ベクトルは設定したトピック数分の要素を持つので、ポスターのペアごとに残差二乗和を計算しました。分類確率θが格納されたファイルを読込んで、全ポスターペアの残差二乗和を計算してファイルに出力する、「ThetaCorr.rb」スクリプトを作成しました。
次に、この距離が近いほどポスター間の内容が近いと考え、ポスター間の関連を表した図を作成することを考えました。
ポスター間にエッジをひく基準として、算出距離が0.3よりも小さいものという設定をし、また各ノードから最低でも4本はエッジをひく、というようにしました。
この基準をもとにネットワーク図を作りますが、去年もお世話になったGraphvizとRubyのライブラリのGvizで実装していきました。使用方法はまとめたものがありますので、こちらからどうぞ。
さて、今回は1枚の画像にネットワーク図をまとめるので、各ポスターごとに基準を満たした相手へのエッジをひいていくだけの実装です。「ThetaDistanceGraph.rb」にまとめました。
distance_hash.each_with_index do |(opp_poster, distance), i|
if distance > @upper_bound #距離が上限を超えていたら
if (i > (@rank -1)) and (distance > last_distance)
break #最低出力数を超えていて、同順位でもなければ
end
end
#エッジを実体化
@gv.route :"p#{host_poster}" => :"p#{opp_poster}"
last_distance = distance #距離を取っておく
end
といったようにエッジをひいていきます。
また、今回もポスターペア間に2本エッジがひかれてしまい、今度はこれを1本だけにしようと思い、GraphvizのDocumentationからオプションを探しました。すると、グラフ全体の設定として、「concentrate」をtrueにすればよさそうだったので、この設定を加えたところ、複数のエッジが1つにまとまるようになりました。
@gv = Gviz.new
@gv.global layout: 'neato', overlap: false, splines: true, concentrate: true
とすれば良いようです。
以上でネットワーク図を出力できるようになりました。まだエッジをひく基準やネットワーク図の見た目などを調整したいので、次回はこれらをいじっていこうとおもいます。また、今回は「トピック」という全体的なくくりがあるので、これもネットワーク図に表現できたらと考えています。