2012/08/31

文系のための「数の可視化」(6)

さて、今回は「箱ひげ図」について話をする。
他のグラフと比較すると馴染みが無いかもしれない。

箱ヒゲ図は、四分位あるいはヒンジに対応する可視化の方法であり、
ヒストグラムと同様に、バラツキに対応する可視化の方法である。

分散標準偏差との対応という点では、
ヒストグラムよりも、より、バラツキの状況を良く表している。

では、早速、データの準備を準備する。
今回も、ヒストグラムの話で用いたデータと同じデータを用いる。
このデータは、農林水産省の「都道府県別魚種別遊漁採捕量」のデータを、

本ブログでの説明用に加工したものであり、他の用途には適していない

いつものように、

# Windows と Linux の人は次のコマンド
X <- read.table("clipboard", sep=",")

# Mac の人は次のコマンド
X <- read.table(pipe("pbpaste") , sep=",")

データを読み込む。

Aji,Saba,Buri,Hirame,Karei,Kasago,Mebaru,Kawahagi,Tai,Isaki,Ika,Tako
Hokkaido,0,2,18,12,1210,7,452,0,0,0,660,3
Aomori,0,0,52,14,111,2,66,0,77,0,25,7
Iwate,0,3,2,0,14,0,230,0,0,0,12,2
Miyagi,1,75,25,33,2140,0,116,0,0,0,1,1
Akita,21,1,33,4,0,1,76,0,55,0,4,5
Yamagata,110,0,19,6,0,0,14,0,24,0,7,0
Fukushima,0,0,0,0,72,0,60,0,0,0,0,0
Iabaraki,14,57,39,45,36,20,112,1,79,0,109,46
Chiba,381,96,92,100,1,29,65,34,154,135,328,2
Tokyo,38,6,0,0,3,1,0,2,1,0,0,2
Kanagawa,683,185,823,1,1,32,56,29,168,21,256,11
Nigata,194,25,56,5,2,1,96,1,161,0,483,0
Toyama,1,0,21,0,0,0,0,0,3,0,9,0
Ishikawa,88,17,25,6,0,5,36,5,32,0,0,0
Fukui,160,5,307,4,0,6,3,23,170,1,157,0
Shizuoka,56,109,58,11,0,65,28,5,28,205,8,0
Aichi,20,67,98,1,1,20,8,3,150,22,5,1
Mie,19,15,106,0,0,18,13,1,210,77,61,0
Kyoto,32,5,81,1,5,15,6,3,91,4,9,0
Osaka,32,0,2,0,0,5,3,0,14,0,4,0
Hyogo,93,23,81,9,0,125,68,3,20,0,15,49
Wakayama,22,80,99,6,0,6,15,4,116,121,59,0
Tottori,16,0,3,0,0,0,2,0,29,14,41,0
Shimane,24,3,15,7,0,11,6,17,25,16,155,0
Okayama,1,0,0,0,0,34,2,0,40,0,1,11
Hiroshima,64,7,1,0,1,45,48,1,17,0,10,24
Yamaguchi,274,27,366,49,3,52,94,66,308,16,1,0
Tokushima,16,10,44,5,0,21,14,1,29,6,96,0
Kagawa,0,0,0,0,0,0,0,0,2,0,0,0
Ehime,58,0,9,0,0,25,9,5,55,2,0,2
Kochi,0,2,1,0,0,0,0,0,2,7,0,0
Fukuoka,0,0,0,0,0,0,0,0,0,48,82,0
Nagasaki,0,0,384,22,0,131,0,0,306,155,0,0
Kumamoto,55,0,3,0,0,53,0,0,123,2,0,0
Oita,544,97,4,17,0,62,2,217,75,12,32,0
Miyazaki,49,27,3,0,0,0,0,1,35,63,0,0
Kagoshima,109,52,130,1,0,56,0,1,140,23,7,25
Okinawa,20,0,21,0,0,0,0,4,7,3,0,0

では、箱ひげ図を書いてみよう。まずは、何の設定もしない。
boxplot(X)

とにかく、何かが表示されたが、色々と欠けている。
何が足りないか、あるいは、不適切であるか、解っているハズ。
boxplot(X, main="Distribution of fish cathes", ylab="Number of fish cathces (tones)", las=2)

ふむ。最初のグラフには、タイトル、y軸ラベルとy軸の単位が記載されていない。
そのようなグラフを描いてはいけない。

欠けているわけではないが、項目名が全て表示されていないのも問題である。
そこで、las=2 というパラメータを設定し、
項目ラベルの方向をx軸に対して垂直になるように再配置している。

ところで、この状態でも悪くは無いのだが、項目ラベルが横向きであると、
少々、見難い。首を90度に曲げてみることになる。実は、横方向に描くことができる
そのようにするには、horizontal パラメータを TRUE に設定すれば良い。
# 項目ラベルが画面からはみ出るので余白を調整
par(mar=c(5,5,3,1))

# 箱ひげ図を描画する。
boxplot(X, main="Distribution of fish cathes", xlab="Number of fish cathces (tones)", las=1, horizontal=TRUE)

今度は、xとyの軸が入れ替わるので、ylablasのパラメータを調整している。
先程の箱ひげ図と比較すると、かなり見易い。

実を言うと、描画に関してはここまで。後は、色を付けるくらいであろうか?

さて、冒頭にも述べたように、箱ひげ図は、四分位あるいはヒンジに対応する。
どちらを採用するかは、ソフトウェアに依存するが、Rではヒンジを使っている。

今度は、説明のために、鯛の箱ひげ図だけを描画してみる。
boxplot(X$Tai, main="Distribution of fish cathes (The case of Aji)", ylab="Number of fish cathces(tones)")

今回は、変数が一つしか存在しないので、対象ラベルを表示できない。
仕方が無いので、グラフタイトルに鯛の箱ひげ図であることを示す。

では、この図を見ながら、箱ひげ図を見ていくことにする。

中央に箱があって、その真ん中に太い横線が入っている。
箱からは、上下に点線(ヒゲ)が伸びていて、点線の端には横棒が描いている。
あと、上の方には丸い点がある。

では、真ん中の箱から。これは四分位範囲(IQR)に対応し、
箱の下の辺は第1四分位数を表し、箱の上の辺は第3四分位数を表している。
なお、Rの場合には、下側ヒンジ上側ヒンジの範囲である。

真ん中の太い横棒は、中央値を表している。

下向きのヒゲの端にある横線は、外れ値を除いた最小値
上向きのヒゲの端にある横線は、外れ値を覗いた最大値を示している。

そして、上の方についてある丸が、上方向の外れ値となる。
このデータには、存在しないが、下方向の外れ値も取り得る

うん?ここで、疑問に感じた人はセンスが良い。
外れ値は、どのようにして決められているのか?以外に難しい問題である。
実際に、色々な方式があって、ソフトウェアにも依存する。

ここでは、一般的によく用いられている説明を紹介する。

その方法とは、「IQR」を基準にする方法である。
この範囲を基準に、外れ値の範囲を決める。

まずは、軽度の外れ値。通常は「○」記号で表す。
  • 軽度の負の外れ値:
  • 軽度の正の外れ値:
次は、軽度の外れ値。通常は「*」記号で表す。
  • 重度の負の外れ値:
  • 重度の正の外れ値:
以上の外れ値の定義から、ヒゲの長さは、最大でもIQRの1.5倍よりも短い
Rの場合、軽度と重度の外れ値を分けず、IQRからの離れ具合は、
rangeパラメータで決める。このパラメータは既定では「1.5」である。

以上が、箱ヒゲ図を読み解く上で、必要最低限の情報である。

さて、この鯛の箱ヒゲ図から、どのような情報が読み取れるかを検討してみる。
図だけだと、色々と具体的な数値が見えないので、
一度、箱ヒゲ図結果を別の変数に格納し、結果を表示する。

# まずは、変数に結果を格納する。プロットは不要。
b.Tai <- boxplot(X$Tai, plot=FALSE)

# 格納されているデータを確認する。
str(b.Tai)

一連の処理結果は以下の通り。

> # まずは、変数に結果を格納する。プロットは不要。
> b.Tai <- boxplot(X$Tai, plot=FALSE)
>
> # 格納されているデータを確認する。
> str(b.Tai)
List of 6
 $ stats: integer [1:5, 1] 0 7 33.5 123 210
 $ n    : num 38
 $ conf : num [1:2, 1] 3.77 63.23
 $ out  : num [1:2] 308 306
 $ group: num [1:2] 1 1
 $ names: chr "1"

必要なデータは、$stat という所に入っているようなので、

b.Tai$stat

中身は以下の通り。

> b.Tai$stat
      [,1]
[1,]   0.0
[2,]   7.0
[3,]  33.5
[4,] 123.0
[5,] 210.0
attr(,"class")
        1
"integer"

ふむふむ。なるほど。最後の結果は、外れ値を除いた状態になっている。
では、箱ヒゲ図に描かれている情報を整理する。

まず、この箱ヒゲ図では、IQRが全体的に下方向に偏っていて、
また、中央値IQRの下側に寄っていることから、

全体的に低い値を取る対象が多く、大きい値を取るものは少ないことが解る。

外れ値を除くと、データは0〜200t の間に収まり、
全データの約50%は、7〜123t の幅に収まっている。

この状況をヒストグラムと比較してみる。
両者を並べて表示させると、状況がより明確に見えてくる。

# ヒストグラムと箱ヒゲ図のレイアウト枠を設定(5:1)
lay <- matrix(c(1,1,1,1,1,2), ncol=1)
layout(lay)

# ヒストグラムをグラフ領域の上に描く。
par(mar=c(4,5,3,1), cex=1.1)
hist(X$Tai, breaks=nclass.FD, freq=FALSE, col="pink", main="", xlab="")
title(main="Density of fish catches for Tai")

# 箱ヒゲ図をヒストグラムの下に描く
par(mar=c(0,5,0,1), bty="n")
boxplot(X$Tai, main="", xlab="", ylim=c(0,350), horizontal=TRUE, xaxt="n", col="pink")
mtext(side=3, "Number of fish catches")


layout()関数は、描画領域の番号を成分とした行列を指定することで、
グラフ領域に複数のグラフを表示することができる関数である。

今回の場合は、最初に「6行✕1列」の行列を作成し、
その成分には、上から5行までは1を、最終行には2を入れてある。

したがって、グラフ領域は、縦方向に6等分され、

上の5つ分のスペースには1つ目のプロット(ヒストグラム)が、
下の1つ分のスペースには2つ目のプロッタ(箱ヒゲ図)が、それぞれ描かれる。

こうして、上の図のように、二つの図を並べて書くことができる。
以前に、par()関数mfrowパラメータを用いたが、
layout()関数のように、描画領域を比率を変えて設定することはできない。

さて、このように二つのグラフを並べて表示することで、
データのバラツキの状況が良く解る。

実は、箱ヒゲ図ヒストグラム両方の特性を持ったグラフも存在するが、
その話は、次の話に置いておくことにする。

0 件のコメント:

コメントを投稿