🦓 『入門 自然言語処理』メモ (3) -単語の処理
作成日: 2021/11/11
1

分析対象テキスト 'LaFeino.txt' を単語・アイテム単位に分割する方法は2種類あります。raw ファイルに word_tokenize() 関数を適用する方法と、テキストファイルに words() メソッドを適用する方法です。

>>> # 生ファイルのトークン化
>>> feino_tokens = nltk.word_tokenize(tekstaro.raw('LaFeino.txt'))
>>> type(feino_tokens)
<class 'list'>
>>> len(feino_tokens)
1064
>>> # 指定ファイルの単語一覧を取得
>>> feino_words = tekstaro.words('LaFeino.txt')
>>> type(feino_words)
<class 'nltk.corpus.reader.util.StreamBackedCorpusView'>
>>> len(feino_words)
1042

word_tokenize() 関数は「テキストを単語や句読点のような基本単位(トークン)へ分解する」と書いてあるのですが、NLTKバージョン3.6.5では特定の条件下でピリオドが単語末に付いたままになる現象が発生します。下図で 'trinki.' となっていることに注意。

[...] 'se', 'vi', 'volas', 'trinki.', '”', '—', '“', 'Vi', 'tute', 'ne', [...]

words() メソッドでは、当該の部分が 'trinki', '.”' のようになります。

[...] 'se', 'vi', 'volas', 'trinki', '.”', '—', '“', 'Vi', 'tute', 'ne', [...]

連続する記号が一つのトークンになる代わりに、単語末にピリオドが残ることはありません。単語の処理をおこなう場合は words() メソッドを使ったほうがよさそうです。

>>> # 単語の頻度分布
>>> fdist_w = nltk.FreqDist(feino_words)
>>> type(fdist_w)
<class 'nltk.probability.FreqDist'>
>>> len(fdist_w)
357
>>> fdist_w
FreqDist({',': 94, 'la': 43, 'ŝi': 30, 'al': 28, '.': 26, 'kaj': 24, '“': 23, 'ke': 19, 'de': 16, 'ĉi': 15, ...})
>>> fdist_w.most_common()
[(',', 94), ('la', 43), ('ŝi', 30), ...(中略)... ('mortis', 1), ('angulo', 1)]

FreqDist() 関数で単語(トークン)の頻度分布を求めます。words() メソッドを使っただけでは記号もトークンなので、統計結果に含まれます。単語だけの頻度分布を求めるには、ちょっと工夫がいります。

>>> feino_vortoj = [w.lower() for w in feino_words if w.isalpha()]
>>> type(feino_vortoj)
<class 'list'>
>>> len(feino_vortoj)
851
>>> feino_vortoj
['la', 'feino', 'unu', 'vidvino', 'havis', ...(中略)... 'angulo', 'de', 'arbaro']

lower() メソッドですべての単語を小文字化し、大文字・小文字の区別を無くします。さらに isalpha() メソッドで数字・記号類を除きます。数字・記号類を含まない、小文字だけの単語リストができました。

>>> fdist_v = nltk.FreqDist(feino_vortoj)
>>> type(fdist_v)
<class 'nltk.probability.FreqDist'>
>>> len(fdist_v)
320
>>> fdist_v
FreqDist({'la': 52, 'ŝi': 33, 'al': 28, 'kaj': 27, 'ke': 19, 'de': 17, 'ĉi': 15, 'vi': 15, 'mi': 14, 'ŝin': 13, ...})
>>> fdist_v.most_common()
[('la', 52), ('ŝi', 33), ('al', 28), ...(中略)... ('mortis', 1), ('angulo', 1)]

この単語リストを FreqDist() 関数に通すと、単語だけの頻度分布が得られました。頻度リスト全部を表示するには most_common() メソッドを使います。


pythonで自然言語処理プログラムが書けるようになりたいと思っています。Ticketnoteで自分の到達度を確認できれば嬉しいです。