是否有使用Matlab计算精度和召回率的函数?
我在matlab中计算分类器的精度和召回率方面有问题。我使用Fisherris数据(由150个数据点、50个setosa、50个VersionColor、50个virginica组成)。我用kNN算法分类。这是我的混淆矩阵:是否有使用Matlab计算精度和召回率的函数?,matlab,knn,confusion-matrix,precision-recall,Matlab,Knn,Confusion Matrix,Precision Recall,我在matlab中计算分类器的精度和召回率方面有问题。我使用Fisherris数据(由150个数据点、50个setosa、50个VersionColor、50个virginica组成)。我用kNN算法分类。这是我的混淆矩阵: 50 0 0 0 48 2 0 4 46 正确分类率为96%(144/150),但如何使用matlab计算准确率和召回率,有什么功能吗? 我知道精度=tp/(tp+fp)和召回率=tp/(tp+fn)的公式,但我在识别组件方
50 0 0
0 48 2
0 4 46
正确分类率为96%(144/150),但如何使用matlab计算准确率和召回率,有什么功能吗?
我知道精度=tp/(tp+fp)和召回率=tp/(tp+fn)的公式,但我在识别组件方面迷失了方向。例如,我能说矩阵中的真正数是144吗?假阳性和假阴性呢?
请帮忙!!!我真的很感激!谢谢大家! 正如丹在评论中指出的那样,精度和召回率通常只针对二进制分类问题定义 但您可以分别计算每个类的精确度和召回率。让我们稍微注释一下您的混淆矩阵:
| true |
| | seto | vers | virg |
-----------------------------------
| seto | 50 0 0
predicted | vers | 0 48 2
| virg | 0 4 46
在这里,我假设通常的约定成立,即列用于真实值,行用于学习算法预测的值。(如果矩阵是以相反的方式构建的,只需对混淆矩阵进行转置即可。)
每个类(=行/列索引)i
的真正正值(tp(i)
)由该行/列中的对角线元素给出。真正的负数(tn
)由剩余对角线元素之和给出。注意,我们只是将每个类i
的否定定义为“非类i
”
如果我们将误报(fp
)和误报(fn
)分别类似地定义为给定行或列中非对角项的总和,我们可以计算每个类别的精度和召回率:
precision(seto) = tp(seto) / (tp(seto) + fp(seto)) = 50 / (50 + (0 + 0)) = 1.0
precision(vers) = 48 / (48 + (0 + 2)) = 0.96
precision(virg) = 46 / (46 + (0 + 4)) = 0.92
recall(seto) = tp(seto) / (tp(seto) + fn(seto)) = 50 / (50 + (0 + 0)) = 1.0
recall(vers) = 48 / (48 + (0 + 4)) = 0.9231
recall(virg) = 46 / (46 + (0 + 2)) = 0.9583
这里我使用类名而不是行索引来进行说明
请查看的答案,以获取关于多类别分类问题的性能度量的更多信息,特别是如果您希望每个类别都有一个数字,而不是一个数字。当然,最简单的方法就是平均每个类的值
更新
我意识到您实际上是在寻找一个Matlab函数来实现这一点。我不认为有任何内置函数,在Matlab文件交换上我只找到了一个。但是,任务非常简单,您可以轻松定义自己的函数,如下所示:
function y = precision(M)
y = diag(M) ./ sum(M,2);
end
function y = recall(M)
y = diag(M) ./ sum(M,1)';
end
这将返回一个列向量,分别包含每个类的精度和召回值。现在你只需打电话
>> mean(precision(M))
ans =
0.9600
>> mean(recall(M))
ans =
0.9605
获取模型的平均精度和召回率值。要添加到pederpansen的答案中,以下是一些匿名Matlab函数,用于计算每个类的精度、召回率和F1分数,以及所有类的平均F1分数:
precision = @(confusionMat) diag(confusionMat)./sum(confusionMat,2);
recall = @(confusionMat) diag(confusionMat)./sum(confusionMat,1)';
f1Scores = @(confusionMat) 2*(precision(confusionMat).*recall(confusionMat))./(precision(confusionMat)+recall(confusionMat))
meanF1 = @(confusionMat) mean(f1Scores(confusionMat))
另一种方法
confMat=[50,0,0;0,48,2;0,4,46];
for i =1:size(confMat,1)
precision(i)=confMat(i,i)/sum(confMat(i,:));
end
precision(isnan(precision))=[];
Precision=sum(precision)/size(confMat,1);
for i =1:size(confMat,1)
recall(i)=confMat(i,i)/sum(confMat(:,i));
end
Recall=sum(recall)/size(confMat,1);
F_score=2*Recall*Precision/(Precision+Recall);
使用以下matab代码
actual = ...
predicted= ...
cm = confusionmat(actual,predicted);
cm = cm';
precision = diag(cm)./sum(cm,2);
overall_precision = mean(precision)
recall= diag(cm)./sum(cm,1)';
overall_recall = mean(recall)
对不起,对不起,我们谈论的是不同的数据。你怎么能得到144?我通过对混淆矩阵的对角线求和得到这个数字,50+48+46,考虑到正确分类的数据,你有3个类?您确定precision和recall可以推广到包含两个以上类的分类吗?@user19565只是一个警告,这里在precision和recall中使用confusionMat是错误的,应该将其转置(行索引表示实际标签索引)。一个简单的示例,其中所有内容都被预测为标签2:recall([0,5;0,5])=[NaN,0.5],而recall([0,5;0,5])。)=[0 1]返回正确的结果。否则,您将得到错误的结果。