【pandas】外れ値を確認・除去する方法【df.quantile()】

データ分析や機械学習では、精度を上げるために外れ値などを除去し、適切なデータセットにすることが重要です

今回は、外れ値を確認し除去する方法をご紹介いたします。

この記事で分かること
  • 記述統計量やグラフから外れ値の確認方法
  • 任意の位数・値から外れ値を除去する方法

この記事のサンプルコード

目次

ライブラリのインポート

まずは必要なライブラリをインポートします。

import warnings
warnings.simplefilter('ignore')
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

データの準備

データはsklearnload_dataset()からボストンの住宅価格データセットを用います。

from sklearn.datasets import load_boston
boston = load_boston()
boston_df = pd.DataFrame(data=boston.data,columns=boston.feature_names)
boston_df['target'] = boston.target
boston_df.head()
CRIMZNINDUSCHASNOX・・・AGEDISRADTAXtarget
00.0063218.02.310.00.538・・・65.24.09001.0296.024.0
10.027310.07.070.00.469・・・78.94.96712.0242.021.6
20.027290.07.070.00.469・・・61.14.96712.0242.034.7
30.032370.02.180.00.458・・・45.86.06223.0222.033.4
40.069050.02.180.00.458・・・54.26.06223.0222.036.2

外れ値の把握

外れ値を考える際には「記述統計量」や「グラフ」からデータがどのような分布になっているかを確認します

今回は町ごとの「一人当たりの犯罪率」を表している"CRIM"を見ていきます。

記述統計量の確認

記述統計量を確認する場合にはdf.describe()関数を用います。
カテゴリ変数を含める場合には、引数にinclude="all"とします。

boston_df[['CRIM','target']].describe()
CRIMtarget
count506.000000506.000000
mean3.61352422.532806
std8.6015459.197104
min0.0063205.000000
25%0.08204517.025000
50%0.25651021.200000
75%3.67708325.000000
max88.97620050.000000

CRIMの最大値を確認すると、犯罪率が88%と異常な値になっています。
ほとんどの値は3.7%以下であることが分かりました。

機械学習・データ分析において、あまり現実的ではない数値はノイズとなります。

次は散布図で可視化してみましょう

グラフでの可視化

データの分布がどのようになっているかグラフで確認してみます。

ヒストグラム

sns.distplot(boston_df.CRIM)

箱ひげ図

sns.boxplot(data=boston_df.CRIM)

散布図

sns.scatterplot(x="CRIM", y="target", data=boston_df)

各種グラフで見られたように以下のことが分かりました。

  1. 全体的な割合では犯罪発生率は20%以下になっている
  2. ほぼ10%以下である
  3. 犯罪発生率が低い程、target(価格)は高くなる負の相関が見られる

これを元に外れ値を除去していきます。

外れ値の除去

外れ値を除去する方法として、主に2種類の方法があります。

  • 分位数を指定する
  • 任意の値を指定する

今回は分位数を指定する方法を見ていきます。

分位数を指定する—df.quantile()

データフレームの任意の分位数での値を出すにはdf.quantile()関数を用います。

pandas.DataFrame.quantile — pandas 1.2.1 documentation

引数として0~1の値を与えて、任意の分位数での値を取得できます。
例えば、中央値の第2四分位数の50%での値を求める場合には0.5とします。

>>> q_50 = boston_df.CRIM.quantile(0.5)
>>> q_50

0.25651

0.25651が中央値となります。念のため、もう一度記述統計量を確認してみましょう。

boston_df[['CRIM','target']].describe()
CRIMtarget
count506.000000506.000000
mean3.61352422.532806
std8.6015459.197104
min0.0063205.000000
25%0.08204517.025000
50%0.25651021.200000
75%3.67708325.000000
max88.97620050.000000

きちんと取得できていますね。
今回は分位数95%の値を取得して、外れ値を除去していきます。

>>> q = boston_df.CRIM.quantile(0.95)
>>> q

15.78915

95%の分位数の値が約15.7となりました。
この値を元に、df.query()関数を使って絞り込みます。

new_boston_df = boston_df.query('CRIM < @q')

犯罪発生率が95%の位数よりも値が小さいデータが抽出できました。

データの確認

外れ値が除去できているか、再度記述統計量を確認してみます。

new_boston_df[['CRIM', 'target']].describe()
CRIMtarget
count480.000000480.000000
mean2.09215723.203542
std3.6488018.932629
min0.0063206.300000
25%0.07883217.800000
50%0.22200021.700000
75%2.25687026.250000
max15.57570050.000000

データ数が506件から480件へ減少し、犯罪発生率の最大値が15.57になりました
うまく抽出できていますね。

散布図でも見ていきましょう。

sns.scatterplot(x="CRIM", y="target", data=new_boston_df)

外れ値が除去されていますね!

この記事のサンプルコード

機械学習・データ処理を学ぶのにおすすめの教材

動画で学習するなら!

本気で取り組むならまずは相談!

じっくり書籍で学習するなら!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

目次
閉じる