日本語テキスト処理は、単語境界が明示的でない点で英語より難しい。本記事では形態素解析ツール 3 種の比較と、 時代の前処理事情を扱います。
形態素解析ツール比較
| ツール | 特徴 | 速度 | 辞書 |
|---|---|---|---|
| MeCab | 業界標準、C++ 実装 | 最速 | IPA 辞書 / NEologd |
| SudachiPy | ワークス徳島大共同、新語に強い | 速い | Sudachi 辞書(高品質) |
| Janome | Pure Python、インストール容易 | 遅い | IPA 辞書 |
| Ginza (spaCy 連携) | 依存解析・固有表現も | 中 | Sudachi |
ストップワード
- 自動生成:頻出語の上位 100 を機械的に除外
- 手動:「です・ます・の・と・が」などをリスト化(slothlib が定番)
- ドメイン特化:業界用語の頻出語を追加
LLM 時代の変化
LLM の前処理は最小限で OK
/ GPT-4 は前処理にかなり頑健。形態素解析・ストップワード除去なしで投げても、性能は落ちないことが多い。前処理を頑張るのは古典的 (TF-IDF + ロジ回 等)の場合。LLM では「クリーニングしすぎない」のも一つの作法。
Python 実装:MeCab vs SudachiPy 比較
MeCab で形態素解析
Python
# !pip install mecab-python3 unidic-liteimport MeCab
tagger = MeCab.Tagger("-Owakati") # 分かち書きtext = "今日は良い天気ですね。データエンジニアリングが楽しい。"print(tagger.parse(text).strip())# → 今日 は 良い 天気 です ね 。 データ エンジニアリング が 楽しい 。
# 詳細解析(品詞付き)tagger = MeCab.Tagger()node = tagger.parseToNode(text)while node: if node.surface: features = node.feature.split(",") print(f"{node.surface:15s} {features[0]:10s} {features[6] if len(features)>6 else '*'}") node = node.nextSudachiPy で形態素解析(より新語に強い)
Python
# !pip install sudachipy sudachidict_corefrom sudachipy import dictionary, tokenizer
tokenizer_obj = dictionary.Dictionary().create()mode = tokenizer.Tokenizer.SplitMode.C # A=最小, B=中, C=最大
text = "デジタルトランスフォーメーションを推進する"tokens = tokenizer_obj.tokenize(text, mode)for t in tokens: print(f"{t.surface():20s} 品詞:{t.part_of_speech()[0]:10s} 正規:{t.normalized_form()}")ストップワード除去 + n-gram 抽出
Python
import re
# slothlib 互換のストップワードリストSTOPWORDS = { "の", "に", "は", "を", "た", "が", "で", "て", "と", "し", "れ", "さ", "ある", "いる", "も", "する", "から", "な", "こと", "として", "い", "や", "れる", "など", "なっ", "ない", "この", "ため", "その", "あっ", "よう", "また", "もの", "という", "あり", "まで",}
def filter_tokens(tokens: list, stopwords=STOPWORDS) -> list: return [t for t in tokens if t not in stopwords and len(t) > 1]
def extract_ngrams(tokens: list, n: int = 2) -> list: return [" ".join(tokens[i:i+n]) for i in range(len(tokens) - n + 1)]
text = "今日は良い天気ですね。データエンジニアリングが楽しい。"tokens = tagger.parse(text).strip().split()filtered = filter_tokens(tokens)bigrams = extract_ngrams(filtered, 2)print("単語:", filtered)print("Bigram:", bigrams)TF-IDF ベクトル化
Python
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [ "データエンジニアリングが楽しい", "データ基盤を構築する", "AIを業務に活用する",]
# 単純な空白区切りで投入(事前に分かち書き済み)def tokenize_jp(text): return tagger.parse(text).strip().split()
vec = TfidfVectorizer(tokenizer=tokenize_jp, token_pattern=None, min_df=1)matrix = vec.fit_transform(corpus)print(vec.get_feature_names_out())print(matrix.toarray())ふくふくの進め方
構築・分類モデル開発でのテキスト前処理を、ユースケースに応じて最適化します。
次回予告
EP.15 は前処理パイプラインの再現性。本編の到達点として、ここまでの個別技術を1本のパイプラインに束ねます。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。