EnsekiTT Blog

EnsekiTTが書くブログです。

外れ値はクリップではなく、 まずはリストアップしろって話

こんにちは、えんせきです。
今日祝日だと昨日知りました。得した気分でしたね。
でも浮かれて昼まで寝てしまいました。損した気分でしたね。
プラマイゼロです。

つまりなにしたの?

まえに、外れ値をクリップする話をしたけど、いきなりクリップする前にリストアップすることにした。

まえにやったクリップするやつはこっち
ensekitt.hatenablog.com

f:id:ensekitt:20180322010249j:plain

どんな関数?

  • 入力: Pandas DataFrameのSeries、バイアス(1.5がデフォルト)
  • 出力: 外れ値判定されたものがTrueのSeries
  • 処理: 四分位範囲を計算してそこからバイアス倍分外側の値をTrueにする

コード

def detect_outlier(series, bias=1.5):
    # 四分位数
    q1 = series.quantile(.25)
    q3 = series.quantile(.75)
    iqr = q3 - q1

    # 外れ値の基準値
    outlier_down = q1 - iqr * bias
    outlier_up = q3 + iqr * bias
    
    print("outliear_min :{0}, outlier_max:{1}".format(outlier_down, outlier_up))
    
    outlier_series = (series >= outlier_up) | (series <= outlier_down)
    return outlier_series

動作の確認

import pandas as pd
import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt

iris = datasets.load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)

# 10%ほど外れ値を突っ込む (actual_outlierが真の外れ値リスト)
actual_outlier = np.array(np.random.randint(100, size=len(iris_df['sepal length (cm)'])) < 10)
iris_df['sepal length (cm)'] = iris_df['sepal length (cm)'].where(~actual_outlier, 12.0)
# 外れ値を検出する (
detected_outlier = detect_outlier(iris_df['sepal length (cm)'])

見つけた外れ値がこちら
f:id:ensekitt:20180322005859p:plain

埋め込んだ外れ値がこちら
f:id:ensekitt:20180322005930p:plain

ちゃんと外れ値を検出できてそう。

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。