这里有一个很好的解释。F1 分数在 wiki 中进行了解释,这有助于衡量成功。
我试图编写一个计算 F1 分数的函数:
/// <param name="realClasses">Class names that exists on the image. A class name may exists more than once.</param>
/// <param name="foundClasses">Predicted class names. A class name may exists more than once.</param>
private static void findPosNeg(List<string> realClasses, List<string> foundClasses, out int truePositive, out int falsePositive, out int falseNegative)
{
Dictionary<string, int> dicReal = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
Dictionary<string, int> dicFound = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
#region fill dictionaries
foreach (string className in realClasses)
{
if (!dicReal.ContainsKey(className))
dicReal[className] = 1;
else
dicReal[className]++;
}
foreach (string className in foundClasses)
{
if (!dicFound.ContainsKey(className))
dicFound[className] = 1;
else
dicFound[className]++;
}
#endregion
truePositive = 0;
falsePositive = 0;
falseNegative = 0;
foreach (string className in dicFound.Keys)
{
if (!dicReal.ContainsKey(className))
falsePositive += dicFound[className];
else
{
int found = dicFound[className];
int real = dicReal[className];
truePositive += Math.Min(found, real);
if (real > found)
falseNegative += real - found;
else if (found > real)
falsePositive += found - real;
}
}
foreach (string className in dicReal.Keys)
if (!dicFound.ContainsKey(className))
falseNegative += dicReal[className];
}
/// <summary>
/// Calculates F1Score ref:https://en.wikipedia.org/wiki/Precision_and_recall
/// </summary>
private static double calc_F1Score(int truePositive, int falsePositive, int falseNegative, out double precision, out double recall)
{
precision = (double)truePositive / ((double)truePositive + (double)falsePositive);
recall = (double)truePositive / ((double)truePositive + (double)falseNegative);
double div = (precision + recall);
return (div != 0d) ? 2d * precision * recall / div : 0d;
}