Skip to content

Commit 9d5786d

Browse files
committed
Fixing ShapWrapper predcit_proba method and adding tests
1 parent 56f3ccf commit 9d5786d

File tree

5 files changed

+73
-7
lines changed

5 files changed

+73
-7
lines changed

bigml/model.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ def __init__(self, model, api=None, fields=None, cache_get=None,
450450
else:
451451
self.tree_type = CLASSIFICATION
452452
self.offsets = c.OFFSETS[str(self.weighted)]
453-
454453
else:
455454
raise Exception("Cannot create the Model instance."
456455
" Only correctly finished models can be"

bigml/shapwrapper.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def __init__(self, model, api=None, cache_get=None,
4242
objective_id = getattr(self.local_model, "objective_id", None)
4343
self.fields = Fields(self.local_model.fields,
4444
objective_field=objective_id)
45+
self.objective_categories = self.local_model.objective_categories
4546
self.x_headers = [self.fields.field_name(field_id) for field_id in
4647
self.fields.sorted_field_ids()]
4748
self.y_header = self.fields.field_name(self.fields.objective_field)
@@ -64,8 +65,10 @@ def predict_proba(self, x_test):
6465
raise ValueError("This method is only available for classification"
6566
" models.")
6667
input_data_list = self.fields.from_numpy(x_test)
67-
predictions = np.ndarray([])
68-
for input_data in inner_data_list:
69-
prediction = self.predict_probability(input_data, compact=True)
70-
np.append(predictions, np.ndarray(prediction))
71-
return predictions
68+
np_list = np.empty(shape=(len(input_data_list),
69+
len(self.objective_categories)))
70+
for index, input_data in enumerate(input_data_list):
71+
prediction = self.local_model.predict_probability(
72+
input_data, compact=True)
73+
np_list[index] = np.asarray([prediction])
74+
return np_list

bigml/supervised.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ def __init__(self, model, api=None, cache_get=None,
139139
self.local_model = local_model
140140
self.regression = resource_type == "linearregression" or \
141141
self.local_model.regression
142+
if not self.regression:
143+
self.objective_categories = self.local_model.objective_categories
142144
self.name = self.local_model.name
143145
self.description = self.local_model.description
144146

bigml/tests/compare_predictions_steps.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from bigml.local_model import LocalModel
3535
from bigml.fusion import Fusion
3636
from bigml.pca import PCA
37+
from bigml.shapwrapper import ShapWrapper
3738

3839

3940
from .create_prediction_steps import check_prediction
@@ -94,6 +95,11 @@ def i_create_a_local_supervised_model_from_file(step, model_file):
9495
step.bigml["local_model"] = SupervisedModel(res_filename(model_file))
9596

9697

98+
def i_create_a_local_shap_wrapper_from_file(step, model_file):
99+
"""Step: I create a local ShapWrapper from a <model_file> file"""
100+
step.bigml["local_model"] = ShapWrapper(res_filename(model_file))
101+
102+
97103
def i_create_a_local_model(step, pre_model=False):
98104
"""Step: I create a local model"""
99105
step.bigml["local_model"] = Model(world.model)
@@ -148,6 +154,7 @@ def the_local_bigml_prediction_is(step, value, prediction_type=None, key=None,
148154
eq_(value, prediction, precision=precision)
149155

150156

157+
151158
def i_create_a_local_prediction_with_confidence(step, data=None,
152159
pre_model=None):
153160
"""Step: I create a local prediction for <data> with confidence"""
@@ -160,6 +167,14 @@ def i_create_a_local_prediction_with_confidence(step, data=None,
160167
input_data, full=True)
161168

162169

170+
def i_create_a_shap_local_prediction(step, data=None):
171+
"""Step: I create a local prediction for <numpy_input>"""
172+
if data is None:
173+
data = "[]"
174+
step.bigml["local_prediction"] = step.bigml["local_model"].predict(
175+
data).tolist()[0]
176+
177+
163178
def i_create_a_local_prediction(step, data=None, pre_model=None):
164179
"""Step: I create a local prediction for <data>"""
165180
if data is None:
@@ -213,6 +228,13 @@ def i_create_local_probabilities(step, data=None):
213228
data, compact=True)
214229

215230

231+
def i_create_shap_local_probabilities(step, data=None):
232+
"""Step: I create shap local probabilities for <data>"""
233+
model = step.bigml["local_model"]
234+
step.bigml["local_probabilities"] = model.predict_proba(
235+
data).tolist()[0]
236+
237+
216238
def i_create_a_local_ensemble_prediction(step, data=None):
217239
"""Step: I create a local ensemble prediction for <data>"""
218240
if data is None:
@@ -452,6 +474,14 @@ def the_local_probabilities_are(step, prediction):
452474
approx_(local, expected, precision=4)
453475

454476

477+
def the_local_proba_prediction_is(step, proba_prediction):
478+
"""Step: the local probabilities prediction is <proba_prediction>"""
479+
local_probabilities = step.bigml["local_probabilities"]
480+
481+
for local, expected in zip(local_probabilities, proba_prediction):
482+
approx_(local, expected, precision=4)
483+
484+
455485
def the_local_ensemble_prediction_is(step, prediction):
456486
"""Step: the local ensemble prediction is <prediction>"""
457487
if isinstance(step.bigml["local_prediction"], (list, tuple)):

bigml/tests/test_03_local_prediction.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,10 @@ def test_scenario5(self):
175175
examples = [
176176
['data/imgs_deepnet.zip', "data/images/cats/pexels-pixabay-33358.jpg",
177177
{"region_score_threshold": 0.7},
178-
'{"prediction": [{"box": [0.68164, 0.30469, 0.79688, 0.36979], "label": "eye", "score": 0.79633}, {"box": [0.38086, 0.27865, 0.50391, 0.36068], "label": "eye", "score": 0.74563}]}']]
178+
('{"prediction": [{"box": [0.68164, 0.30469, 0.79688, 0.36979], '
179+
'"label": "eye", "score": 0.79633}, '
180+
'{"box": [0.38086, 0.27865, 0.50391, 0.36068], '
181+
'"label": "eye", "score": 0.74563}]}')]]
179182
for example in examples:
180183
example = dict(zip(headers, example))
181184
show_method(self, self.bigml["method"], example)
@@ -186,3 +189,32 @@ def test_scenario5(self):
186189
self, example["input_data"])
187190
prediction_compare.the_local_regions_prediction_is(
188191
self, example["prediction"])
192+
193+
def test_scenario6(self):
194+
"""
195+
Scenario 6: Successfully creating a prediction from a ShapWrapper of a model in a json file:
196+
Given I create a local model using ShapWrapper from a "<model>" file
197+
When I create a local prediction for "<numpy_input>"
198+
Then the local prediction is "<prediction>"
199+
When I create a local probabilities prediction for "<numpy_input>"
200+
Then the local probabilities prediction is "<proba_prediction>"
201+
"""
202+
import numpy as np
203+
show_doc(self.test_scenario6)
204+
headers = ["file_path", "numpy_input", "prediction", "proba_prediction"]
205+
examples = [
206+
['data/iris_model.json', np.asarray([np.asarray([0.5,1.0,1.0])]),
207+
0., [0.9818, 0.00921, 0.00899]]]
208+
for example in examples:
209+
example = dict(zip(headers, example))
210+
show_method(self, self.bigml["method"], example)
211+
prediction_compare.i_create_a_local_shap_wrapper_from_file(
212+
self, example["file_path"])
213+
prediction_compare.i_create_a_shap_local_prediction(
214+
self, example["numpy_input"])
215+
prediction_compare.the_local_prediction_is(
216+
self, example["prediction"])
217+
prediction_compare.i_create_shap_local_probabilities(
218+
self, example["numpy_input"])
219+
prediction_compare.the_local_proba_prediction_is(
220+
self, example["proba_prediction"])

0 commit comments

Comments
 (0)