public static double CalculateFMeasureOneHot(Parameters parameters) { //Fill confusion matrix with zero values var classesCount = parameters.Entities[0].Classes.Count; var confusionMatrix = new List <List <int> >(classesCount); for (int i = 0; i < classesCount; i++) { var confusionMatrixRow = new List <int>(classesCount); for (int j = 0; j < classesCount; j++) { confusionMatrixRow.Add(0); } confusionMatrix.Add(confusionMatrixRow); } //Iterate over leave-one-out for (int i = 0; i < parameters.Entities.Count; i++) { var queryEntityClasses = new List <double>(); switch (parameters.WindowType) { case WindowType.Fixed: for (int j = 0; j < parameters.Entities.Count - 1; j++) { if (parameters.DistancesForEachElement[i][j].Value >= parameters.WindowWidth) { parameters.NeighborsCount = j; break; } if (j == parameters.Entities.Count - 2) { parameters.NeighborsCount = j + 1; break; } } break; case WindowType.Variable: parameters.WindowWidth = parameters.DistancesForEachElement[i][parameters.NeighborsCount].Value; break; default: break; } if (parameters.WindowWidth == 0) { for (int k = 0; k < classesCount; k++) { queryEntityClasses.Add(GetAverageOneHot(parameters, i, k)); } } else { var numerator = 0d; var denominator = 0d; for (int j = 0; j < classesCount; j++) { for (int k = 0; k < parameters.Entities.Count - 1; k++) { var kernel = CalculateKernel( parameters.DistancesForEachElement[i][k].Value / parameters.WindowWidth, parameters.KernelFunctionType); var classColumn = parameters.Entities[parameters.DistancesForEachElement[i][k].EntityIndex].Classes[j]; numerator += classColumn * kernel; denominator += kernel; } if (denominator == 0) { queryEntityClasses.Add(GetAverageOneHot(parameters, i, j)); } else { queryEntityClasses.Add(numerator / denominator); } } } //Add prediction to confusion matrix. If two columns have similar values choose first occurence var predictedClass = queryEntityClasses.IndexOf(queryEntityClasses.Max()); confusionMatrix[parameters.Entities[i].ClassNumber][predictedClass] += 1; } var fMeasure = FMeasureService.CalculateFMeasure(confusionMatrix); return(fMeasure); }
public static double CalculateFMeasureNaive(Parameters parameters) { //Fill confusion matrix with zero values var classesCount = parameters.Entities[0].Classes.Count; var confusionMatrix = new List <List <int> >(classesCount); for (int i = 0; i < classesCount; i++) { var confusionMatrixRow = new List <int>(classesCount); for (int j = 0; j < classesCount; j++) { confusionMatrixRow.Add(0); } confusionMatrix.Add(confusionMatrixRow); } //Iterate over leave-one-out for (int i = 0; i < parameters.Entities.Count; i++) { var queryEntityClassNumber = 0d; switch (parameters.WindowType) { case WindowType.Fixed: for (int j = 0; j < parameters.Entities.Count - 1; j++) { if (parameters.DistancesForEachElement[i][j].Value >= parameters.WindowWidth) { parameters.NeighborsCount = j; break; } if (j == parameters.Entities.Count - 2) { parameters.NeighborsCount = j + 1; break; } } break; case WindowType.Variable: parameters.WindowWidth = parameters.DistancesForEachElement[i][parameters.NeighborsCount].Value; break; default: break; } if (parameters.WindowWidth == 0) { queryEntityClassNumber = GetAverageNaive(parameters, i); } else { var numerator = 0d; var denominator = 0d; for (int j = 0; j < parameters.Entities.Count - 1; j++) { var kernel = CalculateKernel( parameters.DistancesForEachElement[i][j].Value / parameters.WindowWidth, parameters.KernelFunctionType); var classNumber = parameters.Entities[parameters.DistancesForEachElement[i][j].EntityIndex].ClassNumber; numerator += classNumber * kernel; denominator += kernel; } if (denominator == 0) { queryEntityClassNumber = GetAverageNaive(parameters, i); } else { queryEntityClassNumber = numerator / denominator; } } //Add prediction to confusion matrix confusionMatrix[parameters.Entities[i].ClassNumber][Convert.ToInt32(Math.Round(queryEntityClassNumber))] += 1; } var fMeasure = FMeasureService.CalculateFMeasure(confusionMatrix); return(fMeasure); }