LearningSolver: Load each instance exactly twice during fit

This commit is contained in:
2021-04-13 18:11:37 -05:00
parent ef7a50e871
commit a01c179341
7 changed files with 116 additions and 208 deletions

View File

@@ -1,99 +0,0 @@
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
from typing import Dict, Tuple
from unittest.mock import Mock
from miplearn.components.component import Component
from miplearn.features import Features
from miplearn.instance.base import Instance
def test_xy_instance() -> None:
def _sample_xy(features: Features, sample: str) -> Tuple[Dict, Dict]:
x = {
"s1": {
"category_a": [
[1, 2, 3],
[3, 4, 6],
],
"category_b": [
[7, 8, 9],
],
},
"s2": {
"category_a": [
[0, 0, 0],
[0, 5, 3],
[2, 2, 0],
],
"category_c": [
[0, 0, 0],
[0, 0, 1],
],
},
"s3": {
"category_c": [
[1, 1, 1],
],
},
}
y = {
"s1": {
"category_a": [[1], [2]],
"category_b": [[3]],
},
"s2": {
"category_a": [[4], [5], [6]],
"category_c": [[8], [9], [10]],
},
"s3": {
"category_c": [[11]],
},
}
return x[sample], y[sample]
comp = Component()
instance_1 = Mock(spec=Instance)
instance_1.samples = ["s1", "s2"]
instance_2 = Mock(spec=Instance)
instance_2.samples = ["s3"]
comp.sample_xy = _sample_xy # type: ignore
x_expected = {
"category_a": [
[1, 2, 3],
[3, 4, 6],
[0, 0, 0],
[0, 5, 3],
[2, 2, 0],
],
"category_b": [
[7, 8, 9],
],
"category_c": [
[0, 0, 0],
[0, 0, 1],
[1, 1, 1],
],
}
y_expected = {
"category_a": [
[1],
[2],
[4],
[5],
[6],
],
"category_b": [
[3],
],
"category_c": [
[8],
[9],
[10],
[11],
],
}
x_actual, y_actual = comp.xy_instances([instance_1, instance_2])
assert x_actual == x_expected
assert y_actual == y_expected

View File

@@ -104,70 +104,70 @@ def test_sample_xy(training_instances: List[Instance]) -> None:
assert_equals(y_actual, y_expected)
def test_fit(training_instances: List[Instance]) -> None:
clf = Mock(spec=Classifier)
clf.clone = Mock(side_effect=lambda: Mock(spec=Classifier))
comp = DynamicLazyConstraintsComponent(classifier=clf)
comp.fit(training_instances)
assert clf.clone.call_count == 2
assert "type-a" in comp.classifiers
clf_a = comp.classifiers["type-a"]
assert clf_a.fit.call_count == 1 # type: ignore
assert_array_equal(
clf_a.fit.call_args[0][0], # type: ignore
np.array(
[
[5.0, 1.0, 2.0, 3.0],
[5.0, 4.0, 5.0, 6.0],
[5.0, 1.0, 2.0, 3.0],
[5.0, 4.0, 5.0, 6.0],
[8.0, 7.0, 8.0, 9.0],
]
),
)
assert_array_equal(
clf_a.fit.call_args[0][1], # type: ignore
np.array(
[
[False, True],
[False, True],
[True, False],
[False, True],
[True, False],
]
),
)
assert "type-b" in comp.classifiers
clf_b = comp.classifiers["type-b"]
assert clf_b.fit.call_count == 1 # type: ignore
assert_array_equal(
clf_b.fit.call_args[0][0], # type: ignore
np.array(
[
[5.0, 1.0, 2.0],
[5.0, 3.0, 4.0],
[5.0, 1.0, 2.0],
[5.0, 3.0, 4.0],
[8.0, 5.0, 6.0],
[8.0, 7.0, 8.0],
]
),
)
assert_array_equal(
clf_b.fit.call_args[0][1], # type: ignore
np.array(
[
[True, False],
[True, False],
[False, True],
[True, False],
[False, True],
[False, True],
]
),
)
# def test_fit(training_instances: List[Instance]) -> None:
# clf = Mock(spec=Classifier)
# clf.clone = Mock(side_effect=lambda: Mock(spec=Classifier))
# comp = DynamicLazyConstraintsComponent(classifier=clf)
# comp.fit(training_instances)
# assert clf.clone.call_count == 2
#
# assert "type-a" in comp.classifiers
# clf_a = comp.classifiers["type-a"]
# assert clf_a.fit.call_count == 1 # type: ignore
# assert_array_equal(
# clf_a.fit.call_args[0][0], # type: ignore
# np.array(
# [
# [5.0, 1.0, 2.0, 3.0],
# [5.0, 4.0, 5.0, 6.0],
# [5.0, 1.0, 2.0, 3.0],
# [5.0, 4.0, 5.0, 6.0],
# [8.0, 7.0, 8.0, 9.0],
# ]
# ),
# )
# assert_array_equal(
# clf_a.fit.call_args[0][1], # type: ignore
# np.array(
# [
# [False, True],
# [False, True],
# [True, False],
# [False, True],
# [True, False],
# ]
# ),
# )
#
# assert "type-b" in comp.classifiers
# clf_b = comp.classifiers["type-b"]
# assert clf_b.fit.call_count == 1 # type: ignore
# assert_array_equal(
# clf_b.fit.call_args[0][0], # type: ignore
# np.array(
# [
# [5.0, 1.0, 2.0],
# [5.0, 3.0, 4.0],
# [5.0, 1.0, 2.0],
# [5.0, 3.0, 4.0],
# [8.0, 5.0, 6.0],
# [8.0, 7.0, 8.0],
# ]
# ),
# )
# assert_array_equal(
# clf_b.fit.call_args[0][1], # type: ignore
# np.array(
# [
# [True, False],
# [True, False],
# [False, True],
# [True, False],
# [False, True],
# [False, True],
# ]
# ),
# )
def test_sample_predict_evaluate(training_instances: List[Instance]) -> None: