Esempio n. 1
0
        public void StateBuilder_KMeansType()
        {
            // Arrange
            KMeansResult result = new KMeansResult()
            {
                Coordinator      = new Point(1, 1),
                Note             = ENote.C,
                NumberOfElements = 100,
                Pixel            = Color.Red
            };

            StatesBuilder stateBuilder = new StatesBuilder(new List <IResult>()
            {
                result
            }, EModelType.KMeans);

            // Act
            List <IState> states = stateBuilder.Build();

            // Arrange
            Assert.IsFalse(states.IsNullOrEmpty());
            states.ForEach(s =>
            {
                Assert.IsTrue(s.ModelType == EModelType.KMeans);
                Assert.IsInstanceOfType(s, typeof(KMeansState));
                Assert.IsNotNull(((KMeansState)s).Element);
            });
        }
Esempio n. 2
0
        private KMeansResult OneDimentinalKMeans(IEnumerable <double> values, int k)
        {
            var           ordered       = values.OrderBy(x => x);
            var           first         = ordered.First();
            var           last          = ordered.Last();
            var           sampleRange   = last - first;
            var           partitionSize = sampleRange / (double)k;
            List <double> means         = Enumerable.Repeat(0.0, k).ToList();

            for (int i = 0; i < k; i++)
            {
                means[i] = i * partitionSize + first;
            }

            double iterChange = double.PositiveInfinity;

            //iterate until little has changed
            while (iterChange > 0.001)
            {
                var newMeans = PerformKMeansIteration(values, k, means);

                iterChange = 0;
                for (int i = 0; i < means.Count; ++i)
                {
                    iterChange += Math.Abs(newMeans[i] - means[i]);
                }

                means = newMeans;
            }

            KMeansResult res = new KMeansResult()
            {
                GroupAssignments = GetCluseters(values, means), Means = means
            };

            return(res);
        }
Esempio n. 3
0
        private KMeansResult RemoveRedundantClusters(KMeansResult kmeans, int precentOfSamplesConsideredTooSmall = 5)
        {
            var fivePercent     = ((double)kmeans.GroupAssignments.Count()) * ((double)precentOfSamplesConsideredTooSmall / 100d);
            var groups          = kmeans.GroupAssignments.GroupBy(p => p.Value);
            var removedGroups   = groups.Where(g => g.Count() < fivePercent).Select(g => g.Key);
            var remainingGroups = groups.Where(g => g.Count() >= fivePercent).Select(g => g.Key);
            var switchMap       = new Dictionary <int, int>();

            //create a map so we can reassign the points
            foreach (var group in removedGroups)
            {
                for (int i = group - 1; i >= 0; i--)
                {
                    if (remainingGroups.Contains(i))
                    {
                        switchMap.Add(group, i);
                        break;
                    }
                }

                if (!switchMap.ContainsKey(group))
                {
                    for (int i = group + 1; i <= kmeans.Means.Count; i++)
                    {
                        if (remainingGroups.Contains(i))
                        {
                            switchMap.Add(group, i);
                            break;
                        }
                    }
                }
            }

            int idx = 0;

            foreach (var group in remainingGroups.OrderBy(g => g))
            {
                switchMap.Add(group, idx);
                ++idx;
            }

            //unpdate switchmap with the index changes of the remaining groups
            foreach (var key in switchMap.Keys.ToList())
            {
                if (removedGroups.Contains(key))
                {
                    switchMap[key] = switchMap[switchMap[key]];
                }
            }

            //remove groups from means list
            List <double> newMeans = kmeans.Means.Where((m, i) => remainingGroups.Contains(i)).ToList();

            Dictionary <double, int> gAssignments = new Dictionary <double, int>();

            kmeans.GroupAssignments.ToList().ForEach(a =>
            {
                gAssignments.Add(a.Key, switchMap[a.Value]);
            });

            return(new KMeansResult()
            {
                Means = newMeans, GroupAssignments = gAssignments
            });
        }