説明
トライ木っぽいのが必要になったので作ることにしました。プレフィックス木とも言うらしい。
以下、Wikipediaより引用です。
トライ木(英: trie)やプレフィックス木(英: prefix tree)とは、順序付き木の一種。あるノードの配下の全ノードは、自身に対応する文字列に共通するプレフィックス(接頭部)があり、ルート(根)には空の文字列が対応している。値は一般に全ノードに対応して存在するわけではなく、末端ノードや一部の中間ノードだけがキーに対応した値を格納している。2分探索木と異なり、各ノードに個々のキーが格納されるのではなく、木構造上のノードの位置とキーが対応している。
今回は文字列ではなく単語列を対象にしてトライ木っぽいのを作ります。
例えば、
- I like cats.
- I like dogs.
- I play the guitar.
- He makes me happy.
という英文があった時、先頭の候補は「I」と「He」、先頭が「I」の場合の次の候補は「like」と「play」、先頭から「I」「play」と続いた場合の次の候補は「the」のみ、となるような構造を作ります。
実装
まず、以下のようなファイルを用意します。
sentences.txt
He went to the store.
The pizza smells good.
The music makes me happy.
I like cats.
I like dogs.
I like an apple.
I play the guitar.
そして以下のスクリプトで文章の読み込みから単語リストの作成、トライ木の作成を行います。
def addTree(tree, sentence):
if not sentence[0:]:
return None
if sentence[0] not in tree:
tree[sentence[0]] = {}
tree[sentence[0]] = addTree(tree[sentence[0]], sentence[1:])
return tree
def createTree(sentences):
tree = {}
for sentence in sentences:
tree = addTree(tree, sentence)
return tree
sentences = []
with open('./sentences.txt', 'r') as f:
for row in f:
sentences.append(row.split())
tree = createTree(sentences)
ここで得たtreeに対して以下のように単語ごとのアクセスを繰り返すことで、文章を絞り込むことができます。
print(tree['He'])
print(tree['He']['went'])
print(tree['The'])
print(tree['The']['pizza'])
print(tree['The']['music'])
print(tree['I'])
print(tree['I']['like'])
print(tree['I']['play'])
結果
{'went': {'to': {'the': {'store.': None}}}}
{'to': {'the': {'store.': None}}}
{'pizza': {'smells': {'good.': None}}, 'music': {'makes': {'me': {'happy.': None}}}}
{'smells': {'good.': None}}
{'makes': {'me': {'happy.': None}}}
{'like': {'cats.': None, 'dogs.': None, 'an': {'apple.': None}}, 'play': {'the': {'guitar.': None}}}
{'cats.': None, 'dogs.': None, 'an': {'apple.': None}}
{'the': {'guitar.': None}}
ちなみに、生成された木構造全体は以下のようになっています。
結果
{'He': {'went': {'to': {'the': {'store.': None}}}}, 'The': {'pizza': {'smells': {'good.': None}}, 'music': {'makes': {'me': {'happy.': None}}}}, 'I': {'like': {'cats.': None, 'dogs.': None, 'an': {'apple.': None}}, 'play': {'the': {'guitar.': None}}}}
tree['単語1']['単語2']['単語3']... というふうに繰り返すことで、文章を絞り込めます。