% results = bm([contingency matrix])
%
% contingency matrix -> contingency table of network prediction and training targets
% ie. classification x target'
%
% results <- structure of results with the following fields
% contingencyMatrix: As provided as argument 1 to function
% recall: Ratio of times class correctly predicted
% to total times it was actually that class
% precision: Ratio of times class correctly predicted
% to total times it was predicted to be that class
% weightedAverage: Ratio of correct predicted classes
% to total number of cases
% F: Harmonic mean
% Fall: F for all classes
% G: Geometric mean
% Gall: G for all classes
% bookmakerMatrix: Matrix of bookmaker results per class
% bookmaker: Bookmaker result for all classes
%
% matlab: sf 16/03/03
% octave: dp 11//03 - also extended to weight k>2 combinations of bm, F and G correctly
function results = bm(cm)
if (size(cm,1) ~= size(cm,2))
error('Contingency matrix must be square');
else
k = size(cm,1);
end
N = sum(sum(cm));
rprob = sum(cm) ./ N;
pprob = sum(cm') ./ N;
recall = diag(cm)' ./ sum(cm);
precision = diag(cm')' ./ sum(cm');
wav = sum(diag(cm)) ./ N;
F = (2.*precision.*recall) ./ (precision + recall);
G = sqrt(precision.*recall);
% Fall - use weighted harmonic mean
Fall = 1 / sum(rprob./F); %(assume real distribution)
Fall = k / sum(ones(1,k)./F); %(assume equiprobable)
% Gall - use weighted geometric mean
Gall = prod(G.^rprob); %(assume real distribution)
Gall = (prod(G)^(1/k)); %(assume equiprobable)
mask = diag(ones(1,k));
maskc = reshape(mask,k*k,1);
ind = find(maskc==0);
maskc(ind) = -1;
mask = reshape(maskc,k,k);
prob = rprob;
prob = prob(ones(k,1),:)';
probc = reshape(prob,k*k,1);
probc(ind) = 1-probc(ind);
prob = reshape(probc,k,k);
bmcm = cm ./ prob;
bmcm = bmcm .* mask;
bms = sum(bmcm') / N;
bm = bms * pprob';
%results.contingencyMatrix = cm;
results.N = N;
results.recall = recall;
results.precision = precision;
results.weightedAverage = wav;
results.F = F;
results.Fall = Fall;
results.G = G;
results.Gall = Gall;
%results.bookmakerMatrix = bmcm;
results.bookmakerSum = bms;
results.bookmaker = bm;