public void DiscoverTest() { // data is null { string parameterName = "data"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: null, maximumNumberOfParts: 2); }, expectedType: typeof(ArgumentNullException), expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage, expectedParameterName: parameterName); } // maximumNumberOfParts is one { var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"), "1"); string parameterName = "maximumNumberOfParts"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: DoubleMatrix.Dense(10, 5), maximumNumberOfParts: 1); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE, expectedParameterName: parameterName); } // maximumNumberOfParts is zero { var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"), "1"); string parameterName = "maximumNumberOfParts"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: DoubleMatrix.Dense(10, 5), maximumNumberOfParts: 0); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE, expectedParameterName: parameterName); } // maximumNumberOfParts is negative { var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"), "1"); string parameterName = "maximumNumberOfParts"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: DoubleMatrix.Dense(10, 5), maximumNumberOfParts: -1); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE, expectedParameterName: parameterName); } // maximumNumberOfParts is equal to the number of rows in data { var STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS"), "maximumNumberOfParts", "data"); string parameterName = "maximumNumberOfParts"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: DoubleMatrix.Dense(10, 5), maximumNumberOfParts: 10); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS, expectedParameterName: parameterName); } // maximumNumberOfParts is greater than the number of rows in data { var STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS"), "maximumNumberOfParts", "data"); string parameterName = "maximumNumberOfParts"; ArgumentExceptionAssert.Throw( () => { Clusters.Discover( data: DoubleMatrix.Dense(10, 5), maximumNumberOfParts: 11); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS, expectedParameterName: parameterName); } // Valid input { const int numberOfItems = 12; const int numberOfFeatures = 7; var source = DoubleMatrix.Dense(numberOfItems, 1, new double[numberOfItems] { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2 }); var expectedPartition = IndexPartition.Create(source); var data = DoubleMatrix.Dense(numberOfItems, numberOfFeatures); double mu = 1.0; var partIdentifiers = expectedPartition.Identifiers; for (int i = 0; i < partIdentifiers.Count; i++) { var part = expectedPartition[partIdentifiers[i]]; int partSize = part.Count; for (int j = 0; j < partSize; j++) { data[part[j], ":"] += mu; } mu += 5.0; } var actualPartition = Clusters.Discover( data: data, maximumNumberOfParts: 3); IndexPartitionAssert.HaveEqualIdentifiers( expected: expectedPartition, actual: actualPartition); IndexPartitionAssert.HaveEqualParts( expected: expectedPartition, actual: actualPartition); } }
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 maximum number of parts allowed in the // partition to be discovered. int maximumNumberOfParts = 3; // Select the best partition. IndexPartition <double> optimalPartition = Clusters.Discover( data, maximumNumberOfParts); // Show the results. Console.WriteLine(); Console.WriteLine( "The optimal partition:"); Console.WriteLine(optimalPartition); Console.WriteLine(); Console.WriteLine("The Davies-Bouldin Index for the optimal partition:"); var dbi = IndexPartition.DaviesBouldinIndex( data, optimalPartition); Console.WriteLine(dbi); }