K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

日本語ストップワードを除去する

01.7.8

日本語ストップワードを除去する

最終更新 2020-05-06 読了時間 2 分
まとめ
「する」「こと」「です」「ます」のように、どの文書にも現れて特徴にならない語をストップワードと呼び、TF-IDF やキーワード抽出の前に取り除きます。このページでは unicodedata.normalize("NFKC") と小文字化で表記を揃える normalize_text、正規表現 1 本でかな・漢字の連続を切り出す simple_tokenize、26 語の STOPWORDS 集合と len(t) > 1 で絞り込む remove_stopwords の 3 関数をつなげます。形態素解析器を入れられない環境向けの簡易版なので、正規表現トークナイザが「サービス」を「サ」「ビス」に割ってしまう限界も実行結果で確かめます。

直感 #

レビュー文を単語の出現回数で比べると、どのレビューにも「する」「こと」「です」が上位に来て、商品ごとの違いが埋もれます。こうした語をあらかじめ辞書に入れて除くのがストップワード除去で、残った「丁寧」「初めて」のような語が TF-IDF で浮かび上がります。本格的には形態素解析器(Janome、SudachiPy)で単語に分けてから品詞で落としますが、ここでは標準ライブラリだけで動く 3 段階の簡易版を作ります。まず NFKC 正規化と小文字化で「ABC」と「abc」を同じにし、次に正規表現でかな・漢字の連続を 1 トークンとして切り出し、最後に辞書と文字数でふるい落とします。

Python でフィルタする #

次のコードは 26 語のストップワード集合を定義し、正規化・トークン化・除去の 3 関数を 1 文のレビューに順番に適用して、残ったトークンを表示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import re
import unicodedata

STOPWORDS = {
    "する", "なる", "いる", "ある", "こと", "もの",
    "これ", "それ", "あれ", "ここ", "そこ", "あそこ",
    "ため", "よう", "さん", "して", "した", "です", "ます",
    "から", "まで", "ので", "なら", "そして", "しかし",
}

def normalize_text(text: str) -> str:
    text = unicodedata.normalize("NFKC", text.lower())
    text = re.sub(r"[0-90-9]+", "0", text)
    return text

def remove_stopwords(tokens: list[str]) -> list[str]:
    return [t for t in tokens if t not in STOPWORDS and len(t) > 1]

def simple_tokenize(text: str) -> list[str]:
    return re.findall(r"[ぁ-んァ-ン一-龥]+", text)

text = "このサービスは使いやすくて、ここまで丁寧に対応してくれるのは初めてでした。"
normalized = normalize_text(text)
tokens = simple_tokenize(normalized)
clean_tokens = remove_stopwords(tokens)
print(clean_tokens)

実行結果の読み方 #

残ったのは「このサ」「ビスは使いやすくて」「ここまで丁寧に対応してくれるのは初めてでした」の 3 トークンで、意味の単位にはなっていません。原因は simple_tokenize が単語境界ではなく文字種の切り替わりだけで区切ることにあり、ストップワード除去そのものは正しく動いています。Janome の Tokenizer().tokenize(text, wakati=True) のような分かち書きの結果を remove_stopwords に渡すと、「サービス」「丁寧」「対応」「初めて」のような特徴語が残り、この辞書と len(t) > 1 の 2 段フィルタが意図どおりに働きます。

使いどころと落とし穴 #

ストップワード辞書は業種ごとの頻出語を足してカスタマイズします。たとえばコールセンターのログなら「お客様」「御社」「お世話」を追加しないと、すべての文書で上位に来て TF-IDF の重みを薄めます。形態素解析が使える環境では SudachiPy や Janome で分かち書きし、品詞が助詞・助動詞・記号のトークンを除外してからこの辞書を適用すると、1 文字判定に頼らずに済みます。記号や英数字の多いレビューでは、simple_tokenize の文字クラスに ー と A-Za-z0-9 を加えるかどうかで「サービス」や「iPhone」の扱いが変わるので、分析対象のサンプルを 10 件ほど通して確かめてから決めてください。