Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs @ 8276

Last change on this file since 8276 was 8276, checked in by sforsten, 12 years ago

#1292:

  • merged r8034:8179 from trunk
  • added BackgroundWorker
  • added ProgressBar
  • added SpearmansRankCorrelationCoefficientCalculator
  • corrected bug in HoeffdingsDependenceCalculator
  • made some changes in the GUI
File size: 3.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25
26namespace HeuristicLab.Problems.DataAnalysis {
27  public class SpearmansRankCorrelationCoefficientCalculator {
28
29    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
30      double rs = Math.Abs(Spear(originalValues, estimatedValues, out errorState));
31      if (errorState != OnlineCalculatorError.None) return double.NaN;
32      return rs;
33    }
34
35    /// <summary>
36    /// Calculates Spearmans Rank Correlation Coefficient. Source: Numerical Recipes in C.
37    /// </summary>
38    private static double Spear(IEnumerable<double> xs, IEnumerable<double> ys, out OnlineCalculatorError errorState) {
39      double[] xsArr = xs.ToArray();
40      double[] ysArr = ys.ToArray();
41      if (xsArr.Length != ysArr.Length) throw new ArgumentException("The number of elements in xs and ys does not match");
42
43      int n = xsArr.Length;
44      Array.Sort(xsArr, ysArr);
45      double sf = CRank(xsArr);
46      Array.Sort(ysArr, xsArr);
47      double sg = CRank(ysArr);
48
49      double d = 0.0;
50      for (int j = 0; j < n; j++) //Sum the squared difference of ranks.
51        d += Math.Pow(xsArr[j] - ysArr[j], 2);
52
53      double en, en3n, aved, fac, rs; // vard, zd, t, df, probd, probrs;
54      en = n;
55      en3n = en * en * en - en;
56      aved = en3n / 6.0 - (sf + sg) / 12.0;
57      fac = (1.0 - sf / en3n) * (1.0 - sg / en3n);
58      //vard = ((en - 1.0) * en * en * Math.Pow(en + 1.0, 2) / 36.0) * fac;
59      //zd = (d - aved) / Math.Sqrt(vard);
60      //probd = erfcc(Math.Abs(zd) / 1.4142136);
61      rs = (1.0 - (6.0 / en3n) * (d + (sf + sg) / 12.0)) / Math.Sqrt(fac);
62      //fac = (rs + 1.0) * (1.0 - rs);
63      //if (fac > 0.0) {
64      //  t = rs * Math.Sqrt((en - 2.0) / fac);
65      //  df = en - 2.0;
66      //  probrs = betai(0.5 * df, 0.5, df / (df + t * t));
67      //} else {
68      //  probrs = 0.0;
69      //}
70      errorState = OnlineCalculatorError.None;
71      return rs;
72    }
73
74    /// <summary>
75    /// Calculates midranks. Source: Numerical Recipes in C.
76    /// </summary>
77    /// <param name="w">Sorted array of elements, replaces the elements by their rank, including midranking of ties</param>
78    /// <returns></returns>
79    private static double CRank(double[] w) {
80      int i = 0;
81      int n = w.Length;
82      double s = 0.0;
83      double t;
84      while (i < n - 1) {
85        if (w[i + 1] > w[i]) {    // w[i+1] must be larger or equal w[i] as w must be sorted
86          // not a tie
87          w[i] = i + 1;
88          i++;
89        } else {
90          int j;
91          for (j = i + 1; j < n && w[j] <= w[i]; j++) ; // how far does it go (<= effectively means == as w must be sorted)
92          double rank = 0.5 * (i + j - 1);
93          int k;
94          for (k = i; k <= j - 1; k++) w[k] = rank; // set the rank for all tied entries
95          t = j - i;
96          s += t * t * t - t;
97          i = j;
98        }
99      }
100
101      if (i == n - 1) w[n - 1] = n - 1;   // if the last element was not tied, this is its rank
102      return s;
103    }
104  }
105}
Note: See TracBrowser for help on using the repository browser.