SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

Pythonで日本語を単語単位に分割&品詞情報付与を行う(形態素解析)

f:id:arakan_no_boku:20210912183619p:plain

目次

日本語を単語に分割する

日本語を単語に分割するのは簡単ではありません。

単語ごとに空白で区切られている李後と違い、日本語の文章には単語毎の区切りがないからです。

さらに、同じ文字でも前後の単語との関係で品詞が変わり、区切られる位置も変わりますので、難易度はさらにあがります。

でも、幸いなことに、今では、先人の研究によって、僕でも使える「日本語を単語に分割してくれるツール」が存在します。

Pythonで使える主なツールは以下の2つです。

簡単に整理します。

ツール1:MeCab

f:id:arakan_no_boku:20180802144817j:plain

多分、一番有名で利用されているものです。

JavaC++python他様々な言語で使えます。

なんと、EXCELのVBAで使えるものを公開してくれている方とかも居ます。

Python3版もあります。

pypi.org

ツール2:Janome

100%、pythonで書かれています。

pypi.org

辞書はMeCabと同じものが標準で同梱されてます。

速度が遅いとか言われてますが、個人で使う分には遅いと感じることはないです。

janomeをインストールするには、pipを使います。

pip install Janome

Janomeで単語分割と品詞分解をやってみる

ここからはJanomeを使っていきます。

janomeを使って、「私は田舎で育ちました」という文章を処理します。

from janome.tokenizer import Tokenizer

t = Tokenizer()
malist = t.tokenize("私は田舎で育ちました。")
for n in malist:
    print(n.surface + ":" + n.part_of_speech)

  

 結果はこんな感じです。

:名詞,代名詞,一般,*
:助詞,係助詞,*,*
田舎:名詞,一般,*,*
:助詞,格助詞,一般,*
育ち:動詞,自立,*,*
まし:助動詞,*,*,*
:助動詞,*,*,*
:記号,句点,*,*

単語に分割し、品詞情報が付与されています。

必要な単語を品詞で判断して抜き出すサンプル 

上記の結果には、何の処理に使うにせよ不要な情報が含まれているのがわかります。

代表的なのは、助詞とか記号ですかね。

単語の出現数をカウントするにしても名詞だけカウントしたいとか、普通にあります。

なので、今度は目指す品詞だけを処理するように改善してみます。

とりあえず、名詞と動詞と助動詞だけ残すパターンです。

# -*- coding: utf-8 -*-
from janome.tokenizer import Tokenizer
import re

#正規表現
pat = r'名詞|動詞|助動詞'
regex = re.compile(pat)

t = Tokenizer()
malist = t.tokenize("私は田舎で育ちました。")
for n in malist:
    if(regex.match(n.part_of_speech)):
        print(n.surface + ":" + n.part_of_speech)

 

こんな感じで実行すると、指定の品詞のみが抽出されます。

私:名詞,代名詞,一般,*
田舎:名詞,一般,*,*
育ち:動詞,自立,*,*
まし:助動詞,*,*,*
た:助動詞,*,*,**

同音異義語を統一するサンプル

日本語をコンピュータ処理するときにとても面倒くさいことが一つあります。

それは、同音異義語がたくさんあることです。

例えば、「私は田舎で育ちました。」の「私」ひとつとっても、「わたし」「ワタシ」「俺」「僕」「おいら」「自分」など・・バリエーションは沢山あります。

意味合い的には「私は田舎で育ちました」と「わたしはいなかでそだちました」と「僕はイナカで育ちました」は、まったく同じなんですが、文字コードで判定するとまったく違うものになります。

もし、「私」「わたし」「ワタシ」「僕」「俺」「自分」を、同一のものとして扱わないと具合が悪い場合なら、前処理で置き換えて、例えば「私」に無理やり統一してしまうなどが必要になるので、今後はその例をやります。

サンプルなので、「私は俺だし、僕でもあるし、自分でもあるのだよ。」という文章の、僕・俺・自分の3つを、全部「私」に置き換えるだけにします。

from janome.tokenizer import Tokenizer
import re

# 正規表現
pat = r'名詞|動詞|助動詞'
regex = re.compile(pat)

d = {"僕": "私", "俺": "私", "自分": "私"}
t = Tokenizer()
malist = t.tokenize("私は俺だし、僕でもあるし、自分でもあるのだよ。")
for n in malist:
    if(regex.match(n.part_of_speech)):
        if(n.surface in d):
            print(d[n.surface] + ":" + n.part_of_speech)
        else:
            print(n.surface + ":" + n.part_of_speech)

 

実行すると、すべて私に置き換えて出力されます。

私:名詞,代名詞,一般,*
私:名詞,代名詞,一般,*
だ:助動詞,*,*,*
私:名詞,代名詞,一般,*
ある:動詞,自立,*,*
私:名詞,一般,*,*
ある:動詞,自立,*,*
の:名詞,非自立,一般,*
だ:助動詞,*,*,*

実際には、同音異義語の辞書ファイルを用意するのが、とてつもなく大変です。

なので、まあ、雰囲気だけ。

ではでは。