public void RunTest() { // context is null { string parameterName = "context"; string innerMessage = ArgumentExceptionAssert.NullPartialMessage + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var sample = DoubleMatrix.Dense(1, 1); ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Run", methodArgs: new object[] { null, 1, .01 }); }, expectedInnerType: typeof(ArgumentNullException), expectedInnerMessage: innerMessage); } }
public void RunTest() { // Valid input - Minimization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestablePartitionOptimizationContext00.Get(); var context = testableContext.Context; // Set optimization parameters. int sampleSize = 2000; double rarity = 0.01; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); var expectedPartition = IndexPartition.Create( testableContext.OptimalState); var actualPartition = IndexPartition.Create( results.OptimalState); IndexPartitionAssert.HaveEqualIdentifiers( expected: expectedPartition, actual: actualPartition); IndexPartitionAssert.HaveEqualParts( expected: expectedPartition, actual: actualPartition); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } }
public void Main() { // Create the context. var context = new RosenbrockFunctionMinimizationContext(); // Create the optimizer. var optimizer = new SystemPerformanceOptimizer() { PerformanceEvaluationParallelOptions = { MaxDegreeOfParallelism = -1 }, SampleGenerationParallelOptions = { MaxDegreeOfParallelism = -1 } }; // Set optimization parameters. double rarity = 0.1; int sampleSize = 1000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); // Show the results. Console.WriteLine( "The Cross-Entropy optimizer has converged: {0}.", results.HasConverged); Console.WriteLine(); Console.WriteLine("Initial guess parameter:"); Console.WriteLine(context.InitialParameter); Console.WriteLine(); Console.WriteLine("The minimizer of the performance is:"); Console.WriteLine(results.OptimalState); Console.WriteLine(); Console.WriteLine("The minimum performance is:"); Console.WriteLine(results.OptimalPerformance); }
/// <summary> /// Initializes a new instance of the /// <see cref="CategoricalEntailmentEnsembleClassifier" /> class /// by exploiting the specified <paramref name="trainer"/> /// to select the given /// <paramref name="numberOfTrainedCategoricalEntailments"/>. /// </summary> /// <param name="trainer"> /// An object whose state contains the information needed to /// train the classifier. /// </param> /// <param name="numberOfTrainedCategoricalEntailments"> /// The number of categorical entailments to be trained. /// </param> /// <returns> /// A classifier whose ensemble contains the trained /// categorical entailments. /// </returns> /// <remarks> /// <para> /// The <paramref name="trainer"/> can be equipped with a /// nonempty initial ensemble of categorical entailments. /// This method always trains a classifier by adding /// to such ensemble further entailments, whose number /// is specified by parameter /// <paramref name="numberOfTrainedCategoricalEntailments"/>. /// However, the method returns the partial classifier whose /// ensemble contains the additional trained entailments only /// (no initial entailments). /// </para> /// </remarks> private static CategoricalEntailmentEnsembleClassifier Train( CategoricalEntailmentEnsembleTrainer trainer, int numberOfTrainedCategoricalEntailments) { var optimizer = new SystemPerformanceOptimizer(); int numberOfResponseCategories = trainer.ResponseVariable.NumberOfCategories; var context = new CategoricalEntailmentEnsembleOptimizationContext( objectiveFunction: trainer.Performance, trainer.featureCategoryCounts, numberOfResponseCategories, numberOfTrainedCategoricalEntailments, trainer.allowEntailmentPartialTruthValues, probabilitySmoothingCoefficient: .9, optimizationGoal: OptimizationGoal.Maximization, minimumNumberOfIterations: 10, maximumNumberOfIterations: 1000); int numberOfParameters = numberOfTrainedCategoricalEntailments * ( trainer.featureCategoryCounts.Sum() + numberOfResponseCategories); int sampleSize = 100 * numberOfParameters; double rarity = .01; var results = optimizer.Optimize( context, rarity, sampleSize); var partialClassifier = context.GetCategoricalEntailmentEnsembleClassifier( results.OptimalState, new List <CategoricalVariable>(trainer.FeatureVariables), trainer.ResponseVariable); return(partialClassifier); }
public void SampleGenerationParallelOptionsTest() { // value is null { string parameterName = "value"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.SampleGenerationParallelOptions = null; }, expectedType: typeof(ArgumentNullException), expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage, expectedParameterName: parameterName); } // value is valid { int maxDegreeOfParallelism = 2; var optimizer = new SystemPerformanceOptimizer { SampleGenerationParallelOptions = new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism } }; Assert.AreEqual( expected: 2, actual: optimizer .SampleGenerationParallelOptions.MaxDegreeOfParallelism); } }
public void RunTest() { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableCategoricalEntailmentEnsembleOptimizationContext01.Get(); var context = testableContext.Context; context.TraceExecution = true; // Set optimization parameters. int sampleSize = 3600; double rarity = 0.01; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); var expectedClassifier = new CategoricalEntailmentEnsembleClassifier( featureVariables: testableContext.FeatureVariables, responseVariable: testableContext.ResponseVariable); expectedClassifier.Add( featurePremises: new List <SortedSet <double> >(1) { new SortedSet <double>() { 0.0, 1.0, 2.0 } }, responseConclusion: 0.0, truthValue: 1.0); expectedClassifier.Add( featurePremises: new List <SortedSet <double> >(1) { new SortedSet <double>() { 3.0, 4.0, 5.0 } }, responseConclusion: 1.0, truthValue: 1.0); var actualClassifier = new CategoricalEntailmentEnsembleClassifier( featureVariables: testableContext.FeatureVariables, responseVariable: testableContext.ResponseVariable); actualClassifier.Add( featurePremises: new List <SortedSet <double> >(1) { new SortedSet <double>() { 0.0, 1.0, 2.0 } }, responseConclusion: 0.0, truthValue: 1.0); actualClassifier.Add( context.GetCategoricalEntailmentEnsembleClassifier( state: results.OptimalState, featureVariables: testableContext.FeatureVariables, responseVariable: testableContext.ResponseVariable) .Entailments[0]); var expectedTrainedEntailment = expectedClassifier.Entailments[1]; var actualTrainedEntailment = actualClassifier.Entailments[1]; Assert.IsTrue( expectedTrainedEntailment.FeaturePremises[0] .IsSubsetOf( actualTrainedEntailment.FeaturePremises[0])); Assert.AreEqual( expected: expectedTrainedEntailment.ResponseConclusion, actual: actualTrainedEntailment.ResponseConclusion, DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); }
public void Main() { // Set the number of items and features under study. const int numberOfItems = 12; int numberOfFeatures = 7; // Create a matrix that will represent // an artificial data set, // having 12 items (rows) and 7 features (columns). // This will store the observations which // partition discovery will be based on. var data = DoubleMatrix.Dense( numberOfRows: numberOfItems, numberOfColumns: numberOfFeatures); // Fill the data rows by sampling from a different // distribution while, respectively, drawing observations // for items 0 to 3, 4 to 7, and 8 to 11: these will be the // three different parts expected to be included in the // optimal partition. double mu = 1.0; var g = new GaussianDistribution(mu: mu, sigma: .01); IndexCollection range = IndexCollection.Range(0, 3); for (int j = 0; j < numberOfFeatures; j++) { data[range, j] = g.Sample(sampleSize: range.Count); } mu += 5.0; g.Mu = mu; range = IndexCollection.Range(4, 7); for (int j = 0; j < numberOfFeatures; j++) { data[range, j] = g.Sample(sampleSize: range.Count); } mu += 5.0; g.Mu = mu; range = IndexCollection.Range(8, 11); for (int j = 0; j < numberOfFeatures; j++) { data[range, j] = g.Sample(sampleSize: range.Count); } Console.WriteLine("The data set:"); Console.WriteLine(data); // Define the optimization problem as // the minimization of the Davies-Bouldin Index // of a candidate partition. double objectiveFunction(DoubleMatrix x) { // An argument x has 12 entries, each belonging // to the set {0,...,k-1}, where k is the // maximum number of allowed parts, so // x[j]==i signals that, at x, item j // has been assigned to part i. IndexPartition <double> selected = IndexPartition.Create(x); var performance = IndexPartition.DaviesBouldinIndex( data: data, partition: selected); return(performance); } var optimizationGoal = OptimizationGoal.Minimization; // Define the maximum number of parts allowed in the // partition to be discovered. int maximumNumberOfParts = 3; // Create the required context. var context = new PartitionOptimizationContext( objectiveFunction: objectiveFunction, stateDimension: numberOfItems, partitionDimension: maximumNumberOfParts, probabilitySmoothingCoefficient: .8, optimizationGoal: optimizationGoal, minimumNumberOfIterations: 3, maximumNumberOfIterations: 1000); // Create the optimizer. var optimizer = new SystemPerformanceOptimizer() { PerformanceEvaluationParallelOptions = { MaxDegreeOfParallelism = -1 }, SampleGenerationParallelOptions = { MaxDegreeOfParallelism = -1 } }; // Set optimization parameters. double rarity = 0.01; int sampleSize = 2000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); IndexPartition <double> optimalPartition = IndexPartition.Create(results.OptimalState); // Show the results. Console.WriteLine( "The Cross-Entropy optimizer has converged: {0}.", results.HasConverged); Console.WriteLine(); Console.WriteLine("Initial guess parameter:"); Console.WriteLine(context.InitialParameter); Console.WriteLine(); Console.WriteLine("The minimizer of the performance is:"); Console.WriteLine(results.OptimalState); Console.WriteLine(); Console.WriteLine( "The optimal partition is:"); Console.WriteLine(optimalPartition); Console.WriteLine(); Console.WriteLine("The minimum performance is:"); Console.WriteLine(results.OptimalPerformance); Console.WriteLine(); Console.WriteLine("The Dunn Index for the optimal partition is:"); var di = IndexPartition.DunnIndex( data, optimalPartition); Console.WriteLine(di); }
public void Main() { // Set the number of items and features under study. const int numberOfItems = 12; int numberOfFeatures = 7; // Define a partition that must be explained. // Three parts (clusters) are included, // containing, respectively, items 0 to 3, // 4 to 7, and 8 to 11. var partition = IndexPartition.Create( new double[numberOfItems] { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2 }); // Create a matrix that will represent // an artificial data set, // having 12 items (rows) and 7 features (columns). // This will store the observations which // explanation will be based on. var data = DoubleMatrix.Dense( numberOfRows: numberOfItems, numberOfColumns: numberOfFeatures); // The first 5 features are built to be almost // surely non informative, since they result // as samples drawn from a same distribution. var g = new GaussianDistribution(mu: 0, sigma: .01); for (int j = 0; j < 5; j++) { data[":", j] = g.Sample(sampleSize: numberOfItems); } // Features 5 to 6 are instead built to be informative, // since they are sampled from different distributions // while filling rows whose indexes are in different parts // of the partition to be explained. var partIdentifiers = partition.Identifiers; double mu = 1.0; for (int i = 0; i < partIdentifiers.Count; i++) { var part = partition[partIdentifiers[i]]; int partSize = part.Count; g.Mu = mu; data[part, 5] = g.Sample(sampleSize: partSize); mu += 2.0; g.Mu = mu; data[part, 6] = g.Sample(sampleSize: partSize); mu += 2.0; } Console.WriteLine("The data set:"); Console.WriteLine(data); // Define the selection problem as // the maximization of the Dunn Index. double objectiveFunction(DoubleMatrix x) { // An argument x has entries equal to one, // signaling that the corresponding features // are selected at x. Otherwise, the entries // are zero. IndexCollection selected = x.FindNonzero(); double performance = IndexPartition.DunnIndex( data: data[":", selected], partition: partition); return(performance); } var optimizationGoal = OptimizationGoal.Maximization; // Define how many features must be selected // for explanation. int numberOfExplanatoryFeatures = 2; // Create the required context. var context = new CombinationOptimizationContext( objectiveFunction: objectiveFunction, stateDimension: numberOfFeatures, combinationDimension: numberOfExplanatoryFeatures, probabilitySmoothingCoefficient: .8, optimizationGoal: optimizationGoal, minimumNumberOfIterations: 3, maximumNumberOfIterations: 1000); // Create the optimizer. var optimizer = new SystemPerformanceOptimizer() { PerformanceEvaluationParallelOptions = { MaxDegreeOfParallelism = -1 }, SampleGenerationParallelOptions = { MaxDegreeOfParallelism = -1 } }; // Set optimization parameters. double rarity = 0.01; int sampleSize = 1000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); IndexCollection optimalExplanatoryFeatureIndexes = results.OptimalState.FindNonzero(); // Show the results. Console.WriteLine( "The Cross-Entropy optimizer has converged: {0}.", results.HasConverged); Console.WriteLine(); Console.WriteLine("Initial guess parameter:"); Console.WriteLine(context.InitialParameter); Console.WriteLine(); Console.WriteLine("The maximizer of the performance is:"); Console.WriteLine(results.OptimalState); Console.WriteLine(); Console.WriteLine( "The {0} features best explaining the given partition have column indexes:", numberOfExplanatoryFeatures); Console.WriteLine(optimalExplanatoryFeatureIndexes); Console.WriteLine(); Console.WriteLine("The maximum performance is:"); Console.WriteLine(results.OptimalPerformance); Console.WriteLine(); Console.WriteLine("This is the Dunn Index for the selected features:"); var di = IndexPartition.DunnIndex( data[":", optimalExplanatoryFeatureIndexes], partition); Console.WriteLine(di); }
public void RunTest() { // Valid input - Minimization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableSystemPerformanceOptimizationContext00.Get(); var context = testableContext.Context; // Set optimization parameters. double rarity = 0.05; int sampleSize = 1000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, delta: .03); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } // Valid input - Maximization - with overrides { var optimizer = new SystemPerformanceOptimizer() { PerformanceEvaluationParallelOptions = { MaxDegreeOfParallelism = 1 }, SampleGenerationParallelOptions = { MaxDegreeOfParallelism = 1 } }; // Create the context. var testableContext = TestableSystemPerformanceOptimizationContext01.Get(); var context = testableContext.Context; // Set optimization parameters. double rarity = 0.1; int sampleSize = 1000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } // Valid input - Maximization - without overrides { var optimizer = new SystemPerformanceOptimizer() { PerformanceEvaluationParallelOptions = { MaxDegreeOfParallelism = 1 }, SampleGenerationParallelOptions = { MaxDegreeOfParallelism = 1 } }; // Create the context. var testableContext = TestableSystemPerformanceOptimizationContext02.Get(); var context = testableContext.Context; // Set optimization parameters. double rarity = 0.1; int sampleSize = 1000; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } }
public void RunTest() { // Valid input - Minimization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableContinuousOptimizationContext00.Get(); var context = testableContext.Context; // Set optimization parameters. int sampleSize = 100; double rarity = 0.09; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, delta: .03); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } // Valid input - Maximization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableContinuousOptimizationContext01.Get(); var context = testableContext.Context; // Set optimization parameters. int sampleSize = 100; double rarity = 0.1; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } // Valid input - Maximization - not converging { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableContinuousOptimizationContext01.Get(); var context = new ContinuousOptimizationContext( objectiveFunction: testableContext.ObjectiveFunction, initialArgument: testableContext.InitialArgument, meanSmoothingCoefficient: testableContext.MeanSmoothingCoefficient, standardDeviationSmoothingCoefficient: testableContext.StandardDeviationSmoothingCoefficient, standardDeviationSmoothingExponent: testableContext.StandardDeviationSmoothingExponent, initialStandardDeviation: testableContext.InitialStandardDeviation, terminationTolerance: testableContext.TerminationTolerance, optimizationGoal: testableContext.OptimizationGoal, minimumNumberOfIterations: testableContext.MinimumNumberOfIterations, maximumNumberOfIterations: testableContext.MinimumNumberOfIterations + 1); // Set optimization parameters. int sampleSize = 100; double rarity = 0.1; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: false, actual: results.HasConverged); } }
/// <summary> /// Finds the maximum of the specified /// parametric objective function. /// </summary> /// <param name="objectiveFunction"> /// The objective function to be maximized. /// </param> /// <param name="initialArgument"> /// The argument at which the method starts the search /// for optimality. /// </param> /// <param name="functionParameter"> /// The function parameter. /// </param> /// <typeparam name="TFunctionParameter"> /// The type of the function parameter. /// </typeparam> /// <returns> /// The argument at which the function is maximized. /// </returns> /// <remarks> /// <para> /// It is assumed that the <paramref name="objectiveFunction"/> /// will accept row /// vectors as valid representations of an argument. /// As a consequence, <paramref name="initialArgument"/> is /// expected to be a row vector. /// </para> /// </remarks> /// <example> /// <para> /// In the following example, function /// <latex mode='display'> /// f\round{x,\alpha}=\exp\round{-\round{x-2}^2} /// + \round{\alpha} \exp\round{-\round{x+2}^2} /// </latex> /// is maximized. /// </para> /// <para> /// The search for the maximizer starts from /// the initial argument <latex>-6</latex>. /// </para> /// <para> /// <code title="Maximizing a parametric function." /// source="..\Novacta.Analytics.CodeExamples\ContinuousOptimizationExample1.cs.txt" /// language="cs" /> /// </para> /// </example> /// <exception cref="ArgumentNullException"> /// <paramref name="objectiveFunction"/> is /// <b>null</b>.<br/> /// -or-<br/> /// <paramref name="initialArgument"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="initialArgument"/> is not a row /// vector. /// </exception> public static DoubleMatrix Maximize <TFunctionParameter>( Func <DoubleMatrix, TFunctionParameter, double> objectiveFunction, DoubleMatrix initialArgument, TFunctionParameter functionParameter) { #region Input validation if (objectiveFunction is null) { throw new ArgumentNullException(nameof(objectiveFunction)); } if (initialArgument is null) { throw new ArgumentNullException(nameof(initialArgument)); } if (!initialArgument.IsRowVector) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_ROW_VECTOR"), nameof(initialArgument)); } #endregion double func(DoubleMatrix x) => objectiveFunction(x, functionParameter); int numberOfArguments = initialArgument.Count; var initialParameter = DoubleMatrix.Dense( 2, numberOfArguments); initialParameter[0, ":"] = initialArgument; initialParameter[1, ":"] += 1.0e2; var optimizer = new SystemPerformanceOptimizer(); var context = new ContinuousOptimizationContext( objectiveFunction: func, initialArgument: initialArgument, meanSmoothingCoefficient: .8, standardDeviationSmoothingCoefficient: .7, standardDeviationSmoothingExponent: 6, initialStandardDeviation: 100.0, optimizationGoal: OptimizationGoal.Maximization, terminationTolerance: 1.0e-3, minimumNumberOfIterations: 3, maximumNumberOfIterations: 1000); int sampleSize = 100 * numberOfArguments; double rarity = .01; var results = optimizer.Optimize( context, rarity, sampleSize); return(results.OptimalState); }
public void EvauatePerformancesTest() { // context is null { string parameterName = "context"; string innerMessage = ArgumentExceptionAssert.NullPartialMessage + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var sample = DoubleMatrix.Dense(1, 1); ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "EvaluatePerformances", methodArgs: new object[] { null, sample }); }, expectedInnerType: typeof(ArgumentNullException), expectedInnerMessage: innerMessage); } // sample is null { string parameterName = "sample"; string innerMessage = ArgumentExceptionAssert.NullPartialMessage + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "EvaluatePerformances", methodArgs: new object[] { context, null }); }, expectedInnerType: typeof(ArgumentNullException), expectedInnerMessage: innerMessage); } // sample is not context compatible { string parameterName = "sample"; string innerMessage = ImplementationServices.GetResourceString( "STR_EXCEPT_CEP_SAMPLE_IS_CONTEXT_INCOMPATIBLE") + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "EvaluatePerformances", methodArgs: new object[] { context, DoubleMatrix.Dense(1, context.StateDimension + 1) }); }, expectedInnerType: typeof(ArgumentException), expectedInnerMessage: innerMessage); } }
public void SampleTest() { // context is null { string parameterName = "context"; string innerMessage = ArgumentExceptionAssert.NullPartialMessage + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var parameter = DoubleMatrix.Dense(1, 1); ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { null, 1, parameter }); }, expectedInnerType: typeof(ArgumentNullException), expectedInnerMessage: innerMessage); } // parameter is null { string parameterName = "parameter"; string innerMessage = ArgumentExceptionAssert.NullPartialMessage + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { context, 1, null }); }, expectedInnerType: typeof(ArgumentNullException), expectedInnerMessage: innerMessage); } // sampleSize is zero { string parameterName = "sampleSize"; string innerMessage = ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE") + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { context, 0, context.InitialParameter }); }, expectedInnerType: typeof(ArgumentOutOfRangeException), expectedInnerMessage: innerMessage); } // sampleSize is negative { string parameterName = "sampleSize"; string innerMessage = ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE") + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { context, -1, context.InitialParameter }); }, expectedInnerType: typeof(ArgumentOutOfRangeException), expectedInnerMessage: innerMessage); } // parameter is not context compatible: wrong number of rows { string parameterName = "parameter"; string innerMessage = ImplementationServices.GetResourceString( "STR_EXCEPT_CEP_PARAMETER_IS_CONTEXT_INCOMPATIBLE") + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { context, 1, DoubleMatrix.Dense( context.InitialParameter.NumberOfRows + 1, context.InitialParameter.NumberOfColumns) }); }, expectedInnerType: typeof(ArgumentException), expectedInnerMessage: innerMessage); } // parameter is not context compatible: wrong number of columns { string parameterName = "parameter"; string innerMessage = ImplementationServices.GetResourceString( "STR_EXCEPT_CEP_PARAMETER_IS_CONTEXT_INCOMPATIBLE") + " (Parameter '" + parameterName + "')"; var optimizer = new SystemPerformanceOptimizer(); var context = TestableSystemPerformanceOptimizationContext00.Get().Context; ExceptionAssert.InnerThrow( () => { Reflector.ExecuteBaseMember( obj: optimizer, methodName: "Sample", methodArgs: new object[] { context, 1, DoubleMatrix.Dense( context.InitialParameter.NumberOfRows, context.InitialParameter.NumberOfColumns + 1) }); }, expectedInnerType: typeof(ArgumentException), expectedInnerMessage: innerMessage); } }
/// <summary> /// Explains existing clusters by selecting /// a number of features from the specified corresponding data set. /// </summary> /// <param name="data"> /// The matrix whose columns contain the features observed at the /// items under study. /// </param> /// <param name="partition"> /// A partition of the row indexes valid for <paramref name="data"/>. /// </param> /// <param name="numberOfExplanatoryFeatures"> /// The number of features to be selected. /// </param> /// <remarks> /// <para> /// Method <see cref="Explain( /// DoubleMatrix, IndexPartition{double}, int)"/> /// selects the specified <paramref name="numberOfExplanatoryFeatures"/> /// from the given /// <paramref name="data"/>, by minimizing the Davies-Bouldin /// Index corresponding to /// the <paramref name="partition"/> of the items under study. /// </para> /// <para> /// This method uses a default Cross-Entropy context of /// type <see cref="CombinationOptimizationContext"/> to identify the /// optimal features. /// If different selection criteria need to be applied, /// or extra control on the /// parameters of the underlying algorithm is required, /// a specialized <see cref="CombinationOptimizationContext"/> can be /// can be instantiated and hence exploited executing /// method <see cref="SystemPerformanceOptimizer.Optimize( /// SystemPerformanceOptimizationContext, double, int)">Optimize</see> /// on a <see cref="SystemPerformanceOptimizer"/> object. /// See the documentation about <see cref="CombinationOptimizationContext"/> /// for additional examples. /// </para> /// </remarks> /// <example> /// <para> /// In the following example, an existing partition of 12 items is explained /// by selecting 2 features out of the seven ones available in /// an artificial data set regarding the items under study. /// </para> /// <para> /// <code title="Selecting features from a data set to explain a given partition." /// source="..\Novacta.Analytics.CodeExamples\ClustersExplainExample0.cs.txt" /// language="cs" /> /// </para> /// </example> /// <returns> /// The collection of column indexes, valid for <paramref name="data"/>, that /// correspond to the features selected to explain the /// given <paramref name="partition"/> of row indexes. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> is <b>null</b>.<br/> /// -or-<br/> /// <paramref name="partition"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="numberOfExplanatoryFeatures"/> is not positive. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="numberOfExplanatoryFeatures"/> is not less than /// the number of columns in <paramref name="data"/>.<br/> /// -or-<br/> /// A part in <paramref name="partition"/> contains a position /// which is not valid as a row index of <paramref name="data"/>. /// </exception> /// <seealso cref="IndexPartition.DaviesBouldinIndex( /// DoubleMatrix, IndexPartition{double})"/> /// <seealso cref="CombinationOptimizationContext"/> /// <seealso cref="SystemPerformanceOptimizer"/> public static IndexCollection Explain( DoubleMatrix data, IndexPartition <double> partition, int numberOfExplanatoryFeatures) { #region Input validation if (data is null) { throw new ArgumentNullException(nameof(data)); } if (numberOfExplanatoryFeatures < 1) { throw new ArgumentOutOfRangeException( nameof(numberOfExplanatoryFeatures), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE")); } int stateDimension = data.NumberOfColumns; if (stateDimension <= numberOfExplanatoryFeatures) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_COLUMNS"), nameof(numberOfExplanatoryFeatures), nameof(data)), nameof(numberOfExplanatoryFeatures) ); } if (partition is null) { throw new ArgumentNullException(nameof(partition)); } #endregion double objectiveFunction(DoubleMatrix x) { IndexCollection selected = x.FindNonzero(); double performance = IndexPartition.DaviesBouldinIndex( data: data[":", selected], partition: partition); return(performance); } var optimizer = new SystemPerformanceOptimizer(); var context = new CombinationOptimizationContext( objectiveFunction: objectiveFunction, stateDimension: stateDimension, combinationDimension: numberOfExplanatoryFeatures, probabilitySmoothingCoefficient: .8, optimizationGoal: OptimizationGoal.Minimization, minimumNumberOfIterations: 3, maximumNumberOfIterations: 1000); double rarity = .01; int sampleSize = 1000 * stateDimension; var results = optimizer.Optimize( context, rarity, sampleSize); var optimalState = results.OptimalState; return(optimalState.FindNonzero()); }
public void RunTest() { // Valid input - Minimization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableCombinationOptimizationContext00.Get(); var context = testableContext.Context; // Set optimization parameters. int sampleSize = 300; double rarity = 0.01; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, delta: .03); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } // Valid input - Maximization { var optimizer = new SystemPerformanceOptimizer(); // Create the context. var testableContext = TestableCombinationOptimizationContext01.Get(); var context = testableContext.Context; // Set optimization parameters. int sampleSize = 300; double rarity = 0.01; // Solve the problem. var results = optimizer.Optimize( context, rarity, sampleSize); Assert.AreEqual( expected: true, actual: results.HasConverged); DoubleMatrixAssert.AreEqual( expected: testableContext.OptimalState, actual: results.OptimalState, DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: testableContext.OptimalPerformance, actual: results.OptimalPerformance, DoubleMatrixTest.Accuracy); } }
/// <summary> /// Discovers optimal clusters /// in a data set. /// </summary> /// <param name="maximumNumberOfParts"> /// The maximum number of parts allowed in the optimal /// partition. /// </param> /// <param name="data"> /// The matrix whose rows contain the observations for the /// items under study. /// </param> /// <remarks> /// <para> /// Method <see cref="Discover(DoubleMatrix, int)"/> partitions /// a collection of items in no more than the specified /// <paramref name="maximumNumberOfParts"/>, /// given the specified <paramref name="data"/>, by minimizing the sum of /// intra-cluster squared deviations. /// </para> /// <para> /// This method uses a default Cross-Entropy context of /// type <see cref="PartitionOptimizationContext"/> to identify the /// optimal partition. /// If different partitioning criteria need to be applied, /// or extra control on the /// parameters of the underlying algorithm is required, /// a specialized <see cref="PartitionOptimizationContext"/> can be /// can be instantiated and hence exploited executing /// method <see cref="SystemPerformanceOptimizer.Optimize( /// SystemPerformanceOptimizationContext, double, int)">Optimize</see> /// on a <see cref="SystemPerformanceOptimizer"/> object. /// See the documentation about <see cref="PartitionOptimizationContext"/> /// for additional examples. /// </para> /// </remarks> /// <example> /// <para> /// In the following example, a partition that optimally split 12 items /// is discovered /// given /// an artificial data set regarding the items under study. /// </para> /// <para> /// <code title="Optimal partitioning of a data set." /// source="..\Novacta.Analytics.CodeExamples\ClustersDiscoverExample0.cs.txt" /// language="cs" /> /// </para> /// </example> /// <returns> /// A partition of the row indexes valid for <paramref name="data"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="maximumNumberOfParts"/> is not greater than one. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="maximumNumberOfParts"/> is not less than /// the number of rows in <paramref name="data"/>. /// </exception> /// <seealso cref="PartitionOptimizationContext"/> /// <seealso cref="SystemPerformanceOptimizer"/> public static IndexPartition <double> Discover( DoubleMatrix data, int maximumNumberOfParts) { #region Input validation if (data is null) { throw new ArgumentNullException(nameof(data)); } if (maximumNumberOfParts < 2) { throw new ArgumentOutOfRangeException( nameof(maximumNumberOfParts), string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"), "1")); } int stateDimension = data.NumberOfRows; if (stateDimension <= maximumNumberOfParts) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS"), nameof(maximumNumberOfParts), nameof(data)), nameof(maximumNumberOfParts) ); } #endregion double objectiveFunction(DoubleMatrix x) { double performance = 0.0; var partition = IndexPartition.Create(x); foreach (double category in partition.Identifiers) { performance += Stat.Sum( Stat.SumOfSquaredDeviations( data[partition[category], ":"], DataOperation.OnColumns)); } return(performance); } var optimizer = new SystemPerformanceOptimizer(); var context = new PartitionOptimizationContext( objectiveFunction: objectiveFunction, stateDimension: stateDimension, partitionDimension: maximumNumberOfParts, probabilitySmoothingCoefficient: .8, optimizationGoal: OptimizationGoal.Minimization, minimumNumberOfIterations: 3, maximumNumberOfIterations: 1000); double rarity = .01; int sampleSize = 500 * maximumNumberOfParts; var results = optimizer.Optimize( context, rarity, sampleSize); return(IndexPartition.Create(results.OptimalState)); }
public void OptimizeTest() { // context is null { string parameterName = "context"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: null, rarity: 0.1, sampleSize: 1000); }, expectedType: typeof(ArgumentNullException), expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage, expectedParameterName: parameterName); } // rarity is less than 0 { var STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL"), 0.0, 1.0); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: -0.1, sampleSize: 1000); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL, expectedParameterName: parameterName); } // rarity is equal to 0 { var STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL"), 0.0, 1.0); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: 0.0, sampleSize: 1000); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL, expectedParameterName: parameterName); } // rarity is greater than 1 { var STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL"), 0.0, 1.0); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: 1.1, sampleSize: 1000); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL, expectedParameterName: parameterName); } // rarity is equal to 1 { var STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL"), 0.0, 1.0); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: 1.0, sampleSize: 1000); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_NOT_IN_OPEN_INTERVAL, expectedParameterName: parameterName); } // rarity is too low given context and sample size { var STR_EXCEPT_CEM_TOO_LOW_RARITY = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_CEM_TOO_LOW_RARITY"), "sampleSize"); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext02 .Get().Context, rarity: .01, sampleSize: 50); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_CEM_TOO_LOW_RARITY, expectedParameterName: parameterName); } // rarity is too high given context and sample size { var STR_EXCEPT_CEM_TOO_HIGH_RARITY = String.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_CEM_TOO_HIGH_RARITY"), "sampleSize"); string parameterName = "rarity"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: .99, sampleSize: 50); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_CEM_TOO_HIGH_RARITY, expectedParameterName: parameterName); } // sampleSize is not positive { var STR_EXCEPT_PAR_MUST_BE_POSITIVE = ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE"); string parameterName = "sampleSize"; var optimizer = new SystemPerformanceOptimizer(); ArgumentExceptionAssert.Throw( () => { optimizer.Optimize( context: TestableSystemPerformanceOptimizationContext00 .Get().Context, rarity: 0.1, sampleSize: 0); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_POSITIVE, expectedParameterName: parameterName); } }