private UnivariateContinuousDistribution GetDistribution(double [] samples) { if (samples.Length < 10) { return(new EmpiricalDistribution(samples)); } else { Accord.Math.Random.Generator.Seed = 0; // determining the optimal number of clusters is not easy, we use // a simple heuristics based on the numeber of samples var clusterCount = (int)Math.Ceiling(Math.Log(samples.Length, 10)); var kmean = new KMeans(clusterCount); var clusters = kmean.Learn(samples.Select(x => new double[] { x }).ToArray()); var components = new NormalDistribution[clusters.Count]; for (int i = 0; i < clusters.Count; i++) { var cluster = clusters[i]; components[i] = new NormalDistribution(cluster.Centroid.First()); //, cluster.Proportion); } var mix = new Mixture <NormalDistribution>(components); mix.Fit(samples); return(mix); } }
/// <summary> /// Divides the input data into K clusters modeling each /// cluster as a multivariate Gaussian distribution. /// </summary> public double Compute(double[][] data, GaussianMixtureModelOptions options) { if (data == null) { throw new ArgumentNullException("data"); } int components = this.clusters.Count; if (model == null) { // TODO: Perform K-Means multiple times to avoid // a poor Gaussian Mixture model initialization. double error = Initialize(data, options.Threshold); } // Fit a multivariate Gaussian distribution var mixtureOptions = new MixtureOptions() { Threshold = options.Threshold, InnerOptions = options.NormalOptions, }; model.Fit(data, mixtureOptions); // Return the log-likelihood as a measure of goodness-of-fit return(model.LogLikelihood(data)); }
public void MixtureWeightsFitTest() { // Randomly initialize some mixture components NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); // Create an initial mixture Mixture <NormalDistribution> mixture = new Mixture <NormalDistribution>(components); // Now, suppose we have a weighted data set. Those will be the input points: double[] points = { 0, 3, 1, 7, 3, 5, 1, 2, -1, 2, 7, 6, 8, 6 }; // (14 points) // And those are their respective unnormalized weights: double[] weights = { 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 2, 3, 1, 1 }; // (14 weights) // Let's normalize the weights so they sum up to one: weights = weights.Divide(weights.Sum()); // Now we can fit our model to the data: mixture.Fit(points, weights); // done! // Our model will be: double mean1 = mixture.Components[0].Mean; // 1.41126 double mean2 = mixture.Components[1].Mean; // 6.53301 // With mixture coefficients double pi1 = mixture.Coefficients[0]; // 0.51408489193241225 double pi2 = mixture.Coefficients[1]; // 0.48591510806758775 Assert.AreEqual(1.4112610766836411, mean1); Assert.AreEqual(6.5330177004151064, mean2); Assert.AreEqual(0.51408489193241225, pi1); Assert.AreEqual(0.48591510806758775, pi2); /* * // If we need the GaussianMixtureModel functionality, we can * // use the estimated mixture to initialize a new model: * GaussianMixtureModel gmm = new GaussianMixtureModel(mixture); * * Assert.AreEqual(mean1, gmm.Gaussians[0].Mean[0]); * Assert.AreEqual(mean2, gmm.Gaussians[1].Mean[0]); * * Assert.AreEqual(mean1, 1.4112610766836404, 1e-15); * Assert.AreEqual(mean2, 6.5330177004151082, 1e-14); * * Assert.AreEqual(mixture.Coefficients[0], gmm.Gaussians[0].Proportion); * Assert.AreEqual(mixture.Coefficients[1], gmm.Gaussians[1].Proportion); */ }
public void FitTest() { double[] coefficients = { 0.50, 0.50 }; NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); var target = new Mixture <NormalDistribution>(coefficients, components); double[] values = { 0, 1, 1, 0, 1, 6, 6, 5, 7, 5 }; double[] part1 = values.Submatrix(0, 4); double[] part2 = values.Submatrix(5, 9); MixtureOptions options = new MixtureOptions() { Threshold = 1e-10 }; target.Fit(values, options); var actual = target; var mean1 = Accord.Statistics.Tools.Mean(part1); var var1 = Accord.Statistics.Tools.Variance(part1); Assert.AreEqual(mean1, actual.Components[0].Mean, 1e-6); Assert.AreEqual(var1, actual.Components[0].Variance, 1e-6); var mean2 = Accord.Statistics.Tools.Mean(part2); var var2 = Accord.Statistics.Tools.Variance(part2); Assert.AreEqual(mean2, actual.Components[1].Mean, 1e-6); Assert.AreEqual(var2, actual.Components[1].Variance, 1e-5); var expectedMean = Accord.Statistics.Tools.Mean(values); var actualMean = actual.Mean; Assert.AreEqual(expectedMean, actualMean, 1e-7); var expectedVar = Accord.Statistics.Tools.Variance(values, false); var actualVar = actual.Variance; Assert.AreEqual(expectedVar, actualVar, 0.15); }
public void FitTest2() { double[] coefficients = { 0.50, 0.50 }; NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); var target = new Mixture <NormalDistribution>(coefficients, components); double[] values = { 12512, 1, 1, 0, 1, 6, 6, 5, 7, 5 }; double[] weights = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; weights = weights.Divide(weights.Sum()); double[] part1 = values.Submatrix(1, 4); double[] part2 = values.Submatrix(5, 9); MixtureOptions opt = new MixtureOptions() { Threshold = 0.000001 }; target.Fit(values, weights, opt); var mean1 = Accord.Statistics.Tools.Mean(part1); var var1 = Accord.Statistics.Tools.Variance(part1); Assert.AreEqual(mean1, target.Components[0].Mean, 1e-5); Assert.AreEqual(var1, target.Components[0].Variance, 1e-5); var mean2 = Accord.Statistics.Tools.Mean(part2); var var2 = Accord.Statistics.Tools.Variance(part2); Assert.AreEqual(mean2, target.Components[1].Mean, 1e-5); Assert.AreEqual(var2, target.Components[1].Variance, 1e-5); var expectedMean = Accord.Statistics.Tools.WeightedMean(values, weights); var actualMean = target.Mean; Assert.AreEqual(expectedMean, actualMean, 1e-5); }
public void MixtureDistributionExample() { var samples1 = new NormalDistribution(mean: -2, stdDev: 1).Generate(10000000); var samples2 = new NormalDistribution(mean: +4, stdDev: 1).Generate(10000000); // Mix the samples from both distributions var samples = samples1.Concatenate(samples2); // Create a new mixture distribution with two Normal components var mixture = new Mixture <NormalDistribution>( new NormalDistribution(-1), new NormalDistribution(+1)); // Estimate the distribution mixture.Fit(samples); var a = mixture.Components[0].ToString("N2"); // N(x; μ = -2.00, σ² = 1.00) var b = mixture.Components[1].ToString("N2"); // N(x; μ = 4.00, σ² = 1.02) Assert.AreEqual("N(x; μ = -2.00, σ² = 0.99)", a); Assert.AreEqual("N(x; μ = 4.00, σ² = 1.01)", b); }
public void MixtureFitTest() { var samples1 = new NormalDistribution(mean: -2, stdDev: 0.5).Generate(100000); var samples2 = new NormalDistribution(mean: +4, stdDev: 0.5).Generate(100000); // Mix the samples from both distributions var samples = samples1.Concatenate(samples2); // Create a new mixture distribution with two Normal components var mixture = new Mixture <NormalDistribution>(new[] { 0.2, 0.8 }, new NormalDistribution(-1), new NormalDistribution(+1)); // Estimate the distribution mixture.Fit(samples, new MixtureOptions { Iterations = 50, Threshold = 0 }); var result = mixture.ToString("N2", System.Globalization.CultureInfo.InvariantCulture); Assert.AreEqual("Mixture(x; 0.50*N(x; μ = -2.00, σ² = 0.25) + 0.50*N(x; μ = 4.00, σ² = 0.25))", result); }
public void MixtureWeightsFitTest() { // Randomly initialize some mixture components NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); // Create an initial mixture Mixture<NormalDistribution> mixture = new Mixture<NormalDistribution>(components); // Now, suppose we have a weighted data // set. Those will be the input points: double[] points = { 0, 3, 1, 7, 3, 5, 1, 2, -1, 2, 7, 6, 8, 6 }; // (14 points) // And those are their respective unormalized weights: double[] weights = { 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 2, 3, 1, 1 }; // (14 weights) // Let's normalize the weights so they sum up to one: weights = weights.Divide(weights.Sum()); // Now we can fit our model to the data: mixture.Fit(points, weights); // done! // Our model will be: double mean1 = mixture.Components[0].Mean; // 1.41126 double mean2 = mixture.Components[1].Mean; // 6.53301 // If we need the GaussianMixtureModel functionality, we can // use the estimated mixture to initialize a new model: GaussianMixtureModel gmm = new GaussianMixtureModel(mixture); Assert.AreEqual(mean1, gmm.Gaussians[0].Mean[0]); Assert.AreEqual(mean2, gmm.Gaussians[1].Mean[0]); Assert.AreEqual(mean1, 1.4112610766836404, 1e-15); Assert.AreEqual(mean2, 6.5330177004151082, 1e-14); Assert.AreEqual(mixture.Coefficients[0], gmm.Gaussians[0].Proportion); Assert.AreEqual(mixture.Coefficients[1], gmm.Gaussians[1].Proportion); }
public void FitTest2() { double[] coefficients = { 0.50, 0.50 }; NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); var target = new Mixture<NormalDistribution>(coefficients, components); double[] values = { 12512, 1, 1, 0, 1, 6, 6, 5, 7, 5 }; double[] weights = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; weights = weights.Divide(weights.Sum()); double[] part1 = values.Submatrix(1, 4); double[] part2 = values.Submatrix(5, 9); MixtureOptions opt = new MixtureOptions() { Threshold = 0.000001 }; target.Fit(values, weights, opt); var mean1 = Accord.Statistics.Tools.Mean(part1); var var1 = Accord.Statistics.Tools.Variance(part1); Assert.AreEqual(mean1, target.Components[0].Mean, 1e-5); Assert.AreEqual(var1, target.Components[0].Variance, 1e-5); var mean2 = Accord.Statistics.Tools.Mean(part2); var var2 = Accord.Statistics.Tools.Variance(part2); Assert.AreEqual(mean2, target.Components[1].Mean, 1e-5); Assert.AreEqual(var2, target.Components[1].Variance, 1e-5); var expectedMean = Accord.Statistics.Tools.WeightedMean(values, weights); var actualMean = target.Mean; Assert.AreEqual(expectedMean, actualMean, 1e-5); }
public void FitTest() { double[] coefficients = { 0.50, 0.50 }; NormalDistribution[] components = new NormalDistribution[2]; components[0] = new NormalDistribution(2, 1); components[1] = new NormalDistribution(5, 1); var target = new Mixture<NormalDistribution>(coefficients, components); double[] values = { 0, 1, 1, 0, 1, 6, 6, 5, 7, 5 }; double[] part1 = values.Submatrix(0, 4); double[] part2 = values.Submatrix(5, 9); MixtureOptions options = new MixtureOptions() { Threshold = 1e-10 }; target.Fit(values, options); var actual = target; var mean1 = Accord.Statistics.Tools.Mean(part1); var var1 = Accord.Statistics.Tools.Variance(part1); Assert.AreEqual(mean1, actual.Components[0].Mean, 1e-6); Assert.AreEqual(var1, actual.Components[0].Variance, 1e-6); var mean2 = Accord.Statistics.Tools.Mean(part2); var var2 = Accord.Statistics.Tools.Variance(part2); Assert.AreEqual(mean2, actual.Components[1].Mean, 1e-6); Assert.AreEqual(var2, actual.Components[1].Variance, 1e-5); var expectedMean = Accord.Statistics.Tools.Mean(values); var actualMean = actual.Mean; Assert.AreEqual(expectedMean, actualMean, 1e-7); var expectedVar = Accord.Statistics.Tools.Variance(values, false); var actualVar = actual.Variance; Assert.AreEqual(expectedVar, actualVar, 0.15); }
public void MixtureDistributionExample() { var samples1 = new NormalDistribution(mean: -2, stdDev: 1).Generate(100000); var samples2 = new NormalDistribution(mean: +4, stdDev: 1).Generate(100000); // Mix the samples from both distributions var samples = samples1.Concatenate(samples2); // Create a new mixture distribution with two Normal components var mixture = new Mixture<NormalDistribution>( new NormalDistribution(-1), new NormalDistribution(+1)); // Estimate the distribution mixture.Fit(samples); var a = mixture.Components[0].ToString("N2"); // N(x; μ = -2.00, σ² = 1.00) var b = mixture.Components[1].ToString("N2"); // N(x; μ = 4.00, σ² = 1.02) Assert.AreEqual("N(x; μ = -2.00, σ² = 1.00)", a); Assert.AreEqual("N(x; μ = 4.00, σ² = 1.02)", b); }
public void MixtureFitTest() { var samples1 = new NormalDistribution(mean: -2, stdDev: 0.5).Generate(100000); var samples2 = new NormalDistribution(mean: +4, stdDev: 0.5).Generate(100000); // Mix the samples from both distributions var samples = samples1.Concatenate(samples2); // Create a new mixture distribution with two Normal components var mixture = new Mixture<NormalDistribution>(new[] { 0.2, 0.8 }, new NormalDistribution(-1), new NormalDistribution(+1)); // Estimate the distribution mixture.Fit(samples, new MixtureOptions { Iterations = 50, Threshold = 0 }); var result = mixture.ToString("N2", System.Globalization.CultureInfo.InvariantCulture); Assert.AreEqual("Mixture(x; 0.50*N(x; μ = -2.00, σ² = 0.25) + 0.50*N(x; μ = 4.00, σ² = 0.25))", result); }