tee*_*jay 19 .net c# arrays correlation
有两个double值数组,我想计算相关系数(单个double值,就像MS Excel中的CORREL函数一样).C#中有一些简单的单行解决方案吗?
我已经发现了名为Meta Numerics的数学库.根据这个问题,它应该做的工作.这是Meta Numerics相关方法的文档,我没有得到.
可以请某人为我提供简单的代码片段或示例如何使用该库?
注意:最后,我被迫使用一种自定义实现.但是,如果有人在阅读这个问题时知道好的,有良好记录的C#数学库/框架来做到这一点,请不要犹豫,并在回答中发布一个链接.
Dus*_*gen 28
您可以将值放在相同索引的单独列表中,并使用简单的值Zip
.
var fitResult = new FitResult();
var values1 = new List<int>();
var values2 = new List<int>();
var correls = values1.Zip(values2, (v1, v2) =>
fitResult.CorrelationCoefficient(v1, v2));
Run Code Online (Sandbox Code Playgroud)
第二种方法是编写自己的自定义实现(我的速度并未优化):
public double ComputeCoeff(double[] values1, double[] values2)
{
if(values1.Length != values2.Length)
throw new ArgumentException("values must be the same length");
var avg1 = values1.Average();
var avg2 = values2.Average();
var sum1 = values1.Zip(values2, (x1, y1) => (x1 - avg1) * (y1 - avg2)).Sum();
var sumSqr1 = values1.Sum(x => Math.Pow((x - avg1), 2.0));
var sumSqr2 = values2.Sum(y => Math.Pow((y - avg2), 2.0));
var result = sum1 / Math.Sqrt(sumSqr1 * sumSqr2);
return result;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var values1 = new List<double> { 3, 2, 4, 5 ,6 };
var values2 = new List<double> { 9, 7, 12 ,15, 17 };
var result = ComputeCoeff(values1.ToArray(), values2.ToArray());
// 0.997054485501581
Debug.Assert(result.ToString("F6") == "0.997054");
Run Code Online (Sandbox Code Playgroud)
另一种方法是直接使用Excel函数:
var values1 = new List<double> { 3, 2, 4, 5 ,6 };
var values2 = new List<double> { 9, 7, 12 ,15, 17 };
// Make sure to add a reference to Microsoft.Office.Interop.Excel.dll
// and use the namespace
var application = new Application();
var worksheetFunction = application.WorksheetFunction;
var result = worksheetFunction.Correl(values1.ToArray(), values2.ToArray());
Console.Write(result); // 0.997054485501581
Run Code Online (Sandbox Code Playgroud)
Rub*_*ron 20
Math.NET Numerics是一个记录良好的数学库,包含一个Correlation类.它计算了Pearson和Spearman排名相关性:http://numerics.mathdotnet.com/api/MathNet.Numerics.Statistics/Correlation.htm
该库可在非常自由的MIT/X11许可下使用.用它来计算相关系数很简单如下:
using MathNet.Numerics.Statistics;
...
correlation = Correlation.Pearson(arrayOfValues1, arrayOfValues2);
Run Code Online (Sandbox Code Playgroud)
祝好运!
为了计算Pearson乘积矩相关系数
http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient
你可以使用这个简单的代码:
public static Double Correlation(Double[] Xs, Double[] Ys) {
Double sumX = 0;
Double sumX2 = 0;
Double sumY = 0;
Double sumY2 = 0;
Double sumXY = 0;
int n = Xs.Length < Ys.Length ? Xs.Length : Ys.Length;
for (int i = 0; i < n; ++i) {
Double x = Xs[i];
Double y = Ys[i];
sumX += x;
sumX2 += x * x;
sumY += y;
sumY2 += y * y;
sumXY += x * y;
}
Double stdX = Math.Sqrt(sumX2 / n - sumX * sumX / n / n);
Double stdY = Math.Sqrt(sumY2 / n - sumY * sumY / n / n);
Double covariance = (sumXY / n - sumX * sumY / n / n);
return covariance / stdX / stdY;
}
Run Code Online (Sandbox Code Playgroud)
如果您不想使用第三方库,可以使用此帖子中的方法(在此处发布代码进行备份).
public double Correlation(double[] array1, double[] array2)
{
double[] array_xy = new double[array1.Length];
double[] array_xp2 = new double[array1.Length];
double[] array_yp2 = new double[array1.Length];
for (int i = 0; i < array1.Length; i++)
array_xy[i] = array1[i] * array2[i];
for (int i = 0; i < array1.Length; i++)
array_xp2[i] = Math.Pow(array1[i], 2.0);
for (int i = 0; i < array1.Length; i++)
array_yp2[i] = Math.Pow(array2[i], 2.0);
double sum_x = 0;
double sum_y = 0;
foreach (double n in array1)
sum_x += n;
foreach (double n in array2)
sum_y += n;
double sum_xy = 0;
foreach (double n in array_xy)
sum_xy += n;
double sum_xpow2 = 0;
foreach (double n in array_xp2)
sum_xpow2 += n;
double sum_ypow2 = 0;
foreach (double n in array_yp2)
sum_ypow2 += n;
double Ex2 = Math.Pow(sum_x, 2.00);
double Ey2 = Math.Pow(sum_y, 2.00);
return (array1.Length * sum_xy - sum_x * sum_y) /
Math.Sqrt((array1.Length * sum_xpow2 - Ex2) * (array1.Length * sum_ypow2 - Ey2));
}
Run Code Online (Sandbox Code Playgroud)