Shikata Ga Nai

Private? There is no such things.

12. データの前処理② 〜異常値の検出と対処法〜

Hello there, ('ω')ノ

🔍 1. 異常値とは?

異常値(アウトライアー)とは、データの中で他のデータと大きく異なる値 のことです。
例えば、以下のようなケースが異常値に該当します。

📌 異常値の例 - 年齢データ: あるアンケートで「500歳」の回答がある
- 収入データ: 平均年収500万円のデータに「5億円」が含まれている
- センサー測定値: ほとんどが0〜100の範囲なのに、突然「−999」や「9999」が出現

異常値の影響で、平均値がずれたり、モデルが誤った学習をする ことがあるため、適切に処理することが重要です!


📊 2. 異常値を検出する方法

異常値を特定するために、以下の手法を使います。

✅ (1) 統計的手法(IQR, Zスコア)

統計的な指標を使って異常値を検出する方法 です。

📌 ① 四分位範囲(IQR: Interquartile Range)

IQRとは、データの「中央値」を基準にした異常値の検出手法 です。

計算方法: 1. 第1四分位数(Q1):データの下位25%の中央値
2. 第3四分位数(Q3):データの上位25%の中央値
3. IQR = Q3 - Q1(データのばらつき)
4. 異常値の判定ルール:
- 下限値 = Q1 - 1.5 × IQR
- 上限値 = Q3 + 1.5 × IQR
- 範囲外のデータは異常値と判断!

📌 PythonでIQRを使った異常値検出

import numpy as np
import pandas as pd

# サンプルデータ
data = pd.DataFrame({"Value": [10, 12, 14, 16, 100, 18, 20, 22, 24, 26]})

# Q1, Q3, IQRを計算
Q1 = data["Value"].quantile(0.25)
Q3 = data["Value"].quantile(0.75)
IQR = Q3 - Q1

# 異常値の範囲
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 異常値の検出
outliers = data[(data["Value"] < lower_bound) | (data["Value"] > upper_bound)]
print("異常値:")
print(outliers)

IQRを使うと、四分位範囲から外れた異常値を特定できる!


📌 ② Zスコアを使った異常値検出

Zスコアとは、各データが平均からどれだけ離れているかを標準偏差の単位で表した値 です。
Zスコアが±3を超える値を異常値とみなす のが一般的です。

📌 PythonでZスコアを使った異常値検出

from scipy import stats

# Zスコアの計算
data["Z-score"] = np.abs(stats.zscore(data["Value"]))

# 異常値を抽出(Zスコアが3以上)
outliers = data[data["Z-score"] > 3]
print("異常値:")
print(outliers)

Zスコアを使うと、平均から大きく外れた異常値を特定できる!


✅ (2) 可視化による異常値検出

データを グラフで可視化 すると、異常値が一目で分かります。

📌 箱ひげ図(Box Plot)

pip install japanize-matplotlib


import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib  # ← 追加(matplotlibで日本語対応)

sns.boxplot(data["Value"])
plt.title("箱ひげ図で異常値を確認")
plt.show()

箱ひげ図では、上限・下限から大きく外れた点が異常値!

📌 散布図(Scatter Plot)

plt.scatter(range(len(data["Value"])), data["Value"])
plt.title("散布図で異常値を確認")
plt.show()

散布図では、他の点と大きく離れた値が異常値!


✅ (3) 機械学習を使った異常値検出

異常値が複雑なパターンで存在する場合、機械学習モデルを使って異常値を特定 できます。

📌 Isolation Forest(異常検知アルゴリズム)

import pandas as pd
from sklearn.ensemble import IsolationForest

# ダミーデータの作成
data = pd.DataFrame({"Value": [10, 12, 13, 12, 100, 11, 10, 9, 300, 12]})

# モデルの作成
model = IsolationForest(contamination=0.05, random_state=42)

# fit_predict() に NumPy 配列を渡すことで警告を回避
data["Outlier"] = model.fit_predict(data[["Value"]].values)

# 異常値の表示(-1が異常値)
print(data[data["Outlier"] == -1])

機械学習モデルを使うと、より高度な異常値検出が可能!


📌 3. 異常値の対処法

異常値を検出した後は、適切に処理する必要があります。

✅ (1) 異常値を削除

異常値をそのまま削除する方法です。

# IQRを使って異常値を除去
data_cleaned = data[(data["Value"] >= lower_bound) & (data["Value"] <= upper_bound)]

シンプルな方法だが、データが少なくなる点に注意!


✅ (2) 異常値を変換(Winsorization)

異常値を 上限・下限に置き換える 方法です。

# 異常値を上下限値に置き換え
data["Value"] = np.where(data["Value"] > upper_bound, upper_bound, data["Value"])
data["Value"] = np.where(data["Value"] < lower_bound, lower_bound, data["Value"])

データを削除せずに異常値の影響を抑えられる!


✅ (3) 平均値や中央値で補完

異常値を 中央値や平均値で置き換える 方法です。

import numpy as np
import pandas as pd

# ダミーデータの作成
data = pd.DataFrame({"Value": [10, 12, 13, 12, 100, 11, 10, 9, 300, 12]})

# Zスコアの計算
data["Z-score"] = (data["Value"] - data["Value"].mean()) / data["Value"].std()

# 中央値で補完
median_value = data["Value"].median()
data["Value"] = np.where(data["Z-score"] > 3, median_value, data["Value"])

# Z-score列を削除(不要なら)
data.drop(columns=["Z-score"], inplace=True)

# 結果を表示
print(data)

中央値で補完すると、極端な値の影響を受けにくい!


🎯 まとめ

異常値はデータ分析の精度に大きく影響するため、適切に処理が必要!
IQR・Zスコア・可視化・機械学習で異常値を検出できる!
異常値を削除・変換・補完することで、モデルの精度を向上できる!

Best regards, (^^ゞ