今回は、日本語の文章を解析して、よく使われている単語をピックアップするプログラムをつくってみよう。その例として、夏目漱石の代表作「こころ」を題材にして、頻出語句を調べる。漱石が作中で最も使った単語は何だろうか。プログラミングで数えてみよう。

日本語を単語ごとを区切るのは簡単ではない

そもそも、スペースで区切られている英語と違って、日本語は単語の区切れが分かりづらい。英文であれば、文章をスペースで区切って、前方から出現単語をカウントすれば良いので容易にカウントできる。

これに対して、日本語の文章では、語句が連続しているため、単純に単語の区切りを得ることが難しい。もちろん句読点を入れることはあるが、それは意味の区切りであって単語の区切りではない。

それで、日本語の文章を単語ごとに分けるためには、どうしても、単語辞書などを利用して、文章を前方から少しずつ区切っていくという作業が必要になる。しかも、日本語は動詞の末尾が変化するので、それらを考慮に入れなくてはならない。

形態素解析ライブラリを使おう

だが、心配は無用だ。昨今では、日本語の文章を区切ってくれる便利なライブラリがある。それが「形態素解析」という技術だ。「形態素解析」とは、文章を意味のある最小単位の要素である「形態素」に分割する処理のことだ。しかも、多くの形態素解析ツールやライブラリが、オープンソースで公開されている。

それで、今回は、インストールが手軽という点に注目して、Pythonで形態素解析を行うライブラリ「Janome」を利用してみよう。

Janomeをインストールを行うには、コマンドラインから以下のようなコマンドを実行する。WindowsでAnacondaを利用しているなら、Windowsメニューから「Anaconda > Anaconda Prompt」を起動しよう。オリジナルPythonを利用しているなら、PowerShellを起動します。macOSでは、ターミナル.appを起動しよう。

[Windowsの場合 / macOS + Anacondaの場合]

pip install janome

[macOSでPythonを利用する場合]

pip3 install janome

Janomeを使ってみよう

それでは、Janomeを使ってみよう。以下は、簡単な文章「今日は家族でラーメンを食べに行った。」を形態素に分解して表示するプログラムだ。まずは、以下のプログラムを「test_janome.py」という名前で保存しよう。

# Janomeを使うための宣言 --- (*1)
from janome.tokenizer import Tokenizer
# Janomeの準備 --- (*2)
tok = Tokenizer()
# 形態素に分割 --- (*3)
tokens = tok.tokenize("今日は家族でラーメンを食べに行った。")
# 分割結果を確認 --- (*4)
for t in tokens:
   print(t)

そして、コマンドラインからプログラムを実行してみましょう。(なお、macOSで標準のPythonをインストールしている場合は、コマンドをpythonではなくpython3に変えて実行する。)

python test_janome.py

すると、以下のように、文章が形態素に分割されて表示される。ちなみに、以下は、話題のターミナル「cool-retro-term」を使って、プログラムを実行したところだ。

Janomeで文章を形態素に分解したところ

プログラムを確認してみよう。(*1)の部分はJanomeのライブラリを使うための宣言だ。(*2)の部分では、Janomeを使うために、Tokenizerのオブジェクトを作成する。(*3)の部分では、tokenize()メソッドを使って、文章を形態素に分割する。そして、最後(*4)の部分では、分割した形態素を一つずつ表示する。

夏目漱石の「こころ」をダウンロードしよう

Janomeの基本的な使い方が分かったところで、夏目漱石の「こころ」をダウンロードしよう。明治の文学作品は、原則著作権が消滅しているので、こちらの青空文庫から自由にダウンロードできる。ここでは、テキストファイル(zip形式)をダウンロードして使ってみよう。

青空文庫からテキストファイルをダウンロード

ダウンロードしたZIPファイルを、解凍すると「kokoro.txt」というファイルが作成される。このテキストファイルは、文字エンコーディング「Shift_JIS」になっている。これを踏まえて、テキストファイルを読み込んで、形態素に分割し、単語をカウントしてみよう。

カウントするプログラム

以下が、こころの頻出語句ベスト100を表示するプログラムだ。「count_kokoro.py」という名前で保存しよう。

# Janomeを使うための宣言 
from janome.tokenizer import Tokenizer

# 「こころ」を読み込む --- (*1)
fp = open("kokoro.txt", "rt", encoding="sjis")
text = fp.read()

# Janomeの準備 --- (*2)
tok = Tokenizer()
tokens = tok.tokenize(text)

# 形態素をカウント --- (*3)
counter = {}
for t in tokens:
    bf = t.base_form
    if not bf in counter: counter[bf] = 0
    counter[bf] += 1

# カウントの多い順に並び替える --- (*4)
sc = sorted(counter.items(), key=lambda x: x[1], reverse=True)
# 並び替えたものを表示 --- (*5)
for i, t in enumerate(sc):
    if i >= 100: break
    key, cnt = t
    print((i + 1), ".", key, "=", cnt)

そして、プログラムを実行するために、コマンドラインに以下を入力しよう。

python count_kokoro.py

「こころ」は、それなりに長い小説なので、形態素解析の処理にも、それなりに時間がかかることだろう。プログラムを実行すると、以下のような結果が表示される。

「こころ」の頻出語句ベスト100を表示したところ

上記の画面では、15行ほどしか表示されていないが、コマンドラインをスクロールすることで、すべての結果を確認できる。

さて、実行結果についてだが、助詞や記号を除けば、「私」「先生」が最も多く使われており、他にも「K」「奥さん」など、ベスト100の上位には、小説の登場人物の名前が並んだ。

それで、続けて登場人物以外で意味のある単語に注目してみると、名詞では、「人」「時」「顔」「言葉」「字」が、動詞なら「来る」「思う」「見る」「聞く」「出る」「帰る」「考える」などがあった。なんとも、漱石らしい言葉が並んだ。

それでは、プログラムを確認しよう。(*1)の部分では、Shift_JISで書かれた「こころ」のテキストを読む。そして。(*2)の部分で、形態素解析を行う。そして、(*3)の部分で単語をカウントする。ここでは、辞書型(dict)を利用する。このとき、単語を辞書のキーに、出現回数を辞書の値にして、単語が出現するたびに、単語をカウントアップする。

そして、プログラムの(*4)の部分で、sorted()関数を利用して、出現回数順に並び替えを行う。並び替えたなら、(*5)の部分で、最大100件を画面に出力する。

まとめ

今回は、日本語の文章に出てくる単語をカウントするプログラムを作ってみた。どうだろうか。これけでも十分面白いので、さらに調査したくなるかもしれない。

素晴らしいことに、Janomeの形態素解析の実行結果には、語句の品詞やヨミガナなども含まれている。そうした情報を利用すれば、助詞や接続語など、不要な情報を削ることができるので、最初からより精度の高い情報が抽出できるだろう。

Janomeや形態素解析は面白いので、また、別の機会にも、使い方を紹介しようと思うので、お楽しみに。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。