blob: d5c4b87726e2500b92ea5f7d7df151120ba01001 [file] [log] [blame]
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package stat
import (
"testing"
"gonum.org/v1/gonum/floats"
)
// Test cases where calculated manually.
func TestROC(t *testing.T) {
cases := []struct {
y []float64
c []bool
w []float64
n int
wantTPR []float64
wantFPR []float64
}{
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
wantTPR: []float64{0, 0.5, 0.5, 1, 1, 1, 1},
wantFPR: []float64{0, 0, 0.25, 0.25, 0.5, 0.75, 1},
},
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
wantTPR: []float64{0, 0.4, 0.4, 1, 1, 1, 1},
wantFPR: []float64{0, 0, 0.125, 0.125, 0.5, 0.75, 1},
},
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
n: int(5),
wantTPR: []float64{0, 0.5, 0.5, 1, 1},
wantFPR: []float64{0, 0, 0.25, 0.5, 1},
},
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
n: int(9),
wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1},
wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.5, 0.5, 1},
},
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
n: int(5),
wantTPR: []float64{0, 0.4, 0.4, 1, 1},
wantFPR: []float64{0, 0, 0.125, 0.5, 1},
},
{
y: []float64{0, 3, 5, 6, 7.5, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
n: int(9),
wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 1, 1, 1, 1},
wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.5, 0.5, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
wantTPR: []float64{0, 0.5, 0.5, 1, 1},
wantFPR: []float64{0, 0, 0.25, 0.75, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
wantTPR: []float64{0, 0.4, 0.4, 1, 1},
wantFPR: []float64{0, 0, 0.125, 0.75, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
n: int(5),
wantTPR: []float64{0, 0.5, 0.5, 1, 1},
wantFPR: []float64{0, 0, 0.25, 0.75, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
n: int(9),
wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1},
wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.75, 0.75, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
n: int(5),
wantTPR: []float64{0, 0.4, 0.4, 1, 1},
wantFPR: []float64{0, 0, 0.125, 0.75, 1},
},
{
y: []float64{0, 3, 6, 6, 6, 8},
c: []bool{true, false, true, false, false, false},
w: []float64{4, 1, 6, 3, 2, 2},
n: int(9),
wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 0.4, 1, 1, 1},
wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.75, 0.75, 1},
},
{
y: []float64{1, 2},
c: []bool{true, true},
wantTPR: []float64{0, 0.5, 1},
wantFPR: []float64{0, 0, 1},
},
{
y: []float64{1, 2},
c: []bool{true, true},
n: int(2),
wantTPR: []float64{0, 1},
wantFPR: []float64{0, 1},
},
{
y: []float64{1, 2},
c: []bool{true, true},
n: int(7),
wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1},
wantFPR: []float64{0, 0, 0, 0, 0, 0, 1},
},
{
y: []float64{1},
c: []bool{true},
wantTPR: []float64{0, 1},
wantFPR: []float64{0, 1},
},
{
y: []float64{1},
c: []bool{true},
n: int(2),
wantTPR: []float64{0, 1},
wantFPR: []float64{0, 1},
},
{
y: []float64{1},
c: []bool{false},
wantTPR: []float64{0, 1},
wantFPR: []float64{0, 1},
},
{
y: []float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 10},
c: []bool{true, false, true, true, false, false, true},
n: int(5),
wantTPR: []float64{0, 0.75, 0.75, 0.75, 1},
wantFPR: []float64{0, 1, 1, 1, 1},
},
{
y: []float64{},
c: []bool{},
wantTPR: nil,
wantFPR: nil,
},
{
y: []float64{},
c: []bool{},
n: int(5),
wantTPR: nil,
wantFPR: nil,
},
}
for i, test := range cases {
gotTPR, gotFPR := ROC(test.n, test.y, test.c, test.w)
if !floats.Same(gotTPR, test.wantTPR) {
t.Errorf("%d: unexpected TPR got:%v want:%v", i, gotTPR, test.wantTPR)
}
if !floats.Same(gotFPR, test.wantFPR) {
t.Errorf("%d: unexpected FPR got:%v want:%v", i, gotFPR, test.wantFPR)
}
}
}