File size: 1,662 Bytes
456264c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import pytest

from pino.genre_benchmark import audit_split, benchmark_split, composition_features, decide


def row(genre, *components):
    return {"genre": genre, "formula": [{"cas": cas, "weight_fraction": weight} for cas, weight in components]}


def test_composition_features_ignore_identity_and_order():
    a = row("a", ("64-17-5", .8), ("x", .15), ("y", .05))
    b = row("b", ("z", .05), ("q", .15), ("64-17-5", .8))
    np.testing.assert_allclose(composition_features([a]), composition_features([b]))


def test_audit_rejects_shared_active_compounds():
    with pytest.raises(ValueError, match="shared compounds"):
        audit_split([row("a", ("x", 1))], [row("b", ("x", 1))])


def test_benchmark_and_negative_decision():
    train = [row("a", ("a1", .1)), row("a", ("a2", .12)), row("b", ("b1", .8)), row("b", ("b2", .82))]
    test = [row("a", ("a3", .11)), row("a", ("a4", .13)), row("b", ("b3", .79)), row("b", ("b4", .81))]
    learned_train = np.zeros((4, 2))
    learned_test = np.zeros((4, 2))
    result = benchmark_split(train, test, learned_train, learned_test, bootstrap_samples=200, seed=4)
    assert result["baseline_accuracy"] == 1.0
    assert decide([result], minimum_splits=1)["decision"] == "negative_result"


def test_decision_requires_every_leakage_free_split_to_clear_ci():
    good = {"leakage_audit": {"passed": True}, "paired_advantage": {"ci95_low": .01}}
    weak = {"leakage_audit": {"passed": True}, "paired_advantage": {"ci95_low": 0.0}}
    assert decide([good, good, good])["decision"] == "learned_representation_supported"
    assert decide([good, good, weak])["decision"] == "negative_result"