forked from tsai/mathnet-numerics
committed by
Christoph Ruegg
4 changed files with 121 additions and 0 deletions
@ -0,0 +1,45 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using MathNet.Numerics.LinearAlgebra.Double; |
||||
|
|
||||
|
namespace MathNet.Numerics.GoodnessOfFit |
||||
|
{ |
||||
|
public class RSquared |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Calculated the R-Squared value given modelled and observed values
|
||||
|
/// </summary>
|
||||
|
/// <param name="modelledValues">The values expected from the modelled</param>
|
||||
|
/// <param name="observedValues">The actual data set values obtained</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static double RSqr(IEnumerable<double> modelledValues, IEnumerable<double> observedValues) |
||||
|
{ |
||||
|
var modelledData = modelledValues as double[] ?? modelledValues.ToArray(); |
||||
|
var observedData = observedValues as double[] ?? observedValues.ToArray(); |
||||
|
var observedDataCount = observedData.Count(); |
||||
|
if ( modelledData.Count() != observedDataCount) |
||||
|
{ |
||||
|
throw new ArgumentException("Dataset length mismatch"); |
||||
|
} |
||||
|
|
||||
|
var observedSum = observedData.Sum(); |
||||
|
var modelledSum = modelledData.Sum(); |
||||
|
|
||||
|
var sumObservedByModelled = 0d; |
||||
|
|
||||
|
for (var itemIndex = 0; itemIndex < observedDataCount; itemIndex++) |
||||
|
{ |
||||
|
sumObservedByModelled += (observedData[itemIndex] * modelledData[itemIndex]); |
||||
|
} |
||||
|
|
||||
|
var sumObservedSquared = observedData.Sum(item => item * item); |
||||
|
var sumModelledSquared = modelledData.Sum(item => item * item); |
||||
|
|
||||
|
return Math.Pow(( observedDataCount * sumObservedByModelled - observedSum * modelledSum ) / |
||||
|
Math.Sqrt((observedDataCount * sumObservedSquared - Math.Pow(observedSum, 2)) |
||||
|
* (observedDataCount * sumModelledSquared - Math.Pow(modelledSum, 2))), 2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using MathNet.Numerics.GoodnessOfFit; |
||||
|
using NUnit.Framework; |
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.GoodnessOfFit |
||||
|
{ |
||||
|
[TestFixture] |
||||
|
public class RSquaredTest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Test the R-squared value of a values with itself
|
||||
|
/// </summary>
|
||||
|
[Test] |
||||
|
public void WhenCalculatingRSquaredOfLinearDistributionWithItselfThenRSquaredIsOne() |
||||
|
{ |
||||
|
var data = new List<double>(); |
||||
|
for (int i = 1; i <= 10; i++) |
||||
|
data.Add(i); |
||||
|
|
||||
|
Assert.That(RSquared.RSqr(data, data), Is.EqualTo(1)); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentException))] |
||||
|
public void WhenGivenTwoDatasetsOfDifferentSizeThenThrowsArgumentException() |
||||
|
{ |
||||
|
var observedData = new List<double>() |
||||
|
{ |
||||
|
23 |
||||
|
,9 |
||||
|
,5 |
||||
|
,7 |
||||
|
,10 |
||||
|
,5 |
||||
|
,4 |
||||
|
,1 |
||||
|
,2 |
||||
|
,1 |
||||
|
}; |
||||
|
|
||||
|
var modelledData = new List<double>() |
||||
|
{ |
||||
|
8 |
||||
|
,9 |
||||
|
,10 |
||||
|
}; |
||||
|
|
||||
|
RSquared.RSqr(modelledData, observedData); |
||||
|
|
||||
|
Assert.Fail("Expected ArgumentException exception wasn't thrown"); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void WhenCalculatingRSquaredOfUnevenDistributionWithLInearDistributionThenRSquaredIsCalculated() |
||||
|
{ |
||||
|
var observedData = new List<double>() |
||||
|
{ |
||||
|
1, 2.3, 3.1, 4.8, 5.6, 6.3 |
||||
|
}; |
||||
|
|
||||
|
var modelledData = new List<double>() |
||||
|
{ |
||||
|
2.6, 2.8, 3.1, 4.7, 5.1, 5.3 |
||||
|
}; |
||||
|
|
||||
|
Assert.That(Math.Round(RSquared.RSqr(modelledData, observedData), 11), Is.EqualTo(Math.Round(0.94878520708673d, 11))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue