【初心者向け】Python×Janomeで形態素解析|名詞の出現頻度カウントとWordCloud可視化

Python

ここでは、Janomeを用いた出現頻度の解析方法について解説しています。

この記事の対象

  • 「Janomeとは何か?」を知りたい方
  • 文字列を品詞解析する方法を知りたい方
  • 具体的な品詞解析例を知りたい方
スポンサーリンク
スポンサーリンク

セットアップ(インストールと動作確認)

pip install janome wordcloud matplotlib
from janome.tokenizer import Tokenizer
t = Tokenizer()
for tok in t.tokenize("すもももももももものうち"):
    print(tok.surface, tok.part_of_speech)

surface(表層形)、part_of_speech(品詞)などが取れます。

結果

すもも 名詞,一般,*,*
も 助詞,係助詞,*,*
もも 名詞,一般,*,*
も 助詞,係助詞,*,*
もも 名詞,一般,*,*
の 助詞,連体化,*,*
うち 名詞,非自立,副詞可能,*

名詞だけを数える(基本形)

まずは手書き集計版(仕組みの理解用):

from janome.tokenizer import Tokenizer
from collections import Counter

text = "私はPythonが好き。Pythonで形態素解析をします。Python最高。"
t = Tokenizer()

cnt = Counter()
for token in t.tokenize(text):
    if token.part_of_speech.startswith("名詞"):
        cnt[token.surface] += 1

print(cnt.most_common(20))

表記ゆれを抑えるなら token.base_form(基本形)で数えるのも手です。

結果

[('Python', 3), ('私', 1), ('好き', 1), ('形態素', 1), ('解析', 1), ('最高', 1)]

正攻法:Analyzer + TokenFilterで頻度表(推奨)

JanomeのAnalyzerを使うと、品詞フィルタや頻度集計を宣言的に書けます。

from janome.analyzer import Analyzer
from janome.tokenizer import Tokenizer
from janome.tokenfilter import POSKeepFilter, TokenCountFilter

text = "私はPythonが好き。Pythonで形態素解析をします。Python最高。"

a = Analyzer(
    tokenizer=Tokenizer(),
    token_filters=[
        POSKeepFilter(['名詞']),           # 名詞だけ残す
        TokenCountFilter(att='base_form',  # 基本形でカウント
                         sorted=True)      # 出現頻度でソート
    ]
)

freq = dict(a.analyze(text))  # {'Python': 3, '私': 1, ...}
print(list(freq.items())[:10])

WordCloudで可視化(日本語フォント指定が必須)

from janome.tokenizer import Tokenizer

#1---テキストデータの指定
txt ="くるしさは、忍従の夜。あきらめの朝。この世とは、あきらめの努めか。わびしさの堪えか。わかさ、かくて、日に虫食われゆき、仕合せも、陋巷ろうこうの内に、見つけし、となむ。-----以下、略"
#2---形態素解析オブジェクトの生成
t = Tokenizer()
#3---テキストを一行ずつ処理
word_txt = {}
lines = txt.split("\r\n")
for line in lines:
    malist = t.tokenize(line)
    for w in malist:
        word = w.surface#4---単語情報の読込
        ps = w.part_of_speech #5---品詞情報の読込
        if ps.find('名詞') < 0: continue #6---名詞のカウント
        if not word in word_txt:
            word_txt[word] = 0
        word_txt[word] += 1 #7---カウント
#8---頻出単語の表示
keys = sorted(word_txt.items(), key=lambda x:x[1], reverse=True)
for word,cnt in keys[:20]:
    print("{0}({1}) ".format(word,cnt), end="")

上記がプログラムになります。

それでは解説していきます。

1の部分はテキストデータを指定しています。

#2---形態素解析オブジェクトの生成
t = Tokenizer()

2の部分ではjanomeの形態素解析オブジェクトを生成しています。

#3---テキストを一行ずつ処理
word_txt = {}
lines = txt.split("\r\n")
for line in lines:
    malist = t.tokenize(line)

3の部分では、はじめにリストを作成し、不要な改行を削除しています。for構文で解析しています。

for w in malist:
        word = w.surface#4---単語情報の読込
        ps = w.part_of_speech #5---品詞情報の読込
        if ps.find('名詞') < 0: continue #6---名詞のカウント
        if not word in word_txt:
            word_txt[word] = 0

4の部分では単語情報のプロパティである「surface」を指定しています。

同時に5の部分では、品詞情報のプロパティである「part_of_speech」を指定しています。

次に6の部分では、名詞だけをカウントしています。

word_txt[word] += 1 #7---カウント

7の部分では、頻出をカウントしています。

#8---頻出単語の表示
keys = sorted(word_txt.items(), key=lambda x:x[1], reverse=True)
for word,cnt in keys[:20]:
    print("{0}({1}) ".format(word,cnt), end="")

8の部分では、解析した内容をソートして上から20個抽出しています。

結果

私(11) 声(6) よう(6) 工場(6) ん(6) 弟(6) 何(5) ひとり(5) の(5) 女工(5) さん(5) 夜(4) 東京(4) もの(4) 仕事(4) それ(4) 甲府(4) I(4) can(4) speak(4)

結果は上記のようになりました。

主題の「I can speak」が出てきていることが分かります。また、私や弟、女工出てきており、人に関する用語も多いことがわかります。

WordCloudでの単語を可視化した結果は以下になります。WordCloudについては下記の関連記事をご参照下さい。

関連記事

項目内容
Word Cloudによるテキストファイルの可視化方法リンク先では、Word Cloudによる可視化方法を解説しています。

つまずきやすいポイント(FAQ)

  • 名詞だけカウントできない
    part_of_speech.startswith("名詞") の判定を確認。Analyzerを使うならPOSKeepFilter(['名詞']) を適用。
  • WordCloudが文字化け
    font_path に日本語フォント(Noto Sans CJK等)を指定。
  • 速度を上げたい
    → 文章量が多い場合はMeCab系(例:fugashi)も検討。辞書導入が必要ですが高速です。
タイトルとURLをコピーしました