🦒 『入門 自然言語処理』メモ (5) - 文の処理
作成日: 2021/11/13
0

テキストを文に分けるためには sents() メソッドを適用します。

>>> feino_sents = tekstaro.sents('LaFeino.txt')
>>> type(feino_sents)
<class 'nltk.corpus.reader.util.StreamBackedCorpusView'>
>>> len(feino_sents)
36
>>> feino_sents
[['La', 'feino', '.'], ['Unu', 'vidvino', 'havis', 'du', 'filinojn', '.'], ...]
>>> feino_sents[0:]
[['La', 'feino', '.'], ['Unu', 'vidvino', ...(中略)... , 'en', 'angulo', 'de', 'arbaro', '.']]

sents() メソッドを適用すると、リストのリストが生成されます。テキスト全体が一つのリストであり、その要素としての文が単語のリストとなっています。'LaFeino.txt' は36個の文から成るテキストであることを示しています。
それぞれの文の長さ(=含まれるトークン数)を求めるには次のようにします。

>>> feino_slen = [len(s) for s in feino_sents]
>>> feino_slen
[3, 6, 48, 34, 37, 11, 27, 28, 12, 37, 66, 53, 19, 22, 12, 14, 24, 28, 17, 28, 70, 14, 59, 23, 18, 27, 69, 15, 22, 13, 41, 15, 34, 8, 42, 46]
>>> sum(feino_slen)  
1042
>>> max(feino_slen)
70
>>> min(feino_slen) 
3
>>> round(sum(feino_slen)/len(feino_slen))   
29

sum() 関数はリスト内の合計値(=テキスト内のトークン総数)を示します。max() 関数は最大値(=最も長い文のトークン数)、min() 関数は最小値(=最も短い文のトークン数)を示します。テキスト内の文の平均長は sum()/len() で求めることができます。
ただし、このやり方では文の長さに句読点や記号類を含むので、「文の長さ=単語数」ではありません。句読点や記号類を含まずに、純粋に単語だけで文の長さを求めるには、以下のようにします。

feino_sents2 = [[w for w in s if w.isalpha()] for s in feino_sents]
>>> type(feino_sents2)
<class 'list'>
>>> len(feino_sents2)
36
>>> feino_sents2
[['La', 'feino'], ['Unu', 'vidvino', 'havis', 'du', 'filinojn'], ...(中略)... , 'en', 'angulo', 'de', 'arbaro']]
>>> sum(feino_slen2)  
851
>>> max(feino_slen2)  
55
>>> min(feino_slen2)  
2
>>> round(sum(feino_slen2)/len(feino_slen2))
24

テキスト内の単語総数は 851個、最も長い文の単語数は 55個、最も短い文の単語数は2個で、文の平均長は24語という結果になりました。トークン数で求めた値よりもそれぞれ少なくなっています。
参考までに、『入門』で取り上げられている 'melville-moby_dick.txt' を同じように処理したところ、テキスト内の文の平均トークン数は 26個、平均単語数は 22個と出ました。


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