Pythonによるテキストデータの表記揺れ対策あれこれ

アンケートデータなどのテキスト情報を集計・分析する時、“表記揺れ”には非常に悩まされます。
例えば、同じ単語でも「Windows10」「Windows10」「WINDOWS10」「Windows-10」・・・といって、人によって様々な書き方があります。
このような表記揺れをそのままにして分析すると、上のすべてが別の単語と見なされてしまい、分析結果も精度の悪いものになってしまいます。

完全に綺麗にするならばテキストを1つ1つ見ていくよりありませんが、何万件などというデータがある場合にそれは現実的ではありません。
しかし、いちいち確認せずとも、ある程度機械的に対応することは可能です。

本記事では、Pythonで簡単にできるテキストデータの表記揺れ対策(データクレンジング)方法について整理しました。

大文字・小文字変換

大文字・小文字の表記は人により様々です。
しかし大文字か小文字かでその文章の意味が変わるということはまず無いので、よっぽどの事がなければ統一した方が良いでしょう。

この変換はすでにPythonに初期装備されており、簡単にできます。
それには、以下のように全て大文字にするならば.upper()、全て小文字にするならば.lower()を文字列の後にくっつけるだけです。

簡単ですね。
大文字小文字どちらに揃えるかは好きな方で良いかと思います。

ちなみに、先頭文字だけ大文字にするcapitalize()や、単語ごとの先頭文字だけ大文字にするtitle()という書き方もあります。

余計な記号の削除

記号も多くの場合は不要です。
記号が固有名詞の一部になっているなどといった場合もありますが、そうだとしても人がテキストを入力している場合は全員が記号を間違えず入力している保証はありません。
それならば、いっそ記号は取ってしまった方が良い、と考えられます。
(気をつけた方が良いとすれば、文章中にURLやメールアドレスがあってその情報が重要な場合には「/」や「@」といった半角記号は残しておいた方が良い時もあります。)

このように「指定した文字を一律で消す」には、Pythonに標準搭載されているreplaceメソッドを使います。

たとえば「、」を消したい場合。

「、」が消えています。
なお、replaceは「指定した文字を消す」のではなく、「指定した文字を置換する」メソッドです。
上記の処理は「、」を「」に置換することによって、“「、」を消す”という処理を実現しています。

また、消したい文字が複数ある場合もあります。例えば「、」と「。」を消したい場合は以下のように書けます。

これでOKです。
ですが、この例のように何個も並べて書くと面倒な上に見栄えが悪いので、消したい文字が多い場合は正規表現ライブラリrere.subメソッドを使った方が良いでしょう。

このように、置換したい文字を正規表現で指定します。[ ]の中に文字を並べれば何文字でも指定できます。
replaceとは少々書き方が異なるのでご注意ください。

また、「もう記号は全部消しちゃえ!」という場合は、以下のような正規表現を指定すれば記号はおおよそ消えます。

1行目が半角記号すべてを消す正規表現、2行目が全角記号すべてを消す正規表現となっています。

全角・半角変換

続いては全角・半角の変換です。
半角カタカナを使う事はめっきり少なくなりましたが、英字や数字を全角で書くか半角で書くかは人によって流派があります。
しかしこちらも全角か半角かで意味が変わる事はそう無いので、一般的には統一しておくべきです。

これにはmojimojiというライブラリが便利です。
mojimojiライブラリのzen_to_hanで全角文字を半角文字に変える処理、han_to_zenで半角文字を全角文字に変える処理ができます。わかりやすいメソッド名で良いですね。

変換できているようです。
特に何もしなければ、英字も数字もカタカナも全て変換されます。(すでに変換済の文字はそのまま表示されます。)

ちなみに、英字だけは触りたくない場合は引数にascii=False、数字だけは触りたく無い場合は引数にdigit=False、カタカナだけ触りたく無い場合は引数にkana=Falseを指定すればOKです。

おわりに

ということで、一律で以下の処理を掛けてしまえば、ほぼ労力ゼロである程度の表記揺れに対応できます。

この方法ではスペルミスなどまでは対処しきれませんが、完璧に綺麗にしようとするとやはり1つ1つ人間がチェックせねばならず、それは非常に手間がかかります。

テキストマイニングではまずここに示した処理を一律で掛けておいて、それで対応できない表記揺れはもう無視するという方針で行うのが、精度面と作業の手間の両面で、良いバランスなのではないでしょうか。