京橋のバイオインフォマティシャンの日常

まずは、データ分析、コマンドラインのメモとして

R言語で実行するSudachiPyによる日本語形態素解析

SudachiPyは、日本語形態素解析器SudachiのPython版である。

今回、R/RStudio上でのSudachiPyの実行例を概説する。

個人的には、RユーザーにとってPythonパッケージがR環境上で実行できると、いろいろと良いのでは考えている*1

例の如く、HomeBrewでPythonの環境構築を行う。

skume.hatenablog.com

今回の内容

実行環境

MacOSX 10.15.6
R version 4.0.2 (2020-06-22)
RStudio 1.3.1056
Python 3.8.5
pip 20.1.1 from /usr/local/lib/python3.8/site-packages/pip (python 3.8)

SudachiPyのデフォルト・インストール

まずは、Terminalを起動して、SudachiPyをインストールする。

$ pip install sudachipy
$ pip install sudachidict_core

Sudachi 辞書 fullの設定

Sudachiでは、3種類の辞書が提供されている。

  • small: UniDicの語彙のみが含まれる。

  • core: 基本的な語彙を含む(デフォルト)。

  • full: その他の固有名詞が含まれる。

Sudachi 辞書 full をインストールして、辞書を切り替えてみる。

$ pip install sudachidict_full

#辞書の切替
$ sudachipy link -t full

また、SudachiPyには、コマンドライン版とPython版があり、pipでどちらもインストールされる。

上記コマンドは、RStudioのTerminalタブからも実行できる。

また、もう面倒で、Rコンソール上でインストールしたい場合には、以下で通るはず。

#sudachipyインストール
system("pip install sudachipy sudachidict_core sudachidict_full")

#辞書の切替
system("sudachipy link -t full")

R上でのコマンドライン版sudachipyの実行

コマンドライン版sudachipyの実行例を下記に示す。

#sudachipyのヘルプ表示
system("sudachipy tokenize -h")
#(出力省略)

#Sudachiのデフォルト形態素解析
system('echo "外国人参政権" | sudachipy')

#外国人参政権    名詞,普通名詞,一般,*,*,*    外国人参政権
#EOS

#`-a`オプションで、すべての出力を表示させる
system('echo "外国人参政権" | sudachipy -a')
 
#外国人参政権    名詞,普通名詞,一般,*,*,*    外国人参政権  外国人参政権  ガイコクジンサンセイケン    0
#EOS

#もしR側に出力を返したい場合には、「intern=T」をいれる 
Res <- system('echo "外国人参政権" | sudachipy', intern=T)
Res

#[1] "外国人参政権\t名詞,普通名詞,一般,*,*,*\t外国人参政権"
#[2] "EOS"  

#Split A modeで形態素解析
system('echo "外国人参政権" | sudachipy -m A')

#外国    名詞,普通名詞,一般,*,*,*    外国
#人   接尾辞,名詞的,一般,*,*,*    人
#参政    名詞,普通名詞,一般,*,*,*    参政
#権   接尾辞,名詞的,一般,*,*,*    権
#EOS

Split modeについては補足に記載している。

次に、Pythonパッケージの方について概説する。

R上でのPythonパッケージ版sudachipyの実行

HomeBrewでインストールしたPythonは、/usr/local/bin/pythonに入っている。

お使いの環境で、use_pythonのパスは変更のこと。

Pythonパッケージ版sudachipyの実行例を下記に示す。

#SudachiPyの設定
reticulate::use_python("/usr/local/bin/python", required =T)
sudachipy <- reticulate::import(module = "sudachipy")

#sudachipyのヘルプ表示
reticulate::py_help(sudachipy)

ここから、SudachiPyで形態素解析を実行してみる。

#tokenizerの作成
tokenizer_obj = sudachipy$dictionary$Dictionary()$create()
tokenizer_obj

#形態素解析の実行
text = '国家公務員'
m = tokenizer_obj$tokenize(text=text)[0]

#各出力結果
m$surface()
#[1] "国家公務員"

m$dictionary_form()
#[1] "国家公務員"

m$reading_form()
#[1] "コッカコウムイン"

m$part_of_speech()
#[1] "名詞"     "普通名詞" "一般"     "*"        "*"        "*"     

次に、Split modeのオプジェクトを設定して、形態素解析をやってみる。

#Split modeのオプジェクト設定
SplitA = sudachipy$tokenizer$Tokenizer$SplitMode$A
SplitB = sudachipy$tokenizer$Tokenizer$SplitMode$B
SplitC = sudachipy$tokenizer$Tokenizer$SplitMode$C

#Split mode Aの場合
tokenizer_obj$tokenize(text=text, mode=SplitA)[0]
#国家
tokenizer_obj$tokenize(text=text, mode=SplitA)[1]
#公務
tokenizer_obj$tokenize(text=text, mode=SplitA)[2]
#員

#Split mode Bの場合
tokenizer_obj$tokenize(text=text, mode=SplitB)[0]
#国家
tokenizer_obj$tokenize(text=text, mode=SplitB)[1]
#公務員

#Split mode Cの場合
tokenizer_obj$tokenize(text=text, mode=SplitC)[0]
#国家公務員

また、SudachiPyでは、語彙のノーマライズ機能 (Ex. 附属 => 付属)もあるようだ。

m1 = tokenizer_obj$tokenize(text="附属")[0]
m1$normalized_form()
#[1] "付属"

自作関数SudachiTokenizerRについて

Pythonパッケージ版SudachiをRで動かすのは若干面倒なのだが、実行挙動を逆手にとって関数を作成した*2

これまでのコマンドが動作した環境が前提で、コマンドライン版とほぼ同出力となる関数を作成した。以下が実行例である。

#スクリプト読み込み
source("https://gist.githubusercontent.com/kumeS/db75fdb0389f9a84846c58f5dcf302c1/raw/662d60b9c1d371577e40b3d1a311cd7d1b1de327/SudachiTokenizerR")

#実行
Res <- SudachiTokenizerR(text='国家公務員', mode=SplitA)
Res

#(出力結果)
#  語彙 品詞タグ01 品詞タグ02 品詞タグ03 品詞タグ04 品詞タグ05 品詞タグ06
#1 国家       名詞   普通名詞       一般          *          *          *
#2 公務       名詞   普通名詞       一般          *          *          *
#3   員     接尾辞     名詞的       一般          *          *          *


print(system('echo "国家公務員" | sudachipy -m A', intern=T))

#(出力結果)
#[1] "国家\t名詞,普通名詞,一般,*,*,*\t国家"
#[2] "公務\t名詞,普通名詞,一般,*,*,*\t公務"
#[3] "員\t接尾辞,名詞的,一般,*,*,*\t員"    
#[4] "EOS" 

R上でもSudachi形態素解析が使えれば、Rでの解析の幅も広がるはず。

SudachiTokenizerRで、Pythonパッケージ版の形態素解析もR上で少しは使いものになりそう*3

補足

Rはイチスタート、Pythonはゼロスター

Rでは、1,2,3...と 1 からベクトル位置が始まるが、Python他では、0,1,2,3...と 0 からベクトル位置が始まるのが一般的である。

'"の使い分け

Rでは、"..."(ダブルクォーテーション囲い)は、文字列指定の際に使用する。

"..."内にもう一度、"..."を入れたい場合は、個人的な使い方としては、'..."..."...'というように、外側を'...'(シングルクォーテーション囲い)にして、内側を"..."と記載する*4

一部、'...'を使っているところもあるけども、R上ではだいたい同じ挙動となる。

Split mode について

英語原文より

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 :テキストは、UniDicショートユニットに相当する最短ユニットに分割されます

B :テキストをAとCの間の中間単位に分割します

C :名前付きエンティティを抽出します

参考資料

pypi.org

github.com

ichi.pro

*1:Python言語の習得やPython環境、データ構造への慣れが特に不要になる。また、すでにRプログラミング中級者以上なら、もう1つインタプリンタ言語(低速言語)を習得するのはやはり非効率だと思うわけである。

*2:若干騙し騙し的な感じで、Pythonの実行エラーがR側でコマンド実行に使われない仕組みを活用している。

*3:まだ発展途上だけど

*4:おそらくは、その逆でも動く