LoginSignup
14
16

More than 5 years have passed since last update.

形態素解析器「sudachi」を使ってみた

Last updated at Posted at 2018-05-25

自然言語処理として今まで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などをやっていきたいと思います。
14
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16