/// /// 二つの集合の相関係数を求める。二つのシーケンスの先頭から順番にペアとして要素を取り出し、要素数の多いシーケンスの残りの要素は無視される。 /// 計算式にはピアソンの積率相関係数を用いている。 /// 例外: ArgumentNullException 引数がnullシーケンス。 /// DivideByZeroException 引数が空のシーケンス。 /// /// 集合1 /// 集合2 /// 相関係数 public static double CorrelationCoefficient(this IEnumerable List1, IEnumerable List2) { if (List1 == null) throw new ArgumentNullException("引数List1がnullです。"); if (List2 == null) throw new ArgumentNullException("引数List2がnullです。"); var calcMember = List1.Zip(List2, (x, y) => new { x, y }).ToArray(); //入力された二つのシーケンスを合流して、(x, y)の一対のデーターになった配列に変換する。 //多い方の余った要素は無視される。 if (calcMember.Length == 0) { //要素数がゼロなら例外発生。 StringBuilder sb = new StringBuilder("計算する要素数がゼロです。"); if (List1.Count() == 0) sb.Append("引数List1が空のシーケンスです。"); if (List1.Count() == 0) sb.Append("引数List2が空のシーケンスです。"); throw new DivideByZeroException(sb.ToString()); } ///ピアソンの積率相関係数を計算 /// SIGMA((xi-ax)(yi-ay)) / SQRT(SIGMA((xi-ax)^2) / SQRT(SIGMA((yi-ya)^2)) var ax = calcMember.Select(r => r.x).Average(); var ay = calcMember.Select(r => r.y).Average(); var result = calcMember .Select(r => new { xi = r.x - ax, yi = r.y - ay }) .Select(r => new { a = r.xi * r.yi, b = r.xi * r.xi, c = r.yi * r.yi }) .Aggregate((t, i) => new { a = t.a + i.a, b = t.b + i.b, c = t.c + i.c }); return result.a / Math.Sqrt(result.b) / Math.Sqrt(result.c); }