4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

とりあえずの統計学〜相関係数〜

Last updated at Posted at 2017-05-31

相関係数というものを聞いたのでそれをまとめてみようかなと
(そして、相関係数を計算するクラスをSwiftで作ってしまおうとw

自分なりの解釈なので間違ってましたらご指摘いただけるとありがたいです。

相関係数とは

事柄Aと事柄Bの関係(相関)の強さを表した数値です

  • A型の人は、几帳面が多い
  • 商品Aを買った人は、商品Bも買う人が多い
  • 英語のテストの点数が高い人は、国語のテストの点数も高い人が多い

などの関係を数値化したものです

相関係数の計算

いきなり求めるのは大変なので、相関係数の計算に必要なものから求めていきます

クラスを作っておきます

class CorrelationCoefficient {
}

例題

わかりやすくするため、ある学校のテスト(英語と国語)の点数から相関係数を求める。という問題をやっていきましょう。
以下の表がある学校の英語と国語のテストの点数を表しています。

英語 国語
Aくん 40 38
Bさん 50 65
Cさん 44 40
Dくん 74 87
Eさん 92 90

英語も国語もやること(計算方法)は同じなので、英語の場合のみ求めていきます

Swift

計算しやすいように配列に入れておきます

let English: [Double] = [40, 50, 44, 74, 92]
let Japanese: [Double] = [38, 65, 40, 87, 90]

平均

まずはテストの平均を求めてみます
テストの点数の合計を人数で割れば良いですね

(40 + 50 + 44 + 74 + 92) ÷ 5 = 60

Swift

計算しやすいように配列にしておいたので、reduceを使っていきましょう

func average(_ array:[Double]) -> Double {
	return array.reduce(0, +) / Double(array.count)
}

偏差

偏差という言葉はあまり聞きなれないかとおもいます
平均から各値がどのくらい離れているかのことです
計算は簡単で、各値と平均の差を求めるだけです

40 - 60 = -20
50 - 60 = -10
44 - 60 = -16
74 - 60 = 14
92 - 60 = 32

Swift

今回も配列なのを利用し、mapメソッドで偏差の配列を返すようにします

func deviation(_ array:[Double]) -> [Double] {
	let average = self.average(array)
	return array.map({ (value) -> Double in
		value - average
	})
}

分散

分散はなんとなくわかるかと思いますが、データのばらつきを表します
先ほど求めた偏差の平均を取るのですが、平均は必ず0になってしまいますw
そこで、偏差の2乗の平均を求めます(平均ではなく合計を個数 - 1で割ることもあるそうです)

( (-20)^2 + (-10)^2 + (-16)^2 + 14^2 + 32^2 ) ÷ 5 = 395.2

Swift

先ほどの偏差の返り値が配列なのを利用し、reduceで足していきます

func dispersion(_ array:[Double]) -> Double {
	let deviations = deviation(array)
	return deviations.reduce(0, { (result, value) -> Double in
		result + (value * value)
	}) / Double(deviations.count)
}

標準偏差

また聞きなれない言葉が出てきましたねw
分散は各値のばらつきを表していましたね。しかし、都合上各偏差を2乗していました。
そこで、元のデータを単位(次元)を合わせた方が感覚的にわかりやすくなるということで標準偏差というのが用いられます
計算は、分散の正の平方根を求めるだけです

√395.2 = 19.87

**[余談]**ちなみに、国語のテストの点数の標準偏差は22.17なので、国語のテストの点数の方がばらつきがあると言えます

Swift

平方根は、sqrt()というメソッドが用意されてるのでそれを使います

func standardDeviation(_ array:[Double]) -> Double {
	return sqrt(dispersion(array))	
}

一旦休憩

知らない言葉が出てきて疲れたかと思うので、一旦余談で休憩でもはさみましょうw
みなさんご存知、偏差値ですが、ここまで求めた値から出すことができます

頭の良さそうなEさんの英語のテストの偏差値を求めてみましょう

// ((Eさんの点数 - 平均) / 標準偏差) × 10 + 50
((92 - 60) / 19.87) × 10 + 50 = 66.10

偏差値はご存知の通り、真ん中が50なので頭が良いですね:blush:
一応、簡単に解説すると、

  • + 50 -> 値の中心を50にします
  • × 10 -> 幅を10までとります

幅を10にするというのは、偏差値40平均 - 標準偏差偏差値60平均 + 標準偏差の点数になるように調整してます

Swift

偏差値を知りたい時用につくりました

func deviationValue(_ array:[Double],_ value:Double) -> Double {
	return ((value - average(array)) / standardDeviation(array)) * 10 + 50
}

共分散

またしても聞きなれない言葉がw
各値の分布を数値化してくれてると考えて大丈夫かと思います....
各テストの偏差の積の平均で求められます(平均ではなく合計を個数 - 1で割ることもあるそうです)

// (英語のテストの偏差) × (国語のテストの偏差)
(40 - 60) × (38 - 64) = 520
(50 - 60) × (65 - 64) = -10
(44 - 60) × (40 - 64) = 384
(74 - 60) × (87 - 64) = 322
(92 - 60) × (90 - 64) = 832

(520 + (-10) + 384 + 322 + 832) ÷ 5 = 409.6

Swift

2つのデータ配列を受け取れるように引数を2つとります
また、2つの配列の要素の個数が違う場合は、0を返すようにしてあります

func covariance(_ array1:[Double],_ array2:[Double]) -> Double {
	let deviation1 = deviation(array1)
	let deviation2 = deviation(array2)
	if deviation1.count != deviation2.count {
		return 0
	} 
	return deviation1.enumerated().reduce(0) { (result, value) -> Double in
		result + value.element * deviation2[value.offset]
	} / Double(deviation1.count)
}

相関係数

やっと相関係数を求めます
おまたせしました
共分散各標準偏差を使用します

// 英語のテストの標準偏差:19.87
// 国語のテストの標準偏差:22.17
// 共分散:409.6
// 共分散 ÷ (英語のテストの標準偏差 × 国語のテストの標準偏差)
409.6 ÷ (19.87 × 22.17) = 0.92

相関関数は、-1以上1以下になります

Swift

今まで作ったメソッドを使えば簡単ですねw

func correlationCoefficient(_ array1:[Double],_ array2:[Double]) -> Double {
	return covariance(array1, array2) / (standardDeviation(array1) * standardDeviation(array2))
}

相関係数の意味

相関係数を求めることまではできましたね
しかし、ただ相関係数が0.92だよと言われてもぽかんですよねw
そこで相関係数の持つ意味を解説していきたいと思います(簡単にですが)

相関係数をrとして、下の表に表します

相関係数の値 2つの事柄の関係
r = 1 完全な正の関係がある
0.7 <= r < 1 強い正の関係がある
0.4 <= r < 0.7 やや強い正の関係がある
0.2 <= r < 0.4 やや正の関係がある
相関係数の値 2つの事柄の関係
-0.2 < r < 0.2 ほとんど関係がない
r = 0 完全に関係ない
相関係数の値 2つの事柄の関係
-0.4 < r <= -0.2 やや負の関係がある
-0.7 < r <= 0.4 やや強い負の関係がある
-1 < r <= 0.7 強い負の関係がある
r = -1 完全な負の関係がある

今回の例題でいうと、

  • 正の関係というのは、英語の点数が高い人は国語の点数も高い人が多い
  • 負の関係というのは、英語の点数が高い人は国語の点数は低い人が多い

という関係になります。
r=1で完全な正の関係があるという場合は、英語の点数が高い人は確実に国語の点数も高いとなります

今回は、正の関係になるように例題を作ったのですが、0.92と予想以上に相関係数が高くなってしまいましたねw

Swift

最終的な相関係数求めるクラス

import Foundation

let English: [Double] = [40, 50, 44, 74, 92]
let Japanese: [Double] = [38, 65, 40, 87, 90]

class CorrelationCoefficient {
	
	func average(_ array:[Double]) -> Double {
		return array.reduce(0, +) / Double(array.count)
	}
	
	func deviation(_ array:[Double]) -> [Double] {
		let average = self.average(array)
		return array.map({ (value) -> Double in
			value - average
		})
	}
	
	func dispersion(_ array:[Double]) -> Double {
		let deviations = deviation(array)
		return deviations.reduce(0, { (result, value) -> Double in
			result + (value * value)
		}) / Double(deviations.count)
	}
	
	func standardDeviation(_ array:[Double]) -> Double {
		return sqrt(dispersion(array))
	}
	
	func deviationValue(_ array:[Double], value:Double) -> Double {
		return ((value - average(array)) / standardDeviation(array)) * 10 + 50
	}
	
	func deviationValue(_ array:[Double],_ value:Double) -> Double {
		return ((value - average(array)) / standardDeviation(array)) * 10 + 50
	}

	func covariance(_ array1:[Double],_ array2:[Double]) -> Double {
		let deviation1 = deviation(array1)
		let deviation2 = deviation(array2)
		return deviation1.enumerated().reduce(0) { (result, value) -> Double in
			result + value.element * deviation2[value.offset]
		} / Double(deviation1.count)
	}
	
	func correlationCoefficient(_ array1:[Double],_ array2:[Double]) -> Double {
		return covariance(array1, array2) / (standardDeviation(array1) * standardDeviation(array2))
	}
}

// Usage
let correlationCoefficient = CorrelationCoefficient()
correlationCoefficient.correlationCoefficient(English, Japanese) // 0.92

参考

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?