PythonのJanomeで名詞の出現回数をカウントする【自然言語, 形態素解析】
- 作成日: 2020-10-03
- 更新日: 2023-12-24
- カテゴリ: 自然言語処理
Pythonで形態素解析
人間が自然発生的に使っている言語を「自然言語」と言います。
その自然言語を構造的に解析する手法の1つに「形態素解析(けいたいそかいせき)」というジャンルがあります。
自然言語に対して形態素解析を行うと、名詞や動詞を抽出したりできるようになります。
Pythonには形態素解析を行うライブラリに「Janome」があります。
Janomeは形態素解析器として有名な「MeCab」の辞書を使っており、精度的にはMeCabと同程度の解析が可能です。
MeCabのインストールは一手間かかる物でしたが、Janomeではこの手間が簡略化され、pip
でインストールすればそのまま使うことが可能になっています。
ただし速度的にはCで書かれたMeCabの方が速いため、PythonのJanomeに対して速度と簡便さのトレードオフの関係になっています。
特に速度を必要としないのであればJanomeで問題はなさそうです。
Janomeのインストール
pip
を使って↓のようにすればインストール可能です。
$ pip install janome
Janomeでトークン列に分解
Janomeのtokenizer
モジュールのTokenizer
クラスを使うと自然言語を簡単に解析することができます。
Tokenizer
クラスをインスタンス化して、メソッドtokenize
に自然言語が書かれたテキストを渡すと、Tokenizer
は自然言語をトークン列に分解します。
各トークンはprint
で出力することが可能です。
from janome.tokenizer import Tokenizer
t = Tokenizer() # トーカナイザー
s = '本日は晴天なり' # 解析対象の自然言語
# 自然言語をトークン列に分解
for tok in t.tokenize(s):
print(tok)
出力結果。
本日 名詞,副詞可能,*,*,*,*,本日,ホンジツ,ホンジツ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
晴天 名詞,一般,*,*,*,*,晴天,セイテン,セイテン
なり 助動詞,*,*,*,文語・ナリ,基本形,なり,ナリ,ナリ
自力で名詞を抽出する
Tokenizer.tokenize
で生成されるトークンの型はjanome.tokenizer.Token
です。
from janome.tokenizer import Tokenizer
t = Tokenizer() # トーカナイザー
s = '本日は晴天なり' # 自然言語
toks = list(t.tokenize(s)) # トークン列に分解
print(type(toks[0])) # 最初のトークンのタイプは?
<class 'janome.tokenizer.Token'>
Token
は属性にpart_of_speech
を持っています。
このpart_of_speech
にはトークンの持つ品詞がカンマ(,
)区切りで並べられています。
from janome.tokenizer import Tokenizer
t = Tokenizer() # トーカナイザー
s = '本日は晴天なり' # 自然言語
# トークン列に分解
for tok in t.tokenize(s):
print(tok.part_of_speech) # 品詞を出力
名詞,副詞可能,*,*
助詞,係助詞,*,*
名詞,一般,*,*
助動詞,*,*,*
part_of_speech
に「名詞」が含まれていればそのトークンは名詞に分類されているわけなので、これを調べることで単語が名詞かどうか判断できます。
↓のコードはpart_of_speech
をsplit
で分解し、分解したリストに「名詞」が含まれていればトークンを出力します。
from janome.tokenizer import Tokenizer
t = Tokenizer() # トーカナイザー
s = '本日は晴天なり' # 自然言語
# トークン列に分解
for tok in t.tokenize(s):
pos = tok.part_of_speech.split(',') # 品詞を分解
if '名詞' in pos: # 品詞に「名詞」が含まれていれば
print(tok) # トークンを出力
本日 名詞,副詞可能,*,*,*,*,本日,ホンジツ,ホンジツ
晴天 名詞,一般,*,*,*,*,晴天,セイテン,セイテン
ちなみにトークンのsurface
を参照すると、元の文字列で使われている形をそのまま取得できます。
reading
では読み、phonetic
では発音を参照できます。
from janome.tokenizer import Tokenizer
t = Tokenizer()
s = '本日は晴天なり'
for tok in t.tokenize(s):
pos = tok.part_of_speech.split(',')
if '名詞' in pos:
print(tok.surface) # 表層形を出力
print(tok.reading) # 読みを出力
print(tok.phonetic) # 発音を出力
本日
ホンジツ
ホンジツ
晴天
セイテン
セイテン
自力で名詞の出現回数をカウントする
自力で名詞の出現回数をカウントするにはたとえば↓のようにします。
stat
という辞書を用意して、キーにトークンの表層形を使います。
トークンが名詞であればそのトークンの表層形のstat
にカウントを追加します。
from janome.tokenizer import Tokenizer
t = Tokenizer() # トーカナイザー
s = '猫が猫に話しかけると鳥が犬をくわえて逃げた' # 自然言語
stat = {} # 統計用の辞書
# トークン列に分解
for tok in t.tokenize(s):
pos = tok.part_of_speech.split(',') # 品詞を分解
if '名詞' in pos: # 品詞に名詞が含まれていれば
if tok.surface in stat.keys(): # 統計にトークンの表層形が含まれていれば
stat[tok.surface] += 1 # カウントする
else:
stat[tok.surface] = 1 # 新規カウントする
print(stat) # 結果を出力
{'猫': 2, '鳥': 1, '犬': 1}
また、標準ライブラリのcollections.Counter
を使えば↓のようにも書けます。
from janome.tokenizer import Tokenizer
import collections
t = Tokenizer() # トーカナイザー
s = '猫が猫に話しかけると鳥が犬をくわえて逃げた' # 自然言語
meisi = []
# トークン列に分解
for tok in t.tokenize(s):
pos = tok.part_of_speech.split(',') # 品詞を分解
if '名詞' in pos: # 品詞に名詞が含まれていれば
meisi.append(tok.surface) # 名詞のトークンの表層形を保存
c = collections.Counter(meisi) # Counterで出現回数をカウント
print(c) # 結果を出力
Counter({'猫': 2, '鳥': 1, '犬': 1})
これはかなり原始的なコードです。
Janomeには名詞を抽出したり、単語をカウントするためのモジュールが備わっているため、これを使うと簡単に処理を書くことが出来ます。
Analyzerで名詞を抽出する
Janomeのanalyzer.Analyzer
モジュールを使うと、簡単に名詞を抽出することができます。
Analyzer
にはフィルターを指定することが出来ます。たとえば名詞のみのトークンを抽出したい場合は↓のようにPOSKeepFilter
を指定します。
こうすることでトークン列の分解で名詞のみのトークンを抽出できます。
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter
# アナライザーのフィルター
token_filters = [
POSKeepFilter(['名詞']) # 名詞を抽出するようにする
]
analyzer = Analyzer(token_filters=token_filters) # フィルターからアナライザーを生成
s = '本日は晴天なり' # 自然言語
# トークン列に分解
for tok in analyzer.analyze(s):
print(tok) # トークンを出力
Janomeで名詞の出現回数をカウントする
TokenCountFilter
をAnalyzer
に指定すると、トークンの出現回数をカウントできます。
このフィルターとPOSKeepFilter
を組み合わせれば、名詞のトークンの出現回数をカウントすることが可能です。
Analyzer.analyze()
の結果をdict
で辞書に変換すれば、カウント回数に対して単語のキーでアクセスできます。
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter, TokenCountFilter
# アナライザーのフィルター
token_filters = [
POSKeepFilter(['名詞']), # 名詞を抽出するようにする
TokenCountFilter(), # トークンの出現回数をカウントする
]
analyzer = Analyzer(token_filters=token_filters) # フィルターからアナライザーを生成
s = '猫が猫に話しかけると鳥が犬をくわえて逃げた' # 自然言語
paris = analyzer.analyze(s) # カウントする
print(dict(paris)) # 結果を辞書に変換
出力結果。
{'猫': 2, '鳥': 1, '犬': 1}
問題
Q1: JanomeのToken
の品詞を参照したい。適当な属性を答えよ
- part_of_speech
- surface
- reading
Q2: Janomeで名詞を抽出したい。適当な処理を答えよ
- part_of_speechを参照して名詞のトークンを保存
- POSKeepFilterを使って名詞を抽出
- TokenCountFilterで名詞を抽出
Q3: Janomeで単語をカウントしたい。適当な処理を答えよ
- POSKeepFilterで単語をカウント
- TokenCountFilterで単語をカウント
- GreatSpeakerで単語をカウント
正解はこちら↓
Q1: 1
Q2: 1, 2
Q3: 2