<jupyter_start><jupyter_text>1. はじめに---[Toiro](https://github.com/taishi-i/toiro) は、形態素解析器を比較する Python ライブラリです。各解析器の比較を数行のコードで行えます。*   処理速度の比較*   単語分割の比較*   後段タスク（テキスト分類）での精度比較Google Colab では、下記のインストールにより7種類の解析器を比較することができます。```pip install toiro[all_tokenizers]```<jupyter_code>pip install toiro[all_tokenizers]
# 各ライブラリのインポート
import pprint
import warnings

import matplotlib.pyplot as plt

from toiro import tokenizers
from toiro import datadownloader
from toiro import classifiers

warnings.simplefilter('ignore')<jupyter_output><empty_output><jupyter_text>2. 解析器の一覧を表示する---Toiroでは、次の解析器（単語分割器、形態素解析器、サブワードトークナイザー）を比較することができます。*   mecab-python3*   janome*   nagisa*   spacy*   sudachipy*   ginza*   sentencepiece*   KyTea（本体のインストールが必要）*   Juman++（本体のインストールが必要）また、Docker Hub からコンテナを利用することで、環境構築なしに9種類の解析器を比較することができます。```$ docker run --rm -it taishii/toiro /bin/bash```<jupyter_code># 実行環境で利用可能な解析器を表示する
available_tokenizers = tokenizers.available_tokenizers()
pprint.pprint(available_tokenizers)<jupyter_output>{'ginza': {'is_available': True, 'version': '2.3.2'},
 'janome': {'is_available': True, 'version': '0.3.10'},
 'jumanpp': {'is_available': False, 'version': False},
 'kytea': {'is_available': False, 'version': False},
 'mecab-python3': {'is_available': True, 'version': '0.996'},
 'nagisa': {'is_available': True, 'version': '0.2.7'},
 'sentencepiece': {'is_available': True, 'version': '0.1.91'},
 'spacy': {'is_available': True, 'version': '2.3.2'},
 'sudachipy': {'is_available': True, 'version': '0.4.9'}}<jupyter_text>3. コーパスをダウンロードする---Toiroでは、日本語コーパスのダウンローダーと前処理機能を標準で搭載しています。現時点では、3種類の日本語コーパスを利用することができます。*   Livedoor news corpus*   Yahoo movie reviews*   Amazon reviewsコーパスのダウンロード後は、内部で前処理を行い、pandas.DataFrame として扱うことができます。<jupyter_code># ダウンロード可能なコーパスの一覧を表示する
corpora = datadownloader.available_corpus()
print(corpora)
# Livedoor News Corpus をダウンロードし、pandas.DataFrame として読み込む
corpus = corpora[0]
datadownloader.download_corpus(corpus)
train_df, dev_df, test_df = datadownloader.load_corpus(corpus)
texts = train_df[1]
train_df.head()<jupyter_output>Downloading ldcc-20140209.tar.gz from https://www.rondhuit.com/download/ldcc-20140209.tar.gz: 31.6MB [00:04, 7.62MB/s]<jupyter_text>4. 各解析器の処理速度を比較する---ダウンロードした Livedoor news corpus を利用して、各解析器の処理速度を比較します。実行環境の情報、入力データの情報、各解析器の処理速度を辞書形式で出力します。<jupyter_code># tokenizers.compare では、リストを入力とする
report = tokenizers.compare(texts)
pprint.pprint(report)<jupyter_output>49%|████▊     | 2869/5900 [00:00<00:00, 28689.75it/s]<jupyter_text>5. 各解析器の単語分割を比較する---入力テキストの単語分割結果を比較できます。tokenizers.tokenize_*TOKENIZER_NAME* を利用することで、各解析器の単語分割の結果を取得できます。<jupyter_code># 各解析器の単語分割結果を出力する
text = "都庁所在地は新宿区。"
tokenizers.print_words(text, delimiter="|")
# sudachipy の単語分割結果を出力する
words = tokenizers.tokenize_sudachipy(text)
print(words)
# sentencepiece の単語分割結果を出力する
words = tokenizers.tokenize_sentencepiece(text)
print(words)<jupyter_output>['▁', '都', '庁', '所在地', 'は', '新宿', '区', '。']<jupyter_text>6. 各解析器の結果を取得する---Toiroでは、各解析器の元の解析結果を取得できます。tokenizers.original_*TOKENIZER_NAME* を利用することで、各解析器の解析結果を取得できます。<jupyter_code># mecab-python3 の解析結果を出力する
tokens = tokenizers.original_mecab(text)
print(tokens)
# GiNZA の解析結果を出力する
token = tokenizers.original_ginza(text)
for sent in token.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.tag_, token.dep_, token.head.i)
    print('EOS')<jupyter_output>0 都庁 都庁 NOUN 名詞-普通名詞-一般 compound 1
1 所在地 所在地 NOUN 名詞-普通名詞-一般 nsubj 3
2 は は ADP 助詞-係助詞 case 1
3 新宿区 新宿区 PROPN 名詞-固有名詞-地名-一般 ROOT 3
4 。 。 PUNCT 補助記号-句点 punct 3
EOS<jupyter_text>7. 後段タスク（テキスト分類）による精度比較---Toiroでは、SVM と BERT によるテキスト分類機能を搭載しています。ここでは、SVM によるテキスト分類結果を比較することで、単語分割の性能を比較します。BERT を利用する場合は、次のインストールを行ってください。```pip install toiro[all]```<jupyter_code># Janome を単語分割に利用した SVM モデルの学習  
model = classifiers.SVMClassificationModel(tokenizer='janome')                                                                                                                                   
model.fit(train_df, dev_df)                                                     
                                                                                
# 分類精度の評価                                               
result = model.eval(test_df)                                                    
print(result)

# 分類結果の予測
pred_y = model.predict(text)
print(pred_y)
# matplotlib のマーカを定義する
markers = [".", "X", "^", "<", ">", "p", "*", "h", "H", "+", "1"]

# 実行環境で利用できる解析器を取得する
avaiable_tokenizers = tokenizers.get_avaiable_tokenizers()
num_tokenizers = len(avaiable_tokenizers.items())

# 各解析器を利用した SVM モデル学習と評価を行う
for i, (k, v) in  enumerate(avaiable_tokenizers.items(), 1):                                                                      
    model = classifiers.SVMClassificationModel(tokenizer=k)                       
    model.fit(train_df, dev_df)                                                 
    result = model.eval(test_df)                                                
    elapsed_time = result["elapsed_time"]                                                                              
    accuracy_score = result["accuracy_score"]                                                                                                                                
    plt.scatter([elapsed_time ], [accuracy_score], label=k, marker=markers[i-1])
    print(f"[{i}/{num_tokenizers}]: {k:<13}, {accuracy_score}, {elapsed_time}")

# 処理速度と分類精度の図を表示する
plt.title(f"{corpus}: Accuracy and elapsed time")
plt.ylabel("Accuracy score")
plt.xlabel("Elapsed time (s)")                                                                                                          
plt.legend()                                                                                                                       
plt.show()<jupyter_output>[1/7]: mecab-python3, 0.8575305291723202, 0.819605827331543
[2/7]: janome       , 0.8629579375848032, 13.41454267501831
[3/7]: nagisa       , 0.858887381275441, 27.619521141052246
[4/7]: sudachipy    , 0.8616010854816825, 13.070273637771606
[5/7]: spacy        , 0.8724559023066486, 16.287087440490723
[6/7]: ginza        , 0.8656716417910447, 16.847912549972534
[7/7]: sentencepiece, 0.8670284938941656, 0.8188068866729736
{'fraction_non_alphanumeric': 0.12215453671048412, 'fraction_numerical': 0.05690926579031741, 'mean_word_length': 2.783505154639175, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 24, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 46, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '49021', 'license': 'Apache-2.0', 'n_tokens_mistral': 3071, 'n_tokens_neox': 2824, 'n_words': 341, 'path': 'examples/01_getting_started_ja.ipynb', 'repo_name': 'taishi-i/toiro', 'size': '6238'}