/// <summary> /// Starts the k-NearestNeighbor Algorithm using the EuclideanDistance Method. /// </summary> /// <param name="k">The number of Chunks to use.</param> public void Start_kNN(int k, int kfold, CalculationMethod method = CalculationMethod.EuclideanDistance) { DistanceCalculator calculationMethod = new EuclideanDistanceStrategy(); if (method == CalculationMethod.ManhattanDistance) { calculationMethod = new ManhattanDistanceStrategy(); } else if (method == CalculationMethod.CorrectedEuclideanDistance) { calculationMethod = new CorrectedEuclideanStrategy(); } Console.WriteLine("Calculating with method: {0} ...", method.ToString()); #region Calculate Chunk Size SplitDataIntoChunks(kfold); #endregion #region Heuristic // The Result int[,] confusionMatrix = new int[10, 10]; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); foreach (var testingChunk in _Chunks) { foreach (var unknownWine in testingChunk.Value) // For each wine, which is not part of the current Chunk { _NearestNeighbor = new SortedList <float, int>(new DuplicateKeyComparer <float>()); // Get NearestNeighbor foreach (var nnChunk in _Chunks.Where(x => testingChunk.Key != x.Key)) { foreach (var knownWine in nnChunk.Value) { float currDistance = calculationMethod.GetDistance(knownWine, unknownWine); _NearestNeighbor.Add(currDistance, knownWine.Quality); } } // Get most occuring quality var w = _NearestNeighbor.Values.Take(k); var dict = w.ToLookup(x => x); var maxCount = dict.Max(x => x.Count()); int mostQuality = dict.Where(x => x.Count() == maxCount).Select(x => x.Key).FirstOrDefault(); // Add the current guess to the result confusionMatrix[unknownWine.Quality, mostQuality]++; } } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0} Minutes, {1} Seconds, {2} ms", ts.Minutes, ts.Seconds, ts.Milliseconds); PrintResult(confusionMatrix, elapsedTime); #endregion }