def test_general_params():
    # Format: name, type, default_value, valid_values, invalid_values, invalid_type_value
    params = [
        ("c", float, 0.01, [0.0, 1.0, 0.01, 0.05, 0.5], [-1.01, 1.01, 100.0], "str"),
        ("n_iter", int, 10000, [0, 1, 1000, 1000000000], [-1, -100], 1.4),
        ("ablation", int, 0, [0, 1, 2], [-1, 3, 100], 1.5),
        ("min_support", float, 0.01, [0.0, 0.25, 0.5], [-0.01, 0.6, 1.5], "str"),
        ("map_type", str, "prefix", ["none", "prefix", "captured"], ["yay", "asdf"], 4),
        ("policy", str, "lower_bound", ["bfs", "curious", "lower_bound", "objective", "dfs"], ["yay", "asdf"], 4),
        ("max_card", int, 2, [1, 2, 3], [0, -1], 1.4),
        ("verbosity", list, ["rulelist"], [["rule", "label", "mine"], ["label"], ["samples", "mine", "minor"], ["progress", "loud"]], [["whoops"], ["rule", "label", "nope"]], "str")
    ]

    for param in params:
        # Test constructor default initialization
        c = C()
        assert getattr(c, param[0]) == param[2]
        assert type(getattr(c, param[0])) == param[1]
        
        # Test constructor assignment and valid arguments
        for v in param[3]:
            c = C(**{param[0]: v}).fit(toy_X, toy_y)
            assert getattr(c, param[0]) == v
            assert type(getattr(c, param[0])) == param[1]

        # Test value errors
        for v in param[4]:
            with pytest.raises(ValueError):
                C(**{param[0]: v}).fit([[1, 0]], [1])
         
        # Test type error
        with pytest.raises(TypeError):
            C(**{param[0]: param[5]}).fit([[1, 0]], [1])
def test_min_support():
    X = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    y = [1, 0, 0]

    nrules1 = len(C(verbosity=[]).fit(X, y).rl().rules)
    nrules2 = len(C(verbosity=[], min_support=0.4).fit(X, y).rl().rules)

    assert nrules1 > 1
    assert nrules2 == 1
def test_prediction_name():
    with pytest.raises(TypeError):
        C().fit(toy_X, toy_y, prediction_name=4)

    name = "name"
    rname = C(verbosity=[]).fit(toy_X, toy_y, prediction_name=name).rl().prediction_name
    assert rname == name
    
    rname = C(verbosity=[]).fit(toy_X, toy_y).rl().prediction_name
    assert rname == "prediction"
def test_maxcard():
    # Test cardinality cannot be greater than n_features
    with pytest.raises(ValueError):
        C(max_card=10).fit(toy_X, toy_y)

    max_cards = [1, 2, 3]
    rule_cards = [] 
    
    for max_card in max_cards:
        c = C(c=0.0, max_card=max_card, verbosity=[]).fit(compas_X, compas_y)

        rule_cards.append(len(c.rl().rules[0]["antecedents"]))

    for i in range(1, len(rule_cards)):
        assert rule_cards[i] > rule_cards[i - 1]
def test_set_params():
    c = C()

    r = 0.1
    n_iter = 10
    map_type = "captured"
    policy = "dfs"
    verbosity = ["loud", "samples"]
    ablation = 2
    max_card = 4
    min_support = 0.1

    c.set_params(c=r, n_iter=n_iter, map_type=map_type, policy=policy,
                 verbosity=verbosity, ablation=ablation, max_card=max_card,
                 min_support=min_support)

    assert c.c == r
    assert c.n_iter == n_iter
    assert c.map_type == map_type
    assert c.policy == policy
    assert c.verbosity == verbosity
    assert c.ablation == ablation
    assert c.max_card == c.max_card
    assert c.min_support == c.min_support

    # Test singular assignment
    c.set_params(n_iter=1234)
    assert c.n_iter == 1234

    with pytest.raises(ValueError):
        c.set_params(random_param=4)
def test_c():
    cl = C(verbosity=[], n_iter=100000)
    cs = [0.3, 0.01, 0.0]
    rls = []

    for c in cs:
        cl.set_params(c=c)
        rls.append(cl.fit(compas_X, compas_y).rl())
    
    for i in range(1, len(rls)):
        assert len(rls[i].rules) > len(rls[i - 1].rules)

    warnings.simplefilter("error", RuntimeWarning)

    # Sanity check
    cl.set_params(c=0.01)
    cl.fit(compas_X, compas_y)

    # Test warnings
    with pytest.warns(RuntimeWarning):
        cl.set_params(c=(0.8 / compas_X.shape[0]))
        cl.fit(compas_X, compas_y)
 
    with pytest.warns(RuntimeWarning):
        cl.set_params(c=0.49)
        cl.fit(compas_X, compas_y)
def test_general_other():
    c = C(verbosity=[])
    
    data_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data_train.csv")
    data_X, data_y, data_features, data_prediction = load_from_csv(data_path)

    rl = c.fit(data_X, data_y, data_features, data_prediction).rl()

    assert rl.__str__() == "RULELIST:\nlabel = False"
def test_notfitted():
    c = C()

    with pytest.raises(ValueError) as ex_info:
        c.predict([[1, 0]])
    
    assert "not fitted yet" in str(ex_info.value)

    with pytest.raises(ValueError) as ex_info:
        c.score([[1, 0]], [1])

    assert "not fitted yet" in str(ex_info.value)
def test_get_params():
    c = C()

    params = c.get_params()

    assert params["c"] == 0.01
    assert params["n_iter"] == 10000
    assert params["map_type"] == "prefix"
    assert params["policy"] == "lower_bound"
    assert params["verbosity"] == ["rulelist"]
    assert params["ablation"] == 0
    assert params["max_card"] == 2
    assert params["min_support"] == 0.01
def test_niter():
    times = []
    n_iters = [10, 100000]

    for n_iter in n_iters:
        s = time.time()
        C(n_iter=n_iter, verbosity=[]).fit(compas_X, compas_y)
        t = time.time() - s
        
        times.append(t)

    for i in range(1, len(times)):
        assert times[i] > times[i - 1]
def test_general_compas():
    # Test the whole algorithm
    c = C(verbosity=[], c=0.001)

    rl = c.fit(compas_X, compas_y, compas_features, compas_prediction).rl()

    assert rl.__str__() == "RULELIST:\nif [Age=24-30 && Prior-Crimes=0]:\n  Recidivate-Within-Two-Years = False\nelse if [not Age=18-25 && not Prior-Crimes>3]:\n  Recidivate-Within-Two-Years = False\nelse \n  Recidivate-Within-Two-Years = True"

    # Test using the same classifier twice    
    c.set_params(max_card=1)
    rl = c.fit(compas_X, compas_y, compas_features, compas_prediction).rl()

    assert rl.__str__() == "RULELIST:\nif [Prior-Crimes>5]:\n  Recidivate-Within-Two-Years = True\nelse if [Age<=40]:\n  Recidivate-Within-Two-Years = False\nelse if [Age=18-20]:\n  Recidivate-Within-Two-Years = True\nelse if [Prior-Crimes>3]:\n  Recidivate-Within-Two-Years = True\nelse if [Age>=30]:\n  Recidivate-Within-Two-Years = False\nelse if [Prior-Crimes=0]:\n  Recidivate-Within-Two-Years = False\nelse \n  Recidivate-Within-Two-Years = True"
def test_score():
    c = C(verbosity=[])

    # Test score with a predict vector
    assert c.score([1, 0], [1, 0]) == 1.0

    # Can it learn simple datasets?
    assert c.fit(toy_X, toy_y).score(toy_X, toy_y) == 1.0

    c.fit(compas_X, compas_y)
    c_score = c.score(compas_X, compas_y)
    assert abs(c_score - 0.6609370) < 0.0001
    assert c_score == c.score(c.predict(compas_X), compas_y)
def test_features():
    c = C(verbosity=[])

    with pytest.raises(ValueError):
        c.fit(toy_X, toy_y, features=["only_one"])

    with pytest.raises(TypeError):
        c.fit(toy_X, toy_y, features="wrong_type")
    
    with pytest.raises(TypeError):
        c.fit(toy_X, toy_y, features=["wrong_inner_type", 4])
    
    f1 = c.fit(toy_X, toy_y).rl().features
    assert f1 == ["feature" + str(i + 1) for i in range(len(toy_y)) ]

    custom = ["custom" + str(i + 1) for i in range(len(toy_y)) ]
    f2 = c.fit(toy_X, toy_y, features=custom).rl().features
    assert f2 == custom
def test_store(tmp_path):
    c = C(verbosity=[]).fit(toy_X, toy_y)

    rl = c.rl()
    params = c.get_params()
   
    fname = str(tmp_path / "r.save")
    c.save(fname)

    for name,_ in params.items():
        c.set_params(**{ name: 0 })
    c.rl_ = 0;

    assert c.get_params() != params

    c.load(fname)

    assert c.get_params() == params
    assert c.rl().rules == rl.rules
def test_rl():
    c = C(verbosity=[])

    with pytest.raises(ValueError) as ex_info:
        _ = c.rl()
    assert "not fitted yet" in str(ex_info.value)

    c.fit(toy_X, toy_y)

    assert c.rl_ == c.rl()

    with pytest.raises(ValueError):
        c.rl(0)
    
    with pytest.raises(TypeError):
        c.rl(RuleList(1, 1, 1))

    assert str(c.rl()) != "RULELIST:\npred = 0"
    c.rl(RuleList([{"antecedents":[0],"prediction":0}], ["feature1"], "pred"))
    assert str(c.rl()) == "RULELIST:\npred = 0"
def test_predict():
    # Test predict
    invalid_type = ["wrong_type", 1]
    invalid_value = [[1, 0], [[2, 0]]]

    c = C(verbosity=[])
    
    c.fit([[1, 0]], [1])
     
    for p in invalid_type:
        with pytest.raises(TypeError):
            c.predict(p)
    
    for p in invalid_value:
        with pytest.raises(ValueError):
            c.predict(p)

    c.fit(toy_X, toy_y)
    assert np.array_equal(c.predict(toy_X), toy_y)
    
    c.fit(compas_X, compas_y)
    assert np.sum(c.predict(compas_X)) == 3057
Beispiel #17
0
def test_store(tmp_path):
    r = C(verbosity=[]).fit(toy_X, toy_y).rl()

    p_rules = r.rules
    p_features = r.features
    p_prediction = r.prediction_name

    fname = str(tmp_path / "r.save")

    r.save(fname)

    r.rules = "garbage"
    r.features = "garbage"
    r.prediction_name = "garbage"

    r.load(fname)

    assert r.rules == p_rules
    assert r.features == p_features
    assert r.prediction_name == p_prediction

    # Sanity check
    assert r.rules != "garbage"
def test_fit_Xy():
    c = C(verbosity=[])

    valid = [
        ([[1, 0]], [1]),
        (np.array([[1, 0]]), np.array([1])),
        ([[1, 0, 1], [0, 1, 0]], np.array([1, 0]))
    ]

    invalid_type = [
        ("wrong_type", [1, 0]),
        ([[1, 0]], "wrong_type"),
        (1, 1)
    ]

    invalid_value = [
        ([1, 0], [1]),
        ([[1, 0]], [1, 0]),
        ([[1, 0]], [[1]]),
        ([[2, 0]], [1]),
        ([[1, 0]], [2])
    ]

    for pair in valid:
        c.fit(pair[0], pair[1])
        c.score(pair[0], pair[1])
        c.predict(pair[0])

    for pair in invalid_type:
        with pytest.raises(TypeError):
            c.fit(pair[0], pair[1])
            c.score(pair[0], pair[1])
    
    for pair in invalid_value:
        with pytest.raises(ValueError):
            c.fit(pair[0], pair[1])
            c.score(pair[0], pair[1])
Beispiel #19
0
def test_repr():
    r = C(verbosity=[]).fit(toy_X, toy_y).rl()

    assert repr(
        r
    ) == "RULELIST:\nif [feature1]:\n  prediction = True\nelse \n  prediction = False\nAll features: (['feature1', 'feature2', 'feature3'])"
Beispiel #20
0
def test_str():
    r = C(verbosity=[]).fit(toy_X, toy_y).rl()

    assert str(
        r
    ) == "RULELIST:\nif [feature1]:\n  prediction = True\nelse \n  prediction = False"