Ejemplo n.º 1
0
        private static IEnumerable <Assignment> AngularCluster(IList <Matrix <double> > features, ulong numberClusters)
        {
            if (features == null)
            {
                throw new ArgumentNullException(nameof(features));
            }

            var size = features.Count;

            if (size == 0)
            {
                throw new ArgumentException("The dataset can't be empty", nameof(features));
            }

            var featureSize = features[0].Size;

            for (var index = 0; index < size; ++index)
            {
                if (features[index].Size != featureSize)
                {
                    throw new ArgumentException("All feature vectors must have the same length.", nameof(features));
                }
            }

            // find the centroid of feats
            Matrix <double> tmp;
            var             m = Matrix <double> .CreateTemplateParameterizeMatrix(0, 1);

            for (var index = 0; index < size; ++index)
            {
                tmp = m + features[index];
                m.Dispose();
                m = tmp;
            }

            tmp = m;
            m   = tmp / size;
            tmp.Dispose();

            // Now center feats and then project onto the unit sphere.  The reason for projecting
            // onto the unit sphere is so pick_initial_centers() works in a sensible way.
            for (var index = 0; index < size; ++index)
            {
                tmp = features[index] - m;
                features[index].Dispose();
                features[index] = tmp;

                var length = Dlib.Length(features[index]);
                if (Math.Abs(length) > double.Epsilon)
                {
                    tmp = features[index] / length;
                    features[index].Dispose();
                    features[index] = tmp;
                }
            }

            // now do angular clustering of the points
            var linearKernel = new LinearKernel <Matrix <double> >(0, 1);
            var tempCenters  = Dlib.PickInitialCenters((int)numberClusters, features, linearKernel, 0.05).ToArray();
            var centers      = Dlib.FindClustersUsingAngularKMeans(features, tempCenters).ToArray();

            foreach (var center in tempCenters)
            {
                center.Dispose();
            }
            linearKernel.Dispose();

            // and then report the resulting assignments
            var assignments = new List <Assignment>(size);

            for (var index = 0; index < size; ++index)
            {
                var temp = new Assignment();
                temp.C = Dlib.NearestCenter(centers, features[index]);
                using (var temp2 = features[index] - centers[temp.C])
                    temp.Distance = Dlib.Length(temp2);
                temp.Index = (ulong)index;
                assignments.Add(temp);
            }

            return(assignments);
        }