データ分析のプロセスにおいて、収集したデータの中に含まれる極端な値、すなわち「外れ値」の扱いは解析結果の妥当性を左右する極めて重要な工程です。
不適切な外れ値が混入したまま統計処理や機械学習モデルの構築を行うと、平均値の偏りや予測精度の著しい低下を招くリスクがあります。
本記事では、Pythonのデータ解析ライブラリであるPandasを活用し、統計学的な根拠に基づいた外れ値の除外手法を具体的に解説します。
外れ値がデータ分析に与える影響
外れ値とは、他のデータポイントから大きく逸脱した値のことであり、測定エラーや入力ミス、あるいは稀に発生する異常現象など、その原因は多岐にわたります。
例えば、平均値は外れ値の影響を非常に受けやすく、たった一つの極端な値によってデータセット全体の実態を正しく反映できなくなることがあります。
一方で、中央値などは外れ値に対して頑健(ロバスト)な性質を持ちますが、解析の目的によってはデータの分布そのものを正常化する必要があります。
機械学習のアルゴリズム、特に線形回帰やニューラルネットワークでは、外れ値が存在することで学習の収束が遅れたり、汎化性能が損なわれたりすることが一般的です。
そのため、分析を開始する前のデータクリーニング段階で外れ値を適切に検出し、除外または補正することが求められます。
事前準備:サンプルデータの作成
まずは、外れ値を含むデータセットをPandasで作成し、処理の効果を確認できる準備を整えましょう。
import pandas as pd
import numpy as np
# 乱数シードの固定
np.random.seed(42)
# 正規分布に従うデータを作成
data = np.random.normal(loc=50, scale=10, size=100)
# 意図的に外れ値を挿入
data = np.append(data, [150, -20, 160])
# DataFrameに変換
df = pd.DataFrame(data, columns=['value'])
print(df.describe())
value
count 103.000000
mean 52.333061
std 20.730303
min -20.000000
25% 43.513476
50% 50.132517
75% 57.068305
max 160.000000
上記の実行結果を見ると、平均値(mean)が52であるのに対し、最大値(max)が160、最小値(min)が-20となっており、標準偏差(std)も大きくなっていることが分かります。
手法1:IQR(四分位範囲)を用いた外れ値の除外
IQR法は、データの分布に特定の確率分布(正規分布など)を仮定せずに適用できる、非常に汎用性の高い手法です。
データの第1四分位点(25%点、Q1)と第3四分位点(75%点、Q3)の差をIQR(Interquartile Range)と呼びます。
一般的には、「Q1 – 1.5 × IQR」未満の値、または「Q3 + 1.5 × IQR」を超える値を外れ値として定義します。
PandasによるIQRの実装
Pandasのquantile()メソッドを使用することで、四分位点を簡単に算出できます。
# 第1四分位数と第3四分位数の算出
q1 = df['value'].quantile(0.25)
q3 = df['value'].quantile(0.75)
# IQRの計算
iqr = q3 - q1
# 境界値の設定
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
print(f"下限値: {lower_bound}")
print(f"上限値: {upper_bound}")
# 外れ値を除外したデータの抽出
df_cleaned_iqr = df[(df['value'] >= lower_bound) & (df['value'] <= upper_bound)]
print(f"除外前のデータ数: {len(df)}")
print(f"除外後のデータ数: {len(df_cleaned_iqr)}")
下限値: 23.18123180479703
上限値: 77.40054881079313
除外前のデータ数: 103
除外後のデータ数: 97
IQR法を用いることで、分布の端にある極端なデータが自動的にフィルタリングされました。
この手法の利点は、外れ値が計算自体(四分位点)に与える影響が少ないため、安定した判定が可能である点にあります。
手法2:Zスコア(標準化)を用いた外れ値の除外
Zスコア法は、データが正規分布に従っていると仮定できる場合に非常に有効な統計的手法です。
各データが平均値から標準偏差の何倍離れているかを計算し、その絶対値が一定の閾値を超えた場合に外れ値とみなします。
一般的には、閾値を3(3σ法)に設定することが多く、これは統計学的に全体の約99.7%のデータがこの範囲内に収まることを根拠としています。
PandasによるZスコアの実装
平均と標準偏差を算出し、ベクトル演算を利用して各行のZスコアを求めます。
# 平均と標準偏差の算出
mean_val = df['value'].mean()
std_val = df['value'].std()
# Zスコアの算出
df['z_score'] = (df['value'] - mean_val) / std_val
# 閾値を3に設定してフィルタリング
threshold = 3
df_cleaned_z = df[df['z_score'].abs() <= threshold]
print(f"除外前のデータ数: {len(df)}")
print(f"除外後のデータ数: {len(df_cleaned_z)}")
除外前のデータ数: 103
除外後のデータ数: 100
Zスコア法は計算が非常に高速であり、大規模なデータセットに対しても効率的に適用できるメリットがあります。
ただし、平均値や標準偏差自体が外れ値によって大きく変動している場合、本来除外すべき値を見逃してしまう可能性がある点に注意が必要です。
手法3:データのクリッピング(Winsorizing)
分析の目的によっては、データを完全に削除(除外)するのではなく、特定の境界値に置き換える「クリッピング」という手法が選ばれることもあります。
これは、極端な値を上限値または下限値に「丸める」処理であり、データの件数を維持したい場合に有効です。
Pandasにはclip()という専用のメソッドが用意されており、これを利用することで簡潔に記述できます。
# 下限値と上限値を指定してクリッピング
# ここではIQR法で求めた境界値を利用
df_clipped = df['value'].clip(lower=lower_bound, upper=upper_bound)
print(df_clipped.describe())
count 103.000000
mean 50.219816
std 9.610665
min 23.181232
25% 43.513476
50% 50.132517
75% 57.068305
max 77.400549
クリッピングを行うことで、データのサンプルサイズを減らすことなく、外れ値の悪影響だけを抑制することが可能になります。
最新のPandasにおける最適化手法
2026年現在のPandasでは、Copy-on-Write(CoW)の最適化が進んでおり、データクリーニングのパフォーマンスが大幅に向上しています。
大量のデータを扱う場合、フィルタリング結果を新しい変数に代入する際のメモリ効率が最適化されているため、メソッドチェーンを活用した記述が推奨されます。
# メソッドチェーンを活用した効率的なクリーニング例
def remove_outliers_iqr(df, column):
q1 = df[column].quantile(0.25)
q3 = df[column].quantile(0.75)
iqr = q3 - q1
return df.loc[df[column].between(q1 - 1.5 * iqr, q3 + 1.5 * iqr)]
# 実行
df_final = df.pipe(remove_outliers_iqr, 'value')
between()メソッドやpipe()メソッドを活用することで、コードの可読性が高まり、再利用性も向上します。
手法の比較と選択基準
どの手法を選択すべきかは、データの特性と分析の目的によって異なります。
| 手法 | 適したケース | メリット | デメリット |
|---|---|---|---|
| IQR法 | 分布が非対称なデータ | 外れ値の影響を受けにくい | 境界値が機械的になりやすい |
| Zスコア法 | 正規分布に近いデータ | 統計的根拠が明確 | 平均・標準偏差が外れ値に釣られる |
| クリッピング | サンプル数を維持したい場合 | 情報損失が少ない | データの分布が歪む可能性がある |
基本的には、まずはIQR法で分布を確認し、データの特性に応じて他の手法を検討するという流れが定石です。
まとめ
Pandasを用いた外れ値の除外は、データクリーニングにおける必須のスキルです。
IQR法はロバストな判定が可能であり、Zスコア法は正規分布に基づいた理論的な判定を可能にします。
また、単純な削除だけでなく、クリッピングによる値の補正も選択肢に含めることで、より柔軟なデータ処理が実現できます。
本記事で紹介したコードを参考に、分析対象となるデータの特性を見極め、最適な外れ値処理を実装してください。
精度の高いデータクリーニングこそが、信頼性の高い分析結果を得るための第一歩となります。
