diff --git a/src/AiDotNet.csproj b/src/AiDotNet.csproj index 4b36453c1..e0663f08f 100644 --- a/src/AiDotNet.csproj +++ b/src/AiDotNet.csproj @@ -1,24 +1,25 @@  - net8.0 - enable - enable - True - 0.0.1-preview - Ai for .Net - This is a preview library that will eventually showcase the latest and greatest in ai breakthroughs and bring them to the .net community - Ooples Finance - ooples - Ooples Finance LLC 2023 - https://github.com/ooples/AiDotNet - git - https://github.com/ooples/AiDotNet - ai; regression; machine learning; artificial; intelligence; machine; chatgpt; learning; algorithm; algo; chatgpt-4 - Apache-2.0 - True - Favicon.jpg - README.md + net8.0;net7.0;net6.0;netstandard2.0;netstandard2.1;net48 + enable + enable + True + 0.0.1-preview + Ai for .Net + This is a preview library that will eventually showcase the latest and greatest in ai breakthroughs and bring them to the .net community + Ooples Finance + ooples + Ooples Finance LLC 2023 + https://github.com/ooples/AiDotNet + git + https://github.com/ooples/AiDotNet + ai; regression; machine learning; artificial; intelligence; machine; chatgpt; learning; algorithm; algo; chatgpt-4 + Apache-2.0 + True + latest + Favicon.jpg + README.md diff --git a/src/Interfaces/IMetrics.cs b/src/Interfaces/IMetrics.cs index 7502c981c..701737fdc 100644 --- a/src/Interfaces/IMetrics.cs +++ b/src/Interfaces/IMetrics.cs @@ -5,4 +5,18 @@ public abstract class IMetrics internal abstract double CalculateMeanSquaredError(); internal abstract double CalculateRootMeanSquaredError(); + + internal abstract double CalculateR2(); + + internal abstract double CalculateAdjustedR2(double r2); + + internal abstract double CalculateAverageStandardError(); + + internal abstract double CalculatePredictionStandardError(); + + internal abstract double CalculateAverageStandardDeviation(); + + internal abstract double CalculatePredictionStandardDeviation(); + + internal abstract int CalculateDegreesOfFreedom(); } \ No newline at end of file diff --git a/src/Metrics/Metrics.cs b/src/Metrics/Metrics.cs index 6b1d09352..d0b8598b5 100644 --- a/src/Metrics/Metrics.cs +++ b/src/Metrics/Metrics.cs @@ -2,36 +2,109 @@ namespace AiDotNet; -public class Metrics : IMetrics +public sealed class Metrics : IMetrics { public double MeanSquaredError { get; private set; } public double RootMeanSquaredError { get; private set; } - + public double AdjustedR2 { get; private set; } + public double R2 { get; private set; } + public double PredictionsStandardError { get; private set; } + public double PredictionsStandardDeviation { get; private set; } + public double AverageStandardError { get; private set; } + public double AverageStandardDeviation { get; private set; } + public int DegreesOfFreedom { get; private set; } + private double[] _oosPredictions { get; } + private double _oosPredictionsAvg { get; } private double[] _oosActualValues { get; } + private double _oosActualValuesAvg { get; } + private int _paramsCount { get; } + private int _sampleSize { get; } + private double _residualSumOfSquares { get; set; } + private double _totalSumOfSquares { get; set; } - public Metrics(double[] OosPredictions, double[] OosActualValues) + public Metrics(double[] OosPredictions, double[] OosActualValues, int paramCount) { _oosPredictions = OosPredictions; + _oosPredictionsAvg = _oosPredictions.Average(); _oosActualValues = OosActualValues; + _oosActualValuesAvg = _oosActualValues.Average(); + _paramsCount = paramCount; + _sampleSize = _oosPredictions.Length; + DegreesOfFreedom = CalculateDegreesOfFreedom(); + R2 = CalculateR2(); + AdjustedR2 = CalculateAdjustedR2(R2); + AverageStandardDeviation = CalculateAverageStandardDeviation(); + PredictionsStandardDeviation = CalculatePredictionStandardDeviation(); + AverageStandardError = CalculateAverageStandardError(); + PredictionsStandardError = CalculatePredictionStandardError(); MeanSquaredError = CalculateMeanSquaredError(); RootMeanSquaredError = CalculateRootMeanSquaredError(); } - internal sealed override double CalculateMeanSquaredError() + internal override double CalculateMeanSquaredError() + { + return _residualSumOfSquares / _sampleSize; + } + + internal override double CalculateRootMeanSquaredError() + { + return MeanSquaredError >= 0 ? Math.Sqrt(MeanSquaredError) : 0; + } + + internal override double CalculateR2() { - double sum = 0; - for (var i = 0; i < _oosPredictions.Length; i++) + double residualSumSquares = 0, totalSumSquares = 0; + for (int i = 0; i < _sampleSize; i++) { - sum += Math.Pow(_oosActualValues[i] - _oosPredictions[i], 2); + residualSumSquares += Math.Pow(_oosActualValues[i] - _oosPredictions[i], 2); + totalSumSquares += Math.Pow(_oosActualValues[i] - _oosActualValuesAvg, 2); } - return sum / _oosPredictions.Length; + // We are saving these values for later reuse + _residualSumOfSquares = residualSumSquares; + _totalSumOfSquares = totalSumSquares; + + return _totalSumOfSquares != 0 ? 1 - (_residualSumOfSquares / _totalSumOfSquares) : 0; } - internal sealed override double CalculateRootMeanSquaredError() + internal override double CalculateAdjustedR2(double r2) { - return MeanSquaredError >= 0 ? Math.Sqrt(MeanSquaredError) : 0; + return _sampleSize != 1 && DegreesOfFreedom != 1 ? 1 - (1 - Math.Pow(r2, 2)) * (_sampleSize - 1) / (DegreesOfFreedom - 1) : 0; + } + + internal override double CalculateAverageStandardError() + { + return AverageStandardDeviation / Math.Sqrt(_sampleSize); + } + + internal override double CalculatePredictionStandardError() + { + return PredictionsStandardDeviation / Math.Sqrt(_sampleSize); + } + + private static double CalculateStandardDeviation(double avgSumSquares) + { + return avgSumSquares >= 0 ? Math.Sqrt(avgSumSquares) : 0; + } + + internal override double CalculateAverageStandardDeviation() + { + var avgSumSquares = _totalSumOfSquares / _sampleSize; + + return CalculateStandardDeviation(avgSumSquares); + } + + internal override double CalculatePredictionStandardDeviation() + { + var avgSumSquares = _residualSumOfSquares / _sampleSize; + + return CalculateStandardDeviation(avgSumSquares); + } + + internal override int CalculateDegreesOfFreedom() + { + return _sampleSize - _paramsCount; } } \ No newline at end of file diff --git a/src/Regression/SimpleRegression.cs b/src/Regression/SimpleRegression.cs index 66730a6be..51ddb1c36 100644 --- a/src/Regression/SimpleRegression.cs +++ b/src/Regression/SimpleRegression.cs @@ -59,7 +59,7 @@ public SimpleRegression(double[] inputs, double[] outputs, int trainingPctSize = Fit(TrainingInputs, TrainingOutputs); Predictions = Transform(OutOfSampleInputs); - Metrics = new Metrics(Predictions, OutOfSampleOutputs); + Metrics = new Metrics(Predictions, OutOfSampleOutputs, inputs.Rank); } internal sealed override void Fit(double[] x, double[] y) diff --git a/testconsole/AiDotNetTestConsole.csproj b/testconsole/AiDotNetTestConsole.csproj index 90a193471..09818f08f 100644 --- a/testconsole/AiDotNetTestConsole.csproj +++ b/testconsole/AiDotNetTestConsole.csproj @@ -2,9 +2,10 @@ Exe - net8.0 + net8.0;net7.0;net6.0;netstandard2.0;netstandard2.1;net48 enable enable + latest diff --git a/tests/AiDotNetUnitTests.csproj b/tests/AiDotNetUnitTests.csproj index a3c240f93..5b6daeebd 100644 --- a/tests/AiDotNetUnitTests.csproj +++ b/tests/AiDotNetUnitTests.csproj @@ -1,12 +1,12 @@ - + - net8.0 + net8.0;net7.0;net6.0;netstandard2.0;netstandard2.1;net48 enable enable - - false + false true + latest