相関係数とは、2つのデータまたは確率変数の間にある線形な関係の強弱を測る指標です。相関係数は無次元量で、1以上1以下の実数になります。相関係数が正のとき正の相関があり、負のとき負の相関があるといいます。また相関係数が0のときは無相関であることになります。
相関係数がどの程度の値なら相関があるのかという統一的な基準は決まっていませんが、以下の基準がよく用いられます。
相関係数が
マイナス1以上でマイナス0.7以下 ⇒ 強い負の相関
マイナス0.7 以上で マイナス0.4以下 ⇒ 負の相関
マイナス0.4 以上で マイナス0.2以下 ⇒ 弱い負の相関
マイナス0.2 以上で 0.2以下 ⇒ ほとんど相関がない
0.2 以上で 0.4以下 ⇒ 弱い正の相関
0.4 以上で 0.7以下 ⇒ 正の相関
0.7 以上で 1以下 ⇒ 強い正の相関
相関係数の求め方ですが、 PythonならPandas の corr() 関数を使って相関係数を計算することができます。PythonでできるならC#でもできるはずです。ここは相関係数の求め方にしたがって計算していくことにします。
A、Bそれぞれの変数の平均値を求める
A、Bそれぞれの変数の偏差を求める
A、Bそれぞれの変数の標準偏差を求める
共分散(偏差の積の平均)を求める
共分散を 2 つの変数の標準偏差で割って相関係数を得る
偏差とは数値から平均値を引いたものです。平均よりも大きければ正の値になり、平均よりも小さければ負の値になります。これらをそのまま足すと0になってしまいあまり意味がないのですが、それらを二乗すると必ず0以上の値になります。これらを全部足して全体の数で割ったもの(偏差の二乗平均)が「分散」であり、その正の平方根が標準偏差です。
共分散とは偏差の積の平均です。A1が30でAの平均が36、B1が70でBの平均が76であれば(30 – 36)×(70 – 76)なので36です。これをすべてのデータで計算してその積の平均を求めます。これが共分散です。
最後に共分散をAとBの標準偏差の積で割ります。これで相関係数がわかります。
たとえば
Aのデータが 30, 30, 20, 90, 10
Bのデータが 70, 60, 70, 100, 80
Aの平均は36、Bの平均は76です。偏差は以下のようになります。
Aの偏差は -6, -6, -16, 54, -26
Bの偏差は -6, -16, -6, 24, 4
それぞれを2乗すると
36, 36, 256, 2916, 676
36, 256, 36, 576, 16
それぞれの平均は 784 と 184 であり、ここからそれぞれの標準偏差は 28 と 13.56465997 になります。
共分散を計算してみましょう。偏差の積は
-6 × -6 = 36
-6 × -16 = 96
-16 × -6 = 96
54 × 24 = 1296
-26 × 4 = -104
なので、その平均値は 1420 / 5 = 284 です。したがって共分散も 284 です。
ここから 相関係数は 0.747741349 となり、「強い正の相関」があることがわかります。
ではC#をつかって計算してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
class Program { static void Main() { // ふたつのデータをカンマ区切りで入力する // 入力例 // 30, 30, 20, 90, 10 // 70, 60, 70, 100, 80 string str1 = Console.ReadLine(); string str2 = Console.ReadLine(); str1 = str1.Replace(" ", ""); str2 = str2.Replace(" ", ""); // 値を取得 double[] vs1; double[] vs2; try { vs1 = str1.Split(',').Select(_ => double.Parse(_)).ToArray(); vs2 = str2.Split(',').Select(_ => double.Parse(_)).ToArray(); if (vs1.Length != vs2.Length || vs1.Length == 0) throw new Exception(); } catch { Console.WriteLine("入力されたデータが不正です"); return; } // 値の平均 double avr1 = vs1.Average(); double avr2 = vs2.Average(); // 偏差を取得 double[] dev1 = vs1.Select(_ => _ - avr1).ToArray(); double[] dev2 = vs2.Select(_ => _ - avr2).ToArray(); // 標準偏差を取得 double stdDev1 = Math.Sqrt(dev1.Select(_ => _ * _).Average()); double stdDev2 = Math.Sqrt(dev2.Select(_ => _ * _).Average()); // 偏差の積 double[] products = new double[vs1.Length]; for (int i = 0; i < vs1.Length; i++) products[i] = dev1[i] * dev2[i]; // 共分散 double covariance = products.Average(); // これが相関係数 double result = covariance / stdDev1 / stdDev2; Console.WriteLine(result); // 入力例の場合は0.747741349071264となる } } |
注意しなければならないのは、「相関関係があるといっても因果関係があるかどうかはわからない」ということです。数理経済学者の佐和隆光氏は以下のように述べています。
しばしば統計は、他人をだますための方便ともなる。統計の悪用と誤用は、日常茶飯のごとく見受けられる。数字の氾濫するこの世の中において、「統計のウソ」に対する抵抗力を備えておくことは、将来どういう仕事に携わる人にとっても必要不可欠なはずである
鳩でも分かるC#管理人からのお願い
できる仕事であれば請け負います。鳩でもわかるC#管理人はクラウドワークスに在宅ワーカーとして登録しています。お仕事の依頼もお待ちしております。
⇒ 仕事を依頼する
コメントについて
コメントで英語などの外国語でコメントをされる方がいますが、管理人は日本語以外はわからないので基本的に内容が理解できず、承認することもありません。それからへんな薬を売っているサイトやリンク先のサイトが存在しないというスパムコメントも多々あります。
Some people make comments in foreign languages such as English, but since the manager does not understand anything other than Japanese, he basically cannot understand the content and does not approve it. Please use Japanese when making comments.
そんななか日本語のコメントもいただけるようになりました。「○○という変数はどこで宣言されているのか?」「××というメソッドはどこにあるのか」「例外が発生する」「いっそのことソース丸ごとくれ」という質問ですが、管理人としては嬉しく思います。「自分が書いた記事は読まれているんだな」と。疑問点には可能な限り答えます。記事に問題があれば修正いたします。
そのうえでお願いがあります。「匿名」という味も素っ気もない名前ではなく、捨てハンでいいのでなにかハンドルネームをつくってほしいと思います。
管理人のモチベーションアップのために
よろしければご支援お願いします。
⇒ 管理人の物乞いリスト