2012/08/30

文系のための「データのバラツキ」(2)

ようやく、データ分析の入り口に辿り着いた。
ここまでの話は、基礎的な話が多かった。

今日の話は、データの「要約」について。

元のデータを分析する前に、データの全容を把握することは重要である。
本来、データの可視化は、全体的な状況を把握してから行うべきであって、
可視化してから考えるのではない。

まず、基本的な情報として考えられるものは何だろうか?
これまでに、やってきた情報を整理すると、
  • 行数=対象の数
  • 列数=属性(変数)の総数
  • 各変数の平均と中央値
  • 各変数の分散と標準偏差
  • 各変数間の共分散と相関係数
と言ったところか。

これだけの情報が得られるだけで、様々なことが解るのだが、
今回は、これらの指標に加えて、「分位数(quantile)」について考えてみる。

分位数は、データのバラツキを、分散とは違った方法で観察する方法とも言える。

とにかく、説明するよりも、手を動かした方が理解しやすい。
とりあえず、いつものように...

# 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

このデータは、ヒストグラムの話で用いたデータと同じ。
農林水産省の「都道府県別魚種別遊漁採捕量」のデータを編集して作ったデータ。
架空とまでは言わないが、現実の分析には適さない。

では、早速。分位数を出してみる。まずは、鯵の分位数を計算。

quantile(X$Aji, probs=seq(0,1,by=0.25))

ここでは、quantile()関数を用いて分位数を計算している。
quantile は、日本語では「分位数」を意味する。

この何分割するかを決めているのが、probs パラメータである。
四分位の場合には、probs=seq(0,1,by=0.25) となっているということは、
0〜1までを、0.25刻みで「四等分」している。

このように、4つに分ける分位数のことを「四分位(quartiles)」と呼ぶ。

つまり、0.00, 0.25, 0.50, 0.75, 1.00 というベクトルによって指定しているわけである。
ここで、注意するべきは、0番目の値が存在すること。したがって、
四分位の場合は、5つの値が返ってくる

中央値の話でも述べたが、様々な分位数が存在し、それぞれに名前が付いている。
  • 二分位(median)=中央値
  • 三分位(tertiles) 
  • 四分位(quartiles)
  • 五分位(quintiles)
  • 六分位(sextiles)
  • 十分位(deciles) 
  • 十二分位(duo-deciles)
  • 二十分位(vigintiles)
  • 百分位(percentiles)
  • 千分位(permiles)
Rの quantile()関数で、これらを計算することは難しくない。

quantile(X$Aji, probs=seq(0,1,by=0.5))    # 中央値
quantile(X$Aji, probs=seq(0,1,by=0.2))    # 五分位
quantile(X$Aji, probs=seq(0,1,by=0.1))    # 十分位

実行結果は以下の通り。

> quantile(X$Aji, probs=seq(0,1,by=0.5))    # 中央値
  0%  50% 100%
   0   23  683
> quantile(X$Aji, probs=seq(0,1,by=0.2))    # 五分位
   0%   20%   40%   60%   80%  100%
  0.0   0.4  19.8  40.2 102.6 683.0
> quantile(X$Aji, probs=seq(0,1,by=0.1))    # 十分位
   0%   10%   20%   30%   40%   50%   60%   70%   80%   90%  100%
  0.0   0.0   0.4  14.2  19.8  23.0  40.2  57.8 102.6 218.0 683.0

色々とあるが、四分位が最も一般的であるので、
quantile()関数既定は四分位。したがって、パラメータ指定も不要

quantile(X$Aji)

パラメータ指定無しで、このようにすると、以下のように四分位が計算される。

> quantile(X$Aji)
  0%  25%  50%  75% 100%
   0    1   23   82  683

ここで、四分位の考え方を整理してみる。
  • 全体の下から0/4(0%)番目の数:第0四分位数(最小値)
  • 全体の下から1/4(25%)番目の数:第1四分位数
  • 全体の下から2/4(50%)番目の数:第2四分位数(中央値)
  • 全体の下から3/4(75%)番目の数:第3四分位数
  • 全体の下から4/4(100%)番目の数:第4四分位数(最大値)
となる。ここで、第1四分位数〜第3四分位数の範囲のことを四分位範囲と呼ぶ。

これは、データの下から25%番目目と75%番目の間の範囲である。
別の言い方をするならば、中央値を中心に全データの50%が収まる範囲である。

英語では、Inter-Quantile Range と呼び、IQRと表記する。
Rには、IQR()関数が存在し、四分位範囲も容易に計算できる。

IQR(X$Aji)

実行結果は、以下の通り。

> IQR(X$Aji)
[1] 81

今回のデータの場合は、1〜82までの範囲なので、
四分位範囲は、「82-1=81」となり、正常に計算されている。

やはり、数理的な話も必要であろう。ここからは、数学的な話。

実は、色々と前提となる知識を必要とするので、
色々と正しくない表記も含まれる。表記方法は変則的。厳密な説明ではない。
Wikipedia の解説では、分位数を関数として定義し、実数空間への投影で説明。

意味の解る人は、Wikipedia へ。
意味の解らない人は、以下の説明へ。

まず、以下のようなベクトルがあったとして、



これを昇順に並べ変えたものを次のように定義する。



総数を「n」とし、求めたい分位数を「q」とすると、
次のように表すことができる。



うん?添字の部分が...何番目?落ち着いて考えてみる。

通常は、1から数えるが、コンピュータでは0番目を基準とする場合が多い。
そこで、「(n-1)q」のところで、一番目を「0」からの順番に書き直している。

少し、混乱するかも。要するに、元のデータが以下のようになっていて、



これを、「0」からの順番で書きなおし、



「1」ずらした分を後で、正しい位置に戻すために「+1」としている
少々、回りくどい表現であるが仕方あるまい。

さて、これで計算できるかと言うと、実は以下のような条件が付随する。
添字部分が、「(n-1)q+1」だと解りにくいので、とりあえず「t」と置く。



見慣れない記号が一杯出てくる。とりあえず、順番に。

まず、」の記号は、ある集合に含まれていることを表す記号で、
逆が、」 の記号。つまり、ある集合に含まれていない状況を表す。

では、一体何の集合なのかというと、 という記号が教えてくれている。
これは、Natural の「N」だから、自然数を表している。自然数は1以上の整数

要するに、上の条件というのは、「整数」だったらそのままで良いけれど、
「小数点」の値が出てきた場合には、再配分し直しましょう、と言っている。

では、早速、この式に当てはめてRで確認する。
仮に、第1四分位を求めたいのであれば、q = 1/4 = 0.25 となる。

# まずは、データをソートする。
x <- sort(X$Aji)

# 第1四分位数を算出する
(t <- (length(x)-1)*0.25+1)

実行結果は以下の通り。

> (t <- (length(x)-1)*0.25+1)
[1] 10.25

なるほど。見事に、自然数では無い。
ということで、厄介な自然数で無い場合の処理

((ceiling(t)-t)*x[floor(t)]+(t-floor(t))*x[ceiling(t)])

そして、その結果は、以下の通り。

> ((ceiling(t)-t)*x[floor(t)]+(t-floor(t))*x[ceiling(t)])
[1] 1

確かに、合っているようだが、「1」というのは特殊すぎて自身が無い。
そこで、第1四分位〜第4四分位を連続して計算してみる。

x <- sort(X$Aji)    # まずは、データをソートし、ベクトルxに格納
n <- length(x)        # ベクトルxの数を数える

# For文による繰り返し処理
for(q in seq(0, 1, by=0.25)){
    # 四分位数を算出する
    t <- (n-1)*q+1

    # 自然数かをチェックする。
    if (t > 0 && identical(round(t),t)==TRUE) {
        # 自然数の場合はそのまま
        print(x[t])
    } else {
        # 自然数で無い場合は調整する
        print((ceiling(t)-t)*x[floor(t)]+(t-floor(t))*x[ceiling(t)])
    }
}

さて、ここでは、length()関数if文identical()関数が初登場である。

まず、length()関数は、ベクトルに含まれるスカラーの個数を返す関数である。
行列のnrow()関数nrow()関数に似ているが、行列に対してlength()関数を使うと、
その行列に含まれる全成分の総数を返す

 identical()関数は、二つの値が同じあるかを確認するための関数であり、
同じ場合には、「TRUE」を返し、異なる場合には「FALSE」を返す。
ここでは、四捨五入した値と元の数字を比較するために用いている。

if文は、for文と同様に、プログラミングの基本となる構文であり、
ある処理の条件分岐を定義する。

ここでは、「t」が自然数であるか、否か、の分岐を示している。
括弧内の処理が、TRUEの場合は、そのままの値を出力し、
それ以外の場合else)の時には、値を調整して出力している。

この分岐処理の内部では、二つの条件が含まれている。
一つ目は、t > 0 という条件(1以上の正の整数であるという条件)
二つ目は、t が小数点を含んでいるか否か?という条件である。

この二つの条件は、「&&」で結ばれている。これをAND演算と呼ぶ。
すなわち、両方の条件が揃った場合を「真」とする条件が与えられている。

さて、この処理の実行結果は以下の通り。

[1] 0
[1] 1
[1] 23
[1] 82
[1] 683

なるほど、Rの quantile()関数 の結果と見事に同じである。
以上が、分位数の算出方法である。

ところで、今回は、分位数の算出方法を、



で説明した。Excel や R の既定(type 7)はこの方法に従っている。

しかしながら、分位数の分割方法は9通りも存在し、
この辺りは実に厄介な話である。実を言うと、良く理解できない。

この四分位に対して、ヒンジという考え方がある。
これは、四分位と異なり、考え方は至ってシンプル。

中央値より上側の中央値を上側ヒンジと呼び、
中央値より下側の中央値を下側ヒンジと呼ぶ。

R では、fivenum()関数によって計算することができる。

fivenum(X$Aji)

実行結果は以下の通り。

> fivenum(X$Aji)
[1]   0   1  23  88 683

この方法は、五数要約と呼ばれ、fivenum()関数は、
最小値下側ヒンジ中央値上側ヒンジ最大値、の5つの値を返す。

実用上は、四分位五数要約を意識することは無いが、
箱ひげ図の場合には、五数要約を用いる。

最後に、今回のデータの四分位をまとめて出力してみる。
これは、summary()関数を用いることで、簡単に計算できる。

summary(X)

行列データから、直接的計算してくれる。非常に楽。
よく見ると、四分位だけではなく、平均値も計算されている。

> summary(X)
      Aji              Saba             Buri           Hirame       
 Min.   :  0.00   Min.   :  0.00   Min.   :  0.0   Min.   :  0.000  
 1st Qu.:  1.00   1st Qu.:  0.00   1st Qu.:  3.0   1st Qu.:  0.000  
 Median : 23.00   Median :  5.00   Median : 23.0   Median :  1.000  
 Mean   : 84.08   Mean   : 26.21   Mean   : 79.5   Mean   :  9.447  
 3rd Qu.: 82.00   3rd Qu.: 27.00   3rd Qu.: 81.0   3rd Qu.:  8.500  
 Max.   :683.00   Max.   :185.00   Max.   :823.0   Max.   :100.000  

     Karei             Kasago           Mebaru          Kawahagi     
 Min.   :   0.00   Min.   :  0.00   Min.   :  0.00   Min.   :  0.00  
 1st Qu.:   0.00   1st Qu.:  0.00   1st Qu.:  0.50   1st Qu.:  0.00  
 Median :   0.00   Median :  6.50   Median : 11.00   Median :  1.00  
 Mean   :  94.74   Mean   : 22.32   Mean   : 44.74   Mean   : 11.24  
 3rd Qu.:   1.75   3rd Qu.: 31.25   3rd Qu.: 63.75   3rd Qu.:  4.00  
 Max.   :2140.00   Max.   :131.00   Max.   :452.00   Max.   :217.00  

      Tai             Isaki             Ika              Tako       
 Min.   :  0.00   Min.   :  0.00   Min.   :  0.00   Min.   : 0.000  
 1st Qu.:  8.75   1st Qu.:  0.00   1st Qu.:  0.25   1st Qu.: 0.000  
 Median : 33.50   Median :  2.00   Median :  8.50   Median : 0.000  
 Mean   : 72.26   Mean   : 25.08   Mean   : 69.39   Mean   : 5.026  
 3rd Qu.:121.25   3rd Qu.: 19.75   3rd Qu.: 60.50   3rd Qu.: 2.000  
 Max.   :308.00   Max.   :205.00   Max.   :660.00   Max.   :49.000  

四分位は、分散と同様にデータ全体のバラツキを観察する上で重要であるが、
この状況を、眺めても、いまいち解りにくい。やはり、標準偏差の方が解かりやすいか?

しかしながら、この状況を可視化することで、非常に重要な参考資料となり得る。
その可視化方法こそが、「箱ひげ図」なのである。この話については、次の話で。

3 件のコメント:

  1. 「行数=属性(変数)の総数
    列数=対象の数」
    とありますが、逆では?

    返信削除
    返信
    1. ご指摘ありがとうございます。修正しました。

      削除
  2. 目次とページタイトルが異なっていたので修正しました。

    返信削除