经常把分类问题(多分类问题)看成是二类问题。譬如 一个文档集合中的所有文档可能属于 culture, military, education 的某一类。但是针对某一个具体类别来说,我们又可以这样考虑:即有多少篇文章属于该类?有多少篇文章不属于该类?
如果将属于该类的文章定义为“正例”,不属于该类别的文章定义为负例,那么就有了 查准率,查全率,F-score等性能评估标准。
分类器的混合矩阵:
可以这样考虑TP,FN,FP,TN的含义:
TP(Truly Positve):是指那些分类为正例实际上也是正例的文章;
FP(Falsely Postive):是指那些分类为正例但是实际上为负例的文章;
FN(Falsely Negtive):是指那些分类为负例但是实际上为正例的文章;
TN(Truly Negtive):是指那些分类为负例,实际上也为负例的文章。
查准率(precision)p=TP/(TP+FP)。它的含义是:测试集中被正确分类的正例数量除以测试集中被分类为正例的数据数量。
查全率(recall) r=TP/(TP+FN)。 它的含义是:测试集中被正确分类的正例数量除以测试集中实际正例数量。
F-score=2pr/(p+r)。 它是查准率和查全率的调和平均值。 F-score更接近于p,r两个数种较小的那个
下面给出计算这三个指标的代码
计算TP
/************************************************************************/
/* 计算实际分类正确的正例样本数目 */
/************************************************************************/
double Preprocess::getTP(string classLabel,RESULTINFO classifyResults,string tablename)
{
double TP=0;
int TPnum=0;
for(RESULTINFO::iterator it=classifyResults.begin();it!=classifyResults.end();it++)
{
if(it->second==classLabel)
{
string counterpart=GetCategorizationInfoById(it->first,tablename);
if(counterpart==classLabel)
{
TPnum++;
}
}
}
TP=(double)TPnum;
return TP;
}
计算Precision
计算查准率
/************************************************************************/
/* 计算查准率 */
/************************************************************************/
double Preprocess::getPrecision(string classLabel,RESULTINFO classifyResults,string tablename)
{
double TP=getTP(classLabel,classifyResults,tablename);
double denominator=0;
for(RESULTINFO::iterator it=classifyResults.begin();it!=classifyResults.end();it++)
{
if(it->second==classLabel)
{
denominator+=1;
}
}
return TP/denominator;
}
/* 计算查准率 */
/************************************************************************/
double Preprocess::getPrecision(string classLabel,RESULTINFO classifyResults,string tablename)
{
double TP=getTP(classLabel,classifyResults,tablename);
double denominator=0;
for(RESULTINFO::iterator it=classifyResults.begin();it!=classifyResults.end();it++)
{
if(it->second==classLabel)
{
denominator+=1;
}
}
return TP/denominator;
}
计算查全率
代码
/************************************************************************/
/* 计算查全率 */
/************************************************************************/
double Preprocess::getRecall(string classLabel,RESULTINFO classifyResults,string tablename)
{
double TP=getTP(classLabel,classifyResults,tablename);
double denominator=getCategorizationNum(classLabel,tablename);
return TP/denominator;
}
/* 计算查全率 */
/************************************************************************/
double Preprocess::getRecall(string classLabel,RESULTINFO classifyResults,string tablename)
{
double TP=getTP(classLabel,classifyResults,tablename);
double denominator=getCategorizationNum(classLabel,tablename);
return TP/denominator;
}
计算F-score
计算F值
/************************************************************************/
/* 计算F值 */
/************************************************************************/
double Preprocess::getFscore(string classLabel,RESULTINFO classifyResults,string tablename)
{
double precison=getPrecision(classLabel,classifyResults,tablename);
double recall=getRecall(classLabel,classifyResults,tablename);
return 2*precison*recall/(precison+recall);
}
/* 计算F值 */
/************************************************************************/
double Preprocess::getFscore(string classLabel,RESULTINFO classifyResults,string tablename)
{
double precison=getPrecision(classLabel,classifyResults,tablename);
double recall=getRecall(classLabel,classifyResults,tablename);
return 2*precison*recall/(precison+recall);
}