【第6回】箱ひげ図
今回は箱ひげ図と、四分位範囲に基づいた外れ値についての記事を書いてみたいと思います。
準備
Pythonの実行環境はGoogle Colaboratoryを使うことにします。
でーたかじり虫さんの記事がとても分かりやすく、参考にさせていただきました。ありがとうございます!
Google Colaboratoryのファイルを新規作成しましたら、まずは必要なライブラリの読込からです。
今回はNumpy、Pandas、Matplotlibを利用します。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
今回は、第2回・第3回の記事でも使いました平成27年国勢調査より、日本の都道府県別面積のデータを使いたいと思います。
上記サイトより、次のExcelファイルをダウンロードしました。
表番号6:面積及び人口密度-全国,都道府県(大正9年~平成27年)
都道府県の列と平成27年の面積のデータの列のみを残して、他の列を削除し、ファイル名「都道府県別面積.xlsx」で保存しました。
これをGoogleドライブのマイドライブ内にある「Colab Notebooks」にアップロードし、Google Colaboratoryで読み込みを行います。
まずは、Googleドライブのマウントを行い、このファイルのパスをコピーしておきます。
Pandasのread_excel( )メソッドを利用してファイルを読み込んだデータフレームを、変数 df に格納します。
df = pd.read_excel("パス名")
ここで、読み込むファイルのパス名は上でコピーしたものを貼り付けます。
df = pd.read_excel("/content/drive/MyDrive/Colab Notebooks/都道府県別面積.xlsx")
df
上記を実行すると次が出力されます。
このデータフレームの面積の列をNumpyの配列として、変数area に格納します。df["面積"]で「面積」の列を抽出したSeries型データをNumpy配列に変換しています。
area = np.array(df["面積"])
area
箱ひげ図
このあたりで、箱ひげ図について簡単に確認してみたいと思います。
箱ひげ図は名前の通り、「箱」と「ひげ」をつかって、データの5数要約(最小値、第1四分位数、中央値、第3四分位数、最大値)を可視化した図です。下の図のように表します。
第1四分位数から第3四分位数までのデータが「箱」の中に入っており、これが中央値付近50%のデータです。この箱の大きさがデータが中央値付近にどれだけ集まっているかをみる一つの指標になります。
箱の大きさを表しているのが、「第3四分位数と第1四分位数の差」であり、これを四分位範囲(IQR:interquartile range)といいます。
余談ですが、箱ひげ図を上のような色で書くと、何か肉みたいですね。
四分位数に基づいた外れ値
失礼いたしました。それでは、データ内の極端な値である「外れ値」の四分位数に基づいた定義を述べてみたいと思います。
よく使われるのは、第1四分位数、第3四分位数から四分位範囲の1.5倍より離れている値を外れ値と定義するといったものです。
すなわち、四分位範囲をIQRとしたときに、
下限値 = 第1四分位数 - 1.5 × IQR
上限値 = 第3四分位数 + 1.5 × IQR
と定め、下限値より小さい値または上限値より大きい値を外れ値と定義します。
都道府県別面積データにおける外れ値
それでは、都道府県別面積のデータでの外れ値を見てみたいと思います。
まずは四分位数と四分位範囲、そこから算出した下限値と上限値をPythonを使って求めてみましょう。なおここでの四分位数の定義は表計算ソフトのQUARTILE.INC関数で採用しているになります。
Q1 = np.quantile(area,0.25)
Q2 = np.quantile(area,0.5)
Q3 = np.quantile(area,0.75)
IQR = Q3 - Q1
lowerLim = Q1 - 1.5 * IQR
upperLim = Q3 + 1.5 * IQR
print(f"第1四分位数: {Q1}, 第2四分位数: {Q2}, 第3四分位数: {Q3}")
print("四分位範囲:", IQR)
print(f"下限値: {lowerLim}, 上限値: {upperLim}")
これを実行すると、下記が出力されます。
第1四分位数: 4166.37, 第2四分位数: 6097.06, 第3四分位数: 8089.19
四分位範囲: 3922.8199999999997
下限値: -1717.8599999999997, 上限値: 13973.419999999998
下限値は無視して問題ありませんね。問題は上限値です。
すぐ見て分かるのは、北海道(83,424㎢)はこれを余裕で超えています。
上限値を上回っている都道府県をdfから抽出してみましょう。
Pandasのquery( )メソッドを利用します。
df.query("面積 > @upperLim")
実行すると、次のような出力になります。
北海道と岩手県の面積が「外れ値」であると判定されました。
Matplotlibで箱ひげ図を描画
Matplotlib.pyplotでは、boxplotを利用して箱ひげ図を簡単に描画できます。その際の初期設定では、上記の定義に従った外れ値を白丸で表し、外れ値を除いたデータで最小値・最大値を求めて箱ひげ図を描画します。
実際に下記コードを実行させてみてみましょう。
plt.figure(figsize = (8,3))
plt.boxplot(area, vert = False, widths = 0.4)
plt.grid()
plt.show()
出力結果を見る前に簡単にコードの補足をします。
figure( )メソッドは、グラフの横と縦の長さを、figsize =(8,3)のように指定するメソッドです。
boxplot(配列, [オプション] )が箱ひげ図の描画するメソッドです。今回は配列 area のデータで箱ひげ図を描画します。vert = Falseは横向きの箱ひげ図にするというオプションで、デフォルトはTrue(縦向き)です。widths = 0.4は箱ひげ図の大きさ(箱の縦幅)で0~1の数値(描画エリアに対する割合)で指定します。
grid( )メソッドでグリッド線を入れ、show( )メソッドでグラフを描画します。
それでは、実行結果を見てみましょう。
80,000を大きく超えている白丸が北海道、15,000付近の白丸が岩手県を指しています。
描画エリアの左の「1」というのは箱ひげ図のラベルで、boxplot( )メソッドのオプションで任意のラベルをつけることができます。(なお、日本語だと文字化けをしてしまうので、英数字で指定します。)
plt.boxplot(area, labels = ["area"], vert = False, widths = 0.4)
のように記述します。
外れ値を除外しないで箱ひげ図を描きたいときは、boxplot( )メソッドのオプションにwhis = "range"を入れます。
plt.figure(figsize = (8,3))
plt.boxplot(area, labels = ["area"], whis = "range", vert = False, widths = 0.4)
plt.grid()
plt.show()
右のひげがとても長くなりました。
外れ値をどのように処理するかによって、上記の両者を使い分けることになると思います。
いずれにしましても、四分位数は平均値と比較して外れ値の影響を受けにくいため、データの値のおおよその散らばり方を見る上では有効な方法といえます。箱ひげ図をしっかりと読み取れるようにしておきたいものです。
おまけ
前回記事の「四分位数の複数の定義」について補足します。
このデータを使って、検定教科書における定義と表計算ソフトの採用している定義に基づいた四分位数を比較してみます。
検定教科書における四分位数の定義
第1四分位数: 4146.65(徳島県)
第2四分位数: 6097.06(茨城県)
第3四分位数: 8400.96(兵庫県)
表計算ソフトのQUARTILE.INC関数の四分位数の定義
第1四分位数: 4166.37(徳島県と石川県の平均)
第2四分位数: 6097.06(茨城県)
第3四分位数: 8089.19(静岡県と兵庫県の平均)
データの散らばり方をみる指標として、これらの違いはさほど気にならないところだと思われます。
最後までお読みいただきありがとうございました。
本年もよろしくお願いいたします。