天天看點

【原創】開源Math.NET基礎數學類庫使用(11)C#計算相關系數

【原創】開源Math.NET基礎數學類庫使用(11)C#計算相關系數

資料集的基本統計計算是應用數學,以及統計應用中最常用的功能。如計算資料集的均值,方差,标準差,最大值,最小值,熵等等。Math.NET中的MathNet.Numerics.Statistics命名空間就包括了大量的這些統計計算的函數。今天就為大家介紹的是使用Math.NET計算相關系數的類:Correlation。相關系數,或稱線性相關系數、皮氏積矩相關系數(Pearson product-moment correlation coefficient, PPCC)等,是衡量兩個随機變量之間線性相關程度的名額。它由卡爾·皮爾森(Karl Pearson)在1880年代提出[1],現已廣泛地應用于科學的各個領域。 相關系數計算公式中,取值範圍為[-1,1],r0表示正相關,r0表示負相關,|r|表示了變量之間相關程度的高低。特殊地,r=1稱為完全正相關,r=-1稱為完全負相關,r=0稱為不相

               本部落格所有文章分類的總目錄:【總目錄】本部落格博文總目錄-實時更新 

開源Math.NET基礎數學類庫使用總目錄:【目錄】開源Math.NET基礎數學類庫使用總目錄

前言

  資料集的基本統計計算是應用數學,以及統計應用中最常用的功能。如計算資料集的均值,方差,标準差,最大值,最小值,熵等等。Math.NET中的MathNet.Numerics.Statistics命名空間就包括了大量的這些統計計算的函數。今天就為大家介紹的是使用Math.NET計算相關系數的類:Correlation。

  如果本文資源或者顯示有問題,請參考 本文原文位址:http://www.cnblogs.com/asxinyu/p/4301519.html

1.Math.NET計算相關系數的類

  Correlation類在Math.NET在MathNet.Numerics.Statistics的命名空間下:

Correlation,靜态類,計算2個資料集的相關度,如皮爾遜積差相關系數,權重皮爾遜積差相關系數,皮爾遜積差相關矩陣等;

  相關系數的定義如下:

  相關系數,或稱線性相關系數、皮氏積矩相關系數(Pearson product-moment correlation coefficient, PPCC)等,是衡量兩個随機變量之間線性相關程度的名額。它由卡爾·皮爾森(Karl Pearson)在1880年代提出[1],現已廣泛地應用于科學的各個領域。 相關系數計算公式中,取值範圍為[-1,1],r>0表示正相關,r<0表示負相關,|r|表示了變量之間相關程度的高低。特殊地,r=1稱為完全正相關,r=-1稱為完全負相關,r=0稱為不相關。通常|r|大于0.8時,認為兩個變量有很強的線性相關性。

  Correlation類中的相關系數類型,如權重皮爾遜積差相關系數,皮爾遜積差相關矩陣的含義大家自己進行百度或者根據需要選擇閱讀。

2.Correlation的實作

  在介紹其使用之前,還是介紹一下Correlation類型的實作和源碼。該類型是靜态類,其中的靜态方法都是每一個類型的相關系數的計算,是以在使用的時候,根據需要進行調用即可。其包含的内容如下,為了友善大家觀看,已經将其中的注釋翻譯為英文了,也相對于說明吧。

/// <summary>2個資料集的相關度計算類</summary>
public static class Correlation
{
    /// <summary>計算皮爾遜積差相關系數</summary>
    /// <param name="dataA">資料樣本A.</param>
    /// <param name="dataB">資料樣本B.</param>
    /// <returns>傳回皮爾遜積差相關系數.</returns>
    public static double Pearson(IEnumerable<double> dataA, IEnumerable<double> dataB)
    {
        int n = 0;
        double r = 0.0;

        double meanA = 0;
        double meanB = 0;
        double varA = 0;
        double varB = 0;

        using (IEnumerator<double> ieA = dataA.GetEnumerator())
        using (IEnumerator<double> ieB = dataB.GetEnumerator())
        {
            while (ieA.MoveNext())
            {
                if (!ieB.MoveNext())
                {
                    throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
                }

                double currentA = ieA.Current;
                double currentB = ieB.Current;

                double deltaA = currentA - meanA;
                double scaleDeltaA = deltaA/++n;

                double deltaB = currentB - meanB;
                double scaleDeltaB = deltaB/n;

                meanA += scaleDeltaA;
                meanB += scaleDeltaB;

                varA += scaleDeltaA*deltaA*(n - 1);
                varB += scaleDeltaB*deltaB*(n - 1);
                r += (deltaA*deltaB*(n - 1))/n;
            }

            if (ieB.MoveNext())
            {
                throw new ArgumentOutOfRangeException("dataA", Resources.ArgumentArraysSameLength);
            }
        }

        return r/Math.Sqrt(varA*varB);
    }

    /// <summary>計算權重皮爾遜積差相關系數.</summary>
    /// <param name="dataA">資料樣本A.</param>
    /// <param name="dataB">資料樣本B.</param>
    /// <param name="weights">資料權重.</param>
    /// <returns>權重皮爾遜積差相關系數.</returns>
    public static double WeightedPearson(IEnumerable<double> dataA, IEnumerable<double> dataB, IEnumerable<double> weights)
    {
        int n = 0;

        double meanA = 0;
        double meanB = 0;
        double varA = 0;
        double varB = 0;
        double sumWeight = 0;

        double covariance = 0;

        using (IEnumerator<double> ieA = dataA.GetEnumerator())
        using (IEnumerator<double> ieB = dataB.GetEnumerator())
        using (IEnumerator<double> ieW = weights.GetEnumerator())
        {
            while (ieA.MoveNext())
            {
                if (!ieB.MoveNext())
                {
                    throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
                }
                if (!ieW.MoveNext())
                {
                    throw new ArgumentOutOfRangeException("weights", Resources.ArgumentArraysSameLength);
                }
                ++n;

                double xi = ieA.Current;
                double yi = ieB.Current;
                double wi = ieW.Current;

                double temp = sumWeight + wi;

                double deltaX = xi - meanA;
                double rX = deltaX*wi/temp;
                meanA += rX;
                varA += sumWeight*deltaX*rX;

                double deltaY = yi - meanB;
                double rY = deltaY*wi/temp;
                meanB += rY;
                varB += sumWeight*deltaY*rY;

                sumWeight = temp;

                covariance += deltaX*deltaY*(n - 1)*wi/n;
            }
            if (ieB.MoveNext())
            {
                throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
            }
            if (ieW.MoveNext())
            {
                throw new ArgumentOutOfRangeException("weights", Resources.ArgumentArraysSameLength);
            }
        }
        return covariance/Math.Sqrt(varA*varB);
    }

    /// <summary>計算皮爾遜積差相關矩陣</summary>
    /// <param name="vectors">資料矩陣</param>
    /// <returns>皮爾遜積差相關矩陣.</returns>
    public static Matrix<double> PearsonMatrix(params double[][] vectors)
    {
        var m = Matrix<double>.Build.DenseIdentity(vectors.Length);
        for (int i = 0; i < vectors.Length; i++)
        {
            for (int j = i + 1; j < vectors.Length; j++)
            {
                var c = Pearson(vectors[i], vectors[j]);
                m.At(i, j, c);
                m.At(j, i, c);
            }
        }

        return m;
    }

    /// <summary> 計算皮爾遜積差相關矩陣</summary>
    /// <param name="vectors">資料集合.</param>
    /// <returns>皮爾遜積差相關矩陣.</returns>
    public static Matrix<double> PearsonMatrix(IEnumerable<double[]> vectors)
    {
        return PearsonMatrix(vectors as double[][] ?? vectors.ToArray());
    }

    /// <summary>
    /// 斯皮爾曼等級相關系數
    /// </summary>
    /// <param name="dataA">資料集A.</param>
    /// <param name="dataB">資料集B.</param>
    /// <returns>斯皮爾曼等級相關系數.</returns>
    public static double Spearman(IEnumerable<double> dataA, IEnumerable<double> dataB)
    {
        return Pearson(Rank(dataA), Rank(dataB));
    }

    /// <summary>
    /// 斯皮爾曼等級相關矩陣
    /// Computes the Spearman Ranked Correlation matrix.
    /// </summary>
    /// <param name="vectors">資料集.</param>
    /// <returns>斯皮爾曼等級相關矩陣.</returns>
    public static Matrix<double> SpearmanMatrix(params double[][] vectors)
    {
        return PearsonMatrix(vectors.Select(Rank).ToArray());
    }

    /// <summary>計算斯皮爾曼等級相關矩陣</summary>
    /// <param name="vectors">資料集合.</param>
    /// <returns>斯皮爾曼等級相關矩陣.</returns>
    public static Matrix<double> SpearmanMatrix(IEnumerable<double[]> vectors)
    {
        return PearsonMatrix(vectors.Select(Rank).ToArray());
    }

    static double[] Rank(IEnumerable<double> series)
    {
        if (series == null)
        {
            return new double[0];
        }

        // WARNING: do not try to cast series to an array and use it directly,
        // as we need to sort it (inplace operation)

        var data = series.ToArray();
        return ArrayStatistics.RanksInplace(data, RankDefinition.Average);
    }
}      

3.使用案例

  使用非常簡單,看下面代碼,随便生成的一個資料,沒有啥意思,實際中,大家按需進行吧。  

1 //先生成資料集合data
 2 var chiSquare = new ChiSquared(5);
 3 Console.WriteLine(@"2. Generate 1000 samples of the ChiSquare(5) distribution");
 4 var data = new double[1000];
 5 for (var i = 0; i < data.Length; i++)
 6 {
 7     data[i] = chiSquare.Sample();
 8 }
 9 
10 //生成資料集合dataB
11 var chiSquareB = new ChiSquared(2);
12 var dataB = new double[1000];
13 for (var i = 0; i < data.Length; i++)
14 {
15     dataB[i] = chiSquareB.Sample();
16 }
17 
18 // 5. 計算data和dataB的相關系數
19 var r1 =  Correlation.Pearson(data, dataB);
20 var r2 = Correlation.Spearman(data, dataB);      

4.資源

  源碼下載下傳:http://www.cnblogs.com/asxinyu/p/4264638.html

  如果本文資源或者顯示有問題,請參考 本文原文位址:http://www.cnblogs.com/asxinyu/p/4301519.html 

.NET資料挖掘與機器學習,作者部落格:

http://www.cnblogs.com/asxinyu

E-mail:[email protected]

繼續閱讀