MeCab
参考文献
- 日本テレビ東京で学ぶMeCabのコスト計算 | mwSoft (2024年03月19日参照).
Snippets
形態素解析する
「UniDic」国語研短単位自動解析用辞書|バックナンバーから辞書をダウンロードして配置し、形態素解析すると以下のようになる。
import MeCab
tagger = MeCab.Tagger('-d "C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full"')
print(tagger.parse('ヒンメルはもういないじゃない'))
ヒンメル 名詞,普通名詞,一般,,,
は 助詞,係助詞,,,,,ハ,は,は,ワ,は,ワ,和,"","","","","","",係助,ハ,ハ,ハ,ハ,"","動詞%F2@0,名詞%F1,形容詞%F2@-1","",8059703733133824,29321
もう 副詞,,,,,,モウ,もう,もう,モー,もう,モー,和,"","","","","","",相,モウ,モウ,モウ,モウ,"0,1","","",10326896709607936,37569
い 動詞,非自立可能,,,上一段-ア行,未然形-一般,イル,居る,い,イ,いる,イル,和,"","","","","","",用,イ,イル,イ,イル,"0","C4","M4@1",710568013079105,2585
ない 助動詞,,,,助動詞-ナイ,終止形-一般,ナイ,ない,ない,ナイ,ない,ナイ,和,"","","","","","",助動,ナイ,ナイ,ナイ,ナイ,"","動詞%F3@0","",7542108634358443,27438
じゃ 助動詞,,,,助動詞-ダ,連用形-融合,ダ,だ,じゃ,ジャ,だ,ダ,和,"","","","","","",助動,ジャ,ダ,ジャ,ダ,"","名詞%F1","",6299110739157638,22916
ない 形容詞,非自立可能,,,形容詞,終止形-一般,ナイ,無い,ない,ナイ,ない,ナイ,和,"","","","","","",相,ナイ,ナイ,ナイ,ナイ,"1","C3","",7543208145986219,27442
EOS
ただこれだと結果の意味がわからないのでわかりやすくするとこうなる。
from IPython.display import display, HTML
import MeCab
import re
import pandas as pd
# ダブルクオートで囲まれていないカンマにマッチする正規表現
split_pattern = re.compile(r',(?=[^"]*(?:"[^"]*"[^"]*)*$)')
tagger = MeCab.Tagger('-d "C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full"')
cols = [ # C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full/dicrc をみると各トークンの特徴名リストがある
'pos1', 'pos2', 'pos3', 'pos4', 'cType', 'cForm', 'lForm', 'lemma',
'orth', 'pron', 'orthBase', 'pronBase', 'goshu', 'iType', 'iForm', 'fType', 'fForm',
'iConType', 'fConType', 'type', 'kana', 'kanaBase',
'form', 'formBase', 'aType', 'aConType', 'aModType', 'lid', 'lemma_id']
cols_ja = [ # https://clrd.ninjal.ac.jp/unidic/faq.html, https://hayashibe.jp/tr/mecab/dictionary/unidic/field
'品詞大分類', '品詞中分類', '品詞小分類', '品詞細分類', '活用型', '活用形', '語彙素読み', '語彙素',
'書字形出現形', '発音形出現形', '書字形基本形', '発音形基本形', '語種', '語頭変化化型', '語頭変化形',
'語末変化化型', '語末変化形', '語頭変化結合型', '語末変化結合型', '語彙素類', '仮名形出現形', '仮名形基本形',
'語形出現形', '語形基本形', 'アクセント型', 'アクセント結合型', 'アクセント修飾型', '語彙表ID', '語彙素ID']
# 形態素解析結果を格納するデータフレーム
df = pd.DataFrame(columns=pd.MultiIndex.from_tuples(
[('surface', '表層形')] + [(col, col_ja) for col, col_ja in zip(cols, cols_ja)], names=['feature name', '特徴名']))
tokens = tagger.parse('ヒンメルはもういないじゃない').split('')
for i_token, token in enumerate(tokens):
if token.strip() == 'EOS':
break
v = token.strip().split('\t')
info = split_pattern.split(v[1])
df.loc[i_token] = [v[0]] + info + [''] * (29 - len(info))
display(HTML(df.to_html()))
feature name | surface | pos1 | pos2 | pos3 | pos4 | cType | cForm | lForm | lemma | orth | pron | orthBase | pronBase | goshu | iType | iForm | fType | fForm | iConType | fConType | type | kana | kanaBase | form | formBase | aType | aConType | aModType | lid | lemma_id |
---|
特徴名 | 表層形 | 品詞大分類 | 品詞中分類 | 品詞小分類 | 品詞細分類 | 活用型 | 活用形 | 語彙素読み | 語彙素 | 書字形出現形 | 発音形出現形 | 書字形基本形 | 発音形基本形 | 語種 | 語頭変化化型 | 語頭変化形 | 語末変化化型 | 語末変化形 | 語頭変化結合型 | 語末変化結合型 | 語彙素類 | 仮名形出現形 | 仮名形基本形 | 語形出現形 | 語形基本形 | アクセント型 | アクセント結合型 | アクセント修飾型 | 語彙表ID | 語彙素ID |
---|
0 | ヒンメル | 名詞 | 普通名詞 | 一般 | | | | | | | | | | | | | | | | | | | | | | | | | | |
---|
1 | は | 助詞 | 係助詞 | | | | | ハ | は | は | ワ | は | ワ | 和 | "" | "" | "" | "" | "" | "" | 係助 | ハ | ハ | ハ | ハ | "" | "動詞%F2@0,名詞%F1,形容詞%F2@-1" | "" | 8059703733133824 | 29321 |
---|
2 | もう | 副詞 | | | | | | モウ | もう | もう | モー | もう | モー | 和 | "" | "" | "" | "" | "" | "" | 相 | モウ | モウ | モウ | モウ | "0,1" | "" | "" | 10326896709607936 | 37569 |
---|
3 | い | 動詞 | 非自立可能 | | | 上一段-ア行 | 未然形-一般 | イル | 居る | い | イ | いる | イル | 和 | "" | "" | "" | "" | "" | "" | 用 | イ | イル | イ | イル | "0" | "C4" | "M4@1" | 710568013079105 | 2585 |
---|
4 | ない | 助動詞 | | | | 助動詞-ナイ | 終止形-一般 | ナイ | ない | ない | ナイ | ない | ナイ | 和 | "" | "" | "" | "" | "" | "" | 助動 | ナイ | ナイ | ナイ | ナイ | "" | "動詞%F3@0" | "" | 7542108634358443 | 27438 |
---|
5 | じゃ | 助動詞 | | | | 助動詞-ダ | 連用形-融合 | ダ | だ | じゃ | ジャ | だ | ダ | 和 | "" | "" | "" | "" | "" | "" | 助動 | ジャ | ダ | ジャ | ダ | "" | "名詞%F1" | "" | 6299110739157638 | 22916 |
---|
6 | ない | 形容詞 | 非自立可能 | | | 形容詞 | 終止形-一般 | ナイ | 無い | ない | ナイ | ない | ナイ | 和 | "" | "" | "" | "" | "" | "" | 相 | ナイ | ナイ | ナイ | ナイ | "1" | "C3" | "" | 7543208145986219 | 27442 |
---|
ユーザ辞書を追加する
import MeCab
import subprocess
import os
dic_dir = 'C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full'
# まずはユーザ辞書なしで形態素解析する
tagger = MeCab.Tagger(f'-d "{dic_dir}"')
node = tagger.parseToNode('葬送のフリーレン')
while node:
print(node.surface)
node = node.next
# ユーザ辞書を生成する
csv_name = 'hoge.csv'
dic_name = 'hoge.dic'
with open(csv_name, mode='w', encoding='utf8', newline='\n') as ofile:
ofile.write('フリーレン,7166,4392,0,名詞,固有名詞,人名,一般,*,*\n')
ret = subprocess.run(
['C:/Program Files/MeCab/bin/mecab-dict-index.exe', '-d', dic_dir,
'-u', dic_name, '-f', 'utf-8', '-t', 'utf-8', csv_name],
capture_output=True, text=True)
print(ret.stdout)
# ユーザ辞書ありで形態素解析する
tagger = MeCab.Tagger(f'-d "{dic_dir}" -u "{os.getcwd()}/{dic_name}"')
node = tagger.parseToNode('葬送のフリーレン')
while node:
print(node.surface)
node = node.next
葬送
の
フリー
レン
reading hoge.csv ... 1
emitting double-array: 100% |###########################################|
done!
葬送
の
フリーレン