/// <summary> /// Sprawdzania do jakiej klasy pasuje podany przez uzytkownika punkt /// </summary> /// <param name="dataSet"></param> /// <param name="testSet"></param> /// <param name="userObj"></param> /// <param name="kValue"></param> public static void EvaluateInput(List <DataPoint> dataSet, List <DataPoint> testSet, DataPoint userObj, int kValue) { double sl, sw, pl, pw, distance; List <EvaluatedPoint> evaluation = new List <EvaluatedPoint>(); foreach (var point in dataSet) { if (!testSet.Contains(point)) { // Obliczanie metryki eukledisowej sl = Math.Pow(point.sepal_length - userObj.sepal_length, 2); sw = Math.Pow(point.sepal_width - userObj.sepal_width, 2); pl = Math.Pow(point.petal_length - userObj.petal_length, 2); pw = Math.Pow(point.petal_width - userObj.petal_width, 2); distance = Math.Sqrt(sl + sw + pl + pw); EvaluatedPoint evaluatedPoint = new EvaluatedPoint() { sepal_length = point.sepal_length, sepal_width = point.sepal_width, petal_length = point.petal_length, petal_width = point.petal_width, species = point.species, Distance = distance }; evaluation.Add(evaluatedPoint); } } // Lista opracowanych rezultatów var results = evaluation .OrderBy(x => x.Distance) // Posortuj .Take(kValue) // Weź k najlepszych .GroupBy(x => x.species) // Pogrupuj .OrderByDescending(x => x.Count()) // Znajdz najlepszych .ToList(); // Ilość punktów Virginica double virginicaAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "virginica") .Count(); // Ilość punktów Versicolor double versicolorAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "versicolor") .Count();; // Ilość punktów Setosa double setosaAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "setosa") .Count(); string bestGuess = results .OrderByDescending(x => x.Select(x => x.Distance)) .Select(x => x.Select(x => x.species)) .Take(1) .ToString(); Console.WriteLine("\nPodany punkt (procentowa szansa zgodności):"); Console.WriteLine($" Virginica: {(virginicaAmount / kValue) * 100}%"); Console.WriteLine($" Versicolor: {(versicolorAmount / kValue) * 100}%"); Console.WriteLine($" Setosa: {(setosaAmount / kValue) * 100}%"); }
/// <summary> /// Sprawdza punkty w zestawie testowym. Dla każdegu puntu sprawdza K liczbę sąsiadów i porównuje ją z istniejącym w zestawie elementem. Wyświetla /// procent będądy ilościa poprawie zgadniętych punktów. /// </summary> /// <param name="dataSet"></param> /// <param name="testSet"></param> /// <param name="kValue"></param> /// <param name="trainSet"></param> public static void EvaluateTest(List <DataPoint> dataSet, List <DataPoint> testSet, int kValue, List <DataPoint> trainSet) { double goodGuess = 0; foreach (var testPoint in testSet) { double sl, sw, pl, pw, distance; List <EvaluatedPoint> evaluation = new List <EvaluatedPoint>(); foreach (var dataPoints in dataSet.Except(testSet).ToList()) { if (true) { // Obliczanie metryki eukledisowej sl = Math.Abs(Math.Pow(dataPoints.sepal_length - testPoint.sepal_length, 2)); sw = Math.Abs(Math.Pow(dataPoints.sepal_width - testPoint.sepal_width, 2)); pl = Math.Abs(Math.Pow(dataPoints.petal_length - testPoint.petal_length, 2)); pw = Math.Abs(Math.Pow(dataPoints.petal_width - testPoint.petal_width, 2)); distance = Math.Sqrt(sl + sw + pl + pw); EvaluatedPoint evaluatedPoint = new EvaluatedPoint() { sepal_length = dataPoints.sepal_length, sepal_width = dataPoints.sepal_width, petal_length = dataPoints.petal_length, petal_width = dataPoints.petal_width, species = dataPoints.species, Distance = distance }; evaluation.Add(evaluatedPoint); } } // Lista opracowanych rezultatów var results = evaluation .OrderBy(x => x.Distance) // Posortuj .Take(kValue) // Weź k najlepszych .GroupBy(x => x.species) // Pogrupuj .OrderByDescending(x => x.Count()) // Znajdz najlepszych .ToList(); // Ilość punktów Virginica double virginicaAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "virginica") .Count(); // Ilość punktów Versicolor double versicolorAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "versicolor") .Count();; // Ilość punktów Setosa double setosaAmount = evaluation .OrderBy(x => x.Distance) .Take(kValue) .Where(x => x.species == "setosa") .Count(); string bestGuess = ""; if (virginicaAmount > versicolorAmount && virginicaAmount > setosaAmount) { bestGuess = "virginica"; } else if (versicolorAmount > virginicaAmount && versicolorAmount > setosaAmount) { bestGuess = "versicolor"; } else if (setosaAmount > virginicaAmount && setosaAmount > versicolorAmount) { bestGuess = "setosa"; } int count = dataSet .Where(x => x.petal_length == testPoint.petal_length) .Where(x => x.petal_width == testPoint.petal_width) .Where(x => x.sepal_length == testPoint.sepal_length) .Where(x => x.sepal_width == testPoint.sepal_width) .Where(x => x.species == bestGuess) .Distinct() .Count(); if (count > 0) { goodGuess++; } } Console.WriteLine($"Ogólna poprawność:"); Console.WriteLine($" Zestaw danych: {(goodGuess / testSet.Count()) * 100}%"); }