はじめに
頑張れば、何かがあるって、信じてる。nikkieです。
2019年12月末から自然言語処理のネタで毎週1本ブログを書いています。
先週から自然言語処理の基礎固めとして『入門 自然言語処理』に取り組んでいます。

- 作者:Steven Bird,Ewan Klein,Edward Loper
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/11/11
- メディア: 大型本
今週は5章「単語の分類とタグ付け」の冒頭部分、品詞タグ付けの紹介から、英語のテキストについて品詞タグ付けを試してみました。
目次
前回までのブログ駆動開発!との関連
先日 janome のチュートリアル1の中で、「風の又三郎」(日本語テキスト)から名詞と動詞を取り出して、WordCloudを作りました。
同チュートリアルは、英語テキストの例として、『不思議の国のアリス』でもWordCloudを作っています2。
『入門 自然言語処理』3で、英語テキストについての品詞タグ付け(以下、タグ付け)を知りました。
「『風の又三郎』の例で品詞を名詞と動詞に絞ったのと同じように、『不思議の国のアリス』でも品詞を絞れるのでは?」と着想し、試してみました。
『不思議の国のアリス』の英語テキストから、名詞と動詞を使ってWordCloudを作ります。
動作環境
先週と同じ環境に、WordCloud作成に必要なパッケージを追加しました。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.14.6 BuildVersion: 18G103 $ python -V # venvによる仮想環境を使用 Python 3.7.3 $ pip list # grepを使って抜粋して表示 beautifulsoup4 4.8.2 ipython 7.12.0 matplotlib 3.1.3 # 追加 nltk 3.4.5 wordcloud 1.6.0 # 追加
WordCloudを作れるよう、janome のチュートリアルに沿った環境構築をします。
$ unzip ~/Downloads/ipagp00303.zip -d . $ wget https://raw.githubusercontent.com/mocobeta/janome-tutorial/master/hands-on/data/alice_utf8.txt .
フォルダ配置
. ├── alice_utf8.txt ├── alice_word_cloud.py ├── env ├── ipagp00303 └── result # 作成したWordCloudの画像を置く
nltk を使ったタグ付け
nltk.word_tokenize したテキスト(トークンのリスト)をnltk.tag.pos_tagでタグ付けできます。
Use NLTK’s currently recommended part of speech tagger to tag the given list of tokens.
今回使われたタガーは averaged_perceptron_tagger のようです(例のごとくnltk.downloadが必要でした)
以下は、同音異義語が登場する例です。
In [8]: text = nltk.word_tokenize("They refuse to permit us to obtain the refuse permit") In [9]: nltk.pos_tag(text) Out[9]: [('They', 'PRP'), ('refuse', 'VBP'), ('to', 'TO'), ('permit', 'VB'), ('us', 'PRP'), ('to', 'TO'), ('obtain', 'VB'), ('the', 'DT'), ('refuse', 'NN'), ('permit', 'NN')]
結果から、
- 名詞はNNで始まる
- 動詞はVBで始まる
ようです。
書籍 例5-1 のプログラムを見たところ、これらはNNやVBで始まると仮定してよさそうだったので、続きを考えていきました(時間の制約により掘り下げられていません)。
ソースコード
import matplotlib.pyplot as plt import nltk from wordcloud import WordCloud SEED = 42 def show_wordcloud(text, save_path): if isinstance(text, list): text = ' '.join(text) wordcloud = WordCloud( font_path='ipagp00303/ipagp.ttf', background_color='white', width=1024, height=674, random_state=SEED, collocations=False).generate(text) plt.imshow(wordcloud, interpolation='bilinear') plt.axis('off') plt.savefig(save_path) if __name__ == '__main__': with open('alice_utf8.txt', encoding='utf8') as f: concatenated_text = f.read() concatenated_text = concatenated_text.lower() # 正規化 show_wordcloud(concatenated_text, 'result/orig_alice_cloud.png') text = nltk.word_tokenize(concatenated_text) print(f'tokenized: {len(text)}') show_wordcloud(text, 'result/tokenized.png') tagged = nltk.pos_tag(text) nouns_and_verbs = [ word for word, tag in tagged if tag.startswith(('NN', 'VB'))] print(f'tagged: {len(nouns_and_verbs)}') show_wordcloud(nouns_and_verbs, 'result/nouns_and_verbs.png')
作成されたWordCloud
上記のスクリプトを実行すると、3つのWordCloudができます。
- 元のファイルの全文から作ったWordCloud
word_tokenizeした後の単語から作ったWordCloud- 2から名詞と動詞を取り出して作ったWordCloud
1.元のファイルの全文から作ったWordCloud

2. word_tokenizeした後の単語から作ったWordCloud

n't という単語が現れているところにトークン化の効果が感じられます。
WordCloud.generateには、自然言語のテキスト(a natural text)を渡す必要があるため、単語のリストを半角スペースでjoinして自然言語のテキストのように見せました。
3. 2から名詞と動詞を取り出して作ったWordCloud

WordCloudに含まれる単語数は
- トークン化で12460語
- 名詞と動詞を取り出して4106語
と変化しました。
queen などの名詞が2より大きく表示されているところに効果を感じます。
風の又三郎の例のように、見ただけで内容が分かるようにしたいので、工夫の余地はありそうですね。
感想
今週平日は別に締切のあったタスクを進め、土日はOOC 2020の当日スタッフをし、いま、OOCの達成感と疲労の中でたびたび意識を飛ばしつつ、この記事を書いています。
これまでの週に比べると短縮版ではありますが、「『風の又三郎』の例でやったことは日本語に限らず英語でもできるんだ」という気づきがありました。
『入門 自然言語処理』を読み進めることで、言語の違いによらない、自然言語処理の抽象的な方法を学べそうという印象です。
土曜日にお別れの会が執り行われたPython2系ですが、『入門 自然言語処理』を通して引き続き思い出作りをしていきます。
課題
startswith(('NN', 'VB'))よりも深堀りした名詞・動詞の取り出し方- そのために5章をもっと読む
- 3章のステミングやレマタイズを取り入れる
- WordCloudの余白は、
matplotlibのコードのどこが原因?