Skip to content

Commit 4be80e8

Browse files
authored
Merge pull request #173 from shakedzy/extra_tests
added additional tests
2 parents 4081b98 + f208f02 commit 4be80e8

8 files changed

Lines changed: 1108 additions & 0 deletions
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import pytest
2+
import numpy as np
3+
from dython.model_utils import _binary_ks_curve
4+
5+
6+
def test_binary_ks_curve_basic():
7+
"""Test basic binary_ks_curve functionality"""
8+
y_true = np.array([0, 1, 0, 1, 1, 0])
9+
y_probas = np.array([0.1, 0.9, 0.3, 0.8, 0.7, 0.2])
10+
11+
thresholds, pct1, pct2, ks_stat, max_dist, classes = _binary_ks_curve(y_true, y_probas)
12+
13+
assert len(thresholds) > 0
14+
assert len(pct1) == len(thresholds)
15+
assert len(pct2) == len(thresholds)
16+
assert 0 <= ks_stat <= 1
17+
assert len(classes) == 2
18+
19+
20+
def test_binary_ks_curve_multiclass_error():
21+
"""Test binary_ks_curve with more than 2 classes"""
22+
y_true = np.array([0, 1, 2, 0, 1, 2])
23+
y_probas = np.array([0.1, 0.5, 0.9, 0.2, 0.6, 0.8])
24+
25+
with pytest.raises(ValueError):
26+
_binary_ks_curve(y_true, y_probas)
27+
28+
29+
def test_binary_ks_curve_thresholds_start_with_zero():
30+
"""Test that thresholds start with 0"""
31+
y_true = np.array([0, 1, 0, 1])
32+
y_probas = np.array([0.2, 0.8, 0.3, 0.9])
33+
34+
thresholds, _, _, _, _, _ = _binary_ks_curve(y_true, y_probas)
35+
36+
assert thresholds[0] == 0.0
37+
38+
39+
def test_binary_ks_curve_thresholds_end_with_one():
40+
"""Test that thresholds end with 1"""
41+
y_true = np.array([0, 1, 0, 1])
42+
y_probas = np.array([0.2, 0.8, 0.3, 0.7])
43+
44+
thresholds, _, _, _, _, _ = _binary_ks_curve(y_true, y_probas)
45+
46+
assert thresholds[-1] == 1.0
47+
48+
49+
def test_binary_ks_curve_with_edge_probabilities():
50+
"""Test binary_ks_curve with probabilities at 0 and 1"""
51+
y_true = np.array([0, 1, 0, 1])
52+
y_probas = np.array([0.0, 1.0, 0.1, 0.9])
53+
54+
thresholds, pct1, pct2, ks_stat, max_dist, _ = _binary_ks_curve(y_true, y_probas)
55+
56+
assert len(thresholds) > 0
57+
assert thresholds[0] == 0.0
58+
assert thresholds[-1] == 1.0
59+
60+
61+
def test_binary_ks_curve_data1_exhausted_first():
62+
"""Test binary_ks_curve when data1 is exhausted before data2"""
63+
y_true = np.array([0, 0, 1, 1, 1])
64+
y_probas = np.array([0.1, 0.2, 0.6, 0.7, 0.8])
65+
66+
thresholds, pct1, pct2, ks_stat, max_dist, _ = _binary_ks_curve(y_true, y_probas)
67+
68+
assert len(thresholds) > 0
69+
assert pct1[-1] == 1.0
70+
assert pct2[-1] == 1.0
71+
72+
73+
def test_binary_ks_curve_data2_exhausted_first():
74+
"""Test binary_ks_curve when data2 is exhausted before data1"""
75+
y_true = np.array([0, 0, 0, 1, 1])
76+
y_probas = np.array([0.6, 0.7, 0.8, 0.1, 0.2])
77+
78+
thresholds, pct1, pct2, ks_stat, max_dist, _ = _binary_ks_curve(y_true, y_probas)
79+
80+
assert len(thresholds) > 0
81+
assert pct1[-1] == 1.0
82+
assert pct2[-1] == 1.0
83+
84+
85+
def test_binary_ks_curve_equal_values():
86+
"""Test binary_ks_curve with equal probability values"""
87+
y_true = np.array([0, 0, 1, 1])
88+
y_probas = np.array([0.5, 0.5, 0.5, 0.5])
89+
90+
thresholds, pct1, pct2, ks_stat, max_dist, _ = _binary_ks_curve(y_true, y_probas)
91+
92+
assert len(thresholds) > 0
93+
94+
95+
def test_binary_ks_curve_interleaved_values():
96+
"""Test binary_ks_curve with interleaved probability values"""
97+
y_true = np.array([0, 1, 0, 1, 0, 1])
98+
y_probas = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
99+
100+
thresholds, pct1, pct2, ks_stat, max_dist, _ = _binary_ks_curve(y_true, y_probas)
101+
102+
assert len(thresholds) > 0
103+
assert 0 <= ks_stat <= 1
104+
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import pytest
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
from dython.model_utils import ks_abc
5+
6+
7+
def test_ks_abc_basic():
8+
"""Test basic ks_abc functionality"""
9+
y_true = [0, 1, 0, 1, 1, 0]
10+
y_pred = [0.1, 0.9, 0.3, 0.8, 0.7, 0.2]
11+
12+
result = ks_abc(y_true, y_pred, plot=False)
13+
assert 'abc' in result
14+
assert 'ks_stat' in result
15+
assert 'eopt' in result
16+
assert 'ax' in result
17+
18+
19+
def test_ks_abc_mismatched_shapes():
20+
"""Test ks_abc with mismatched shapes"""
21+
y_true = [0, 1, 0]
22+
y_pred = [0.1, 0.9, 0.3, 0.8]
23+
24+
with pytest.raises(ValueError):
25+
ks_abc(y_true, y_pred, plot=False)
26+
27+
28+
def test_ks_abc_2d_binary():
29+
"""Test ks_abc with 2D binary array"""
30+
y_true = np.array([[1, 0], [0, 1], [1, 0], [0, 1]])
31+
y_pred = np.array([[0.7, 0.3], [0.2, 0.8], [0.6, 0.4], [0.3, 0.7]])
32+
33+
result = ks_abc(y_true, y_pred, plot=False)
34+
assert 'abc' in result
35+
36+
37+
def test_ks_abc_single_column():
38+
"""Test ks_abc with single column"""
39+
y_true = np.array([[1], [0], [1], [0]])
40+
y_pred = np.array([[0.9], [0.2], [0.7], [0.3]])
41+
42+
result = ks_abc(y_true, y_pred, plot=False)
43+
assert 'abc' in result
44+
45+
46+
def test_ks_abc_multiclass_error():
47+
"""Test ks_abc with multiclass (should raise error)"""
48+
y_true = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
49+
y_pred = np.array([[0.7, 0.2, 0.1], [0.1, 0.8, 0.1], [0.2, 0.1, 0.7]])
50+
51+
with pytest.raises(ValueError):
52+
ks_abc(y_true, y_pred, plot=False)
53+
54+
55+
def test_ks_abc_with_ax():
56+
"""Test ks_abc with provided ax"""
57+
y_true = [0, 1, 0, 1]
58+
y_pred = [0.1, 0.9, 0.3, 0.8]
59+
60+
fig, ax = plt.subplots()
61+
result = ks_abc(y_true, y_pred, ax=ax, plot=False)
62+
assert result['ax'] == ax
63+
plt.close(fig)
64+
65+
66+
def test_ks_abc_with_custom_params():
67+
"""Test ks_abc with custom visualization parameters"""
68+
y_true = [0, 1, 0, 1, 1, 0]
69+
y_pred = [0.1, 0.9, 0.3, 0.8, 0.7, 0.2]
70+
71+
result = ks_abc(
72+
y_true, y_pred,
73+
colors=('red', 'blue'),
74+
title='Custom KS Title',
75+
xlim=(0, 0.5),
76+
ylim=(0, 0.5),
77+
fmt='.3f',
78+
lw=3,
79+
legend='upper left',
80+
plot=False
81+
)
82+
assert 'abc' in result
83+
84+
85+
def test_ks_abc_no_legend():
86+
"""Test ks_abc without legend"""
87+
y_true = [0, 1, 0, 1]
88+
y_pred = [0.1, 0.9, 0.3, 0.8]
89+
90+
result = ks_abc(y_true, y_pred, legend=None, plot=False)
91+
assert 'ax' in result
92+
93+
94+
def test_ks_abc_with_filename(tmp_path):
95+
"""Test ks_abc with filename"""
96+
y_true = [0, 1, 0, 1]
97+
y_pred = [0.1, 0.9, 0.3, 0.8]
98+
99+
filename = tmp_path / "ks_plot.png"
100+
result = ks_abc(y_true, y_pred, filename=str(filename), plot=False)
101+
assert filename.exists()
102+
plt.close('all')
103+
104+
105+
def test_ks_abc_abc_value_range():
106+
"""Test that ABC value is in valid range"""
107+
y_true = [0, 1, 0, 1, 1, 0, 0, 1]
108+
y_pred = [0.1, 0.9, 0.2, 0.8, 0.7, 0.3, 0.15, 0.85]
109+
110+
result = ks_abc(y_true, y_pred, plot=False)
111+
assert 0 <= result['abc'] <= 1
112+
113+
114+
def test_ks_abc_ks_stat_value_range():
115+
"""Test that KS statistic is in valid range"""
116+
y_true = [0, 1, 0, 1, 1, 0, 0, 1]
117+
y_pred = [0.1, 0.9, 0.2, 0.8, 0.7, 0.3, 0.15, 0.85]
118+
119+
result = ks_abc(y_true, y_pred, plot=False)
120+
assert 0 <= result['ks_stat'] <= 1
121+

0 commit comments

Comments
 (0)