Browse Source

GoodnessOfFit: benchmarking indicates pearson correlation is twice as fast

optimization-3
Christoph Ruegg 13 years ago
parent
commit
3ba8773b30
  1. 37
      src/Numerics/GoodnessOfFit.cs
  2. 2
      src/Numerics/Numerics.csproj
  3. 12
      src/UnitTests/GoodnessOfFit/RSquaredTest.cs

37
src/Numerics/GoodnessOfFit/RSquared.cs → src/Numerics/GoodnessOfFit.cs

@ -1,4 +1,4 @@
// <copyright file="RSquared.cs"> // <copyright file="GoodnessOfFit.cs">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
@ -26,13 +26,12 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using MathNet.Numerics.Statistics;
namespace MathNet.Numerics.GoodnessOfFit namespace MathNet.Numerics
{ {
public static class RSquared public static class GoodnessOfFit
{ {
/// <summary> /// <summary>
/// Calculated the R-Squared value given modelled and observed values /// Calculated the R-Squared value given modelled and observed values
@ -40,32 +39,10 @@ namespace MathNet.Numerics.GoodnessOfFit
/// <param name="modelledValues">The values expected from the modelled</param> /// <param name="modelledValues">The values expected from the modelled</param>
/// <param name="observedValues">The actual data set values obtained</param> /// <param name="observedValues">The actual data set values obtained</param>
/// <returns></returns> /// <returns></returns>
public static double RSqr(IEnumerable<double> modelledValues, IEnumerable<double> observedValues) public static double RSquared(IEnumerable<double> modelledValues, IEnumerable<double> observedValues)
{ {
var modelledData = modelledValues as double[] ?? modelledValues.ToArray(); var corr = Correlation.Pearson(modelledValues, observedValues);
var observedData = observedValues as double[] ?? observedValues.ToArray(); return corr * corr;
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);
} }
} }
} }

2
src/Numerics/Numerics.csproj

@ -87,7 +87,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="GoodnessOfFit\RSquared.cs" /> <Compile Include="GoodnessOfFit.cs" />
<Compile Include="Precision.Comparison.cs" /> <Compile Include="Precision.Comparison.cs" />
<Compile Include="Precision.Equality.cs" /> <Compile Include="Precision.Equality.cs" />
<Compile Include="Distributions\Bernoulli.cs" /> <Compile Include="Distributions\Bernoulli.cs" />

12
src/UnitTests/GoodnessOfFit/RSquaredTest.cs

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics.GoodnessOfFit;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.GoodnessOfFit namespace MathNet.Numerics.UnitTests.GoodnessOfFit
@ -21,11 +17,11 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
for (int i = 1; i <= 10; i++) for (int i = 1; i <= 10; i++)
data.Add(i); data.Add(i);
Assert.That(RSquared.RSqr(data, data), Is.EqualTo(1)); Assert.That(Numerics.GoodnessOfFit.RSquared(data, data), Is.EqualTo(1));
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void WhenGivenTwoDatasetsOfDifferentSizeThenThrowsArgumentException() public void WhenGivenTwoDatasetsOfDifferentSizeThenThrowsArgumentException()
{ {
var observedData = new List<double>() var observedData = new List<double>()
@ -49,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
,10 ,10
}; };
RSquared.RSqr(modelledData, observedData); Numerics.GoodnessOfFit.RSquared(modelledData, observedData);
Assert.Fail("Expected ArgumentException exception wasn't thrown"); Assert.Fail("Expected ArgumentException exception wasn't thrown");
} }
@ -67,7 +63,7 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
2.6, 2.8, 3.1, 4.7, 5.1, 5.3 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))); Assert.That(Math.Round(Numerics.GoodnessOfFit.RSquared(modelledData, observedData), 11), Is.EqualTo(Math.Round(0.94878520708673d, 11)));
} }
} }
} }

Loading…
Cancel
Save