[機械学習のはじめ方] Part9: 欠損値処理と外れ値検出

機械学習モデルの精度を高めるための必須テクニック

機械学習モデルを構築する際、データの質はモデルの性能に直接影響します。実際のデータには、値が入っていない「欠損値」や、他の値から大きく外れた「外れ値」が含まれていることがよくあります。これらを適切に処理することは、データ前処理の中でも特に重要なステップです。

このブログ記事では、機械学習の学習ステップ「Step 2: Pythonとデータ前処理」の中の「欠損値処理と外れ値検出」について、基本的な考え方と代表的な手法を解説します。📊

1. 欠損値処理 🤔

欠損値とは、データセットの中で値が存在しない箇所のことです。欠損値があると、多くの機械学習アルゴリズムはそのままでは動作しないか、誤った結果を導く可能性があります。

欠損値の確認方法

PythonのPandasライブラリを使うと、簡単に欠損値の数を確認できます。

import pandas as pd
import numpy as np

# サンプルデータフレームを作成
data = {'col1': [1, 2, np.nan, 4, 5],
        'col2': [np.nan, 7, 8, 9, 10],
        'col3': ['A', 'B', 'C', np.nan, 'E']}
df = pd.DataFrame(data)

# 各列の欠損値の数を表示
print("各列の欠損値の数:")
print(df.isnull().sum())

# データフレーム全体の欠損値の合計数を表示
print("\nデータフレーム全体の欠損値の合計数:")
print(df.isnull().sum().sum())

上記のコードは、各列に含まれる欠損値(np.nan)の数をカウントして表示します。

代表的な欠損値処理手法

欠損値の処理方法は、大きく分けて「削除」と「補完」があります。

手法 説明 メリット デメリット
リストワイズ削除 欠損値を含む行(サンプル)全体を削除する。 実装が簡単。 データ量が減少し、情報が失われる可能性がある。欠損が多い場合に不向き。
ペアワイズ削除 計算に必要な変数のみを用いる方法。(特定の分析手法で利用) リストワイズ削除より多くのデータを利用できる。 分析ごとに使用されるサンプル数が異なる場合がある。
平均値補完 欠損値をその列の平均値で置き換える。(数値データ向け) 実装が簡単。 データの分散を小さくしてしまう可能性がある。外れ値の影響を受けやすい。
中央値補完 欠損値をその列の中央値で置き換える。(数値データ向け) 外れ値の影響を受けにくい。 データの分布形状を変えてしまう可能性がある。
最頻値補完 欠損値をその列の最頻値(最も多く出現する値)で置き換える。(カテゴリカルデータ向け) カテゴリカルデータに適用できる。 データの分布形状を変えてしまう可能性がある。
高度な補完手法 回帰補完、k-NN補完、多重代入法など、他の変数の情報を使って欠損値を予測・補完する。 より精度の高い補完が期待できる。 計算コストが高く、実装が複雑になる場合がある。

どの手法を選択するかは、データの特性、欠損値の量やパターン、分析の目的によって異なります。

Pandasによる欠損値補完の実装例

Pandasの fillna() メソッドを使うと、簡単に欠損値を補完できます。

# 'col1'の欠損値を平均値で補完
mean_val = df['col1'].mean()
df['col1_mean_filled'] = df['col1'].fillna(mean_val)
print("平均値で補完後のcol1:\n", df[['col1', 'col1_mean_filled']])

# 'col2'の欠損値を中央値で補完
median_val = df['col2'].median()
df['col2_median_filled'] = df['col2'].fillna(median_val)
print("\n中央値で補完後のcol2:\n", df[['col2', 'col2_median_filled']])

# 'col3'の欠損値を最頻値で補完
mode_val = df['col3'].mode()[0] # mode()は複数返す可能性があるので[0]で最初の値を取得
df['col3_mode_filled'] = df['col3'].fillna(mode_val)
print("\n最頻値で補完後のcol3:\n", df[['col3', 'col3_mode_filled']])

# 欠損値を含む行を削除 (リストワイズ削除)
df_dropped = df.dropna()
print("\n欠損値を含む行を削除後:\n", df_dropped)

2. 外れ値検出と対処 📈

外れ値とは、データセットの中で他の値から極端に離れている値のことです。外れ値は、測定誤差、入力ミス、あるいは特異な事象によって発生することがあります。外れ値は、平均値などの統計量を歪ませたり、モデルの学習に悪影響を与えたりする可能性があります。

代表的な外れ値検出手法

外れ値を検出するには、主に統計的手法と可視化が用いられます。

  • 統計的手法:
    • 標準偏差法 (e.g., 3σ法): データが正規分布に従うと仮定し、平均値から標準偏差の±3倍以上離れた値を外れ値とみなす方法。
    • 四分位範囲 (IQR) を利用した方法: データの中央値や四分位数を用いるため、正規分布を仮定せず、外れ値に対して頑健(ロバスト)です。第1四分位数 (Q1) と第3四分位数 (Q3) の差 (IQR = Q3 – Q1) を計算し、Q1 - 1.5 * IQR より小さい値、または Q3 + 1.5 * IQR より大きい値を外れ値とみなします。
  • 可視化による検出:
    • 箱ひげ図 (Box Plot): データの分布、中央値、四分位数、そして外れ値候補を視覚的に表示します。IQR法に基づいた外れ値が点で示されることが多いです。
    • 散布図 (Scatter Plot): 2つの変数の関係性をプロットし、他の点から孤立している点を見つけることで外れ値を発見できます。
  • アルゴリズムによる検出:
    • Isolation Forest: データをランダムに分割し、異常なデータ(外れ値)が早く孤立することを利用する手法です。
    • Local Outlier Factor (LOF): ある点の近傍と比較して、密度が低い点を外れ値とみなす手法です。

Pandasによる基本統計量の確認

Pandasの describe() メソッドを使うと、平均値、標準偏差、四分位数などを確認でき、外れ値の存在を推測する手がかりになります。

# サンプルデータフレーム (外れ値を含む可能性のあるデータ)
data_outlier = {'value': [10, 12, 11, 13, 10, 12, 11, 100, 14, 9]}
df_outlier = pd.DataFrame(data_outlier)

# 基本統計量を表示
print("基本統計量:")
print(df_outlier.describe())

# IQRを計算
Q1 = df_outlier['value'].quantile(0.25)
Q3 = df_outlier['value'].quantile(0.75)
IQR = Q3 - Q1

# 外れ値の閾値を計算
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

print(f"\nIQR: {IQR}")
print(f"外れ値の下限閾値: {lower_bound}")
print(f"外れ値の上限閾値: {upper_bound}")

# 外れ値候補を表示
outliers = df_outlier[(df_outlier['value'] < lower_bound) | (df_outlier['value'] > upper_bound)]
print("\n外れ値候補:")
print(outliers)

この例では、value 列の 100 が IQR 法によって外れ値候補として検出されます。

外れ値の対処法

外れ値を検出した場合の対処法はいくつかあります。

  • 削除: 欠損値処理と同様に、外れ値を含むサンプルを削除します。ただし、貴重な情報が失われる可能性もあります。
  • 変換: 対数変換、平方根変換などを行い、データの分布を調整して外れ値の影響を緩和します。
  • 補完 (Winsorizationなど): 外れ値を、外れ値と判断された閾値(例えば、Q1 - 1.5 * IQRQ3 + 1.5 * IQR)や、他の値(例えば、95パーセンタイル値など)で置き換える方法です。
  • そのままにする: 外れ値が測定誤差などではなく、意味のある特異な事象を表している場合(例:不正利用検知など)、モデルにとって重要な情報である可能性があるため、そのまま残すこともあります。ドメイン知識に基づいた判断が重要です。💡

注意: 外れ値の処理は慎重に行う必要があります。安易な削除や修正は、データの持つ重要な情報を歪めてしまう可能性があります。なぜその値が外れ値となったのか、その背景を理解しようとすることが大切です。

3. まとめ ✨

欠損値処理と外れ値検出は、信頼性の高い機械学習モデルを構築するための重要な前処理ステップです。

  • 欠損値は、削除や適切な値での補完が必要です。
  • 外れ値は、統計的手法や可視化によって検出し、その原因を考慮した上で削除、変換、補完、あるいは保持といった対処を行います。

どちらの処理も、データの特性や分析の目的に応じて最適な手法を選択することが重要です。これらの処理を適切に行うことで、モデルの精度や安定性を向上させることができます。 💪

次のステップでは、正規化・標準化・ラベルエンコーディングといった、さらなるデータ前処理のテクニックを学んでいきましょう!