ラベル 基準化 の投稿を表示しています。 すべての投稿を表示
ラベル 基準化 の投稿を表示しています。 すべての投稿を表示

2012/09/01

文系のための「多次元データの要約」(1)

今回は、分散と共分散を楽して「行列」を使って計算するという話。

まずは、復習から。分散の計算は、以下の式で表すことができた。
本来は、二乗の形で表すが、共分散の式との比較のため、このように表す。



一方、共分散の計算は、以下のように表した。
共分散の場合は、二つの変数間のバラツキを表すので、
 と  の二つの変数が使われている。



さて、ここからが今回の話の重要なポイント。
今回は、ちょっとした、行列の掛け算の魔法を垣間見ることになる。

まずは、 」分散の計算から考えてみる。
以下は、 」偏差であり、 」という記号で表した。
「〜」の記号は、チルダと呼ぶのだった。



ここで、 というベクトルの計算を考えてみる。これを展開するとどのようになるか?
tの記号は、転置(transpose)を意味したのだから、


このようになる。これは、どのような計算だったか?
忘れた人は、文系のための内積(1)を参照。

確か、「横✕縦+横✕縦+横✕縦・・・となるから・・・。」

おぉ、なるほど。二乗したのを足していく訳か。
あるベクトルの転置と元のベクトルの掛け算は「二乗和」になるのだった。

したがって、以下のようになる。



うん?これは、確か分散の式のΣの内側と同じ計算となっている。
何が言いたいかと言うと、分散の計算をベクトルで表すと、以下のようになる。



 の分散は、見事にベクトルの式で表すことができる。
確か、共分散のΣの中身は、添字が異なるだけで、分散と同じだった。
つまり、掛ける側のベクトルを とすると、



となり、したがって、



という計算になる。素晴らしい。分散と同様に見事に計算できる
分散と同様に、ベクトルの式で表すと、次のようになる。



ここまでが理解できれば大丈夫。ここまでは、ベクトルの掛け算であったが、
次のような行列を考えてみるとどうなるか?



ちょっと、難しいかもしれないが、落ち着いて考えれば大丈夫。
頑張れる人は、手計算で。自信が無い人は、行列の計算の話を参考に。
頑張れない人は、あとでRを使って練習。

計算の順番と解となる行列での位置は次のようになる。
  • 1行目の横ベクトル×1列目の縦ベクトル(  ) ⇒  Answer[1, 1]
  • 1行目の横ベクトル×2列目の縦ベクトル(  ) ⇒  Answer[1, 2]
  • 1行目の横ベクトル×3列目の縦ベクトル(  ) ⇒  Answer[1, 3]
  • 2行目の横ベクトル×1列目の縦ベクトル(  ) ⇒  Answer[2, 1]
  • 2行目の横ベクトル×2列目の縦ベクトル(  ) ⇒  Answer[2, 2]
  • 2行目の横ベクトル×3列目の縦ベクトル(  ) ⇒  Answer[2, 3]
  • 3行目の横ベクトル×1列目の縦ベクトル(  ) ⇒  Answer[3, 1]
  • 3行目の横ベクトル×2列目の縦ベクトル(  ) ⇒  Answer[3, 2]
  • 3行目の横ベクトル×3列目の縦ベクトル(  ) ⇒  Answer[3, 3]
つまり、以下のように書き換えることが可能。



ここで、注意して見てもらいたいのが、対角成分に何が入っているか?ということ。
自分同士の共分散ということは、何を意味するのだったか?答えは、分散

もうひとつのポイントは、二つの変数の共分散の計算は、
順番を変えても答えは同じ(スカラーでは、A×B=B×A)なので、
対角成分を挟んで上側と下側が同じになる、ということも重要。

したがって、この行列の計算を通して計算された結果は、
対角成分に分散が並び、それ以外に共分散が入った対象行列である。

これを、「分散共分散行列」と呼ぶ。

さらに、元の行列が標準化されていた場合、すなわち、
平均が「0」で分散が「1」となるように基準化されていた場合には、
対角成分が全て「1」で、それ以外の成分が相関係数となる

例えば、先ほどの行列 を標準化した行列を Z としたとき、



という関係が成り立つ。これを、「相関係数行列」と呼ぶ。

分散共分散行列相関係数行列は、データを要約した指標として重要であると同時に、
この行列を用いることで、主成分分析の計算が容易になる。この話は、いずれ。

では、今度は実際のデータを用いて計算の練習をしてみる。
サンプルデータは、分散標準偏差の説明で用いたものを再び使う。

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

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

以下が、そのデータ。前回のものを再掲しただけ。
データの説明に関しては、平均の話を参照。

Oroshi_Kg, Taka, Naka, Yasu
Tai, 1336, 3150, 1217, 53
Chinu, 226, 630, 513, 105
Sawara, 212, 1575, 1259, 840
Yazu, 4834, 840, 315, 179
Suzuki, 618, 1575, 1146, 525
Akou, 21, 4725, 3129, 1575
Kochi, 28, 2100, 874, 210
Okoze, 28, 5250, 2635, 210
Ainame, 29, 3150, 621, 315
Hage, 1205, 1890, 383, 210
Konoshiro, 21, 2100, 1100, 105
Sayori, 12, 5250, 3916, 1260
Anago, 1637, 2625, 1721, 630
Mebaru, 330, 4200, 1680, 315
Tachiuo, 1211, 2310, 930, 105
Hamo, 1622, 3938, 592, 53
Karei, 41, 6300, 3178, 525
Hirame, 540, 2100, 1496, 210
Aji, 5149, 3150, 789, 210
Saba, 5413, 3675, 625, 53
Ika, 2414, 2888, 1083, 105
Tako, 1844, 1890, 1180, 525
Ebi, 560, 7350, 1420, 525
KurumaEbi, 222, 8925, 6508, 2625
Koiwashi, 1316, 1155, 617, 328
ObaIwashi, 2716, 499, 267, 175
Mentai, 678, 1155, 859, 394
Hamachi, 4772, 998, 632, 105
Isaki, 268, 2625, 1465, 840

まずは、行列 と同じサイズで、平均が並んでいる行列が必要だから、

# ステップ1:データの総数(n)を求める。
n <- nrow(X)
# ステップ2:卸売数量の平均を求める。転置が必要。
m <- t(colMeans(X))
# ステップ3:行列の引き算ができるように、平均値を総数個複製する。
M <- matrix(rep(m, each=n), nrow=n, ncol=4)
# ステップ4:元の行列から、平均値が複製された行列Mを引き算する。
tilde_X <- as.matrix(X-M)

最終的に、「tilde_X」という変数に偏差行列が入った。
ここで、分散共分散の式をそのまま当てはめると、

(t(tilde_X) %*% tilde_X)/(n-1)

となり、実行結果は以下のようになる。

> (t(tilde_X) %*% tilde_X)/(n-1)
           Oroshi_Kg       Taka      Naka      Yasu
Oroshi_Kg  2814792.6 -1026368.1 -920404.3 -335784.2
Taka      -1026368.1  4210888.7 2159783.0  685439.7
Naka       -920404.3  2159783.0 1752709.8  637497.8
Yasu       -335784.2   685439.7  637497.8  306021.7

疑い深い人は、分散共分散の話の結果と照合してみよう。
間違いなく、対角成分には分散が並び、それ以外には共分散が入っている。

さて、今度は、元のデータを標準化して計算をしてみる。

# 標準化した行列を作る
Z <- scale(X)

# 共分散の計算。平均は0なので偏差行列は不要
(t(Z) %*% Z)/(n-1)

実行結果は以下の通り。

> cov(Z)
           Oroshi_Kg       Taka       Naka       Yasu
Oroshi_Kg  1.0000000 -0.2981213 -0.4143816 -0.3617937
Taka      -0.2981213  1.0000000  0.7950020  0.6038183
Naka      -0.4143816  0.7950020  1.0000000  0.8704575
Yasu      -0.3617937  0.6038183  0.8704575  1.0000000

対角成分には「1」が並んでいて、それ以外の所は相関係数が入っている。
このようにして、相関係数行列を計算することができる。

ちなみに、前回、登場したcov()関数cor()関数は、
両方とも行列に対応しているので、共分散行列相関係数行列を出せる。

cov(X)    # 分散共分散行列を直接計算する
cor(X)    # 相関係数行列を直接計算する

以下は、実行結果。

> cov(X)    # 分散共分散行列を直接計算する
           Oroshi_Kg       Taka      Naka      Yasu
Oroshi_Kg  2814792.6 -1026368.1 -920404.3 -335784.2
Taka      -1026368.1  4210888.7 2159783.0  685439.7
Naka       -920404.3  2159783.0 1752709.8  637497.8
Yasu       -335784.2   685439.7  637497.8  306021.7

> cor(X)    # 相関係数行列を直接計算する
           Oroshi_Kg       Taka       Naka       Yasu
Oroshi_Kg  1.0000000 -0.2981213 -0.4143816 -0.3617937
Taka      -0.2981213  1.0000000  0.7950020  0.6038183
Naka      -0.4143816  0.7950020  1.0000000  0.8704575
Yasu      -0.3617937  0.6038183  0.8704575  1.0000000

手計算の場合には、結局、展開して計算しないといけないので、
手間は同じであるが、Rのように行列の計算ができるソフトウェアを使えば、
分散共分散相関係数を一度に計算することができ、便利なのである。

2012/08/22

文系のための「二変数の関係」(1)

前回の話では、以下のことについて説明した。
偏差」は、平均からの離れ具合であり、個々の個性を表した
分散」は、偏差の二乗の和であり、全体として個性の強さ、バラツキを表した
そして、「標準偏差」は、分散の平方根をとったものであった。

ふむ。ようやく、データを観察する上での第一段階はクリア。
では、異なる変数(属性)同士の関係を観察するには、どうすれば良いか?
まずは、前回のデータの読み込みから。前回と同じ作業。

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

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

以下が、そのデータ。前回のものを再掲しただけ。

データの説明に関しては、平均の話を参照。

Oroshi_Kg, Taka, Naka, Yasu
Tai, 1336, 3150, 1217, 53
Chinu, 226, 630, 513, 105
Sawara, 212, 1575, 1259, 840
Yazu, 4834, 840, 315, 179
Suzuki, 618, 1575, 1146, 525
Akou, 21, 4725, 3129, 1575
Kochi, 28, 2100, 874, 210
Okoze, 28, 5250, 2635, 210
Ainame, 29, 3150, 621, 315
Hage, 1205, 1890, 383, 210
Konoshiro, 21, 2100, 1100, 105
Sayori, 12, 5250, 3916, 1260
Anago, 1637, 2625, 1721, 630
Mebaru, 330, 4200, 1680, 315
Tachiuo, 1211, 2310, 930, 105
Hamo, 1622, 3938, 592, 53
Karei, 41, 6300, 3178, 525
Hirame, 540, 2100, 1496, 210
Aji, 5149, 3150, 789, 210
Saba, 5413, 3675, 625, 53
Ika, 2414, 2888, 1083, 105
Tako, 1844, 1890, 1180, 525
Ebi, 560, 7350, 1420, 525
KurumaEbi, 222, 8925, 6508, 2625
Koiwashi, 1316, 1155, 617, 328
ObaIwashi, 2716, 499, 267, 175
Mentai, 678, 1155, 859, 394
Hamachi, 4772, 998, 632, 105
Isaki, 268, 2625, 1465, 840

現在、Xという行列の変数に、「魚の卸売価格」の情報が入っている。
このデータを使って、各変数間の関係を観察していくことにする。
さて、ある変数と別の変数との関係とは何か?
そもそも、二つの変数の間に、関係が「ある」のか?、「ない」のか?

もしも、関係があるとしたら、何らかの法則があるはず。
直感的に、考え得る法則は、二つある。
一つ目は、一方の値が高いときに、もう一方も高いという法則(連動)、
二つ目は、一方の値が高いときに、もう一方は低いという法則(反連動)。

どうすれば、この状況が理解できるか、少し考えてみる。

まずは、連動している場合を考えてみる。どのような状況であるか?
一方の値が「」に向いているとき、もう一方は「」に向く。
一方の値が「」に向いているとき、もう一方は「-」に向く

ここで、小学校で習ったことを、思い出してみる。
「+」 × 「+」 = 「+」 であり 「-」×「-」 =「+」 また 「+」 × 「-」 = 「-」 
という、あの法則。確か、そのようなことを教わった。

連動の場合、ある対象における二つの変数をかけ合わせると、
 その結果は、「+」方向に大きくなるし、
反連動の場合、ある対象における二つの変数をかけ合わせると、
 その結果は、「-」方向に大きくなる。
いずれでもない場合、「+」と「-」が打ち消し合って、「0」に近づく

では、実際に、どのように計算するのかを整理する。
二つの変数、「」と「」があったとして、次のように考えることができる。



この計算結果の「正負の符号」を見れば、上の法則のいずれかが解る。

ところで、この式を観察してみる。
なんと、分散の式のΣの計算の部分と似ている。

もしも、 であれば、二乗となるので、この部分は分散と同じ。
したがって、分散の式に合わせて、次のように考えることもできる。



二つの変数の「バラツキ」を同時に見ているので、これを「共分散」と呼ぶ。
とにかく、この指標の「」と「」の大きさを観察すれば、
二つの変数間の全体として関係が解りそう。では、実際の計算を。

そうそう、行列Xと同じサイズの、平均が並んでいる行列が必要なのだった。
これは、前回にもやったので、説明は省く。処理の内容だけ。

# ステップ1:データの総数(n)を求める。
n <- nrow(X)
# ステップ2:卸売数量の平均を求める。転置が必要。
m <- t(colMeans(X))
# ステップ3:行列の引き算ができるように、平均値を総数個複製する。
M <- matrix(rep(m, each=n), nrow=n, ncol=4)
# ステップ4:元の行列から、平均値が複製された行列Mを引き算する。
A <- X-M

とりあえず、これで準備完了。気を取り直して、計算してみる。
全組み合わせは大変。今回は、卸売数量と高値の関係に注目してみる。
この二つの共分散を求める方法は以下の通り。ベクトルの掛け算

(A$Oroshi_Kg %*% A$Taka)/(n-1)

そして、その結果。

> (A$Oroshi_Kg %*% A$Taka)/(n-1)
         [,1]
[1,] -1026368

ふむ。マイナスの結果が出てきた。反連動の関係のようだ。
っで、これは、大きいのか?それとも、小さいのか?
場合によっては、実は、反連動とは言えないかも。判断に困る。

可視化してみると、状況が解るかもしれない。
とりあえず、元の行列Xで確認してみる。
plot(X$Oroshi_Kg,X$Taka)

これを「散布図」と呼ぶ。横軸が卸売数量で、縦軸が高値。
共分散によって表される状況を可視化したものと言える。

さて、結果は...というと、何とも、微妙な...。
なんとなく、右肩下がりになっているような...。
とにかく、コメントしにくい結果である。正直言って、解釈に困る。

反連動と言えなくはない。が、やはり、その程度は不明。
そこで、この結果を、なんとか一般的にわかりやすいようにしたい。
どのようにすれば、良いか。考えてみる。

要するに、この問題は、共分散の上限と下限が決まっていないのが問題
したがって、上限と下限が、固定されれば問題は解決できそうである。

わかりやすいように、偏差の値が、「-1〜1」の間に収まるようにすれば良いか。
つまり、何かの単位で揃えるということか。うん?単位にする?
単位にするということは、何かの逆数を掛ければ良かった。

では、二つの変数の共分散を考えた時、
正の方向に値が最も大きくなるのはどような状況か?

ここで、直感的に分かった人はセンスが良い。実は、二つの変数が同じ状況
この状況は、分散と呼ばれる状況であった。では、分散で単位化すれば良いか?

それはでは「ダメ」!分散は、元の値よりも二乗分値が大きいのであった。
では?何で単位を揃えるべきか。そうそう。思い出した。
平方根をとって元と比較したもの。「標準偏差」を使おう

まずは、標準偏差を求めたい。これも復習。sd()関数を使う。
今回は、結果を変数に入れておく。カッコで括っているのは、結果を表示させるため。

(X.sd.o <- sd(X$Oroshi_Kg))
(X.sd.t <- sd(X$Taka)) (X.sd.n <-  sd(X$Naka)) (X.sd.y <- sd(X$Yasu))

実行結果は、以下のようになる。

> (X.sd.o <- sd(X$Oroshi_Kg))
[1] 1677.734
> (X.sd.t <- sd(X$Taka))
[1] 2052.045
> (X.sd.n <-  sd(X$Naka))
[1] 1323.899
> (X.sd.y <- sd(X$Yasu))
[1] 553.1923


次に、行列Aを作成した時の「ステップ3」を応用して、
行列Xと同じサイズの標準偏差が入った行列を作成する。今回、結果は省略。

(S <- matrix(rep(c(X.sd.o, X.sd.t, X.sd.n, X.sd.y), each=n), nrow=n, ncol=4))

次に、偏差が入っている行列、すなわち行列Aを標準偏差基準化する。

行列の「成分の割り算」であって、行列そのものの計算ではない。
間違っても、逆行列と混同してはいけない

Z <- A/S

さて、ちゃんと基準化されているかを確認してみる。
各変数における分散が1となっていれば良いはず。

var((A/S)$Oroshi_Kg)
var((A/S)$Taka)
var((A/S)$Naka)
var((A/S)$Yasu)

実行結果は以下のようになる。確かに、上手くできている。

> var((A/S)$Oroshi_Kg)
[1] 1
> var((A/S)$Taka)
[1] 1
> var((A/S)$Naka)
[1] 1
> var((A/S)$Yasu)
[1] 1


ついでに、この時の平均についても確認しておく。平均は全て「0」

colMeans((A/S))

そして、その実行結果。結果は、微細な計算誤差があるが限りなく「0」。
結局、上限が1となるように、上限と下限を圧縮しているので、
ちょうど、真ん中となる平均は、基準化する前と変わらず「0」のまま

> colMeans((A/S))
    Oroshi_Kg          Taka          Naka          Yasu 
-3.840319e-17  1.007336e-16 -6.346695e-17  1.339924e-17 

以上の結果から、このように基準化を行うと、分散が1、平均が0となる。
このような基準化の方法を「標準化」と呼び、標準化された値を「Z値」と呼ぶ。
なお、標準化の英語は「scale」と呼ぶ。Rには、scale()関数がある。

かなり、面倒な手続きを踏んだが、以下のようにすれば、
元の行列Xから、簡単に標準化された行列を算出できる。

Z <- scale(X)

ここで、標準化の式も示しておく。以下の値は、個々の成分に作用する。



左から順に。左端は、「i」番目の変数「x」の「z」値という意味。
真ん中のは、「i」番目の変数「x」における実際の計算の式。
右端は、象徴的な式。ある変数xから平均を引いて、
標準偏差で基準化している状況を表している。

では、標準化されたデータを用いて共分散を計算してみる。
共分散は、ベクトルの掛け算で計算できた。解は、-1 〜 1 の間に収まるはず。

(Z$Oroshi_Kg %*% Z$Taka)/(n-1)

そして、その結果。

> (Z$Oroshi_Kg %*% Z$Taka)/(n-1)
           [,1]
[1,] -0.2981213

ふむ。この結果を見てみると、負の値となっているが、それほど大きくない。
卸売数量と高値の関係を、反連動というには難がありそう。

さて、このように標準化を行ったデータで共分散を見てみると、
相互の関係性が「-1〜1」の間に収まるので、見通しが明瞭になる。便利である。
こういった便利な方法には、大抵名前がついている。
これが、いわゆる「相関係数」と呼ばれる指標である。

これまでは、「連動」と「反連動」という言葉を使ってきたが、一般的では無い
通常は、この相関係数から、「正の相関」と「負の相関」と呼ぶ。

余談ではあるが、「負」という言葉な否定的なイメージを持っているため、
「分析上、あまり良くない傾向が出ている」と勘違いする人がいる。
これは大きな間違い。「負の相関」が強く現れるデータにも意味がある

ところで、今回は、元の値を標準化して、その共分散として相関係数導いた
しかし、相関係数は別の方法で導くことも可能であり、
以下の式によって、計算することが可能である。
ここでは、二つの変数を「」と「」として、


少し複雑に見えるかもしれない。よく見れば、難しくない。
分子は、共分散のΣの中身になっている。そして、
分母は、」と「分散のΣの中身の平方根になっている。

ここで、=」の状況を考えてみる。つまり、2つの変数が同じ状況。
確か、平方根の二乗は、元の数に戻るのだったから、


となり、相関係数の値が出てくる。よくできている。
もちろん、Rには、相関係数を算出する関数がある。
通常は、このような回りくどいやり方をせず、次のようにする。


cor(X$Oroshi_Kg, X$Taka)
cor(X$Oroshi_Kg, X$Naka)
cor(X$Oroshi_Kg, X$Yasu)

実行結果は、以下の通り

> cor(X$Oroshi_Kg, X$Taka)
[1] -0.2981213
> cor(X$Oroshi_Kg, X$Naka)
[1] -0.4143816
> cor(X$Oroshi_Kg, X$Yasu)
[1] -0.3617937

ふむふむ。相関係数は、cor()関数の使うのである。
これは、便利。よく使う関数のひとつである。

上記の結果から、卸売数量と高値、中値、安値の関係を見てみると、
全て負の値をとっているので、反連動的な傾向を持っているようである。
一般的に、魚の希少価値が値段に反映すると言われているので、
そのような傾向が相関係数にも現れているのかもしれない。

ただし、これらの値を見てみると、いずれの値も-1よりも0に近く
したがって、明らかに、「負の相関」があるとは言えない

希少価値があっても、クセが強くて用途が限られる不人気な魚や、
逆に、希少価値は低いが、需要が高く、結果として高価となる魚もある。
今回のデータでは、そうした例外的な状況が影響しているようである。

最後に、直感的に強い関連がありそうな組み合わせもやってみる。
おそらく、中値と安値は、強い正の関係がありそう。どうなる?

> cor(X$Naka, X$Yasu)
[1] 0.8704575

結果を見てみると、0.87と1に近い値が出てきた。これは、正の相関と言えそう。
では、このような状況は、どのように可視化できるか?前にやったことを思い出す。

たしか、共分散の関係を標準化したのが相関係数だったので、
散布図で可視化すれば、この状況を上手く表現できるだろう。
plot(X$Naka, X$Yasu)

今度は、明らかに右肩上がりの図になっている。このような散布図を書いた場合、
「正の相関」が強いものは、右肩「上がり」の図となり、各々の点は対角線に集まり、
「負の相関」が強いものは、右肩「下がり」の図となり、各々の点は対角線に集まる。
2つの変数間の関係を観察するには、相関係数と散布図を見比べるのが良い。

なお、「0.7以上は相関がある」などと聞くが、その表現は、正しくない
相関の基準は、誤差の許容範囲と対象数に依存するのであって、
一般的な基準値が存在しているわけではない。この話は、いずれ詳しく述べる。