コード例 #1
0
        private int[] compute(double[][] points)
        {
            // first, select initial points
            double[][] seeds         = createSeeds(points, 2 * Bandwidth);
            var        maxcandidates = new ConcurrentStack <double[]>();

            // construct map of the data
            tree = KDTree.FromData <int>(points, distance);

            // now, for each initial point
            if (UseParallelProcessing)
            {
                Parallel.For(0, seeds.Length, (index) =>
                             iterate(seeds, maxcandidates, index));
            }
            else
            {
                for (int index = 0; index < seeds.Length; index++)
                {
                    iterate(seeds, maxcandidates, index);
                }
            }


            // suppress non-maximum points
            double[][] maximum = cut ? maxcandidates.ToArray() : supress(seeds);

            // create a decision map using seeds
            int[] seedLabels = classifySeeds(seeds, maximum);
            tree = KDTree.FromData(seeds, seedLabels, distance);

            // create the cluster structure
            clusters = new MeanShiftClusterCollection(tree, maximum);

            // label each point
            return(clusters.Nearest(points));
        }
コード例 #2
0
ファイル: MeanShift.cs プロジェクト: zhenyao2008/ai4unity
        /// <summary>
        ///   Divides the input data into clusters.
        /// </summary>
        ///
        /// <param name="points">The data where to compute the algorithm.</param>
        /// <param name="threshold">The relative convergence threshold
        /// for the algorithm. Default is 1e-3.</param>
        /// <param name="maxIterations">The maximum number of iterations. Default is 100.</param>
        ///
        public int[] Compute(double[][] points, double threshold, int maxIterations = 100)
        {
            // first, select initial points
            double[][] seeds         = createSeeds(points, 2 * Bandwidth);
            var        maxcandidates = new ConcurrentStack <double[]>();

            // construct map of the data
            tree = KDTree.FromData <int>(points, distance);

            // now, for each initial point
            global::Accord.Threading.Tasks.Parallel.For(0, seeds.Length,
#if DEBUG
                                                        new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1
            },
#endif

                                                        (index) =>
            {
                double[] point = seeds[index];
                double[] mean  = new double[point.Length];
                double[] delta = new double[point.Length];

                // we will keep moving it in the
                // direction of the density modes

                int iterations = 0;

                // until convergence or max iterations reached
                while (iterations < maxIterations)
                {
                    iterations++;

                    // compute the shifted mean
                    computeMeanShift(point, mean);

                    // extract the mean shift vector
                    for (int j = 0; j < mean.Length; j++)
                    {
                        delta[j] = point[j] - mean[j];
                    }

                    // update the point towards a mode
                    for (int j = 0; j < mean.Length; j++)
                    {
                        point[j] = mean[j];
                    }

                    // Check if we are already near any maximum point
                    if (cut && nearest(point, maxcandidates) != null)
                    {
                        break;
                    }

                    // check for convergence: magnitude of the mean shift
                    // vector converges to zero (Comaniciu 2002, page 606)
                    if (Norm.Euclidean(delta) < threshold * Bandwidth)
                    {
                        break;
                    }
                }

                if (cut)
                {
                    double[] match = nearest(point, maxcandidates);

                    if (match != null)
                    {
                        seeds[index] = match;
                    }

                    else
                    {
                        maxcandidates.Push(point);
                    }
                }
            });


            // suppress non-maximum points
            double[][] maximum = cut ? maxcandidates.ToArray() : supress(seeds);

            // create a decision map using seeds
            int[] seedLabels = classifySeeds(seeds, maximum);
            tree = KDTree.FromData(seeds, seedLabels, distance);

            // create the cluster structure
            clusters = new MeanShiftClusterCollection(tree, maximum);

            // label each point
            return(clusters.Nearest(points));
        }