let performance_curve ~scores ~labels =
let n = Array.length scores in
if n <> Array.length labels
then
invalid_argf
"Biocaml_bin_pred.make_curve: scores and labels have different lengths (%d and %d)"
n (Array.length labels) () ;
let examples =
let r = Array.map2_exn scores labels ~f:(fun x y -> x, y) in
Array.sort ~cmp:(Fn.flip compare) r ;
r
in
let np = Array.count labels ~f:ident in
let nn = Array.count labels ~f:(fun x -> not x) in
let initial = Float.infinity, { tp = 0 ; tn = nn ; fp = 0 ; fn = np } in
let r = Array.create (n + 2) initial in
for i = 0 to n - 1 do
let score, label = examples.(i) in
let m = snd r.(i) in
let m' =
if label then
{ m with tp = m.tp + 1 ; fn = m.fn - 1 }
else
{ m with fp = m.fp + 1 ; tn = m.tn - 1 }
in
r.(i + 1) <- (score,m')
done ;
r.(n + 1) <- Float.neg_infinity, { tp = np ; tn = 0 ; fp = nn ; fn = 0 } ;
r