前回の話では、以下のことについて説明した。
「偏差」は、平均からの離れ具合であり、個々の個性を表した。
「分散」は、偏差の二乗の和であり、全体として個性の強さ、バラツキを表した。
そして、「標準偏差」は、分散の平方根をとったものであった。
ふむ。ようやく、データを観察する上での第一段階はクリア。
では、異なる変数(属性)同士の関係を観察するには、どうすれば良いか?
まずは、前回のデータの読み込みから。前回と同じ作業。
# Windows と Linux の人は次のコマンド
X <- read.table("clipboard", sep=",", header=TRUE)
# Mac の人は次のコマンド
X <- read.table(pipe("pbpaste") , sep=",", header=TRUE)
以下が、そのデータ。前回のものを再掲しただけ。
さて、ある変数と別の変数との関係とは何か?「偏差」は、平均からの離れ具合であり、個々の個性を表した。
「分散」は、偏差の二乗の和であり、全体として個性の強さ、バラツキを表した。
そして、「標準偏差」は、分散の平方根をとったものであった。
ふむ。ようやく、データを観察する上での第一段階はクリア。
では、異なる変数(属性)同士の関係を観察するには、どうすれば良いか?
まずは、前回のデータの読み込みから。前回と同じ作業。
# 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
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
# ステップ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.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)$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」のまま。
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)
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」の間に収まるので、見通しが明瞭になる。便利である。
こういった便利な方法には、大抵名前がついている。
これが、いわゆる「相関係数」と呼ばれる指標である。
これまでは、「連動」と「反連動」という言葉を使ってきたが、一般的では無い。
通常は、この相関係数から、「正の相関」と「負の相関」と呼ぶ。
余談ではあるが、「負」という言葉な否定的なイメージを持っているため、
「分析上、あまり良くない傾向が出ている」と勘違いする人がいる。
これは大きな間違い。「負の相関」が強く現れるデータにも意味がある。
ところで、今回は、元の値を標準化して、その共分散として相関係数導いた。
しかし、相関係数は別の方法で導くことも可能であり、
以下の式によって、計算することが可能である。
ここでは、二つの変数を「」と「」として、
これまでは、「連動」と「反連動」という言葉を使ってきたが、一般的では無い。
通常は、この相関係数から、「正の相関」と「負の相関」と呼ぶ。
余談ではあるが、「負」という言葉な否定的なイメージを持っているため、
「分析上、あまり良くない傾向が出ている」と勘違いする人がいる。
これは大きな間違い。「負の相関」が強く現れるデータにも意味がある。
ところで、今回は、元の値を標準化して、その共分散として相関係数導いた。
しかし、相関係数は別の方法で導くことも可能であり、
以下の式によって、計算することが可能である。
ここでは、二つの変数を「」と「」として、
少し複雑に見えるかもしれない。よく見れば、難しくない。
分子は、共分散のΣの中身になっている。そして、
確か、平方根の二乗は、元の数に戻るのだったから、
となり、相関係数の値が出てくる。よくできている。
もちろん、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
では、このような状況は、どのように可視化できるか?前にやったことを思い出す。
たしか、共分散の関係を標準化したのが相関係数だったので、
散布図で可視化すれば、この状況を上手く表現できるだろう。
plot(X$Naka, X$Yasu)
今度は、明らかに右肩上がりの図になっている。このような散布図を書いた場合、
「正の相関」が強いものは、右肩「上がり」の図となり、各々の点は対角線に集まり、
「負の相関」が強いものは、右肩「下がり」の図となり、各々の点は対角線に集まる。
2つの変数間の関係を観察するには、相関係数と散布図を見比べるのが良い。
なお、「0.7以上は相関がある」などと聞くが、その表現は、正しくない。
相関の基準は、誤差の許容範囲と対象数に依存するのであって、
一般的な基準値が存在しているわけではない。この話は、いずれ詳しく述べる。
相関の基準は、誤差の許容範囲と対象数に依存するのであって、
一般的な基準値が存在しているわけではない。この話は、いずれ詳しく述べる。
以下の一連のコマンドを実行すると、最後にあるようなエラーメッセージが出てきてしまうのですが、何か間違っているでしょうか?
返信削除ちなみに、cor(X$Oroshi_Kg, X$Taka)はちゃんと計算できました。
> # Mac の人は次のコマンド
> X <- read.table(pipe("pbpaste") , sep=",", header=TRUE)
> Z <- scale(X)
>
> (Z$Oroshi_Kg %*% Z$Taka)/(n-1)
以下にエラー Z$Oroshi_Kg : $ operator is invalid for atomic vectors
Rのデータ型が原因かもしれません。
削除現在、手元に確認用のPCが無いので、
後ほど、私の方でも確認してみますが、
試しに、以下のようにして見てください。
X <- data.frame(read.table(pipe("pbpaste"), sep=",", header=TRUE))