中国語学習×グラフデータベース(12) - 類義語間のリンク

前回、登録されていないキーワードを拾い集めたので、それをいったん単語として登録するところから再会。

新しい単語の自動新規登録

今回は、ある種機械的に拾い集めたものなので、単語の詳細は後回しにしつつ、自動登録だよという意味で、autoaddという属性をつけて登録してみた。

for word in unknown_words:
    new_word = Node("Word", keyword=word, autoadd=True)
    graph.create(new_word)

もしautoadd=Trueという属性を持っていたら、その単語は自動的に登録されたものだよということが明確になるのが狙い。

類義語の組み合わせには方向性はない(はず)

続いて、類義語同士を:is_similar_toというrelationshipでつないでみるのだが、少なくとも今回使用した資料には、類義語間の方向性はない。例えば、Aから見てBは類義語だが、Bから見てAは類義語ではないというようなケースは考えない。Neo4jのRelationshipはすべて有方向性にする必要があるが、この場合は2つのアプローチがあると思う。

  • お互いに類義語として、両方向(つまり2本)のRelationshipを設定する。
  • 便宜上片方向となるが1本だけRelationshipを設定する。

今回は、後者のアプローチで行く事にした。理由はクエリを実行する際に方向は無視すれば良いだけで、わざわざ2本を引っ張るとグラフが煩雑になりそうだからという単純な理由。あとは、類語間どうしの「組み合わせ」を見つけて、その間でRelationshipを引けば良いはず。組み合わせを作るのは、itertools.combinationsでOK。

from itertools import combinations as cmb
for words in combinations:
    combination_set = list(cmb(words, 2))
    for element in combination_set:
        graph.cypher.execute("MATCH (w1:Word {{keyword:'{0}'}}), (w2:Word {{keyword:'{1}'}}) CREATE UNIQUE (w1)-[:is_similar_to]->(w2) RETURN w1, w2".format(element[0], element[1]))

comibinationsというリストを作った事を後悔したのはここ。itertools.combinationsの方はcmbという名称で呼び出すことにした。ロジックとしては、単語2つの組み合わせのリストをcombination_setというものを作り、その単語間で:is_similar_toというRelationshipを登録している。

ここまでの出来映え

これでRelationshipが登録されたので、Neo4j側で、こんなクエリを実行してみた。

MATCH (s:Sentence)-[:uses]->(w:Word)-[r:is_similar_to]->(w2:Word)<-[:uses]-(s2:Sentence) RETURN s, s2, w, w2, r

出てきたグラフはこんな感じ。
f:id:deutschina:20160225174522p:plain
緑色の単語同士がつながり、その外側に青色の例文がつながっている様子が分かる。良い感じ。

ということで、一通りの流れを追ってきたが、これまで取り上げられてなかった細々した話を次回で整理したい。

(つづく)

グラフ型データベース入門 - Neo4jを使う

グラフ型データベース入門 - Neo4jを使う

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門