言語処理100本ノック-37(pandas使用):頻度上位10語


言語処理100本ノック 2015「第4章: 形態素解析」37本目「頻度上位10語」記録です。
今回はグラフ表示ということでmatplotlibを使います。matplotlibで誰もが陥ると思われる「豆腐問題」(日本語が表示される豆腐っぽい文字がグラフ上に表示される現象)に対応します。

参考リンク

リンク 備考
037.頻度上位10語.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:37 多くのソース部分のコピペ元
MeCab公式 最初に見ておくMeCabのページ

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.16 複数Python環境を使うことがあるのでpyenv使っています
Python 3.8.1 pyenv上でpython3.8.1を使っています
パッケージはvenvを使って管理しています
Mecab 0.996-5 apt-getでインストール

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
matplotlib 3.1.3
pandas 1.0.1

第4章: 形態素解析

学習内容

夏目漱石の小説『吾輩は猫である』に形態素解析器MeCabを適用し,小説中の単語の統計を求めます.

形態素解析, MeCab, 品詞, 出現頻度, Zipfの法則, matplotlib, Gnuplot

ノック内容

夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ.

なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

37. 頻度上位10語

出現頻度が高い10語とその出現頻度をグラフ(例えば棒グラフなど)で表示せよ.

回答

回答プログラム 037.頻度上位10語.ipynb

import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'IPAexGothic'

def read_text():
    # 0:表層形(surface)
    # 1:品詞(pos)
    # 2:品詞細分類1(pos1)
    # 7:基本形(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')
    return df[(df['pos'] != '空白') & (df['surface'] != 'EOS') & (df['pos'] != '記号')]

df = read_text()

df['surface'].value_counts()[:10].plot.bar()

# 助詞と助動詞を除外
df[~df['pos'].str.startswith('助')]['surface'].value_counts()[:10].plot.bar()

回答解説

豆腐(グラフ文字化け対応)対応

以下の記事を参考にして豆腐(グラフ文字化け対応)対応をしました。対応方法はOSおよびPython環境(pyenv使用など)に大きく依存するので注意ください。
2021/11/25追記: japanize-matplotlibという神ライブラリができていました。記事「1分で簡単!Matplotlibの日本語対応を徹底解説!」参照。

1. フォントインストール

apt-getでフォントをインストールします

apt-get install fonts-ipaexfont

2. キャッシュ削除

matplotlibのフォントキャッシュである以下のファイルを物理削除します。2つの違いがわかっていないのですが、「キャッシュは消してもいいや」の感覚で削除しました。

  • /Users/ユーザー名/.cache/matplotlib/fontlist-v300.json
  • /Users/ユーザー名/.cache/matplotlib/fontlist-v310.json

3. Pythonでフォント指定

Python上の以下の設定でグラフ出力するフォントを指定します。これで「豆腐」対応完了です。

plt.rcParams['font.family'] = 'IPAexGothic'

グラフ出力

pandasだとplotを使ってそのまま出力できるので非常に便利です。

df['surface'].value_counts()[:10].plot.bar()

# 助詞と助動詞を除外
df[~df['pos'].str.startswith('助')]['surface'].value_counts()[:10].plot.bar()

出力結果(実行結果)

プログラム実行すると以下の結果が出力されます。やはり数字だけで見るよりグラフ化した方がわかりやすいですね。

全単語

助詞と助動詞を除外した単語