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

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

言語 JA

カタカナ・ひらがなを統一する

01.7.2

カタカナ・ひらがなを統一する

最終更新 2020-02-12 読了時間 2 分
まとめ
「ファミリーマート」「ふぁみりーまーと」「ファミリーマート」の 3 つは同じ読みなのに、文字列としては別物です。Unicode ではひらがな「ぁ」(U+3041) とカタカナ「ァ」(U+30A1) の差がちょうど 0x60 で、以降の文字も同じ順に並んでいるので、ord と chr で 0x60 を足し引きするだけで片仮名と平仮名を相互変換できます。半角カナは先に unicodedata.normalize("NFKC") で全角に揃えると同じ関数に通せます。名寄せや音声検索の前処理として、かな表記のゆれをどちらか一方に寄せたいときに使います。

直感 #

ふりがな欄やフードメニューには、「ふぁみりーまーと」「ファミリーマート」「ファミリーマート」のように同じ読みの別表記が混ざり、value_counts() を取ると 3 行に割れます。文字コード表を見ると、ひらがなの「あ」は U+3042、カタカナの「ア」は U+30A2 で、差は 0x60(10 進で 96)です。「ん」と「ン」まで同じ差です。だから 1 文字ずつ 0x60 を引けばカタカナ→ひらがな、足せばひらがな→カタカナになります。半角カナだけは別のブロック(U+FF66 以降)にあるため、先に NFKC 正規化で全角カタカナに直してから同じ式に通します。

Python で変換する #

次のコードは kata_to_hira と hira_to_kata の 2 関数を定義し、半角・全角カタカナ・ひらがなの 3 サンプルを NFKC 正規化してから kata_to_hira に通して、すべて同じひらがなになることを確かめます。

 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
27
28
29
30
import unicodedata

HIRA_START = ord("ぁ")
HIRA_END = ord("ゖ")
KATA_START = ord("ァ")

def kata_to_hira(text: str) -> str:
    chars = []
    for ch in text:
        code = ord(ch)
        if KATA_START <= code <= ord("ヺ"):
            chars.append(chr(code - 0x60))
        else:
            chars.append(ch)
    return "".join(chars)

def hira_to_kata(text: str) -> str:
    chars = []
    for ch in text:
        code = ord(ch)
        if HIRA_START <= code <= HIRA_END:
            chars.append(chr(code + 0x60))
        else:
            chars.append(ch)
    return "".join(chars)

samples = ["ファミリーマート", "ファミリーマート", "ふぁみりーまーと"]
for s in samples:
    s_nfkc = unicodedata.normalize("NFKC", s)
    print(s_nfkc, "→", kata_to_hira(s_nfkc))

実行結果の読み方 #

3 行の出力はいずれも矢印の右側が「ふぁみりーまーと」で、左側も NFKC 後の文字列なので 1 件目の半角カナは「ファミリーマート」として表示されます。ひらがなの 3 件目は kata_to_hira の範囲に 1 文字も入らず、何も変わらずに通過しています。変換後の列で nunique() を取ると 3 から 1 に減るので、名寄せの効果を数値で確認できます。

使いどころと落とし穴 #

「ヴ」は kata_to_hira で「ゔ」(U+3094) に写りますが、ひらがなの文章では「ヴ」を「ぶ」と書くことが多いので、「ヴァイオリン」と「ばいおりん」のゆれは 0x60 の変換だけでは吸収できません。「ヵ」「ヶ」も「ゕ」「ゖ」になるものの、住所の「三ヶ日」のような固有名詞では元の表記を残したいはずです。こうした例外は辞書ベースの置換テーブルを kata_to_hira の後に挟んで案件ごとに調整してください。送り仮名付きの漢字(「申し込み」)から読みを取り出したい場合は、fugashi や SudachiPy が返す読み(カタカナ)を kata_to_hira に通すと、ひらがな表記で安定したキーが作れます。