機械学習のためのデータ前処理:同じ意味なのに違う?表記ゆれデータのクレンジング【Pandas入門】
はじめに
機械学習モデルの性能は、使用するデータの質に大きく左右されます。どんなに高度なモデルを使ったとしても、データが「汚れている」と、期待する結果は得られません。データ前処理は、この「データの汚れ」を取り除き、モデルが正しくデータを解釈できるようにするための非常に重要なステップです。
データに含まれる様々な汚れの中でも、ビジネスデータで頻繁に遭遇するのが「表記ゆれ」です。例えば、企業名が「株式会社〇〇」「(株)〇〇」「〇〇(株)」のように異なって入力されている場合などです。これらは人間が見れば同じものを指していると分かりますが、コンピューターにとっては全く異なる文字列として扱われます。
本記事では、この「表記ゆれ」がなぜデータ分析や機械学習において問題となるのかを明らかにし、Pythonの代表的なデータ分析ライブラリであるPandasを使って、表記ゆれを検出し、そして統一(クレンジング)する方法を具体的に解説します。
表記ゆれとは何か?なぜ問題なのか?
表記ゆれとは、同じ意味や同じ対象を指しているにも関わらず、データの入力形式や表現が異なる状態を指します。
具体的な例としては、以下のようなものがあります。
- 略称や正式名称の混在: 「株式会社ABC」「(株)ABC」
- 全角・半角の違い: 「東京都」「東京都」
- スペースの有無や種類: 「Apple Inc.」「Apple Inc」「Apple Inc. 」
- 大文字・小文字の違い: 「Product A」「product a」
- 同義語や別名の混在: 「スマホ」「スマートフォン」
- 旧称と現名称の混在: 「東京エレクトロン」「東京エレク」 (古いデータの場合)
このような表記ゆれがデータに含まれていると、以下のような問題が発生します。
- 正確な集計や分析ができない: 例えば、「株式会社ABC」と「(株)ABC」が別のものとしてカウントされてしまい、正確な企業別の売上合計などが算出できません。
- カテゴリ分けがうまくいかない: 商品カテゴリや顧客セグメントを正確に分類することが困難になります。
- 機械学習モデルの性能低下: モデルが同じものを異なるカテゴリとして認識したり、データの特徴を正しく捉えられなかったりするため、予測精度や分類精度が低下します。
データ分析や機械学習を成功させるためには、これらの表記ゆれを事前に検出し、意味的に同じものは同じ表記に統一する「クレンジング」作業が不可欠です。
Pandasを使った表記ゆれの検出と確認
データセットにどのような表記ゆれが存在するかを確認するためには、特定の列(カラム)に含まれるユニークな値の種類とその出現頻度を調べることが有効です。Pandasでは、value_counts()
メソッドや unique()
メソッドを使って簡単にこれを行うことができます。
まずはサンプルデータを作成してみましょう。
import pandas as pd
# サンプルデータの作成
data = {
'商品カテゴリ': [
'家電', '家具', '家電', 'カデン', '生活雑貨',
'家具', 'かぐ', '生活雑貨', '家電', '家電',
'KaDen', '生活雑貨', '家具'
]
}
df = pd.DataFrame(data)
print(df)
商品カテゴリ
0 家電
1 家具
2 家電
3 カデン
4 生活雑貨
5 家具
6 かぐ
7 生活雑貨
8 家電
9 家電
10 KaDen
11 生活雑貨
12 家具
このデータフレームの「商品カテゴリ」列に含まれる表記ゆれを確認してみます。value_counts()
メソッドを使うと、各ユニークな値の出現回数をカウントできます。
# 「商品カテゴリ」列のユニークな値と出現回数を確認
category_counts = df['商品カテゴリ'].value_counts()
print(category_counts)
商品カテゴリ
家電 4
家具 3
生活雑貨 3
カデン 1
かぐ 1
KaDen 1
Name: count, dtype: int64
上記の出力を見ると、「家電」「カデン」「KaDen」が同じカテゴリを指している可能性があること、「家具」「かぐ」が同じカテゴリを指している可能性があることがすぐに分かります。
また、単にユニークな値の一覧を見たい場合は unique()
メソッドを使用します。
# 「商品カテゴリ」列のユニークな値の一覧を確認
unique_categories = df['商品カテゴリ'].unique()
print(unique_categories)
['家電' '家具' 'カデン' '生活雑貨' 'かぐ' 'KaDen']
どちらの方法も、データに含まれる表記ゆれの種類を把握するのに役立ちます。特に value_counts()
は、出現頻度の低いものが表記ゆれである可能性が高いといった推測の手助けになります。
Pandasを使った表記ゆれの統一(クレンジング)
表記ゆれを確認したら、次はそれらを統一する作業を行います。Pandasでは、文字列操作のための.str
アクセサや、.replace()
メソッドなどが便利です。
1. 基本的な文字列操作による統一
単純な大文字・小文字、全角・半角スペース、不要な文字の除去などには、.str
アクセサを使った文字列操作が有効です。
例えば、先ほどのデータで「KaDen」を「家電」に統一したい場合を考えます。また、今後他のカテゴリでも大文字・小文字のゆれが発生する可能性を考慮し、全てを小文字に統一するといった処理も考えられます。
# 例1: 大文字を小文字に統一(今回のデータにはあまり意味がないが例として)
df['商品カテゴリ_lower'] = df['商品カテゴリ'].str.lower()
print(df[['商品カテゴリ', '商品カテゴリ_lower']])
# 例2: 特定の文字列を別の文字列に置換 (KaDen -> 家電)
# str.replace() は部分一致も置換するため注意
df['商品カテゴリ_replaced'] = df['商品カテゴリ'].str.replace('KaDen', '家電')
print(df[['商品カテゴリ', '商品カテゴリ_replaced']])
商品カテゴリ 商品カテゴリ_lower
0 家電 家電
1 家具 家具
2 家電 家電
3 カデン カデン
4 生活雑貨 生活雑貨
5 家具 家具
6 かぐ かぐ
7 家電 家電
8 家電 家電
9 KaDen kaden # KaDen が kaden に変換されている
10 生活雑貨 生活雑貨
11 家具 家具
商品カテゴリ 商品カテゴリ_replaced
0 家電 家電
1 家具 家具
2 家電 家電
3 カデン カデン
4 生活雑貨 生活雑貨
5 家具 家具
6 かぐ かぐ
7 家電 家電
8 家電 家電
9 KaDen 家電 # KaDen が 家電 に変換されている
10 生活雑貨 生活雑貨
11 家具 家具
.str.replace()
は便利な機能ですが、部分一致でも置換を行ってしまうため、意図しない置換が発生する可能性があります。例えば、「ABCD株式会社」を「(株)ABCD」にしたい場合に .str.replace('株式会社', '(株)')
を使うと、「ABCD株式会社」は「ABCD(株)」になりますが、「EFG株式会社」も「EFG(株)」になります。もし「株式会社」が含まれる文字列全てを置換したいのであれば問題ありませんが、特定の完全一致文字列だけを置換したい場合には向かないことがあります。
2. .replace()
メソッドを使った完全一致での統一
特定の「表記ゆれ文字列」を、対応する「正しい文字列」に一括で置き換えたい場合は、Pandasの .replace()
メソッドを使うのが最も効果的です。.replace()
メソッドは、引数に辞書形式で {'古い値': '新しい値', ...}
を指定することで、完全一致した値をまとめて置換することができます。
先ほどのサンプルデータで、「カデン」と「KaDen」を「家電」に、「かぐ」を「家具」に統一してみましょう。
# 表記ゆれを統一するための置換ルールを辞書で定義
replace_map = {
'カデン': '家電',
'KaDen': '家電',
'かぐ': '家具'
}
# replace() メソッドと辞書を使って値を置換
df['商品カテゴリ_cleaned'] = df['商品カテゴリ'].replace(replace_map)
# クレンジング後のデータで value_counts() を確認
cleaned_category_counts = df['商品カテゴリ_cleaned'].value_counts()
print("\n--- クレンジング後のカテゴリ別出現回数 ---")
print(cleaned_category_counts)
--- クレンジング後のカテゴリ別出現回数 ---
商品カテゴリ_cleaned
家電 6
家具 4
生活雑貨 3
Name: count, dtype: int64
このように、replace()
メソッドに辞書を渡すことで、複数の表記ゆれを一括で、かつ完全一致で統一することができます。これが、表記ゆれクレンジングにおける最も一般的で強力な手法の一つです。
3. その他の表記ゆれへの対応
- 全角・半角、大文字・小文字の統一: Pythonの標準ライブラリ
unicodedata
や、外部ライブラリmojimoji
などを使うと、全角カタカナを半角に、全角英数字を半角に、ひらがなをカタカナに、といった変換が容易になります。これらのライブラリで変換した後に.replace()
でさらに細かい表記ゆれを統一するのが効果的です。また、df['カラム名'].str.lower()
で全て小文字に統一することも一般的です。 - 不要なスペースの除去:
df['カラム名'].str.strip()
で前後のスペースを除去したり、df['カラム名'].str.replace(' ', '')
で途中のスペースを除去したりできます。 - あいまい一致の統一: 上記の完全一致の置換では対応できない、微妙に異なる表記(例:「アップル」「あっぷる」)を統一したい場合は、より高度な手法(正規表現を使ったパターンマッチングや、Levenshtein距離などの文字列類似度を利用した手法)が必要になります。これは入門編としては範囲外ですが、実務では検討が必要になる場合があります。
まとめ
本記事では、機械学習のためのデータ前処理における重要な課題の一つである「表記ゆれ」に焦点を当てて解説しました。
表記ゆれは、データ分析や機械学習モデルの精度を低下させる要因となります。これを解決するためには、データに含まれる表記ゆれを検出し、適切に統一(クレンジング)する作業が不可欠です。
Pandasライブラリを使うことで、value_counts()
や unique()
メソッドによる表記ゆれの検出・確認、そして .str.replace()
や .replace()
メソッド(特に辞書を使った一括置換)による効率的な統一処理を行うことができます。
データ前処理は地道な作業ですが、質の高いデータを準備することが、機械学習プロジェクト成功の鍵となります。本記事で紹介した表記ゆれのクレンジング手法が、皆様のデータ前処理の一助となれば幸いです。