From 2325bbcb34b86e87c759f134263bacd1bc6f4991 Mon Sep 17 00:00:00 2001 From: Esiur Project Date: Thu, 1 Dec 2022 17:11:44 +0300 Subject: [PATCH] KMean --- .../Statistics/StatisticalFunctions.cs | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/Esiur.Analysis/Statistics/StatisticalFunctions.cs b/Esiur.Analysis/Statistics/StatisticalFunctions.cs index fbcfe04..f2ac41c 100644 --- a/Esiur.Analysis/Statistics/StatisticalFunctions.cs +++ b/Esiur.Analysis/Statistics/StatisticalFunctions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; @@ -35,9 +36,9 @@ namespace Esiur.Analysis.Statistics public static double RMS(this double[] x) { - var r = Math.Sqrt(x.Sum(x =>(float) x * (float) x) / x.Length); + var r = Math.Sqrt(x.Sum(x => (float)x * (float)x) / x.Length); //if (double.IsNaN(r) || double.IsInfinity(r)) - // Console.WriteLine(); + // Console.WriteLine(); return r; } @@ -46,5 +47,50 @@ namespace Esiur.Analysis.Statistics { return Covariance(x, y) / (StdDiv(x) * StdDiv(y)); } + + public static double Distance(this PointF from, PointF to) + { + return Math.Sqrt(Math.Pow(from.X - to.X, 2) + Math.Pow(from.Y - to.Y, 2)); + } + + class KClass + { + public int Id; + public PointF Center; + + public override string ToString() + { + return $"C{Id} <{Center.X}, {Center.Y}>"; + } + } + + public static Dictionary KMean(PointF[] seeds, PointF[] points) + { + // calculate distance + + + var classes = new Dictionary>(); + for (var i = 0; i < seeds.Length; i++) + classes.Add(new KClass() { Id = i+1, Center = seeds[i] }, new List()); + + while (true) + { + + foreach (var point in points) + { + var cls = classes.Keys.OrderBy(x => x.Center.Distance(point)).First(); + classes[cls].Add(point); + } + + // update center + foreach(var kv in classes) + { + kv.Key.Center = new PointF() { X = kv.Value.Average(p => p.X), Y = kv.Value.Average(p => p.Y) }; + kv.Value.Clear(); + } + + } + } + } }