クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

検索のためのテキスト処理

このレッスンのあとで: 日本語の文章を、そろえて、2文字ずつに切り、検索に使えるトークンにすることができる。

60分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

索引に入れる前に、文章を整える

検索のためのテキスト処理とは、生の文章を、索引に入れられるトークンに整える作業です。大文字と小文字、全角と半角、記号をそろえ、文を切り分けます。

整え方が違うと、同じ語が別の語になり、検索で見つかりません。日本語には単語の間に空白がないので、切り方も決める必要があります。

このレッスンのゴール

メモ

日本語の文章を、そろえて、2文字ずつに切り、検索に使えるトークンにすることができる。

キーワード

ことばいみれい
正規化書き方の違いをそろえることABC を abc にする
文字バイグラム隣り合う2文字の組電車が → 電車・車が
形態素解析器辞書をもとに、文を単語に切る道具
ストップワードどの文にもあり、検索の手がかりにならない語は、の、です
語幹処理語の終わりを取って、語の形をそろえること遅れた → 遅れ

学生が入力するセルは、このプレビューでは空白です。

同じ語を、同じ書き方にそろえる

全角の「ABC」と半角の「ABC」は、人には同じ語でも、コンピュータには別の文字です。大文字と小文字も同じです。

索引を作る前と、検索語を受け取ったときに、同じ手順でそろえます。これが正規化です。記号も、ここで取り除きます。

例: そろえる前と後

元の書き方そろえた後行ったこと
ABC(全角の大文字)abc全角を半角に、大文字を小文字に
カフェ(半角のカタカナ)カフェ半角のカタカナを、全角に
休み。休み句点を取り除く

学生が入力するセルは、このプレビューでは空白です。

全角を半角にそろえる

コマンド
docker exec jupyter python3 -c "import unicodedata; print(unicodedata.normalize('NFKC', '\uff21\uff22\uff23 \uff11\uff12\uff13').lower())"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

辞書がなくても、2文字ずつなら切れる

日本語は、単語の間に空白がありません。本物の単語の切り分けには、辞書を使う形態素解析器が必要で、このラボには、その辞書がありません。

そこで、隣り合う2文字を1つのトークンにします。これが文字バイグラムで、辞書なしで切れます。検索語と文書を同じ方法で切れば、共通のトークンで探せます。

例: 「電車が遅れます」を2文字ずつに

切り方トークン数
1文字ずつ電・車・が・遅・れ・ま・す7
2文字ずつ電車・車が・が遅・遅れ・れま・ます6
検索語「電車」電車1

学生が入力するセルは、このプレビューでは空白です。

2文字ずつの切り方

コマンド
docker exec jupyter python3 -c "t = 'retrieval'; print([t[n:n + 2] for n in range(len(t) - 1)])"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ストップワードと語尾の扱い

「は」「の」「です」のようなストップワードは、どの文にもあり、手がかりになりません。tf-idf が小さいので、索引から外すこともあります。

「遅れた」「遅れます」は、同じ「遅れ」の形です。語の終わりを取って形をそろえることを、語幹処理と言います。取る語尾の表を使う単純な方法は、あくまで目安です。

語尾を取る単純な規則

コード: python
endings = ["ました", "ます", "ない", "た", "る"]

def stem(word):
    for ending in endings:
        # 語幹が2文字以上残るときだけ、語尾を取ります。
        if word.endswith(ending) and len(word) - len(ending) >= 2:
            return word[:len(word) - len(ending)]
    return word

for word in ["遅れました", "遅れます", "遅れない", "遅れた", "遅れる", "ある"]:
    print(word, "->", stem(word))
# endings に "れ" を足すと、何が起きますか。

よくある間違い

注意

2文字ずつに切れば、単語の検索と同じだと考えがちです。「京都」で探すと、「東京都」も見つかります。バイグラムは目安で、本物の切り分けには辞書が必要です。

さらに挑戦: 3文字ずつに切る

課題の bigrams を、3文字ずつ(文字トライグラム)に変えると、「京都」の検索で「東京都」が見つかるでしょうか。

2文字のままの検索語は、3文字の文書とは合いません。切る長さと見つかり方の関係を、調べてください。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。