예제 #1
0
        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);
            }
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }