0
0

TfidfVectorizer.fitでtokenizeとidf計算にかかる時間の計測

Last updated at Posted at 2023-11-13

概要

TfidfVectorizer.fitにおいてtokenizeとidf計算にどのくらい時間を要しているのか調べました。

背景

TfidfVectorizerのidf辞書のなるべく高速なマージ方法を検討したく、その事前準備として、TfidfVectorizer.fitのどの工程に時間がかかっているのかを調査しようと思いました。fitで時間がかかるのは、形態素解析(tokenize)とidfの計算なので、それら2つの時間を計りました。

実装

ライブラリをインストールします。

pip install scikit-learn datasets

大きな日本語のデータセットを用意します。
今回はmiracl-corpusを使います。700万件弱の文章です。

import time
import MeCab
from sklearn.feature_extraction.text import TfidfVectorizer
from datasets import load_dataset
import tqdm
dataset = load_dataset("miracl/miracl-corpus", "ja")["train"]
dataset = [d["text"] for d in dataset]
print(len(dataset))
6953614

datasetから適当な件数を取得して、tokenizeとidf計算にかかる時間を計測し出力します。tokenizerは使い慣れたmecabを使用しました。

# 形態素解析器の初期化(MeCab)
mecab = MeCab.Tagger("-Owakati")

# 形態素解析を行う関数
def tokenize(text):
    return mecab.parse(text).split()

# 形態素解析の時間計測
for doc_num in [10**2, 10**3, 10**4, 10**5, 10**6]:
    start_time = time.time()
    tokenized_dataset = [tokenize(text) for text in dataset[:doc_num]]
    tokenize_time = time.time() - start_time

    # IDF計算の時間計測
    tfidf_vectorizer = TfidfVectorizer(tokenizer=lambda text: text, preprocessor=lambda text: text)
    start_time = time.time()
    tfidf_vectorizer.fit(tokenized_dataset)
    idf_time = time.time() - start_time

    print(f"文書数: {doc_num}")
    print(f"単語数: {sum([len(t) for t in tokenized_dataset])}")
    print(f"単語種類数: {len(tfidf_vectorizer.get_feature_names_out())}")
    print(f"形態素解析にかかった時間: {tokenize_time}")
    print(f"IDF計算にかかった時間: {idf_time}")
    print("")

結果

上記プログラムの実行結果は以下です。

文書数: 100
単語数: 6809
単語種類数: 1805
形態素解析にかかった時間: 0.07840418815612793
IDF計算にかかった時間: 0.003988027572631836

文書数: 1000
単語数: 75989
単語種類数: 9767
形態素解析にかかった時間: 0.03894186019897461
IDF計算にかかった時間: 0.021020174026489258

文書数: 10000
単語数: 652418
単語種類数: 38772
形態素解析にかかった時間: 0.3236968517303467
IDF計算にかかった時間: 0.15282797813415527

文書数: 100000
単語数: 7253378
単語種類数: 157076
形態素解析にかかった時間: 3.460052013397217
IDF計算にかかった時間: 1.8129661083221436

文書数: 1000000
単語数: 79557632
単語種類数: 538666
形態素解析にかかった時間: 48.29531979560852
IDF計算にかかった時間: 21.297609090805054

考察

以下の傾向が見て取れます。

  • miracl-corpusの特徴
    • 1件あたり平均して70-80単語
    • 単語数が10倍になると単語の種類数は3-4倍
  • 処理時間
    • 形態素解析もIDF計算も処理時間は文書数(あるいは単語数)に概ね比例している
    • 形態素解析はIDF計算の2倍くらい時間がかかっている。

制限事項

mecab以外のtokenizerを使ったらidf計算よりも高速になる可能性もあります。janomeやvibratoのほうがmecabより早いという記事もありました。

参考:【2023年版】python環境で利用できる日本語形態素解析ライブラリを比較してみた

0
0
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
0
0