【自然言語処理】形態素解析のためのトークナイザー(関数)を作る
はじめに
Python初心者のわたくしが偉そうなことは言えませんが、自然言語処理においては、形態素解析が命と思っています。
mecab用の 優秀な辞書NEologd を使って、形態素解析のためのトークナイザー(関数) を作ったので、今後、自分が形態素解析をする際に使うためにも、記事として残しておきたいと思います。
具体的には、テキストを与えたら、
- 記号類を削除
- 数字を0にする
- ストップワードを除外する
- そのうえで、名詞・動詞・形容詞だけを抽出する
というトークナイザー(関数) になります。
NEologdは週に2回以上更新されるなど、新語・固有表現に強い辞書として定評があります。インストールが少し面倒ですが、とにかく優秀なので、知らない方は、是非、一度使ってみてほしいと思います。
NEologdの詳細はこちらをご覧ください
GoogleコラボでMeCabとNEologd辞書を使えるようにする
まずは、googleコラボでmecabとNEologdを使えるようにインストールする必要があります。
ここに記載しているコードは以下の記事を参考にしています。
形態素分析ライブラリーMeCab と 辞書(NEologd)のインストール
!apt-get -q -y install sudo file mecab libmecab-dev mecab-ipadic-utf8 git curl python-mecab > /dev/null
!git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git > /dev/null
!echo yes | mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n > /dev/null 2>&1
!pip install mecab-python3 > /dev/null
# シンボリックリンクによるエラー回避
!ln -s /etc/mecabrc /usr/local/etc/mecabrc
辞書が格納されているパスを確認
!echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
NEologdの威力を確認
サンプルテキストを与えて、標準辞書とNEologd辞書の違いを見てみます。
サンプルテキストは、鬼滅の刃、スターバックス、経営方針です。
import MeCab
sample_txt ="鬼滅の刃、スターバックス、経営方針"
mecab = MeCab.Tagger()
print("標準辞書:\n", mecab.parse(sample_txt))
# さきほど確認した辞書のパスを pathに代入します。その際、頭に、辞書の-dを入れておきます。
path = "-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd"
mecab = MeCab.Tagger(path)
print("Neologd辞書: \n",mecab.parse(sample_txt))
結果はこちら
標準辞書の場合、鬼滅の刃は、「鬼」「滅」「の」「刃」になってしまいます。
スターバックスも「スター」「バックス」に、経営方針も「経営」「方針」に形態素解析されます。
一方、NEologd辞書は、適切にワードを認識しています。
標準辞書:
鬼 名詞,一般,*,*,*,*,鬼,オニ,オニ
滅 名詞,一般,*,*,*,*,滅,メツ,メツ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
刃 名詞,一般,*,*,*,*,刃,ハ,ハ
、 記号,読点,*,*,*,*,、,、,、
スター 名詞,一般,*,*,*,*,スター,スター,スター
バックス 名詞,一般,*,*,*,*,バックス,バックス,バックス
、 記号,読点,*,*,*,*,、,、,、
経営 名詞,サ変接続,*,*,*,*,経営,ケイエイ,ケイエイ
方針 名詞,一般,*,*,*,*,方針,ホウシン,ホーシン
EOS
Neologd辞書:
鬼滅の刃 名詞,固有名詞,一般,*,*,*,鬼滅の刃,キメツノヤイバ,キメツノヤイバ
、 記号,読点,*,*,*,*,、,、,、
スターバックス 名詞,固有名詞,組織,*,*,*,スターバックス,スターバックス,スターバックス
、 記号,読点,*,*,*,*,、,、,、
経営方針 名詞,固有名詞,一般,*,*,*,経営方針,ケイエイホウシン,ケイエイホーシン
EOS
トークナイザーを作る
ストップワードの取得
- ストップワードとして、自ら設定することも可能ですが、ここでは、一般的なストップワードをダウンロードして使っていきたいと思います。
- !wget urlで簡単に取得できます。
!wget http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt
トークナイザー(関数)
import re
#stopwordsの指定
with open("/content/Japanese.txt","r") as f:
stopwords = f.read().split("\n")
#トークナイザー
def mecab_tokenizer(text):
replaced_text = text.lower()
replaced_text = re.sub(r'[【】]', ' ', replaced_text) # 【】の除去
replaced_text = re.sub(r'[()()]', ' ', replaced_text) # ()の除去
replaced_text = re.sub(r'[[]\[\]]', ' ', replaced_text) # []の除去
replaced_text = re.sub(r'[@@]\w+', '', replaced_text) # メンションの除去
replaced_text = re.sub(r'\d+\.*\d*', '', replaced_text) #数字を0にする
path = "-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd"
mecab = MeCab.Tagger(path)
parsed_lines = mecab.parse(replaced_text).split("\n")[:-2]
#表層形を取得
# surfaces = [l.split('\t')[0] for l in parsed_lines]
#原形を取得
token_list = [l.split("\t")[1].split(",")[6] for l in parsed_lines]
#品詞を取得
pos = [l.split('\t')[1].split(",")[0] for l in parsed_lines]
# 名詞,動詞,形容詞のみに絞り込み
target_pos = ["名詞","動詞","形容詞"]
token_list = [t for t, p in zip(token_list, pos) if p in target_pos]
# stopwordsの除去
token_list = [t for t in token_list if t not in stopwords]
# ひらがなのみの単語を除く
kana_re = re.compile("^[ぁ-ゖ]+$")
token_list = [t for t in token_list if not kana_re.match(t)]
return ' '.join(token_list)
トークナイザーを試す
適当な文章をトークナイザーに入れてみましょう。
ある上場企業の有価証券報告書テキストデータの一部をトークナイズしてみました。
text = "IoT関連ビジネスへの進化を目指し、主として電子・工業材料分野に継続的に供給されており、引き続き、拡大が期待される東アジア市場に向け事業を展開してまいります。"
mecab_tokenizer(text)
出力結果はこちら
適切に形態素解析できていますね。
IOT 関連 ビジネス 進化 目指す 電子 工業 材料 分野 継続 供給 引き続く 拡大 期待 東アジア 市場 向ける 事業 展開
さいごに
いかがでしたでしょうか。
優秀なトークナイザーを使えば、その後の自然言語処理の精度も格段に上がると思います。逆に、トークナイザーを疎かにすると、自然言語処理の精度も悪くなりやすいので注意が必要です。
今度は、spaCyのGiNZAを使ったトークナイザーを作ってみたいと思います。
Discussion