データ処理・解析のシリーズで、今日はPythonで外れ値の検出と除去を見ていきましょう。
では、さっそく始めましょう
Pythonで外れ値とは何ですか?
外れ値という概念を深く理解する前に、生データの起源を理解しましょう。
システムに供給される生データは、通常、調査やウェブ上のリアルタイムの行動からデータを抽出することで生成されます。
このため、データにはばらつきがあり、データを記録する際に測定誤差が生じる可能性がある。
そこで登場するのが外れ値です。
外れ値とは、データセットの残りのデータ値から離れている点またはデータ点の集合のことです。
つまり、データセット内のデータ値の全体的な分布から外れているデータ点(複数可)です。
外れ値は、連続的な値でのみ発生します。
従って、外れ値の検出と除去は回帰値にのみ適用される。
基本的に外れ値は、データ要素の全体的な適切で構造化された分布から乖離しているように見える。
これは、クラスまたは母集団から外れて現れる異常な分布と考えることができる。
外れ値の概念を理解した上で、次のセクションでは外れ値を除去する必要性に焦点を当てましょう。
なぜデータから外れ値を取り除く必要があるのでしょうか?
上述したように、外れ値とはデータの通常の分布から外れたところにあるデータ点のことで、データ全体の分布に以下のような影響を与える。
- データの全体的な標準偏差に影響を与える。
 - データの全体的な標準偏差を操作します。
 - データを歪んだ形に変換します。
 - 機械学習モデルの精度推定にバイアスを生じさせる。
 - データセットの分布や統計量に影響を与える。
 
以上の理由により、データセットをモデル化する前に外れ値を検出し、取り除くことが必要です。
外れ値の検出 – IQRアプローチ
データセットに含まれる外れ値は、以下の方法で検出することができる。
- Z スコア
 - 散布図
 - 四分位範囲(IQR)
 
今回は、外れ値を検出し、処理するためにIQR法を実装します。
IQRはInterquartile Rangeの頭文字をとったものです。
データ値の統計的な分散を全体的な分布の指標として測定するものです。
IQRは、それぞれ第1四分位値(Q1)と第3四分位値(Q3)の差に相当します。
ここで、Q1 は第 1 四分位値すなわち 25%、Q3 は第 3 四分位値すなわち 75%を意味します。
我々は、データセットに存在する外れ値を検出し、可視化するために、箱ひげ図を使用します。
箱ひげ図は、データの分布を四分位数で表したもので、次の要素で構成されている。
- Q1-25%
 - Q2-50%
 - Q3-75%
 - 下限/ヒゲ
 - 上ヒゲ/境界
 
import pandas
import numpy
BIKE = pandas.read_csv("Bike.csv")
 | 
下限値より下、上限値より上にあるデータ点は、外れ値とみなされる。
以下の例で、外れ値を検出するためにBoxplotを実装してみましょう。
例えば、以下の様になります。
まず、データセットを環境に取り込む。
データセットはここにある。
numeric_col = ['temp','hum','windspeed']
categorical_col = ['season', 'yr', 'mnth', 'holiday', 'weekday', 'workingday', 'weathersit']
 | 
さらに、変数を数値とカテゴリに分離しました。
BIKE.boxplot(numeric_col) | 
以下のように、数値変数に対して boxplot() 関数 を用いて Boxplot を適用します。
for x in ['windspeed']:
    q75,q25 = np.percentile(BIKE.loc[:,x],[75,25])
    intr_qr = q75-q25
    max = q75+(1.5*intr_qr)
    min = q25-(1.5*intr_qr)
    BIKE.loc[BIKE[x] < min,x] = np.nan
    BIKE.loc[BIKE[x] > max,x] = np.nan
 | 
BIKE.isnull().sum()
 | 
上で見たように、変数 ‘windspeed’ は、下限より上にある異常値を含んでいます。
外れ値の除去
前節のBoxplotで検出された外れ値を処理します。
IQR を使って、以下のような方法で外れ値を NULL 値に置き換えることができます。
- 第1四分位と第3四分位を算出します。
 - さらに、四分位範囲 IQR = Q3-Q1 を評価します。
下限値を推定、下限値 = Q1***1.5 - 上界を推定、上界=Q3*1.5
 - 下界と上界から外れるデータ点をNULL値で置き換える。
 
season        0
yr            0
mnth          0
holiday       0
weathersit    0
temp          0
hum           0
windspeed     5
cnt           0
dtype: int64 | 
このように、numpy.percentile() methodを用いて、Q1とQ3の値を算出しています。
さらに、外れ値をNULL値としてnumpy.nanに置き換えています。
外れ値をnanに置き換えた後、以下のコードでNULL値や欠損値の合計を確認してみましょう。
BIKE = BIKE.dropna(axis = 0)
 | 
データセットの各列のNULL値/外れ値の数の合計。
BIKE.isnull().sum()
 | 
ここで、NULL値を処理するために、以下の技術のいずれかを使用することができます。
- 平均値、中央値、Knn インプット値で欠損値をインプットします。
 - NULL値を削除する(割合が比較的少ない場合)。
 
ここでは、 pandas.dataframe.dropna() 関数を使用して、NULL 値を削除します。
season        0
yr            0
mnth          0
holiday       0
weathersit    0
temp          0
hum           0
windspeed     0
cnt           0
dtype: int64 | 
外れ値を処理した後、データセットに欠損値やNULL値があるかどうかを確認します。

結果は以下の通りです。
出力-

このように、データセットに存在するすべての外れ値が検出され、処理(除去)された。
まとめ
ここまでで、このトピックは終了です。
何か疑問があれば、お気軽にコメントください。
Pythonに関連するこのような投稿をもっと見るには。