LoginSignup
1
1

More than 5 years have passed since last update.

箱ひげ図で外れ値になる確率を計算する

Posted at

この記事の概要

  • 正規分布を仮定したときに、箱ひげ図における「外れ値」がどれぐらいの確率で出現するのかを調査
  • 「外れ値」の定義:第1四分位点-四分位範囲*1.5 より小さい、または、第1四分位点-四分位範囲*1.5 より大きい標本(極値も含んでます)
  • 「外れ値」が出現する確率は、およそ 0.70 %

この記事を書こうと思った動機

  • 業務で統計解析を行う際に、箱ひげ図を描いてみると、「外れ値」がよく出てくる
  • ある分布を仮定したときに、「外れ値」がどれぐらいの確率で出現するのかを知りたくなった

はじめに:箱ひげ図と外れ値

箱ひげ図および箱ひげ図における外れ値に関する説明は以下のサイトなどを参照してください。
- 箱ひげ図 - Wikipedia
- 箱ひげ図の読み方

正規分布における外れ値の出現確率を算出する

標準正規分布の確率密度関数を使って、外れ値となる確率を計算してみます。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

q1_ideal = stats.norm.ppf(q=0.25, loc=mu, scale=sd) # 第1四分位点
q3_ideal = stats.norm.ppf(q=0.75, loc=mu, scale=sd) # 第3四分位点
iqr_ideal = q3_ideal-q1_ideal # 四分位範囲
lb_ideal = q1_ideal-1.5*iqr_ideal # 下側外れ値境界
ub_ideal = q3_ideal+1.5*iqr_ideal # 上側外れ値境界

print('Q1:', q1_ideal)
print('Q3:', q3_ideal)
print('IQR:', iqr_ideal)
print('Lower Bound:', lb_ideal)
print('Upper Bound:', ub_ideal)
print('下側外れ値となる確率:',stats.norm.cdf(x=lb_ideal, loc=mu, scale=sd) *100,'%')
print('上側外れ値となる確率:',stats.norm.sf(x=ub_ideal, loc=mu, scale=sd) *100,'%')
print('外れ値となる確率:',(stats.norm.sf(x=ub_ideal, loc=mu, scale=sd)+stats.norm.cdf(x=lb_ideal, loc=mu, scale=sd)) *100,'%')

>Q1: -0.674489750196
>Q3: 0.674489750196
>IQR: 1.34897950039
>Lower Bound: -2.69795900078
>Upper Bound: 2.69795900078
>下側外れ値となる確率: 0.348830161964 %
>上側外れ値となる確率: 0.348830161964 %
>外れ値となる確率: 0.697660323928 %

というわけで、正規分布であれば外れ値が得られる確率は、0.7%という結果です。1000個の標本があれば、7個ぐらいは外れ値となります。3σの外側に来るのが0.3%なので、それよりは多いですね。

実際にそうなっているか検証

正規分布からランダムサンプリングしたデータを使って、本当にそうなるのか確かめてみます。

# データ生成
n = 1000000 # サンプル数
mu = 0 # 平均
sd = 1 # 標準偏差
q1 = stats.scoreatpercentile(data, 25)
q3 = stats.scoreatpercentile(data, 75)
iqr = q3-q1
lb = q1-1.5*iqr
ub = q3+1.5*iqr
print('Q1:', q1)
print('Q2:', med)
print('Q3:', q3)
print('IQR:', iqr)
print('Lower Bound:', lb)
print('Upper Bound:', ub)
print('上側外れ値となった標本数の全標本数に占める割合:', len(np.where(data<lb)[0]) / n * 100,'%')
print('下側外れ値となった標本数の全標本数に占める割合:', len(np.where(data>ub)[0]) / n * 100,'%')
print('外れ値となった標本数の全標本数に占める割合:', (len(np.where(data>ub)[0])+len(np.where(data<lb))) / n * 100,'%')

>Q1: -0.674873830027
>Q2: -0.00106013590319
>Q3: 0.673290672641
>IQR: 1.34816450267
>Lower Bound: -2.69712058403
>Upper Bound: 2.69553742664
>上側外れ値となった標本数の全標本数に占める割合: 0.3554 %
>下側外れ値となった標本数の全標本数に占める割合: 0.3478 %
>外れ値となった標本数の全標本数に占める割合: 0.7032 %

ランダムサンプリングで計算した外れ値となる標本の割合は0.7%となり、確率密度関数から計算した値とほぼ一致しました。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1