01.7.9
ルビ付きテキストから読み仮名を抽出・除去する
<ruby>教師あり学習<rt>きょうしあり</rt></ruby> のような HTML ルビを、1 つの関数で本文から取り除き、同時に (漢字, 読み) のペアとして別リストに保存します。仕組みは正規表現 re.sub にコールバック関数を渡し、一致するたびに読みを readings へ追記してから漢字だけを返す、というものです。読み仮名は検索用の別カラムに、ルビを除いた本文は形態素解析に渡す、という 2 つの用途を 1 回の走査で満たします。直感 #
「機械学習(きかいがくしゅう)を支える」をそのまま形態素解析器に入れると、「(」「きかいがくしゅう」「)」が独立したトークンになり、単語の頻度も文の長さも歪みます。ルビは本文ではなく「漢字に付いた注釈」です。だから本文からは外し、別の場所に「機械学習 → きかいがくしゅう」という対応だけ残しておけば、検索では読みで引けて、解析では本文だけを使えます。括弧ルビは「漢字の連続の直後に全角括弧で囲まれた仮名」というパターンで、HTML ルビは <ruby> と <rt> のタグで囲まれているので、どちらも正規表現 1 本ずつで見つけられます。
Python で抽出する #
次のコードは括弧ルビと HTML ルビの 2 つの正規表現を定義し、extract_ruby がルビを除いた本文と (漢字, 読み) のリストを返します。サンプルは 1 文の中に両方の形式を含んでいます。
| |
実行結果の読み方 #
cleaned は「機械学習を支える教師あり学習の基礎」で、形態素解析に渡してもルビの括弧やタグがトークンに混ざりません。ruby_list は 2 要素のリストで、1 つ目が括弧ルビ、2 つ目が HTML ルビから取れた (漢字, 読み) のペアです。括弧ルビの読みに長音「ー」が含まれる「珈琲(コーヒー)」のようなケースは一致しないので、対象データにカタカナ読みが多いなら PAREN_RUBY の文字クラスに ー を足してください。
使いどころと落とし穴 #
読み仮名を別フィールドに分離したうえで、検索時には漢字・かな・ローマ字のすべてから引ける逆引き辞書({"きかいがくしゅう": "機械学習"})を作ると、ユーザーが読みしか知らない語でも検索でヒットします。電子書籍の EPUB では <rb> <rt> <rp> の組み合わせが使われるため、HTML_RUBY ではなく BeautifulSoup でタグを抽出します。応用として、文書全体に対する len(ruby_list) と文字数の比率を「ルビ密度」として算出し、密度が高いページを優先的にやさしい日本語版や翻訳の対象にする、といったワークフローにも使えます。