中国語学習×グラフデータベース(10) - 単語と短文を紐付ける

今日のお題は、単語と短文のNodeを紐付けるのだが、いくつか考えるべきところがある。

Relationshipだらけに意味はあるか

中国語で一番使われている漢字はなんだろうか?ぶっちゃけ分からないけど、「我」「你」「是」「不」みたいな字は、登場頻度が高いような気がする。例えば、将来データベースが大きくなって、10,000ぐらいの短文が格納されたとして、3,000ぐらいの文に「我」が含まれていることが分かっても、少なくとも中国語学習にあたって、実際のところあまり意味がないと思う。

もちろん、機械的に割り当ててしまって、それらのデータを引っ張り出して参照する際にLIMITをかけて出力される数を制限するという考え方もありだと思うが、ひとまず短文に紐付けた方が良さそうなキーワードは自分で決めた上でRelationshipを設定するという考え方でとりあえず行くことにする。

で、正規表現の出番

使い回せるように、Pythonでこんな関数を作ってみた。keywordが文中に含まれる(先頭や末尾の場合を含む)短文に対してCREATE UNIQUEで:usesというRelationshipを設定するのが狙いだ。単純にキーワードが短文中に含まれたらという条件になっている。

def connect_sentence_to_word(keyword):
    result = graph.cypher.execute("MATCH (w:Word {{keyword:'{0}'}}), (s:Sentence) WHERE s.sentence =~'.*{0}.*' CREATE UNIQUE (s)-[:uses]->(w) RETURN w, s".format(keyword))
    return result

動作確認の意味でいくつか動かしてみる。

connect_sentence_to_word('爱')
   | w                                                                    | s                                     
---+----------------------------------------------------------------------+----------------------------------------
 1 | (n1682:Word {keyword:"爱",meaning:"愛する、愛",pinyin:"ai4",pinyinf:"ài"}) | (n3:Sentence {sentence:"他爱上了一个同班同学。"})
 2 | (n1682:Word {keyword:"爱",meaning:"愛する、愛",pinyin:"ai4",pinyinf:"ài"}) | (n4:Sentence {sentence:"爱不起来也不能强迫。"}) 

行幅の関係で見づらいというか、RETURN w.keyword, sにするべきだったと思うが、ひとまず狙った感じでRelationshipが作られたように見える。

ただ、自分としてはKeywordだと思っているのに、単語として登録されていないケースもある。

connect_sentence_to_word('拔')
  | w | s
--+---+---

こんな場合は、空のリストが返ってくる。

離合詞め

ただ、中国語には離合詞というのがあって、要は2つの字の間に目的語が挟まるパターンだ。卒業を意味する「毕业」などはこれに該当する。なので、関数に少し改良を加えてみる。

def connect_sentence_to_word_L(keyword):
    first = keyword[0]
    second = keyword[1:]
    result = graph.cypher.execute("MATCH (w:Word {{keyword:'{0}'}}), (s:Sentence) WHERE s.sentence =~'.*{1}.*{2}.*' CREATE UNIQUE (s)-[:uses]->(w) RETURN w, s".format(keyword, first, second))
    return result

離合詞が2文字で構成されると決めつけている危うさはあるが、cypher.execute()の中の条件を少し変更している。1文字目と2文字目の間に0文字以上の任意の字が挟まっているケースも拾える。

試してみよう。

connect_sentence_to_word_L('毕业')
   | w                                                                       | s                                                   
---+-------------------------------------------------------------------------+------------------------------------------------------
 1 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n88:Sentence {sentence:"他毕业得比我早,是我的学长。"})          
 2 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n89:Sentence {sentence:"拿不到这个学分,就毕不了业了。"})         
 3 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n90:Sentence {sentence:"他毕业于一个地方大学。"})             
 4 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n91:Sentence {sentence:"他毕业快一年了。"})                
 5 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n405:Sentence {sentence:"孩子毕业后在南方闯了几年,很有长进。"})     
 6 | (n1855:Word {keyword:"毕业",meaning:"",pinyin:"bi4 ye4",pinyinf:"bì yè"}) | (n514:Sentence {sentence:"她高中毕业后耽误了一年,所以十九岁才考上大学。"})

少しわかりにくいが、2つめの短文に「毕不了业」という部分があり、きちんと拾えていることが分かる。

気をつける必要があること

とりあえず、いくつかのパターンを試してみて、気がついたことを整理しておく。

離合詞の扱い

  • 自動化するには、その単語が離合詞かどうかの情報が必要だが、今のところDBにはそのような属性を持たせていない。
  • 離合詞は常に2文字なのかがよく分からない。(でも、多分そう。)

単語の漏れ

  • 基本的な単語だと思っていた按,拔などが登録されていない。文から新規単語を登録する仕組みが必要。
  • 比と比较のようなケースは、どのように扱うか?両方に紐付ける?片方だけとする場合は、ルール作りが必要。
  • 動詞と名詞の両方があるような単語の場合どうするか?(例:包)

使って行くにあたって、いろいろ決めておくべき事が多いというのは分かった感じ。

(つづく)

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

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

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

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