ベトナム語の tokenize の速度比較

# 1. はじめに
ベトナム語に関する日本語の記事が全くないので、ベトナム語を tokenize するライブラリの速度を比較してみます。

ちなみに、ベトナム語はベトナムで話されている言語です。昔は漢字やチュノムと呼ばれる文字を使って書かれていましたが、今はアルファベットが使用されています。
ただ子音も母音も区別がかなり多いのと、声調によって意味を区別するので、それらを明示的に表すために、見た目は賑やかになっています。

```bash
Ý nghĩa ngày sinh nhật mà có thể bạn không biết
あなたが多分知らない誕生日の意味
```

これを単語に分けるとこうなります。

```bash: 
Ý nghĩa / ngày sinh nhật / mà / có thể / bạn / không / biết
```

なので、慣れるまではまずどこが単語の切れ目かも分からない言語になっています。日本語や中国語と同じですね。一方動詞の活用というような、単語が形を変えることは一切ありません。

# 2. 所要時間の測り方
処理を1000回行い、その平均所要時間を算出します。

```python
from functools import wraps
from time import perf_counter
from statistics import mean

def timeit(func):
    @wraps(func)
    def _wrapper(*args, **kwargs):
        es = []
        for _ in range(1000):
            t = perf_counter()
            result = func(*args, **kwargs)
            e = perf_counter() - t
            es.append(e)
        return result, mean(es)
    return _wrapper
```

# 3. 使用するライブラリ
下記の4種類のライブラリを比較します。

```bash
py_vncorenlp==0.1.4
pyvi==0.1.1
underthesea==6.2.0
vi-core-news-lg==0.0.1
```

## 3-1. VnCoreNLP
https://github.com/vncorenlp/VnCoreNLP

```python
import py_vncorenlp

rdrsegmenter = py_vncorenlp.VnCoreNLP(annotators=['wseg'], save_dir='/path/to/VnCoreNLP')

@timeit
def tokenize_by_vncorenlp(sent: str) -> list[str]:
    output = rdrsegmenter.word_segment(sent)
    return [word.replace('_', ' ') for word in ' '.join(output).split(' ')]
```

## 3-2. pyvi
https://github.com/trungtv/pyvi

```python
from pyvi import ViTokenizer

@timeit
def tokenize_by_pyvi(sent: str) -> list[str]:
    return [word.replace('_', ' ') for word in ViTokenizer.tokenize(sent).split(' ')]
```

## 3-3. underthesea
https://github.com/undertheseanlp/underthesea

```python
import underthesea

@timeit
def tokenize_by_underthesea(sent: str) -> list[str]:
    return underthesea.word_tokenize(sent)
```

## 3-4. Vietnamese language models for Spacy.io
https://gitlab.com/trungtv/vi_spacy

tokenize 周りに `pyvi` を使用しています。

```python
import spacy

nlp = spacy.load('vi_core_news_lg', disable=['tok2vec', 'tagger', 'parser'])

@timeit
def tokenize_by_vispacy(sent: str) -> list[str]:
    return [token.text.replace('_', ' ') for token in nlp(sent)]
```

# 4. 検証結果

## 4-1. 文章①
`Ý nghĩa ngày sinh nhật mà có thể bạn không biết`

| ライブラリ | 出力 | 速度 |
| :-- | :-- | :-- |
| VnCoreNLP | Ý nghĩa / ngày / sinh nhật / mà / có thể / bạn / không / biết | 0.00028 |
| pyvi | Ý nghĩa / ngày sinh nhật / mà / có thể / bạn / không / biết | 0.00016 |
| underthesea | Ý nghĩa / ngày sinh nhật / mà / có thể / bạn / không / biết | 0.00057 |
| vi_spacy | Ý nghĩa / ngày sinh nhật / mà / có thể / bạn / không / biết | 0.00020 |

## 4-2. 文章②
`Lào Cai là địa phương có tỷ lệ tiêm vaccine COVID-19 cao trên toàn quốc.`

| ライブラリ | 出力 | 速度 |
| :-- | :-- | :-- |
| VnCoreNLP | Lào Cai / là / địa phương / có / tỷ lệ / tiêm / vaccine / COVID-19 / cao / trên / toàn quốc / . | 0.00049 |
| pyvi | Lào Cai / là / địa phương / có / tỷ lệ / tiêm / vaccine / COVID / - / 19 / cao / trên / toàn quốc / . | 0.00025 |
| underthesea | Lào Cai / là / địa phương / có / tỷ lệ / tiêm / vaccine / COVID-19 / cao / trên / toàn quốc / . | 0.00079 |
| vi_spacy | Lào Cai / là / địa phương / có / tỷ lệ / tiêm / vaccine / COVID / - / 19 / cao / trên / toàn quốc / . | 0.00032 |

## 4-3. 文章③
`Tại đây, Thứ trưởng Nguyễn Thị Liên Hương đã thăm hỏi, động viên và tặng quà Tết cho những người bệnh đang cấp cứu và điều trị tại khoa Cấp cứu.`

| ライブラリ | 出力 | 速度 |
| :-- | :-- | :-- |
| VnCoreNLP | Tại / đây / , / Thứ trưởng / Nguyễn Thị Liên Hương / đã / thăm hỏi / , / động viên / và / tặng / quà / Tết / cho / những / người bệnh / đang / cấp cứu / và / điều trị / tại / khoa / Cấp cứu / . | 0.00073 |
| pyvi | Tại / đây / , / Thứ trưởng / Nguyễn Thị Liên Hương / đã / thăm hỏi / , / động viên / và / tặng / quà / Tết / cho / những / người bệnh / đang / cấp cứu / và / điều trị / tại / khoa / Cấp cứu / . | 0.00048 |
| underthesea | Tại / đây / , / Thứ trưởng / Nguyễn Thị Liên Hương / đã / thăm hỏi / , / động viên / và / tặng / quà / Tết / cho / những / người bệnh / đang / cấp cứu / và / điều trị / tại / khoa / Cấp cứu / . | 0.00164 |
| vi_spacy | Tại / đây / , / Thứ trưởng / Nguyễn Thị Liên Hương / đã / thăm hỏi / , / động viên / và / tặng / quà / Tết / cho / những / người bệnh / đang / cấp cứu / và / điều trị / tại / khoa / Cấp cứu / . | 0.00056 |

# 5. 終わりに
`pyvi` が最も早いことが分かりました。

# 6. ちなみに
`vietnamese-tokenizer` というトピックには他にも色々とライブラリが存在したのですが、Pythonで使えるのは上記くらいでした。

https://github.com/topics/vietnamese-tokenizer

ほぼ同じライブラリで tokenize だけでなく品詞タグ付けとNERの速度比較もやっている記事があるので、よかったらご覧ください。

https://huybik.github.io/Word-Tokenizer-Benchmark/