From d5115b5227aa6e79306dfcad62cf663c6320c4f9 Mon Sep 17 00:00:00 2001 From: mdabros Date: Sun, 16 Feb 2025 20:41:15 +0100 Subject: [PATCH 01/42] Add SharpLearning.Benchmarks --- SharpLearning.sln | 6 +++ .../DecisionTreeLearnerBenchmarks.cs | 44 +++++++++++++++++++ .../SharpLearning.Benchmarks.csproj | 24 ++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs create mode 100644 src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj diff --git a/SharpLearning.sln b/SharpLearning.sln index 5f580ccb..ba8e45cb 100644 --- a/SharpLearning.sln +++ b/SharpLearning.sln @@ -84,6 +84,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2204FA16-973 src\SourceLink.GitHub.props = src\SourceLink.GitHub.props EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLearning.Benchmarks", "src\SharpLearning.Benchmarks\SharpLearning.Benchmarks.csproj", "{81B3AA72-5F95-956D-C168-AE856C226E15}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -198,6 +200,10 @@ Global {FFD79827-ED40-47EB-9CB8-2E683DEA3606}.Debug|Any CPU.Build.0 = Debug|Any CPU {FFD79827-ED40-47EB-9CB8-2E683DEA3606}.Release|Any CPU.ActiveCfg = Release|Any CPU {FFD79827-ED40-47EB-9CB8-2E683DEA3606}.Release|Any CPU.Build.0 = Release|Any CPU + {81B3AA72-5F95-956D-C168-AE856C226E15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81B3AA72-5F95-956D-C168-AE856C226E15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81B3AA72-5F95-956D-C168-AE856C226E15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81B3AA72-5F95-956D-C168-AE856C226E15}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs new file mode 100644 index 00000000..01bd52a0 --- /dev/null +++ b/src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs @@ -0,0 +1,44 @@ +using System; +using System.Linq; +using BenchmarkDotNet.Attributes; +using SharpLearning.Common.Interfaces; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; + +namespace SharpLearning.Benchmarks; + +[MemoryDiagnoser] +public class DecisionTreeLearnerBenchmarks +{ + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + + ILearner m_learner; + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = GenerateData(Rows, 1, seed); + var features = GenerateData(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + + // Use default parameters. + m_learner = new RegressionDecisionTreeLearner(); + } + + [Benchmark] + public void RegressionDecisionTreeLearner_Learn() + { + m_learner.Learn(m_features, m_targets); + } + + public static double[] GenerateData(int rows, int cols, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.NextDouble()).ToArray(); + } +} diff --git a/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj new file mode 100644 index 00000000..60bdad53 --- /dev/null +++ b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj @@ -0,0 +1,24 @@ + + + + $(LibraryTargetFramework) + false + pdbonly + true + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + From f01219c7cd9cba217f087429471eb9572b61ff93 Mon Sep 17 00:00:00 2001 From: mdabros Date: Sun, 16 Feb 2025 21:04:52 +0100 Subject: [PATCH 02/42] Add SharpLearning.Benchmarks with RegressionDecisionTreeLearnerBenchmark --- src/Directory.Build.props | 1 + ...RegressionDecisionTreeLearnerBenchmark.cs} | 8 ++++---- .../SharpLearning.Benchmarks.csproj | 3 ++- src/SharpLearning.Benchmarks/program.cs | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) rename src/SharpLearning.Benchmarks/{DecisionTreeLearnerBenchmarks.cs => RegressionDecisionTreeLearnerBenchmark.cs} (86%) create mode 100644 src/SharpLearning.Benchmarks/program.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 4a5cd026..b3baaa71 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,6 +15,7 @@ netstandard2.0 net8 + $(TestTargetFramework) 12.0 true diff --git a/src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs similarity index 86% rename from src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs rename to src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs index 01bd52a0..2bf26135 100644 --- a/src/SharpLearning.Benchmarks/DecisionTreeLearnerBenchmarks.cs +++ b/src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs @@ -8,10 +8,10 @@ namespace SharpLearning.Benchmarks; [MemoryDiagnoser] -public class DecisionTreeLearnerBenchmarks +public class RegressionDecisionTreeLearnerBenchmark { - const int Rows = 1000; - const int Cols = 10; + const int Rows = 10000; + const int Cols = 50; F64Matrix m_features; double[] m_targets; @@ -30,7 +30,7 @@ public void GlobalSetup() } [Benchmark] - public void RegressionDecisionTreeLearner_Learn() + public void Learn() { m_learner.Learn(m_features, m_targets); } diff --git a/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj index 60bdad53..cf128922 100644 --- a/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj +++ b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj @@ -1,10 +1,11 @@ - $(LibraryTargetFramework) + $(ExecutableTargetFramework) false pdbonly true + Exe diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs new file mode 100644 index 00000000..ca4be518 --- /dev/null +++ b/src/SharpLearning.Benchmarks/program.cs @@ -0,0 +1,19 @@ +// Type 'Program' can be sealed because it has no subtypes in its containing assembly and is not externally visible +#pragma warning disable CA1852 +using System; +using System.Diagnostics; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; +using SharpLearning.Benchmarks; + +[assembly: System.Runtime.InteropServices.ComVisible(false)] + +Action log = t => { Console.WriteLine(t); Trace.WriteLine(t); }; + +log($"{Environment.Version} args: {args.Length}"); + +var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) + .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); + +BenchmarkRunner.Run(typeof(RegressionDecisionTreeLearnerBenchmark), config, args); From 78756229ee8530818b75afdc5eca03cdeeaed473 Mon Sep 17 00:00:00 2001 From: mdabros Date: Sun, 16 Feb 2025 21:24:11 +0100 Subject: [PATCH 03/42] Add more benchmarks --- ...hmark.cs => RegressionLearnerBenchmark.cs} | 12 ++++++----- .../RegressionLearnerBenchmarks.cs | 21 +++++++++++++++++++ .../SharpLearning.Benchmarks.csproj | 3 +++ src/SharpLearning.Benchmarks/program.cs | 4 ++++ 4 files changed, 35 insertions(+), 5 deletions(-) rename src/SharpLearning.Benchmarks/{RegressionDecisionTreeLearnerBenchmark.cs => RegressionLearnerBenchmark.cs} (74%) create mode 100644 src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs diff --git a/src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs similarity index 74% rename from src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs rename to src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs index 2bf26135..8337bd55 100644 --- a/src/SharpLearning.Benchmarks/RegressionDecisionTreeLearnerBenchmark.cs +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs @@ -3,15 +3,17 @@ using BenchmarkDotNet.Attributes; using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; namespace SharpLearning.Benchmarks; [MemoryDiagnoser] -public class RegressionDecisionTreeLearnerBenchmark +public abstract class RegressionLearnerBenchmark( + Func> createLearner) { - const int Rows = 10000; - const int Cols = 50; + readonly Func> m_createLearner = createLearner ?? throw new ArgumentNullException(nameof(createLearner)); + + const int Rows = 1000; + const int Cols = 10; F64Matrix m_features; double[] m_targets; @@ -26,7 +28,7 @@ public void GlobalSetup() m_features = new F64Matrix(features, Rows, Cols); // Use default parameters. - m_learner = new RegressionDecisionTreeLearner(); + m_learner = m_createLearner(); } [Benchmark] diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs new file mode 100644 index 00000000..f82d3dd3 --- /dev/null +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs @@ -0,0 +1,21 @@ +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.RandomForest.Learners; +using SharpLearning.GradientBoost.Learners; + +namespace SharpLearning.Benchmarks; + +public class RegressionDecisionTreeLearnerBenchmark() + : RegressionLearnerBenchmark(() => new RegressionDecisionTreeLearner()); + +public class RegressionAdaboostLearnerBenchmark() + : RegressionLearnerBenchmark(() => new RegressionAdaBoostLearner()); + +public class RegressionRandomForestLearnerBenchmark() + : RegressionLearnerBenchmark(() => new RegressionRandomForestLearner()); + +public class RegressionExtremelyRandomizedLearnerBenchmark() + : RegressionLearnerBenchmark(() => new RegressionExtremelyRandomizedTreesLearner()); + +public class RegressionSquareLossGradientBoostLearnerBenchmark() + : RegressionLearnerBenchmark(() => new RegressionSquareLossGradientBoostLearner()); diff --git a/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj index cf128922..ccb83163 100644 --- a/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj +++ b/src/SharpLearning.Benchmarks/SharpLearning.Benchmarks.csproj @@ -9,8 +9,11 @@ + + + diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index ca4be518..41e9ff50 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -17,3 +17,7 @@ .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); BenchmarkRunner.Run(typeof(RegressionDecisionTreeLearnerBenchmark), config, args); +BenchmarkRunner.Run(typeof(RegressionAdaboostLearnerBenchmark), config, args); +BenchmarkRunner.Run(typeof(RegressionRandomForestLearnerBenchmark), config, args); +BenchmarkRunner.Run(typeof(RegressionExtremelyRandomizedLearnerBenchmark), config, args); +BenchmarkRunner.Run(typeof(RegressionSquareLossGradientBoostLearnerBenchmark), config, args); From 93e28a40d07a8b73372bf6e46c4eb41f7399a8d3 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 20:38:01 +0100 Subject: [PATCH 04/42] refactor --- .../Benchmarks.Regression.cs | 27 +++++++++++++++++++ .../RegressionLearnerBenchmarks.cs | 21 --------------- src/SharpLearning.Benchmarks/program.cs | 10 +++---- 3 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 src/SharpLearning.Benchmarks/Benchmarks.Regression.cs delete mode 100644 src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs b/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs new file mode 100644 index 00000000..d8606575 --- /dev/null +++ b/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs @@ -0,0 +1,27 @@ +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.RandomForest.Learners; +using SharpLearning.GradientBoost.Learners; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + public static partial class Regression + { + public class DecisionTreeLearner() + : RegressionLearnerBenchmark(() => new RegressionDecisionTreeLearner()); + + public class AdaboostLearner() + : RegressionLearnerBenchmark(() => new RegressionAdaBoostLearner()); + + public class RandomForestLearner() + : RegressionLearnerBenchmark(() => new RegressionRandomForestLearner()); + + public class ExtremelyRandomizedTreeLearner() + : RegressionLearnerBenchmark(() => new RegressionExtremelyRandomizedTreesLearner()); + + public class SquareLossGradientBoostLearner() + : RegressionLearnerBenchmark(() => new RegressionSquareLossGradientBoostLearner()); + } +} diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs deleted file mode 100644 index f82d3dd3..00000000 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs +++ /dev/null @@ -1,21 +0,0 @@ -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.AdaBoost.Learners; -using SharpLearning.RandomForest.Learners; -using SharpLearning.GradientBoost.Learners; - -namespace SharpLearning.Benchmarks; - -public class RegressionDecisionTreeLearnerBenchmark() - : RegressionLearnerBenchmark(() => new RegressionDecisionTreeLearner()); - -public class RegressionAdaboostLearnerBenchmark() - : RegressionLearnerBenchmark(() => new RegressionAdaBoostLearner()); - -public class RegressionRandomForestLearnerBenchmark() - : RegressionLearnerBenchmark(() => new RegressionRandomForestLearner()); - -public class RegressionExtremelyRandomizedLearnerBenchmark() - : RegressionLearnerBenchmark(() => new RegressionExtremelyRandomizedTreesLearner()); - -public class RegressionSquareLossGradientBoostLearnerBenchmark() - : RegressionLearnerBenchmark(() => new RegressionSquareLossGradientBoostLearner()); diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 41e9ff50..6c7cf7f1 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,8 +16,8 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -BenchmarkRunner.Run(typeof(RegressionDecisionTreeLearnerBenchmark), config, args); -BenchmarkRunner.Run(typeof(RegressionAdaboostLearnerBenchmark), config, args); -BenchmarkRunner.Run(typeof(RegressionRandomForestLearnerBenchmark), config, args); -BenchmarkRunner.Run(typeof(RegressionExtremelyRandomizedLearnerBenchmark), config, args); -BenchmarkRunner.Run(typeof(RegressionSquareLossGradientBoostLearnerBenchmark), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.Regression.DecisionTreeLearner), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.Regression.AdaboostLearner), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.Regression.RandomForestLearner), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.Regression.ExtremelyRandomizedTreeLearner), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.Regression.SquareLossGradientBoostLearner), config, args); From 587ad64acdb82110889d14a503f326a93d4394f9 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 20:44:35 +0100 Subject: [PATCH 05/42] Add RegressionLearnerBenchmarks --- .../RegressionLearnerBenchmarks.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs new file mode 100644 index 00000000..965a3c07 --- /dev/null +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs @@ -0,0 +1,72 @@ +using System; +using System.Linq; +using BenchmarkDotNet.Attributes; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.GradientBoost.Learners; +using SharpLearning.RandomForest.Learners; + +namespace SharpLearning.Benchmarks; + +[MemoryDiagnoser] +public class RegressionLearnerBenchmarks +{ + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + + // Define learners here. + readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); + readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); + readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); + readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); + readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = GenerateData(Rows, 1, seed); + var features = GenerateData(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + } + + [Benchmark] + public void RegressionDecisionTreeLearner_Learn() + { + m_regressionDecisionTreeLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionAdaBoostLearner_Learn() + { + m_regressionAdaBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionRandomForestLearner_Learn() + { + m_regressionRandomForestLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionExtremelyRandomizedTreesLearner_Learn() + { + m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionSquareLossGradientBoostLearner_Learn() + { + m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); + } + + public static double[] GenerateData(int rows, int cols, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.NextDouble()).ToArray(); + } +} From c126689c0e32c216f5c73623716a0deeb10b723c Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:27:55 +0100 Subject: [PATCH 06/42] Refactor --- .../RegressionLearnerBenchmarks.cs | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs index 965a3c07..06f63c8f 100644 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; +using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; using SharpLearning.GradientBoost.Learners; @@ -17,12 +19,23 @@ public class RegressionLearnerBenchmarks F64Matrix m_features; double[] m_targets; - // Define learners here. - readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); - readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); - readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); - readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); - readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); + [Params( + typeof(RegressionDecisionTreeLearner), + typeof(RegressionAdaBoostLearner), + typeof(RegressionRandomForestLearner), + typeof(RegressionExtremelyRandomizedTreesLearner), + typeof(RegressionSquareLossGradientBoostLearner) + )] + public Type LearnerType; + + static readonly Dictionary>> LearnerFactory = new() + { + { typeof(RegressionDecisionTreeLearner), () => new RegressionDecisionTreeLearner() }, + { typeof(RegressionAdaBoostLearner), () => new RegressionAdaBoostLearner() }, + { typeof(RegressionRandomForestLearner), () => new RegressionRandomForestLearner() }, + { typeof(RegressionExtremelyRandomizedTreesLearner), () => new RegressionExtremelyRandomizedTreesLearner() }, + { typeof(RegressionSquareLossGradientBoostLearner), () => new RegressionSquareLossGradientBoostLearner() }, + }; [GlobalSetup] public void GlobalSetup() @@ -34,36 +47,13 @@ public void GlobalSetup() } [Benchmark] - public void RegressionDecisionTreeLearner_Learn() - { - m_regressionDecisionTreeLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionAdaBoostLearner_Learn() - { - m_regressionAdaBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionRandomForestLearner_Learn() - { - m_regressionRandomForestLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionExtremelyRandomizedTreesLearner_Learn() - { - m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionSquareLossGradientBoostLearner_Learn() + public void Learn() { - m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); + var learner = LearnerFactory[LearnerType](); + learner.Learn(m_features, m_targets); } - public static double[] GenerateData(int rows, int cols, int seed) + static double[] GenerateData(int rows, int cols, int seed) { var random = new Random(seed); return Enumerable.Range(0, rows * cols) From 75cdb6ea7e2404af70446c26a2229b2d18800293 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:29:47 +0100 Subject: [PATCH 07/42] revert --- .../RegressionLearnerBenchmarks.cs | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs index 06f63c8f..965a3c07 100644 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; -using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; using SharpLearning.GradientBoost.Learners; @@ -19,23 +17,12 @@ public class RegressionLearnerBenchmarks F64Matrix m_features; double[] m_targets; - [Params( - typeof(RegressionDecisionTreeLearner), - typeof(RegressionAdaBoostLearner), - typeof(RegressionRandomForestLearner), - typeof(RegressionExtremelyRandomizedTreesLearner), - typeof(RegressionSquareLossGradientBoostLearner) - )] - public Type LearnerType; - - static readonly Dictionary>> LearnerFactory = new() - { - { typeof(RegressionDecisionTreeLearner), () => new RegressionDecisionTreeLearner() }, - { typeof(RegressionAdaBoostLearner), () => new RegressionAdaBoostLearner() }, - { typeof(RegressionRandomForestLearner), () => new RegressionRandomForestLearner() }, - { typeof(RegressionExtremelyRandomizedTreesLearner), () => new RegressionExtremelyRandomizedTreesLearner() }, - { typeof(RegressionSquareLossGradientBoostLearner), () => new RegressionSquareLossGradientBoostLearner() }, - }; + // Define learners here. + readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); + readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); + readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); + readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); + readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); [GlobalSetup] public void GlobalSetup() @@ -47,13 +34,36 @@ public void GlobalSetup() } [Benchmark] - public void Learn() + public void RegressionDecisionTreeLearner_Learn() + { + m_regressionDecisionTreeLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionAdaBoostLearner_Learn() + { + m_regressionAdaBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionRandomForestLearner_Learn() + { + m_regressionRandomForestLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionExtremelyRandomizedTreesLearner_Learn() + { + m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionSquareLossGradientBoostLearner_Learn() { - var learner = LearnerFactory[LearnerType](); - learner.Learn(m_features, m_targets); + m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); } - static double[] GenerateData(int rows, int cols, int seed) + public static double[] GenerateData(int rows, int cols, int seed) { var random = new Random(seed); return Enumerable.Range(0, rows * cols) From 653d5fe46419001959099c01d3837b9a9e66c9fb Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:31:23 +0100 Subject: [PATCH 08/42] rename --- .../RegressionLearnerBenchmarks.cs | 72 ------------------ .../RegressionLearners.cs | 75 +++++++++++++++++++ src/SharpLearning.Benchmarks/program.cs | 6 +- 3 files changed, 76 insertions(+), 77 deletions(-) delete mode 100644 src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs create mode 100644 src/SharpLearning.Benchmarks/RegressionLearners.cs diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs deleted file mode 100644 index 965a3c07..00000000 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmarks.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Linq; -using BenchmarkDotNet.Attributes; -using SharpLearning.AdaBoost.Learners; -using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.GradientBoost.Learners; -using SharpLearning.RandomForest.Learners; - -namespace SharpLearning.Benchmarks; - -[MemoryDiagnoser] -public class RegressionLearnerBenchmarks -{ - const int Rows = 1000; - const int Cols = 10; - F64Matrix m_features; - double[] m_targets; - - // Define learners here. - readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); - readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); - readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); - readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); - readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); - - [GlobalSetup] - public void GlobalSetup() - { - var seed = 42; - m_targets = GenerateData(Rows, 1, seed); - var features = GenerateData(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); - } - - [Benchmark] - public void RegressionDecisionTreeLearner_Learn() - { - m_regressionDecisionTreeLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionAdaBoostLearner_Learn() - { - m_regressionAdaBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionRandomForestLearner_Learn() - { - m_regressionRandomForestLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionExtremelyRandomizedTreesLearner_Learn() - { - m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionSquareLossGradientBoostLearner_Learn() - { - m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); - } - - public static double[] GenerateData(int rows, int cols, int seed) - { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.NextDouble()).ToArray(); - } -} diff --git a/src/SharpLearning.Benchmarks/RegressionLearners.cs b/src/SharpLearning.Benchmarks/RegressionLearners.cs new file mode 100644 index 00000000..072ace09 --- /dev/null +++ b/src/SharpLearning.Benchmarks/RegressionLearners.cs @@ -0,0 +1,75 @@ +using System; +using System.Linq; +using BenchmarkDotNet.Attributes; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.GradientBoost.Learners; +using SharpLearning.RandomForest.Learners; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + [MemoryDiagnoser] + public class RegressionLearners + { + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + + // Define learners here. + readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); + readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); + readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); + readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); + readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = GenerateData(Rows, 1, seed); + var features = GenerateData(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + } + + [Benchmark] + public void RegressionDecisionTreeLearner_Learn() + { + m_regressionDecisionTreeLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionAdaBoostLearner_Learn() + { + m_regressionAdaBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionRandomForestLearner_Learn() + { + m_regressionRandomForestLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionExtremelyRandomizedTreesLearner_Learn() + { + m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionSquareLossGradientBoostLearner_Learn() + { + m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); + } + + public static double[] GenerateData(int rows, int cols, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.NextDouble()).ToArray(); + } + } +} diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 6c7cf7f1..85a50871 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,8 +16,4 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -BenchmarkRunner.Run(typeof(Benchmarks.Regression.DecisionTreeLearner), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.Regression.AdaboostLearner), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.Regression.RandomForestLearner), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.Regression.ExtremelyRandomizedTreeLearner), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.Regression.SquareLossGradientBoostLearner), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From baf3d30a7166d92d5c8b96f7db47b8d979c3fb88 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:32:07 +0100 Subject: [PATCH 09/42] rename --- .../{RegressionLearners.cs => Benchmarks.RegressionLearners.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/SharpLearning.Benchmarks/{RegressionLearners.cs => Benchmarks.RegressionLearners.cs} (100%) diff --git a/src/SharpLearning.Benchmarks/RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs similarity index 100% rename from src/SharpLearning.Benchmarks/RegressionLearners.cs rename to src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs From 947b7fab9c96ba30f9c45364c8da764a2982f08e Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:35:38 +0100 Subject: [PATCH 10/42] Add ClassificationLearners --- .../Benchmarks.ClassificationLearners.cs | 74 +++++++++++++++++++ src/SharpLearning.Benchmarks/program.cs | 1 + 2 files changed, 75 insertions(+) create mode 100644 src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs new file mode 100644 index 00000000..d49365f4 --- /dev/null +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -0,0 +1,74 @@ +using System; +using System.Linq; +using BenchmarkDotNet.Attributes; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.RandomForest.Learners; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + [MemoryDiagnoser] + public class ClassificationLearners + { + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + + // Define learners here. + readonly ClassificationDecisionTreeLearner m_classificationDecisionTreeLearner = new(); + readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); + readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); + readonly ClassificationExtremelyRandomizedTreesLearner m_classificationExtremelyRandomizedTreesLearner = new(); + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = GenerateIntegers(Rows, 1, min: 0, max: 10, seed); + var features = GenerateDoubles(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + } + + [Benchmark] + public void ClassificationDecisionTreeLearner_Learn() + { + m_classificationDecisionTreeLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void ClassificationAdaBoostLearner_Learn() + { + m_classificationAdaBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void ClassificationRandomForestLearner_Learn() + { + m_classificationRandomForestLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void ClassificationExtremelyRandomizedTreesLearner_Learn() + { + m_classificationExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); + } + + public static double[] GenerateDoubles(int rows, int cols, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.NextDouble()).ToArray(); + } + + public static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.Next(min, max)).Select(i => (double)i).ToArray(); + } + } +} diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 85a50871..60eeefae 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,4 +16,5 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); +BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From c5cace24794c313416c415d8cb140efea89fa591 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:39:43 +0100 Subject: [PATCH 11/42] Refactor --- .../Benchmarks.ClassificationLearners.cs | 25 +++++-------------- .../Benchmarks.RegressionLearners.cs | 15 +++-------- src/SharpLearning.Benchmarks/DataGenerator.cs | 21 ++++++++++++++++ .../RegressionLearnerBenchmark.cs | 12 ++------- src/SharpLearning.Benchmarks/program.cs | 2 +- 5 files changed, 33 insertions(+), 42 deletions(-) create mode 100644 src/SharpLearning.Benchmarks/DataGenerator.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index d49365f4..4f6c883f 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; @@ -15,6 +13,8 @@ public class ClassificationLearners { const int Rows = 1000; const int Cols = 10; + const int MinTargetValue = 0; + const int MaxTargetValue = 10; F64Matrix m_features; double[] m_targets; @@ -28,8 +28,9 @@ public class ClassificationLearners public void GlobalSetup() { var seed = 42; - m_targets = GenerateIntegers(Rows, 1, min: 0, max: 10, seed); - var features = GenerateDoubles(Rows, Cols, seed); + m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, + MinTargetValue, MaxTargetValue, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); } @@ -56,19 +57,5 @@ public void ClassificationExtremelyRandomizedTreesLearner_Learn() { m_classificationExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); } - - public static double[] GenerateDoubles(int rows, int cols, int seed) - { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.NextDouble()).ToArray(); - } - - public static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) - { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.Next(min, max)).Select(i => (double)i).ToArray(); - } } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 072ace09..bd4dfc36 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; @@ -30,8 +28,8 @@ public class RegressionLearners public void GlobalSetup() { var seed = 42; - m_targets = GenerateData(Rows, 1, seed); - var features = GenerateData(Rows, Cols, seed); + m_targets = DataGenerator.GenerateDoubles(Rows, 1, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); } @@ -64,12 +62,5 @@ public void RegressionSquareLossGradientBoostLearner_Learn() { m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); } - - public static double[] GenerateData(int rows, int cols, int seed) - { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.NextDouble()).ToArray(); - } } } diff --git a/src/SharpLearning.Benchmarks/DataGenerator.cs b/src/SharpLearning.Benchmarks/DataGenerator.cs new file mode 100644 index 00000000..928e166b --- /dev/null +++ b/src/SharpLearning.Benchmarks/DataGenerator.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +namespace SharpLearning.Benchmarks; + +public static class DataGenerator +{ + public static double[] GenerateDoubles(int rows, int cols, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.NextDouble()).ToArray(); + } + + public static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) + { + var random = new Random(seed); + return Enumerable.Range(0, rows * cols) + .Select(i => random.Next(min, max)).Select(i => (double)i).ToArray(); + } +} diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs index 8337bd55..e50474ab 100644 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs +++ b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using BenchmarkDotNet.Attributes; using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; @@ -23,8 +22,8 @@ public abstract class RegressionLearnerBenchmark( public void GlobalSetup() { var seed = 42; - m_targets = GenerateData(Rows, 1, seed); - var features = GenerateData(Rows, Cols, seed); + m_targets = DataGenerator.GenerateDoubles(Rows, 1, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); // Use default parameters. @@ -36,11 +35,4 @@ public void Learn() { m_learner.Learn(m_features, m_targets); } - - public static double[] GenerateData(int rows, int cols, int seed) - { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.NextDouble()).ToArray(); - } } diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 60eeefae..3a341caf 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -17,4 +17,4 @@ .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From 2c34a9c24122acb1831016f79f1b40eec0604fd5 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:39:58 +0100 Subject: [PATCH 12/42] enable --- src/SharpLearning.Benchmarks/program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 3a341caf..60eeefae 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -17,4 +17,4 @@ .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From f9e708524ba248a80791821383542ae6a365f0ad Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:44:28 +0100 Subject: [PATCH 13/42] Add ClassificationBinomialGradientBoostLearner --- .../Benchmarks.ClassificationLearners.cs | 8 ++++ .../Benchmarks.Regression.cs | 27 ------------- .../RegressionLearnerBenchmark.cs | 38 ------------------- 3 files changed, 8 insertions(+), 65 deletions(-) delete mode 100644 src/SharpLearning.Benchmarks/Benchmarks.Regression.cs delete mode 100644 src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index 4f6c883f..a433c55c 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -2,6 +2,7 @@ using SharpLearning.AdaBoost.Learners; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; +using SharpLearning.GradientBoost.Learners; using SharpLearning.RandomForest.Learners; namespace SharpLearning.Benchmarks; @@ -23,6 +24,7 @@ public class ClassificationLearners readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); readonly ClassificationExtremelyRandomizedTreesLearner m_classificationExtremelyRandomizedTreesLearner = new(); + readonly ClassificationBinomialGradientBoostLearner m_classificationBinomialGradientBoostLearner = new(); [GlobalSetup] public void GlobalSetup() @@ -57,5 +59,11 @@ public void ClassificationExtremelyRandomizedTreesLearner_Learn() { m_classificationExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); } + + [Benchmark] + public void ClassificationBinomialGradientBoostLearner_Learn() + { + m_classificationBinomialGradientBoostLearner.Learn(m_features, m_targets); + } } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs b/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs deleted file mode 100644 index d8606575..00000000 --- a/src/SharpLearning.Benchmarks/Benchmarks.Regression.cs +++ /dev/null @@ -1,27 +0,0 @@ -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.AdaBoost.Learners; -using SharpLearning.RandomForest.Learners; -using SharpLearning.GradientBoost.Learners; - -namespace SharpLearning.Benchmarks; - -public static partial class Benchmarks -{ - public static partial class Regression - { - public class DecisionTreeLearner() - : RegressionLearnerBenchmark(() => new RegressionDecisionTreeLearner()); - - public class AdaboostLearner() - : RegressionLearnerBenchmark(() => new RegressionAdaBoostLearner()); - - public class RandomForestLearner() - : RegressionLearnerBenchmark(() => new RegressionRandomForestLearner()); - - public class ExtremelyRandomizedTreeLearner() - : RegressionLearnerBenchmark(() => new RegressionExtremelyRandomizedTreesLearner()); - - public class SquareLossGradientBoostLearner() - : RegressionLearnerBenchmark(() => new RegressionSquareLossGradientBoostLearner()); - } -} diff --git a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs b/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs deleted file mode 100644 index e50474ab..00000000 --- a/src/SharpLearning.Benchmarks/RegressionLearnerBenchmark.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using BenchmarkDotNet.Attributes; -using SharpLearning.Common.Interfaces; -using SharpLearning.Containers.Matrices; - -namespace SharpLearning.Benchmarks; - -[MemoryDiagnoser] -public abstract class RegressionLearnerBenchmark( - Func> createLearner) -{ - readonly Func> m_createLearner = createLearner ?? throw new ArgumentNullException(nameof(createLearner)); - - const int Rows = 1000; - const int Cols = 10; - F64Matrix m_features; - double[] m_targets; - - ILearner m_learner; - - [GlobalSetup] - public void GlobalSetup() - { - var seed = 42; - m_targets = DataGenerator.GenerateDoubles(Rows, 1, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); - - // Use default parameters. - m_learner = m_createLearner(); - } - - [Benchmark] - public void Learn() - { - m_learner.Learn(m_features, m_targets); - } -} From 71b08c1c547e288d924f5a7065cbee1b50b9aa11 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 21:45:42 +0100 Subject: [PATCH 14/42] add comment --- .../Benchmarks.ClassificationLearners.cs | 2 +- src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index a433c55c..81ee0d9c 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -19,7 +19,7 @@ public class ClassificationLearners F64Matrix m_features; double[] m_targets; - // Define learners here. + // Define learners here. Use default parameters for benchmarks. readonly ClassificationDecisionTreeLearner m_classificationDecisionTreeLearner = new(); readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index bd4dfc36..a68ba26a 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -17,7 +17,7 @@ public class RegressionLearners F64Matrix m_features; double[] m_targets; - // Define learners here. + // Define learners here. Use default parameters for benchmarks. readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); @@ -28,7 +28,7 @@ public class RegressionLearners public void GlobalSetup() { var seed = 42; - m_targets = DataGenerator.GenerateDoubles(Rows, 1, seed); + m_targets = DataGenerator.GenerateDoubles(Rows, cols: 1, seed); var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); } From cabd0c8f87c7499819e1c3f9275d79d21656758a Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 22:04:23 +0100 Subject: [PATCH 15/42] increase data size --- .../Benchmarks.ClassificationLearners.cs | 4 ++-- src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index 81ee0d9c..a091760b 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -12,8 +12,8 @@ public static partial class Benchmarks [MemoryDiagnoser] public class ClassificationLearners { - const int Rows = 1000; - const int Cols = 10; + const int Rows = 10000; + const int Cols = 50; const int MinTargetValue = 0; const int MaxTargetValue = 10; F64Matrix m_features; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index a68ba26a..72eaa5ef 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -12,8 +12,8 @@ public static partial class Benchmarks [MemoryDiagnoser] public class RegressionLearners { - const int Rows = 1000; - const int Cols = 10; + const int Rows = 10000; + const int Cols = 50; F64Matrix m_features; double[] m_targets; From e2d15cd7856e02f4a793e80b9e758b8c710f20d3 Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 22:09:45 +0100 Subject: [PATCH 16/42] Add ClassificationModels --- .../Benchmarks.ClassificationModels.cs | 45 +++++++++++++++++++ src/SharpLearning.Benchmarks/program.cs | 5 ++- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs new file mode 100644 index 00000000..91b8960a --- /dev/null +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -0,0 +1,45 @@ +using BenchmarkDotNet.Attributes; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.DecisionTrees.Models; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + [MemoryDiagnoser] + public class ClassificationModels + { + const int Rows = 1000; + const int Cols = 10; + const int MinTargetValue = 0; + const int MaxTargetValue = 10; + F64Matrix m_features; + double[] m_targets; + + // Define learners here. Use default parameters for benchmarks. + readonly ClassificationDecisionTreeLearner m_classificationDecisionTreeLearner = new(); + ClassificationDecisionTreeModel m_classificationDecisionTreeModel; + //readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); + //readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); + //readonly ClassificationExtremelyRandomizedTreesLearner m_classificationExtremelyRandomizedTreesLearner = new(); + //readonly ClassificationBinomialGradientBoostLearner m_classificationBinomialGradientBoostLearner = new(); + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, + MinTargetValue, MaxTargetValue, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + m_classificationDecisionTreeModel = m_classificationDecisionTreeLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void ClassificationDecisionTreeModel_Predict() + { + m_classificationDecisionTreeModel.Predict(m_features); + } + } +} diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 60eeefae..25391271 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,5 +16,6 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.ClassificationModels), config, args); +//BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); +//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From 47d577db75c48530893681beb2c2e07ecd969d8c Mon Sep 17 00:00:00 2001 From: mdabros Date: Mon, 17 Feb 2025 22:10:23 +0100 Subject: [PATCH 17/42] Decrease --- .../Benchmarks.ClassificationLearners.cs | 4 ++-- src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index a091760b..81ee0d9c 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -12,8 +12,8 @@ public static partial class Benchmarks [MemoryDiagnoser] public class ClassificationLearners { - const int Rows = 10000; - const int Cols = 50; + const int Rows = 1000; + const int Cols = 10; const int MinTargetValue = 0; const int MaxTargetValue = 10; F64Matrix m_features; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 72eaa5ef..a68ba26a 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -12,8 +12,8 @@ public static partial class Benchmarks [MemoryDiagnoser] public class RegressionLearners { - const int Rows = 10000; - const int Cols = 50; + const int Rows = 1000; + const int Cols = 10; F64Matrix m_features; double[] m_targets; From 982b5c1deba63742a10ff76ace073cce86df3d9f Mon Sep 17 00:00:00 2001 From: mdabros Date: Fri, 21 Feb 2025 19:49:56 +0100 Subject: [PATCH 18/42] Remove --- .../Benchmarks.ClassificationModels.cs | 45 ------------------- src/SharpLearning.Benchmarks/program.cs | 5 +-- 2 files changed, 2 insertions(+), 48 deletions(-) delete mode 100644 src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs deleted file mode 100644 index 91b8960a..00000000 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ /dev/null @@ -1,45 +0,0 @@ -using BenchmarkDotNet.Attributes; -using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.DecisionTrees.Models; - -namespace SharpLearning.Benchmarks; - -public static partial class Benchmarks -{ - [MemoryDiagnoser] - public class ClassificationModels - { - const int Rows = 1000; - const int Cols = 10; - const int MinTargetValue = 0; - const int MaxTargetValue = 10; - F64Matrix m_features; - double[] m_targets; - - // Define learners here. Use default parameters for benchmarks. - readonly ClassificationDecisionTreeLearner m_classificationDecisionTreeLearner = new(); - ClassificationDecisionTreeModel m_classificationDecisionTreeModel; - //readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); - //readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); - //readonly ClassificationExtremelyRandomizedTreesLearner m_classificationExtremelyRandomizedTreesLearner = new(); - //readonly ClassificationBinomialGradientBoostLearner m_classificationBinomialGradientBoostLearner = new(); - - [GlobalSetup] - public void GlobalSetup() - { - var seed = 42; - m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, - MinTargetValue, MaxTargetValue, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); - m_classificationDecisionTreeModel = m_classificationDecisionTreeLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void ClassificationDecisionTreeModel_Predict() - { - m_classificationDecisionTreeModel.Predict(m_features); - } - } -} diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 25391271..60eeefae 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,6 +16,5 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -BenchmarkRunner.Run(typeof(Benchmarks.ClassificationModels), config, args); -//BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); From 01f68a4b6bec3656e4b75ad3dd5e64d76f0ca67a Mon Sep 17 00:00:00 2001 From: mdabros Date: Fri, 21 Feb 2025 20:36:45 +0100 Subject: [PATCH 19/42] Add comment --- .../Benchmarks.ClassificationLearners.cs | 1 + src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index 81ee0d9c..4dfce601 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -12,6 +12,7 @@ public static partial class Benchmarks [MemoryDiagnoser] public class ClassificationLearners { + // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; const int MinTargetValue = 0; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index a68ba26a..93de8132 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -12,6 +12,7 @@ public static partial class Benchmarks [MemoryDiagnoser] public class RegressionLearners { + // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; F64Matrix m_features; From b1576e1f83b51c7990194c441e55008c5755aa15 Mon Sep 17 00:00:00 2001 From: mdabros Date: Fri, 21 Feb 2025 21:35:37 +0100 Subject: [PATCH 20/42] Add remaining gradient boost learners --- .../Benchmarks.RegressionLearners.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 93de8132..d0b85c69 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -23,6 +23,9 @@ public class RegressionLearners readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); + readonly RegressionAbsoluteLossGradientBoostLearner m_regressionAbsoluteLossGradientBoostLearner = new(); + readonly RegressionHuberLossGradientBoostLearner m_regressionHuberLossGradientBoostLearner = new(); + readonly RegressionQuantileLossGradientBoostLearner m_regressionQuantileLossGradientBoostLearner = new(); readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); [GlobalSetup] @@ -58,6 +61,24 @@ public void RegressionExtremelyRandomizedTreesLearner_Learn() m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); } + [Benchmark] + public void RegressionAbsoluteLossGradientBoostLearner_Learn() + { + m_regressionAbsoluteLossGradientBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionHuberLossGradientBoostLearner_Learn() + { + m_regressionHuberLossGradientBoostLearner.Learn(m_features, m_targets); + } + + [Benchmark] + public void RegressionQuantileLossGradientBoostLearner_Learn() + { + m_regressionQuantileLossGradientBoostLearner.Learn(m_features, m_targets); + } + [Benchmark] public void RegressionSquareLossGradientBoostLearner_Learn() { From 65f7342c7c931278f9aff940d111076b90245729 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 17:30:21 +0100 Subject: [PATCH 21/42] Refactor --- .../Benchmarks.ClassificationLearners.cs | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index 4dfce601..d3b28f93 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -1,5 +1,7 @@ -using BenchmarkDotNet.Attributes; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; +using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; using SharpLearning.GradientBoost.Learners; @@ -21,11 +23,14 @@ public class ClassificationLearners double[] m_targets; // Define learners here. Use default parameters for benchmarks. - readonly ClassificationDecisionTreeLearner m_classificationDecisionTreeLearner = new(); - readonly ClassificationAdaBoostLearner m_classificationAdaBoostLearner = new(); - readonly ClassificationRandomForestLearner m_classificationRandomForestLearner = new(); - readonly ClassificationExtremelyRandomizedTreesLearner m_classificationExtremelyRandomizedTreesLearner = new(); - readonly ClassificationBinomialGradientBoostLearner m_classificationBinomialGradientBoostLearner = new(); + readonly Dictionary> m_learners = new() + { + { nameof(ClassificationDecisionTreeLearner), new ClassificationDecisionTreeLearner() }, + { nameof(ClassificationAdaBoostLearner), new ClassificationAdaBoostLearner() }, + { nameof(ClassificationRandomForestLearner), new ClassificationRandomForestLearner() }, + { nameof(ClassificationExtremelyRandomizedTreesLearner), new ClassificationExtremelyRandomizedTreesLearner() }, + { nameof(ClassificationBinomialGradientBoostLearner), new ClassificationBinomialGradientBoostLearner() }, + }; [GlobalSetup] public void GlobalSetup() @@ -38,33 +43,16 @@ public void GlobalSetup() } [Benchmark] - public void ClassificationDecisionTreeLearner_Learn() - { - m_classificationDecisionTreeLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void ClassificationAdaBoostLearner_Learn() - { - m_classificationAdaBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void ClassificationRandomForestLearner_Learn() + [ArgumentsSource(nameof(GetLearners))] + public void Learn(string learnerName) { - m_classificationRandomForestLearner.Learn(m_features, m_targets); + var learner = m_learners[learnerName]; + learner.Learn(m_features, m_targets); } - [Benchmark] - public void ClassificationExtremelyRandomizedTreesLearner_Learn() - { - m_classificationExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void ClassificationBinomialGradientBoostLearner_Learn() + public IEnumerable GetLearners() { - m_classificationBinomialGradientBoostLearner.Learn(m_features, m_targets); + return m_learners.Keys; } } } From 1f98d65e0cf498ca0c569c4af60c13b0dd380a71 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 17:34:16 +0100 Subject: [PATCH 22/42] Refactor --- .../Benchmarks.RegressionLearners.cs | 70 ++++++------------- 1 file changed, 20 insertions(+), 50 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index d0b85c69..0aaa6d4d 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -1,5 +1,7 @@ -using BenchmarkDotNet.Attributes; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; +using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; using SharpLearning.DecisionTrees.Learners; using SharpLearning.GradientBoost.Learners; @@ -19,14 +21,17 @@ public class RegressionLearners double[] m_targets; // Define learners here. Use default parameters for benchmarks. - readonly RegressionDecisionTreeLearner m_regressionDecisionTreeLearner = new(); - readonly RegressionAdaBoostLearner m_regressionAdaBoostLearner = new(); - readonly RegressionRandomForestLearner m_regressionRandomForestLearner = new(); - readonly RegressionExtremelyRandomizedTreesLearner m_regressionExtremelyRandomizedTreesLearner = new(); - readonly RegressionAbsoluteLossGradientBoostLearner m_regressionAbsoluteLossGradientBoostLearner = new(); - readonly RegressionHuberLossGradientBoostLearner m_regressionHuberLossGradientBoostLearner = new(); - readonly RegressionQuantileLossGradientBoostLearner m_regressionQuantileLossGradientBoostLearner = new(); - readonly RegressionSquareLossGradientBoostLearner m_regressionSquareLossGradientBoostLearner = new(); + readonly Dictionary> m_learners = new() + { + { nameof(RegressionDecisionTreeLearner), new RegressionDecisionTreeLearner() }, + { nameof(RegressionAdaBoostLearner), new RegressionAdaBoostLearner() }, + { nameof(RegressionRandomForestLearner), new RegressionRandomForestLearner() }, + { nameof(RegressionExtremelyRandomizedTreesLearner), new RegressionExtremelyRandomizedTreesLearner() }, + { nameof(RegressionAbsoluteLossGradientBoostLearner), new RegressionAbsoluteLossGradientBoostLearner() }, + { nameof(RegressionHuberLossGradientBoostLearner), new RegressionHuberLossGradientBoostLearner() }, + { nameof(RegressionQuantileLossGradientBoostLearner), new RegressionQuantileLossGradientBoostLearner() }, + { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() } + }; [GlobalSetup] public void GlobalSetup() @@ -38,51 +43,16 @@ public void GlobalSetup() } [Benchmark] - public void RegressionDecisionTreeLearner_Learn() + [ArgumentsSource(nameof(GetLearners))] + public void Learn(string learnerName) { - m_regressionDecisionTreeLearner.Learn(m_features, m_targets); + var learner = m_learners[learnerName]; + learner.Learn(m_features, m_targets); } - [Benchmark] - public void RegressionAdaBoostLearner_Learn() - { - m_regressionAdaBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionRandomForestLearner_Learn() - { - m_regressionRandomForestLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionExtremelyRandomizedTreesLearner_Learn() - { - m_regressionExtremelyRandomizedTreesLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionAbsoluteLossGradientBoostLearner_Learn() - { - m_regressionAbsoluteLossGradientBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionHuberLossGradientBoostLearner_Learn() - { - m_regressionHuberLossGradientBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionQuantileLossGradientBoostLearner_Learn() - { - m_regressionQuantileLossGradientBoostLearner.Learn(m_features, m_targets); - } - - [Benchmark] - public void RegressionSquareLossGradientBoostLearner_Learn() + public IEnumerable GetLearners() { - m_regressionSquareLossGradientBoostLearner.Learn(m_features, m_targets); + return m_learners.Keys; } } } From 580ef00af51d715a918cd2f2e4d710a299ed7b67 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 17:35:00 +0100 Subject: [PATCH 23/42] refactor --- .../Benchmarks.ClassificationLearners.cs | 7 +++---- .../Benchmarks.RegressionLearners.cs | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index d3b28f93..ea4330f6 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; using SharpLearning.Common.Interfaces; @@ -50,9 +51,7 @@ public void Learn(string learnerName) learner.Learn(m_features, m_targets); } - public IEnumerable GetLearners() - { - return m_learners.Keys; - } + public IReadOnlyList GetLearners() => + m_learners.Keys.ToArray(); } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 0aaa6d4d..26f05a21 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using SharpLearning.AdaBoost.Learners; using SharpLearning.Common.Interfaces; @@ -50,9 +51,7 @@ public void Learn(string learnerName) learner.Learn(m_features, m_targets); } - public IEnumerable GetLearners() - { - return m_learners.Keys; - } + public IReadOnlyList GetLearners() => + m_learners.Keys.ToArray(); } } From f5529f725e25ebc62375ad8f9364d809aceaa153 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:06:38 +0100 Subject: [PATCH 24/42] Refactor and add Benchmarks.ClassificationModels --- .../Benchmarks.ClassificationLearners.cs | 13 +---- .../Benchmarks.ClassificationModels.cs | 57 +++++++++++++++++++ .../Benchmarks.RegressionLearners.cs | 16 +----- .../DefaultLearners.cs | 36 ++++++++++++ 4 files changed, 99 insertions(+), 23 deletions(-) create mode 100644 src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs create mode 100644 src/SharpLearning.Benchmarks/DefaultLearners.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index ea4330f6..ac0e2f11 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -15,6 +15,9 @@ public static partial class Benchmarks [MemoryDiagnoser] public class ClassificationLearners { + readonly IReadOnlyDictionary> m_learners = + DefaultLearners.NameToClassificationLearner; + // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; @@ -23,16 +26,6 @@ public class ClassificationLearners F64Matrix m_features; double[] m_targets; - // Define learners here. Use default parameters for benchmarks. - readonly Dictionary> m_learners = new() - { - { nameof(ClassificationDecisionTreeLearner), new ClassificationDecisionTreeLearner() }, - { nameof(ClassificationAdaBoostLearner), new ClassificationAdaBoostLearner() }, - { nameof(ClassificationRandomForestLearner), new ClassificationRandomForestLearner() }, - { nameof(ClassificationExtremelyRandomizedTreesLearner), new ClassificationExtremelyRandomizedTreesLearner() }, - { nameof(ClassificationBinomialGradientBoostLearner), new ClassificationBinomialGradientBoostLearner() }, - }; - [GlobalSetup] public void GlobalSetup() { diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs new file mode 100644 index 00000000..0777d407 --- /dev/null +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.Common.Interfaces; +using SharpLearning.Containers.Matrices; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.GradientBoost.Learners; +using SharpLearning.RandomForest.Learners; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + [MemoryDiagnoser] + public class ClassificationLearnersPredict + { + readonly IReadOnlyDictionary> m_learners = + DefaultLearners.NameToClassificationLearner; + + // Data size for benchmarks. + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + Dictionary> m_models; + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, 0, 2, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + + m_models = new Dictionary>(); + foreach (var learner in m_learners) + { + m_models[learner.Key] = learner.Value.Learn(m_features, m_targets); + } + } + + [Benchmark] + [ArgumentsSource(nameof(GetLearners))] + public void Predict(string learnerName) + { + var model = m_models[learnerName]; + model.Predict(m_features); + } + + public IReadOnlyList GetLearners() => + m_learners.Keys.ToArray(); + } +} diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 26f05a21..c6dc29f3 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -15,25 +15,15 @@ public static partial class Benchmarks [MemoryDiagnoser] public class RegressionLearners { + readonly IReadOnlyDictionary> m_learners = + DefaultLearners.NameToRegressionLearner; + // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; F64Matrix m_features; double[] m_targets; - // Define learners here. Use default parameters for benchmarks. - readonly Dictionary> m_learners = new() - { - { nameof(RegressionDecisionTreeLearner), new RegressionDecisionTreeLearner() }, - { nameof(RegressionAdaBoostLearner), new RegressionAdaBoostLearner() }, - { nameof(RegressionRandomForestLearner), new RegressionRandomForestLearner() }, - { nameof(RegressionExtremelyRandomizedTreesLearner), new RegressionExtremelyRandomizedTreesLearner() }, - { nameof(RegressionAbsoluteLossGradientBoostLearner), new RegressionAbsoluteLossGradientBoostLearner() }, - { nameof(RegressionHuberLossGradientBoostLearner), new RegressionHuberLossGradientBoostLearner() }, - { nameof(RegressionQuantileLossGradientBoostLearner), new RegressionQuantileLossGradientBoostLearner() }, - { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() } - }; - [GlobalSetup] public void GlobalSetup() { diff --git a/src/SharpLearning.Benchmarks/DefaultLearners.cs b/src/SharpLearning.Benchmarks/DefaultLearners.cs new file mode 100644 index 00000000..a0b00032 --- /dev/null +++ b/src/SharpLearning.Benchmarks/DefaultLearners.cs @@ -0,0 +1,36 @@ +using SharpLearning.AdaBoost.Learners; +using SharpLearning.Common.Interfaces; +using SharpLearning.DecisionTrees.Learners; +using SharpLearning.GradientBoost.Learners; +using SharpLearning.RandomForest.Learners; +using System.Collections.Generic; + +namespace SharpLearning.Benchmarks; + +public static class DefaultLearners +{ + // Define classification learners here. Use default parameters for benchmarks. + public static readonly IReadOnlyDictionary> NameToClassificationLearner = + new Dictionary>() + { + { nameof(ClassificationDecisionTreeLearner), new ClassificationDecisionTreeLearner() }, + { nameof(ClassificationAdaBoostLearner), new ClassificationAdaBoostLearner() }, + { nameof(ClassificationRandomForestLearner), new ClassificationRandomForestLearner() }, + { nameof(ClassificationExtremelyRandomizedTreesLearner), new ClassificationExtremelyRandomizedTreesLearner() }, + { nameof(ClassificationBinomialGradientBoostLearner), new ClassificationBinomialGradientBoostLearner() } + }; + + // Define regression learners here. Use default parameters for benchmarks. + public static readonly IReadOnlyDictionary> NameToRegressionLearner = + new Dictionary>() + { + { nameof(RegressionDecisionTreeLearner), new RegressionDecisionTreeLearner() }, + { nameof(RegressionAdaBoostLearner), new RegressionAdaBoostLearner() }, + { nameof(RegressionRandomForestLearner), new RegressionRandomForestLearner() }, + { nameof(RegressionExtremelyRandomizedTreesLearner), new RegressionExtremelyRandomizedTreesLearner() }, + { nameof(RegressionAbsoluteLossGradientBoostLearner), new RegressionAbsoluteLossGradientBoostLearner() }, + { nameof(RegressionHuberLossGradientBoostLearner), new RegressionHuberLossGradientBoostLearner() }, + { nameof(RegressionQuantileLossGradientBoostLearner), new RegressionQuantileLossGradientBoostLearner() }, + { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() } + }; +} From c683c1439087244f57c052762844a570056b91b5 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:07:38 +0100 Subject: [PATCH 25/42] refactor --- .../Benchmarks.ClassificationModels.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 0777d407..3a52ae5f 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -36,10 +36,10 @@ public void GlobalSetup() var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); - m_models = new Dictionary>(); - foreach (var learner in m_learners) + m_models = []; + foreach (var (name, learner) in m_learners) { - m_models[learner.Key] = learner.Value.Learn(m_features, m_targets); + m_models[name] = learner.Learn(m_features, m_targets); } } From 623e9233f5abcffd0863746d48f0656f9855623c Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:15:59 +0100 Subject: [PATCH 26/42] Fix usings and add Benchmarks.RegressionModels --- .../Benchmarks.ClassificationLearners.cs | 4 -- .../Benchmarks.ClassificationModels.cs | 9 +--- .../Benchmarks.RegressionLearners.cs | 4 -- .../Benchmarks.RegressionModels.cs | 50 +++++++++++++++++++ 4 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index ac0e2f11..af9778bf 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -1,12 +1,8 @@ using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; -using SharpLearning.AdaBoost.Learners; using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.GradientBoost.Learners; -using SharpLearning.RandomForest.Learners; namespace SharpLearning.Benchmarks; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 3a52ae5f..f16d68a2 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -1,15 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using BenchmarkDotNet.Attributes; -using SharpLearning.AdaBoost.Learners; using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.GradientBoost.Learners; -using SharpLearning.RandomForest.Learners; namespace SharpLearning.Benchmarks; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index c6dc29f3..c12da748 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -1,12 +1,8 @@ using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; -using SharpLearning.AdaBoost.Learners; using SharpLearning.Common.Interfaces; using SharpLearning.Containers.Matrices; -using SharpLearning.DecisionTrees.Learners; -using SharpLearning.GradientBoost.Learners; -using SharpLearning.RandomForest.Learners; namespace SharpLearning.Benchmarks; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs new file mode 100644 index 00000000..4cce8ad2 --- /dev/null +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; +using SharpLearning.Common.Interfaces; +using SharpLearning.Containers.Matrices; + +namespace SharpLearning.Benchmarks; + +public static partial class Benchmarks +{ + [MemoryDiagnoser] + public class RegressionLearnersPredict + { + readonly IReadOnlyDictionary> m_learners = + DefaultLearners.NameToRegressionLearner; + + // Data size for benchmarks. + const int Rows = 1000; + const int Cols = 10; + F64Matrix m_features; + double[] m_targets; + Dictionary> m_models; + + [GlobalSetup] + public void GlobalSetup() + { + var seed = 42; + m_targets = DataGenerator.GenerateDoubles(Rows, cols: 1, seed); + var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); + m_features = new F64Matrix(features, Rows, Cols); + + m_models = new Dictionary>(); + foreach (var (name, learner) in m_learners) + { + m_models[name] = learner.Learn(m_features, m_targets); + } + } + + [Benchmark] + [ArgumentsSource(nameof(GetLearners))] + public void Predict(string learnerName) + { + var model = m_models[learnerName]; + model.Predict(m_features); + } + + public IReadOnlyList GetLearners() => + m_learners.Keys.ToArray(); + } +} From 0458c4989aae550fb38ea084b058aaef02dea58e Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:17:13 +0100 Subject: [PATCH 27/42] refactor --- .../Benchmarks.ClassificationModels.cs | 3 +-- src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index f16d68a2..43193b2f 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -13,13 +13,13 @@ public class ClassificationLearnersPredict { readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToClassificationLearner; + readonly Dictionary> m_models = []; // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; F64Matrix m_features; double[] m_targets; - Dictionary> m_models; [GlobalSetup] public void GlobalSetup() @@ -29,7 +29,6 @@ public void GlobalSetup() var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); - m_models = []; foreach (var (name, learner) in m_learners) { m_models[name] = learner.Learn(m_features, m_targets); diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 4cce8ad2..824480c0 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -13,13 +13,13 @@ public class RegressionLearnersPredict { readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToRegressionLearner; + readonly Dictionary> m_models = []; // Data size for benchmarks. const int Rows = 1000; const int Cols = 10; F64Matrix m_features; double[] m_targets; - Dictionary> m_models; [GlobalSetup] public void GlobalSetup() @@ -29,7 +29,6 @@ public void GlobalSetup() var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); m_features = new F64Matrix(features, Rows, Cols); - m_models = new Dictionary>(); foreach (var (name, learner) in m_learners) { m_models[name] = learner.Learn(m_features, m_targets); From 514610594f86460faeebccedd8ba0af5b4dbbafc Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:34:15 +0100 Subject: [PATCH 28/42] Rename --- src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs | 2 +- src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 43193b2f..43708ed3 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -9,7 +9,7 @@ namespace SharpLearning.Benchmarks; public static partial class Benchmarks { [MemoryDiagnoser] - public class ClassificationLearnersPredict + public class ClassificationModels { readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToClassificationLearner; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 824480c0..82310b22 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -9,7 +9,7 @@ namespace SharpLearning.Benchmarks; public static partial class Benchmarks { [MemoryDiagnoser] - public class RegressionLearnersPredict + public class RegressionModels { readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToRegressionLearner; From 5dc0561670f93f36a3b22e2cd57ff5563fb67252 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:37:57 +0100 Subject: [PATCH 29/42] add --- src/SharpLearning.Benchmarks/program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 60eeefae..fb7976da 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -18,3 +18,5 @@ BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.ClassificationModels), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.RegressionModels), config, args); From b06e4fc00ab90b04d911205defbd719cb723383e Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:56:44 +0100 Subject: [PATCH 30/42] Refactor --- .../Benchmarks.ClassificationLearners.cs | 11 +------- .../Benchmarks.ClassificationModels.cs | 9 +------ .../Benchmarks.RegressionLearners.cs | 8 +----- .../Benchmarks.RegressionModels.cs | 9 +------ src/SharpLearning.Benchmarks/DataGenerator.cs | 26 +++++++++++++++++-- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index af9778bf..54fbf930 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -14,22 +14,13 @@ public class ClassificationLearners readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToClassificationLearner; - // Data size for benchmarks. - const int Rows = 1000; - const int Cols = 10; - const int MinTargetValue = 0; - const int MaxTargetValue = 10; F64Matrix m_features; double[] m_targets; [GlobalSetup] public void GlobalSetup() { - var seed = 42; - m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, - MinTargetValue, MaxTargetValue, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); + (m_features, m_targets) = DataGenerator.GenerateClassificationData(); } [Benchmark] diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 43708ed3..31bbf61c 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -15,20 +15,13 @@ public class ClassificationModels DefaultLearners.NameToClassificationLearner; readonly Dictionary> m_models = []; - // Data size for benchmarks. - const int Rows = 1000; - const int Cols = 10; F64Matrix m_features; double[] m_targets; [GlobalSetup] public void GlobalSetup() { - var seed = 42; - m_targets = DataGenerator.GenerateIntegers(Rows, cols: 1, 0, 2, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); - + (m_features, m_targets) = DataGenerator.GenerateClassificationData(); foreach (var (name, learner) in m_learners) { m_models[name] = learner.Learn(m_features, m_targets); diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index c12da748..516e07c7 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -14,19 +14,13 @@ public class RegressionLearners readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToRegressionLearner; - // Data size for benchmarks. - const int Rows = 1000; - const int Cols = 10; F64Matrix m_features; double[] m_targets; [GlobalSetup] public void GlobalSetup() { - var seed = 42; - m_targets = DataGenerator.GenerateDoubles(Rows, cols: 1, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); + (m_features, m_targets) = DataGenerator.GenerateRegressionData(); } [Benchmark] diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 82310b22..5ed4197c 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -15,20 +15,13 @@ public class RegressionModels DefaultLearners.NameToRegressionLearner; readonly Dictionary> m_models = []; - // Data size for benchmarks. - const int Rows = 1000; - const int Cols = 10; F64Matrix m_features; double[] m_targets; [GlobalSetup] public void GlobalSetup() { - var seed = 42; - m_targets = DataGenerator.GenerateDoubles(Rows, cols: 1, seed); - var features = DataGenerator.GenerateDoubles(Rows, Cols, seed); - m_features = new F64Matrix(features, Rows, Cols); - + (m_features, m_targets) = DataGenerator.GenerateRegressionData(); foreach (var (name, learner) in m_learners) { m_models[name] = learner.Learn(m_features, m_targets); diff --git a/src/SharpLearning.Benchmarks/DataGenerator.cs b/src/SharpLearning.Benchmarks/DataGenerator.cs index 928e166b..ad9e9e0c 100644 --- a/src/SharpLearning.Benchmarks/DataGenerator.cs +++ b/src/SharpLearning.Benchmarks/DataGenerator.cs @@ -1,18 +1,40 @@ using System; using System.Linq; +using SharpLearning.Containers.Matrices; namespace SharpLearning.Benchmarks; public static class DataGenerator { - public static double[] GenerateDoubles(int rows, int cols, int seed) + // default data size for benchmarks. + const int Rows = 1000; + const int Cols = 10; + const int MinTargetValue = 0; + const int MaxTargetValue = 10; + const int Seed = 42; + + public static (F64Matrix Features, double[] Targets) GenerateRegressionData() + { + var targets = GenerateDoubles(Rows, cols: 1, Seed); + var features = GenerateDoubles(Rows, Cols, Seed); + return (new F64Matrix(features, Rows, Cols), targets); + } + + public static (F64Matrix Features, double[] Targets) GenerateClassificationData() + { + var targets = GenerateIntegers(Rows, cols: 1, MinTargetValue, MaxTargetValue, Seed); + var features = GenerateDoubles(Rows, Cols, Seed); + return (new F64Matrix(features, Rows, Cols), targets); + } + + static double[] GenerateDoubles(int rows, int cols, int seed) { var random = new Random(seed); return Enumerable.Range(0, rows * cols) .Select(i => random.NextDouble()).ToArray(); } - public static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) + static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) { var random = new Random(seed); return Enumerable.Range(0, rows * cols) From c25431ffa1ffa5bf7a8318c832d3826deaa33002 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 18:57:25 +0100 Subject: [PATCH 31/42] capital --- src/SharpLearning.Benchmarks/DataGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpLearning.Benchmarks/DataGenerator.cs b/src/SharpLearning.Benchmarks/DataGenerator.cs index ad9e9e0c..b26618c9 100644 --- a/src/SharpLearning.Benchmarks/DataGenerator.cs +++ b/src/SharpLearning.Benchmarks/DataGenerator.cs @@ -6,7 +6,7 @@ namespace SharpLearning.Benchmarks; public static class DataGenerator { - // default data size for benchmarks. + // Default data size for benchmarks. const int Rows = 1000; const int Cols = 10; const int MinTargetValue = 0; From 4f3e6c3c384f192006f170ef4fa2ee523b8f19f3 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:00:05 +0100 Subject: [PATCH 32/42] use for --- src/SharpLearning.Benchmarks/DataGenerator.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/SharpLearning.Benchmarks/DataGenerator.cs b/src/SharpLearning.Benchmarks/DataGenerator.cs index b26618c9..aef935c3 100644 --- a/src/SharpLearning.Benchmarks/DataGenerator.cs +++ b/src/SharpLearning.Benchmarks/DataGenerator.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using SharpLearning.Containers.Matrices; namespace SharpLearning.Benchmarks; @@ -15,29 +14,37 @@ public static class DataGenerator public static (F64Matrix Features, double[] Targets) GenerateRegressionData() { - var targets = GenerateDoubles(Rows, cols: 1, Seed); - var features = GenerateDoubles(Rows, Cols, Seed); + var random = new Random(Seed); + var targets = GenerateDoubles(Rows, 1, random); + var features = GenerateDoubles(Rows, Cols, random); return (new F64Matrix(features, Rows, Cols), targets); } public static (F64Matrix Features, double[] Targets) GenerateClassificationData() { - var targets = GenerateIntegers(Rows, cols: 1, MinTargetValue, MaxTargetValue, Seed); - var features = GenerateDoubles(Rows, Cols, Seed); + var random = new Random(Seed); + var targets = GenerateIntegers(Rows, 1, MinTargetValue, MaxTargetValue, random); + var features = GenerateDoubles(Rows, Cols, random); return (new F64Matrix(features, Rows, Cols), targets); } - static double[] GenerateDoubles(int rows, int cols, int seed) + static double[] GenerateDoubles(int rows, int cols, Random random) { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.NextDouble()).ToArray(); + var data = new double[rows * cols]; + for (var i = 0; i < data.Length; i++) + { + data[i] = random.NextDouble(); + } + return data; } - static double[] GenerateIntegers(int rows, int cols, int min, int max, int seed) + static double[] GenerateIntegers(int rows, int cols, int min, int max, Random random) { - var random = new Random(seed); - return Enumerable.Range(0, rows * cols) - .Select(i => random.Next(min, max)).Select(i => (double)i).ToArray(); + var data = new double[rows * cols]; + for (var i = 0; i < data.Length; i++) + { + data[i] = random.Next(min, max); + } + return data; } } From 797707e80d17aac3e49bd9ac5be306de4154c59b Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:04:04 +0100 Subject: [PATCH 33/42] Refactor --- src/SharpLearning.Benchmarks/DataGenerator.cs | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/SharpLearning.Benchmarks/DataGenerator.cs b/src/SharpLearning.Benchmarks/DataGenerator.cs index aef935c3..fea5210b 100644 --- a/src/SharpLearning.Benchmarks/DataGenerator.cs +++ b/src/SharpLearning.Benchmarks/DataGenerator.cs @@ -6,29 +6,35 @@ namespace SharpLearning.Benchmarks; public static class DataGenerator { // Default data size for benchmarks. - const int Rows = 1000; - const int Cols = 10; - const int MinTargetValue = 0; - const int MaxTargetValue = 10; - const int Seed = 42; + public const int DefaultRows = 1000; + public const int DefaultCols = 10; + public const int DefaultMinTargetValue = 0; + public const int DefaultMaxTargetValue = 10; + public const int DefaultSeed = 42; - public static (F64Matrix Features, double[] Targets) GenerateRegressionData() + public static (F64Matrix Features, double[] Targets) GenerateRegressionData( + int rows = DefaultRows, int cols = DefaultCols, + int seed = DefaultSeed) { - var random = new Random(Seed); - var targets = GenerateDoubles(Rows, 1, random); - var features = GenerateDoubles(Rows, Cols, random); - return (new F64Matrix(features, Rows, Cols), targets); + var random = new Random(seed); + var features = GenerateRandomDoubles(rows, cols, random); + var targets = GenerateRandomDoubles(rows, 1, random); + return (new F64Matrix(features, rows, cols), targets); } - public static (F64Matrix Features, double[] Targets) GenerateClassificationData() + public static (F64Matrix Features, double[] Targets) GenerateClassificationData( + int rows = DefaultRows, int cols = DefaultCols, + int minTargetValue = DefaultMinTargetValue, + int maxTargetValue = DefaultMaxTargetValue, + int seed = DefaultSeed) { - var random = new Random(Seed); - var targets = GenerateIntegers(Rows, 1, MinTargetValue, MaxTargetValue, random); - var features = GenerateDoubles(Rows, Cols, random); - return (new F64Matrix(features, Rows, Cols), targets); + var random = new Random(seed); + var features = GenerateRandomDoubles(rows, cols, random); + var targets = GenerateRandomIntegers(rows, 1, minTargetValue, maxTargetValue, random); + return (new F64Matrix(features, rows, cols), targets); } - static double[] GenerateDoubles(int rows, int cols, Random random) + static double[] GenerateRandomDoubles(int rows, int cols, Random random) { var data = new double[rows * cols]; for (var i = 0; i < data.Length; i++) @@ -38,7 +44,7 @@ static double[] GenerateDoubles(int rows, int cols, Random random) return data; } - static double[] GenerateIntegers(int rows, int cols, int min, int max, Random random) + static double[] GenerateRandomIntegers(int rows, int cols, int min, int max, Random random) { var data = new double[rows * cols]; for (var i = 0; i < data.Length; i++) From 023420c2fcf809ab2a44138b93c9e48f780eb519 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:18:50 +0100 Subject: [PATCH 34/42] Refactor to get model name --- .../Benchmarks.ClassificationModels.cs | 17 +++++++++-------- .../Benchmarks.RegressionModels.cs | 5 +++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 31bbf61c..52ce0d70 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -13,7 +13,7 @@ public class ClassificationModels { readonly IReadOnlyDictionary> m_learners = DefaultLearners.NameToClassificationLearner; - readonly Dictionary> m_models = []; + readonly Dictionary> m_models = new(); F64Matrix m_features; double[] m_targets; @@ -22,21 +22,22 @@ public class ClassificationModels public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateClassificationData(); - foreach (var (name, learner) in m_learners) + foreach (var (_, learner) in m_learners) { - m_models[name] = learner.Learn(m_features, m_targets); + var model = learner.Learn(m_features, m_targets); + m_models[model.GetType().Name] = model; } } [Benchmark] - [ArgumentsSource(nameof(GetLearners))] - public void Predict(string learnerName) + [ArgumentsSource(nameof(GetModels))] + public void Predict(string modelName) { - var model = m_models[learnerName]; + var model = m_models[modelName]; model.Predict(m_features); } - public IReadOnlyList GetLearners() => - m_learners.Keys.ToArray(); + public IReadOnlyList GetModels() => + m_models.Keys.ToArray(); } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 5ed4197c..7587d1a8 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -22,9 +22,10 @@ public class RegressionModels public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateRegressionData(); - foreach (var (name, learner) in m_learners) + foreach (var (_, learner) in m_learners) { - m_models[name] = learner.Learn(m_features, m_targets); + var model = learner.Learn(m_features, m_targets); + m_models[model.GetType().Name] = model; } } From 7d2d78eef56732a0fa1e907335b7bdce3e7439e4 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:30:58 +0100 Subject: [PATCH 35/42] use model names in model benchmarks --- .../Benchmarks.ClassificationModels.cs | 11 +++++++++-- .../Benchmarks.RegressionModels.cs | 17 ++++++++++++----- src/SharpLearning.Benchmarks/program.cs | 4 ++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 52ce0d70..8f584798 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -37,7 +37,14 @@ public void Predict(string modelName) model.Predict(m_features); } - public IReadOnlyList GetModels() => - m_models.Keys.ToArray(); + public IReadOnlyList GetModels() + { + // Hack to ensure m_models is populated before call to GetModels. + if (m_models.Count == 0) + { + GlobalSetup(); + } + return m_models.Keys.ToArray(); + } } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 7587d1a8..774ac579 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -30,14 +30,21 @@ public void GlobalSetup() } [Benchmark] - [ArgumentsSource(nameof(GetLearners))] - public void Predict(string learnerName) + [ArgumentsSource(nameof(GetModels))] + public void Predict(string modelName) { - var model = m_models[learnerName]; + var model = m_models[modelName]; model.Predict(m_features); } - public IReadOnlyList GetLearners() => - m_learners.Keys.ToArray(); + public IReadOnlyList GetModels() + { + // Hack to ensure m_models is populated before call to GetModels. + if (m_models.Count == 0) + { + GlobalSetup(); + } + return m_models.Keys.ToArray(); + } } } diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index fb7976da..01a99f2f 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,7 +16,7 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +//BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); +//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); BenchmarkRunner.Run(typeof(Benchmarks.ClassificationModels), config, args); BenchmarkRunner.Run(typeof(Benchmarks.RegressionModels), config, args); From 5ce530634777fc371d6dcaada73a8a18f4058b6c Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:37:42 +0100 Subject: [PATCH 36/42] nits --- src/SharpLearning.Benchmarks/DefaultLearners.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SharpLearning.Benchmarks/DefaultLearners.cs b/src/SharpLearning.Benchmarks/DefaultLearners.cs index a0b00032..bccb2a40 100644 --- a/src/SharpLearning.Benchmarks/DefaultLearners.cs +++ b/src/SharpLearning.Benchmarks/DefaultLearners.cs @@ -10,14 +10,14 @@ namespace SharpLearning.Benchmarks; public static class DefaultLearners { // Define classification learners here. Use default parameters for benchmarks. - public static readonly IReadOnlyDictionary> NameToClassificationLearner = + public static readonly IReadOnlyDictionary> NameToClassificationLearner = new Dictionary>() { { nameof(ClassificationDecisionTreeLearner), new ClassificationDecisionTreeLearner() }, { nameof(ClassificationAdaBoostLearner), new ClassificationAdaBoostLearner() }, { nameof(ClassificationRandomForestLearner), new ClassificationRandomForestLearner() }, { nameof(ClassificationExtremelyRandomizedTreesLearner), new ClassificationExtremelyRandomizedTreesLearner() }, - { nameof(ClassificationBinomialGradientBoostLearner), new ClassificationBinomialGradientBoostLearner() } + { nameof(ClassificationBinomialGradientBoostLearner), new ClassificationBinomialGradientBoostLearner() }, }; // Define regression learners here. Use default parameters for benchmarks. @@ -31,6 +31,6 @@ public static class DefaultLearners { nameof(RegressionAbsoluteLossGradientBoostLearner), new RegressionAbsoluteLossGradientBoostLearner() }, { nameof(RegressionHuberLossGradientBoostLearner), new RegressionHuberLossGradientBoostLearner() }, { nameof(RegressionQuantileLossGradientBoostLearner), new RegressionQuantileLossGradientBoostLearner() }, - { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() } + { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() }, }; } From af4c161e79ccc047981540871afd20f2c970cbfd Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:39:08 +0100 Subject: [PATCH 37/42] Update comment --- src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 8f584798..1ecf02bc 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -40,6 +40,7 @@ public void Predict(string modelName) public IReadOnlyList GetModels() { // Hack to ensure m_models is populated before call to GetModels. + // This means `GlobalSetup` will be called twice. if (m_models.Count == 0) { GlobalSetup(); From 4e3eb3637e10e06be22b1f1ca22f19039f141555 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:39:51 +0100 Subject: [PATCH 38/42] rename --- .../Benchmarks.ClassificationLearners.cs | 2 +- .../Benchmarks.ClassificationModels.cs | 2 +- src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs | 2 +- src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs | 2 +- src/SharpLearning.Benchmarks/DefaultLearners.cs | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs index 54fbf930..614e4cf0 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationLearners.cs @@ -12,7 +12,7 @@ public static partial class Benchmarks public class ClassificationLearners { readonly IReadOnlyDictionary> m_learners = - DefaultLearners.NameToClassificationLearner; + DefaultLearners.LearnerNameToLearnerClassification; F64Matrix m_features; double[] m_targets; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 1ecf02bc..2df1ede4 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -12,7 +12,7 @@ public static partial class Benchmarks public class ClassificationModels { readonly IReadOnlyDictionary> m_learners = - DefaultLearners.NameToClassificationLearner; + DefaultLearners.LearnerNameToLearnerClassification; readonly Dictionary> m_models = new(); F64Matrix m_features; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs index 516e07c7..b82b0797 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionLearners.cs @@ -12,7 +12,7 @@ public static partial class Benchmarks public class RegressionLearners { readonly IReadOnlyDictionary> m_learners = - DefaultLearners.NameToRegressionLearner; + DefaultLearners.LearnerNameToLearnerRegression; F64Matrix m_features; double[] m_targets; diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 774ac579..021267ef 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -12,7 +12,7 @@ public static partial class Benchmarks public class RegressionModels { readonly IReadOnlyDictionary> m_learners = - DefaultLearners.NameToRegressionLearner; + DefaultLearners.LearnerNameToLearnerRegression; readonly Dictionary> m_models = []; F64Matrix m_features; diff --git a/src/SharpLearning.Benchmarks/DefaultLearners.cs b/src/SharpLearning.Benchmarks/DefaultLearners.cs index bccb2a40..9b8aaa77 100644 --- a/src/SharpLearning.Benchmarks/DefaultLearners.cs +++ b/src/SharpLearning.Benchmarks/DefaultLearners.cs @@ -10,7 +10,7 @@ namespace SharpLearning.Benchmarks; public static class DefaultLearners { // Define classification learners here. Use default parameters for benchmarks. - public static readonly IReadOnlyDictionary> NameToClassificationLearner = + public static readonly IReadOnlyDictionary> LearnerNameToLearnerClassification = new Dictionary>() { { nameof(ClassificationDecisionTreeLearner), new ClassificationDecisionTreeLearner() }, @@ -21,7 +21,7 @@ public static class DefaultLearners }; // Define regression learners here. Use default parameters for benchmarks. - public static readonly IReadOnlyDictionary> NameToRegressionLearner = + public static readonly IReadOnlyDictionary> LearnerNameToLearnerRegression = new Dictionary>() { { nameof(RegressionDecisionTreeLearner), new RegressionDecisionTreeLearner() }, From 7efd3975d6886c4890603434cb68ee59013ceec5 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 19:51:21 +0100 Subject: [PATCH 39/42] Use learner name to model name mapping --- .../Benchmarks.ClassificationModels.cs | 17 +++------ .../Benchmarks.RegressionModels.cs | 16 +++----- .../DefaultLearners.cs | 37 ++++++++++++++++++- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 2df1ede4..79289a92 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -22,10 +22,11 @@ public class ClassificationModels public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateClassificationData(); - foreach (var (_, learner) in m_learners) + foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); - m_models[model.GetType().Name] = model; + var modelName = DefaultLearners.LearnerNameToModelNameRegression[learnerName]; + m_models[modelName] = model; } } @@ -37,15 +38,7 @@ public void Predict(string modelName) model.Predict(m_features); } - public IReadOnlyList GetModels() - { - // Hack to ensure m_models is populated before call to GetModels. - // This means `GlobalSetup` will be called twice. - if (m_models.Count == 0) - { - GlobalSetup(); - } - return m_models.Keys.ToArray(); - } + public IReadOnlyList GetModels() => + m_models.Keys.ToArray(); } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index 021267ef..bcd5a084 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -22,10 +22,11 @@ public class RegressionModels public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateRegressionData(); - foreach (var (_, learner) in m_learners) + foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); - m_models[model.GetType().Name] = model; + var modelName = DefaultLearners.LearnerNameToModelNameClassification[learnerName]; + m_models[modelName] = model; } } @@ -37,14 +38,7 @@ public void Predict(string modelName) model.Predict(m_features); } - public IReadOnlyList GetModels() - { - // Hack to ensure m_models is populated before call to GetModels. - if (m_models.Count == 0) - { - GlobalSetup(); - } - return m_models.Keys.ToArray(); - } + public IReadOnlyList GetModels() => + m_models.Keys.ToArray(); } } diff --git a/src/SharpLearning.Benchmarks/DefaultLearners.cs b/src/SharpLearning.Benchmarks/DefaultLearners.cs index 9b8aaa77..3d52df76 100644 --- a/src/SharpLearning.Benchmarks/DefaultLearners.cs +++ b/src/SharpLearning.Benchmarks/DefaultLearners.cs @@ -1,14 +1,20 @@ -using SharpLearning.AdaBoost.Learners; +using System.Collections.Generic; +using SharpLearning.AdaBoost.Learners; +using SharpLearning.AdaBoost.Models; using SharpLearning.Common.Interfaces; using SharpLearning.DecisionTrees.Learners; +using SharpLearning.DecisionTrees.Models; using SharpLearning.GradientBoost.Learners; +using SharpLearning.GradientBoost.Models; using SharpLearning.RandomForest.Learners; -using System.Collections.Generic; +using SharpLearning.RandomForest.Models; namespace SharpLearning.Benchmarks; public static class DefaultLearners { + const string NameSeparator = "_"; + // Define classification learners here. Use default parameters for benchmarks. public static readonly IReadOnlyDictionary> LearnerNameToLearnerClassification = new Dictionary>() @@ -33,4 +39,31 @@ public static class DefaultLearners { nameof(RegressionQuantileLossGradientBoostLearner), new RegressionQuantileLossGradientBoostLearner() }, { nameof(RegressionSquareLossGradientBoostLearner), new RegressionSquareLossGradientBoostLearner() }, }; + + // Map learner names to model names for classification. Some learners return the same model type, + // so suffixing with the learner name. + public static readonly IReadOnlyDictionary LearnerNameToModelNameClassification = + new Dictionary() + { + { nameof(ClassificationDecisionTreeLearner), nameof(ClassificationDecisionTreeModel) }, + { nameof(ClassificationAdaBoostLearner), nameof(ClassificationAdaBoostModel) }, + { nameof(ClassificationRandomForestLearner), nameof(ClassificationForestModel) + NameSeparator + nameof(ClassificationRandomForestLearner) }, + { nameof(ClassificationExtremelyRandomizedTreesLearner), nameof(ClassificationForestModel) + NameSeparator + nameof(ClassificationExtremelyRandomizedTreesLearner)}, + { nameof(ClassificationBinomialGradientBoostLearner), nameof(ClassificationGradientBoostModel) }, + }; + + // Map learner names to model names for regression. Some learners return the same model type, + // so suffixing with the learner name. + public static readonly IReadOnlyDictionary LearnerNameToModelNameRegression = + new Dictionary() + { + { nameof(RegressionDecisionTreeLearner), nameof(RegressionDecisionTreeModel) }, + { nameof(RegressionAdaBoostLearner), nameof(RegressionAdaBoostModel) }, + { nameof(RegressionRandomForestLearner), nameof(RegressionForestModel) + NameSeparator + nameof(RegressionRandomForestLearner)}, + { nameof(RegressionExtremelyRandomizedTreesLearner), nameof(RegressionForestModel) + NameSeparator + nameof(RegressionExtremelyRandomizedTreesLearner) }, + { nameof(RegressionAbsoluteLossGradientBoostLearner), nameof(RegressionGradientBoostModel) + NameSeparator + nameof(RegressionAbsoluteLossGradientBoostLearner) }, + { nameof(RegressionHuberLossGradientBoostLearner), nameof(RegressionGradientBoostModel) + NameSeparator + nameof(RegressionHuberLossGradientBoostLearner) }, + { nameof(RegressionQuantileLossGradientBoostLearner), nameof(RegressionGradientBoostModel) + NameSeparator + nameof(RegressionQuantileLossGradientBoostLearner) }, + { nameof(RegressionSquareLossGradientBoostLearner), nameof(RegressionGradientBoostModel) + NameSeparator + nameof(RegressionSquareLossGradientBoostLearner) }, + }; } From af7ddee75e51a9e0cff990b11e00b6f3d92267bf Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 20:02:57 +0100 Subject: [PATCH 40/42] Readd and fix --- .../Benchmarks.ClassificationModels.cs | 14 +++++++++++--- .../Benchmarks.RegressionModels.cs | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index 79289a92..af481123 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -25,7 +25,7 @@ public void GlobalSetup() foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); - var modelName = DefaultLearners.LearnerNameToModelNameRegression[learnerName]; + var modelName = DefaultLearners.LearnerNameToModelNameClassification[learnerName]; m_models[modelName] = model; } } @@ -38,7 +38,15 @@ public void Predict(string modelName) model.Predict(m_features); } - public IReadOnlyList GetModels() => - m_models.Keys.ToArray(); + public IReadOnlyList GetModels() + { + // Hack to ensure m_models is populated before call to GetModels. + // This means `GlobalSetup` will be called twice. + if (m_models.Count == 0) + { + GlobalSetup(); + } + return m_models.Keys.ToArray(); + } } } diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index bcd5a084..f2114df2 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -25,7 +25,7 @@ public void GlobalSetup() foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); - var modelName = DefaultLearners.LearnerNameToModelNameClassification[learnerName]; + var modelName = DefaultLearners.LearnerNameToModelNameRegression[learnerName]; m_models[modelName] = model; } } @@ -38,7 +38,15 @@ public void Predict(string modelName) model.Predict(m_features); } - public IReadOnlyList GetModels() => - m_models.Keys.ToArray(); + public IReadOnlyList GetModels() + { + // Hack to ensure m_models is populated before call to GetModels. + // This means `GlobalSetup` will be called twice. + if (m_models.Count == 0) + { + GlobalSetup(); + } + return m_models.Keys.ToArray(); + } } } From e56bc0e5d9c999a998c484c4765dfecd0a1d8205 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 20:06:51 +0100 Subject: [PATCH 41/42] Use single row for prediction benchmark --- .../Benchmarks.ClassificationModels.cs | 6 +++++- src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs index af481123..f2d11248 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.ClassificationModels.cs @@ -15,13 +15,17 @@ public class ClassificationModels DefaultLearners.LearnerNameToLearnerClassification; readonly Dictionary> m_models = new(); + // For creating models. F64Matrix m_features; double[] m_targets; + // For prediction. + double[] m_featureRow; [GlobalSetup] public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateClassificationData(); + m_featureRow = m_features.Row(0); foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); @@ -35,7 +39,7 @@ public void GlobalSetup() public void Predict(string modelName) { var model = m_models[modelName]; - model.Predict(m_features); + model.Predict(m_featureRow); } public IReadOnlyList GetModels() diff --git a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs index f2114df2..e7cbd6d6 100644 --- a/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs +++ b/src/SharpLearning.Benchmarks/Benchmarks.RegressionModels.cs @@ -15,13 +15,17 @@ public class RegressionModels DefaultLearners.LearnerNameToLearnerRegression; readonly Dictionary> m_models = []; + // For creating models. F64Matrix m_features; double[] m_targets; + // For prediction. + double[] m_featureRow; [GlobalSetup] public void GlobalSetup() { (m_features, m_targets) = DataGenerator.GenerateRegressionData(); + m_featureRow = m_features.Row(0); foreach (var (learnerName, learner) in m_learners) { var model = learner.Learn(m_features, m_targets); @@ -35,7 +39,7 @@ public void GlobalSetup() public void Predict(string modelName) { var model = m_models[modelName]; - model.Predict(m_features); + model.Predict(m_featureRow); } public IReadOnlyList GetModels() From 124ccb75fb13f8a1b62d66caa93c467a29c594f7 Mon Sep 17 00:00:00 2001 From: Mads Dabros Date: Sun, 16 Mar 2025 20:15:01 +0100 Subject: [PATCH 42/42] enable --- src/SharpLearning.Benchmarks/program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SharpLearning.Benchmarks/program.cs b/src/SharpLearning.Benchmarks/program.cs index 01a99f2f..fb7976da 100644 --- a/src/SharpLearning.Benchmarks/program.cs +++ b/src/SharpLearning.Benchmarks/program.cs @@ -16,7 +16,7 @@ var config = (Debugger.IsAttached ? new DebugInProcessConfig() : DefaultConfig.Instance) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(200)); -//BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); -//BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.ClassificationLearners), config, args); +BenchmarkRunner.Run(typeof(Benchmarks.RegressionLearners), config, args); BenchmarkRunner.Run(typeof(Benchmarks.ClassificationModels), config, args); BenchmarkRunner.Run(typeof(Benchmarks.RegressionModels), config, args);