Why perfcurve does not return a consistent result?

5 views (last 30 days)
Zeynab Mousavikhamene on 8 Jun 2020
Commented: Sharon Kim on 5 Apr 2022
when I run the perfcurve function like this:
[X,Y,T,AUC] = perfcurve(labels,scores,posclass)
some times the length of X, Y and T =length(labels)+1 and some times they are equal.
Why this happnes? I expect the lengths to be equal.
I need to make the output X, Y and T to be consistant (either equal or +1). Any idea how to do that?
Sharon Kim on 5 Apr 2022
Hello,
This is a rather late reply but hopefully anyone else asking this same question will benefit.
The perfcurve function performs a check on the scores vector to search for NaN or identical values. The presence of either will truncate the output.
You can further examine this in the R2022a perfcurve.m function from the comments on lines 460-465 for Wcum (the matrix of cumulative weights), and the local function makeccum from lines 759-790 which does the checks for NaNs and identical values.
Lines 460-465:
% Make Wcum, a matrix of cumulative weights in each class.
% Adjust Wcum and scores using the specified behavior for NaN scores.
% Output sorted distinct scores into sScores and corresponding rows into Wcum.
% Wcum and output sScores do not have the same size as W and input sScores.
% To access the full vector of scores, use scores(sorted).
[Wcum,sScores] = makeccum(W,sScores,processNaN);
Lines 759-790:
function [Wcum,scores] = makeccum(W,scores,processNaN)
% Discard instances that do not belong to any class
idxNone = ~any(W,2);
W(idxNone,:) = [];
scores(idxNone) = [];
% Get rid of NaN's in scores
Wnanrow = zeros(1,size(W,2),'like',scores);
idxNaN = isnan(scores);
if ~isempty(idxNaN)
Wnanrow = sum(W(idxNaN,:),1);
end
end
scores(idxNaN) = [];
W(idxNaN,:) = [];
% Make a matrix of counts with NaN instances included
Wnan = zeros(size(W,1)+2,size(W,2),'like',scores);
Wnan(1,2:end) = Wnanrow(2:end);% FP (always accepted)
Wnan(2:end-1,:) = W;
Wnan(end,1) = Wnanrow(1);% FN (always rejected)
% Compute cumulative counts in each class
Wcum = cumsum(Wnan,1);
% Compact Wcum in case of identical scores
idxEq = find( scores(1:end-1) < scores(2:end) + ...
max([eps(scores(1:end-1)) eps(scores(2:end))],[],2) );
Wcum(idxEq+1,:) = [];
scores(idxEq) = [];
end