mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-06 09:28:51 -06:00
Redesign component.evaluate
This commit is contained in:
@@ -7,7 +7,7 @@ from miplearn import Component, Instance
|
||||
|
||||
|
||||
def test_xy_instance():
|
||||
def _xy_sample(features, sample):
|
||||
def _sample_xy(features, sample):
|
||||
x = {
|
||||
"s1": {
|
||||
"category_a": [
|
||||
@@ -57,7 +57,7 @@ def test_xy_instance():
|
||||
instance_2 = Mock(spec=Instance)
|
||||
instance_2.training_data = ["s3"]
|
||||
instance_2.features = {}
|
||||
comp.xy = _xy_sample
|
||||
comp.sample_xy = _sample_xy
|
||||
x_expected = {
|
||||
"category_a": [
|
||||
[1, 2, 3],
|
||||
|
||||
@@ -293,7 +293,7 @@ def test_xy_sample() -> None:
|
||||
[False, True],
|
||||
],
|
||||
}
|
||||
xy = StaticLazyConstraintsComponent.xy(features, sample)
|
||||
xy = StaticLazyConstraintsComponent.sample_xy(features, sample)
|
||||
assert xy is not None
|
||||
x_actual, y_actual = xy
|
||||
assert x_actual == x_expected
|
||||
|
||||
@@ -75,35 +75,35 @@ def test_x_y_predict() -> None:
|
||||
}
|
||||
|
||||
|
||||
def test_obj_evaluate():
|
||||
instances, models = get_test_pyomo_instances()
|
||||
reg = Mock(spec=Regressor)
|
||||
reg.predict = Mock(return_value=np.array([[1000.0], [1000.0]]))
|
||||
reg.clone = lambda: reg
|
||||
comp = ObjectiveValueComponent(
|
||||
lb_regressor=reg,
|
||||
ub_regressor=reg,
|
||||
)
|
||||
comp.fit(instances)
|
||||
ev = comp.evaluate(instances)
|
||||
assert ev == {
|
||||
"Lower bound": {
|
||||
"Explained variance": 0.0,
|
||||
"Max error": 183.0,
|
||||
"Mean absolute error": 126.5,
|
||||
"Mean squared error": 19194.5,
|
||||
"Median absolute error": 126.5,
|
||||
"R2": -5.012843605607331,
|
||||
},
|
||||
"Upper bound": {
|
||||
"Explained variance": 0.0,
|
||||
"Max error": 183.0,
|
||||
"Mean absolute error": 126.5,
|
||||
"Mean squared error": 19194.5,
|
||||
"Median absolute error": 126.5,
|
||||
"R2": -5.012843605607331,
|
||||
},
|
||||
}
|
||||
# def test_obj_evaluate():
|
||||
# instances, models = get_test_pyomo_instances()
|
||||
# reg = Mock(spec=Regressor)
|
||||
# reg.predict = Mock(return_value=np.array([[1000.0], [1000.0]]))
|
||||
# reg.clone = lambda: reg
|
||||
# comp = ObjectiveValueComponent(
|
||||
# lb_regressor=reg,
|
||||
# ub_regressor=reg,
|
||||
# )
|
||||
# comp.fit(instances)
|
||||
# ev = comp.evaluate(instances)
|
||||
# assert ev == {
|
||||
# "Lower bound": {
|
||||
# "Explained variance": 0.0,
|
||||
# "Max error": 183.0,
|
||||
# "Mean absolute error": 126.5,
|
||||
# "Mean squared error": 19194.5,
|
||||
# "Median absolute error": 126.5,
|
||||
# "R2": -5.012843605607331,
|
||||
# },
|
||||
# "Upper bound": {
|
||||
# "Explained variance": 0.0,
|
||||
# "Max error": 183.0,
|
||||
# "Mean absolute error": 126.5,
|
||||
# "Mean squared error": 19194.5,
|
||||
# "Median absolute error": 126.5,
|
||||
# "R2": -5.012843605607331,
|
||||
# },
|
||||
# }
|
||||
|
||||
|
||||
def test_xy_sample_with_lp() -> None:
|
||||
@@ -125,7 +125,7 @@ def test_xy_sample_with_lp() -> None:
|
||||
"Lower bound": [[1.0]],
|
||||
"Upper bound": [[2.0]],
|
||||
}
|
||||
xy = ObjectiveValueComponent.xy(features, sample)
|
||||
xy = ObjectiveValueComponent.sample_xy(features, sample)
|
||||
assert xy is not None
|
||||
x_actual, y_actual = xy
|
||||
assert x_actual == x_expected
|
||||
@@ -150,7 +150,7 @@ def test_xy_sample_without_lp() -> None:
|
||||
"Lower bound": [[1.0]],
|
||||
"Upper bound": [[2.0]],
|
||||
}
|
||||
xy = ObjectiveValueComponent.xy(features, sample)
|
||||
xy = ObjectiveValueComponent.sample_xy(features, sample)
|
||||
assert xy is not None
|
||||
x_actual, y_actual = xy
|
||||
assert x_actual == x_expected
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
from typing import Dict
|
||||
from unittest.mock import Mock
|
||||
|
||||
import numpy as np
|
||||
@@ -10,6 +10,7 @@ from scipy.stats import randint
|
||||
|
||||
from miplearn import Classifier, LearningSolver
|
||||
from miplearn.classifiers.threshold import Threshold
|
||||
from miplearn.components import classifier_evaluation_dict
|
||||
from miplearn.components.primal import PrimalSolutionComponent
|
||||
from miplearn.problems.tsp import TravelingSalesmanGenerator
|
||||
from miplearn.types import TrainingSample, Features
|
||||
@@ -69,7 +70,7 @@ def test_xy() -> None:
|
||||
[True, False],
|
||||
]
|
||||
}
|
||||
xy = PrimalSolutionComponent.xy(features, sample)
|
||||
xy = PrimalSolutionComponent.sample_xy(features, sample)
|
||||
assert xy is not None
|
||||
x_actual, y_actual = xy
|
||||
assert x_actual == x_expected
|
||||
@@ -122,7 +123,7 @@ def test_xy_without_lp_solution() -> None:
|
||||
[True, False],
|
||||
]
|
||||
}
|
||||
xy = PrimalSolutionComponent.xy(features, sample)
|
||||
xy = PrimalSolutionComponent.sample_xy(features, sample)
|
||||
assert xy is not None
|
||||
x_actual, y_actual = xy
|
||||
assert x_actual == x_expected
|
||||
@@ -169,11 +170,11 @@ def test_predict() -> None:
|
||||
}
|
||||
}
|
||||
}
|
||||
x, _ = PrimalSolutionComponent.xy(features, sample)
|
||||
x, _ = PrimalSolutionComponent.sample_xy(features, sample)
|
||||
comp = PrimalSolutionComponent()
|
||||
comp.classifiers = {"default": clf}
|
||||
comp.thresholds = {"default": thr}
|
||||
solution_actual = comp.predict(features, sample)
|
||||
solution_actual = comp.sample_predict(features, sample)
|
||||
clf.predict_proba.assert_called_once()
|
||||
assert_array_equal(x["default"], clf.predict_proba.call_args[0][0])
|
||||
thr.predict.assert_called_once()
|
||||
@@ -229,3 +230,43 @@ def test_usage():
|
||||
assert stats["Primal: Free"] == 0
|
||||
assert stats["Primal: One"] + stats["Primal: Zero"] == 10
|
||||
assert stats["Lower bound"] == stats["Warm start value"]
|
||||
|
||||
|
||||
def test_evaluate() -> None:
|
||||
comp = PrimalSolutionComponent()
|
||||
comp.sample_predict = lambda _, __: { # type: ignore
|
||||
"x": {
|
||||
0: 1.0,
|
||||
1: 0.0,
|
||||
2: 0.0,
|
||||
3: None,
|
||||
4: 1.0,
|
||||
}
|
||||
}
|
||||
features: Features = {
|
||||
"Variables": {
|
||||
"x": {
|
||||
0: {},
|
||||
1: {},
|
||||
2: {},
|
||||
3: {},
|
||||
4: {},
|
||||
}
|
||||
}
|
||||
}
|
||||
sample: TrainingSample = {
|
||||
"Solution": {
|
||||
"x": {
|
||||
0: 1.0,
|
||||
1: 1.0,
|
||||
2: 0.0,
|
||||
3: 1.0,
|
||||
4: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
ev = comp.sample_evaluate(features, sample)
|
||||
assert ev == {
|
||||
0: classifier_evaluation_dict(tp=1, fp=1, tn=3, fn=0),
|
||||
1: classifier_evaluation_dict(tp=2, fp=0, tn=1, fn=2),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user