自然言語処理として今までmecabやjuman++を使って来ましたが、「sudachi」が良いという話を聞いて一回使ってみました。
日本語の文章の分け方をショート・ミドル・ロングといった形で指定して分けることが出来るのが特徴です。(特徴は他にもあると思いますが…)
引用
Sudachi provides three modes of splitting. In A mode, texts are divided into the shortest units equivalent to the UniDic short unit. In C mode, it extracts named entities. In B mode, into the middle units.
A:カンヌ/国際/映画/祭
B:カンヌ/国際/映画祭
C:カンヌ国際映画祭
詳しくはこちら参照してください
https://github.com/WorksApplications/Sudachi
http://www.lrec-conf.org/proceedings/lrec2018/summaries/8884.html
sudachiPyのインストール
では実際に使ってみます。私の環境は以下の通りです。
macOS High Sierra 10.13
Python 3.6.5
sudachiPyのインストールは下記のサイトの方法に従って行えば簡単に出来ました。サイトにも記載されていますが、最初は辞書が入っていない状態ですので別途ダウンロードしてresources
ディレクトリに名前をsystem.dic
として入れておくことが必要です。
SudachiPy
https://github.com/WorksApplications/SudachiPy
使ってみる
元々juman++を使っていましたので、両方の形態素解析器を使えるようにしています。python初心者ですのでお恥ずかしいソースですいません。
処理スピードはjumann++は遅いと言われていた通り遅いのですが、sudachiは早かったです。(感覚的に)
#テキストデータからリスト型の形態素解析データを作成する
import pandas as pd
from tqdm import tqdm_notebook as tqdm
#Juman++
from pyknp import Jumanpp
#sudachi
import json
from sudachipy import tokenizer
from sudachipy import dictionary
from sudachipy import config
#オブジェクトを作る
jumanpp = Jumanpp()
with open(config.SETTINGFILE, "r", encoding="utf-8") as f:
settings = json.load(f)
tokenizer_obj = dictionary.Dictionary(settings).create()
#csvファイルに読み込んで一旦データフレームに入れる
file_df = pd.read_csv("hoge.csv")
wakati_list=[]
def wakati_by_jumanpp(text):
"""
juman++を使った分かち書き
"""
result = jumanpp.analysis(text)
word_list = []
for mrph in result.mrph_list():
hinsi = mrph.hinsi
if hinsi in ["名詞", "動詞", "形容詞"]: # 対象とする品詞
word = mrph.midasi
word_list.append(word)
return " ".join(word_list) #スペースで繋げていく
def wakati_by_sudachi(text):
"""
sudachiを使った分かち書き
"""
mode = tokenizer.Tokenizer.SplitMode.C #モードCの一番長い形で分ける
results =[m.surface() for m in tokenizer_obj.tokenize(mode, text)]
word_list = []
for mrph in results:
if not (mrph == ""): #何故か分かち書きの結果として空白データ('')ができたための省く処理
seikika = tokenizer_obj.tokenize(mode,mrph)[0].normalized_form() #正規化(標準化?)してなるべく言葉の揺れを無くす e.g. 打込む → 打ち込む かつ丼 → カツ丼
hinsi = tokenizer_obj.tokenize(mode,seikika)[0].part_of_speech()[0]
if hinsi in ["名詞", "動詞", "形容詞"]: # 対象とする品詞を指定
word = tokenizer_obj.tokenize(mode,seikika)[0].dictionary_form()
word_list.append(word)
return " ".join(word_list) #スペースで繋げていく
#データをそれぞれ分かち書きしていく
for lines in tqdm(file_df["___テキストデータが入っているカラム__"]):
#wakati_list.append(wakati_by_jumanpp(lines)) # 分かち書きはjuman++を利用したい時はこちら
wakati_list.append(wakati_by_sudachi(lines)) # 形態素解析はsudachiを利用したい時はこちら
#分かち書きしたデータは元のcsvファイルにくっ付ける形で保存
file_df['wakati'] = wakati_list
file_df.to_csv("hoge_wakati.csv")
結果
分かち書きした結果を見てみます。何個か違いが出た単語を挙げます。
なお、sudachiのみ正規化などをして単語を一定の形に成形しています。
元の単語 | sudachi(modeC) | juman++ |
オールインワン | オール イン ワン | オールインワン |
差し込み | 差し込み | 差 込 |
取扱説明書 | 取り扱い 説明書 | 取扱 説明 書 |
オールインワンなんかはモードCなら分かれないかなと思うのですが、分れた形になりました。全体的に1文字の漢字に分れているものがsudachiは少なかったのでなかなか良い気がします。(個人の感想です)
元々、mecabを含め形態素解析はやり始めたばかりですので、何が良いとか正直わかっておりませんが、sudachiは使いやすく早かったし単語も10年間は更新するとも記載がありましたのでこれを使ってword2vecなどをやっていきたいと思います。