|
1 | | -from collections import OrderedDict |
| 1 | +from collections import OrderedDict, defaultdict |
2 | 2 | import json |
3 | 3 | import sys |
4 | 4 | import time |
|
8 | 8 |
|
9 | 9 | import openml |
10 | 10 | from ..tasks import get_task |
11 | | -from .._api_calls import _perform_api_call |
| 11 | +from .._api_calls import _perform_api_call, _file_id_to_url, _read_url_files |
12 | 12 | from ..exceptions import PyOpenMLError |
13 | 13 |
|
14 | 14 | class OpenMLRun(object): |
@@ -106,6 +106,83 @@ def _generate_trace_arff_dict(self): |
106 | 106 |
|
107 | 107 | return arff_dict |
108 | 108 |
|
| 109 | + def get_metric_score(self, sklearn_fn, kwargs={}): |
| 110 | + '''Calculates metric scores based on predicted values. Assumes the |
| 111 | + run has been executed locally (and contans run_data). Furthermore, |
| 112 | + it assumes that the 'correct' field has been set (which is |
| 113 | + automatically the case for local runs) |
| 114 | +
|
| 115 | + Parameters |
| 116 | + ------- |
| 117 | + sklearn_fn : function |
| 118 | + a function pointer to a sklearn function that |
| 119 | + accepts y_true, y_pred and *kwargs |
| 120 | +
|
| 121 | + Returns |
| 122 | + ------- |
| 123 | + scores : list |
| 124 | + a list of floats, of length num_folds * num_repeats |
| 125 | + ''' |
| 126 | + if self.data_content is not None: |
| 127 | + predictions_arff = self._generate_arff_dict() |
| 128 | + elif 'predictions' in self.output_files: |
| 129 | + raise ValueError('Not Implemented Yet: Function can currently only be used on locally executed runs (contributor needed!)') |
| 130 | + else: |
| 131 | + raise ValueError('Run should have been locally executed.') |
| 132 | + |
| 133 | + def _attribute_list_to_dict(attribute_list): |
| 134 | + # convenience function |
| 135 | + res = dict() |
| 136 | + for idx in range(len(attribute_list)): |
| 137 | + res[attribute_list[idx][0]] = idx |
| 138 | + return res |
| 139 | + attribute_dict = _attribute_list_to_dict(predictions_arff['attributes']) |
| 140 | + |
| 141 | + # might throw KeyError! |
| 142 | + predicted_idx = attribute_dict['prediction'] |
| 143 | + correct_idx = attribute_dict['correct'] |
| 144 | + repeat_idx = attribute_dict['repeat'] |
| 145 | + fold_idx = attribute_dict['fold'] |
| 146 | + sample_idx = attribute_dict['sample'] # TODO: this one might be zero |
| 147 | + |
| 148 | + if predictions_arff['attributes'][predicted_idx][1] != predictions_arff['attributes'][correct_idx][1]: |
| 149 | + pred = predictions_arff['attributes'][predicted_idx][1] |
| 150 | + corr = predictions_arff['attributes'][correct_idx][1] |
| 151 | + raise ValueError('Predicted and Correct do not have equal values: %s Vs. %s' %(str(pred), str(corr))) |
| 152 | + |
| 153 | + # TODO: these could be cached |
| 154 | + values_predict = {} |
| 155 | + values_correct = {} |
| 156 | + for line_idx, line in enumerate(predictions_arff['data']): |
| 157 | + rep = line[repeat_idx] |
| 158 | + fold = line[fold_idx] |
| 159 | + samp = line[sample_idx] |
| 160 | + |
| 161 | + # TODO: can be sped up bt preprocessing index, but OK for now. |
| 162 | + prediction = predictions_arff['attributes'][predicted_idx][1].index(line[predicted_idx]) |
| 163 | + correct = predictions_arff['attributes'][predicted_idx][1].index(line[correct_idx]) |
| 164 | + if rep not in values_predict: |
| 165 | + values_predict[rep] = dict() |
| 166 | + values_correct[rep] = dict() |
| 167 | + if fold not in values_predict[rep]: |
| 168 | + values_predict[rep][fold] = dict() |
| 169 | + values_correct[rep][fold] = dict() |
| 170 | + if samp not in values_predict[rep][fold]: |
| 171 | + values_predict[rep][fold][samp] = [] |
| 172 | + values_correct[rep][fold][samp] = [] |
| 173 | + |
| 174 | + values_predict[line[repeat_idx]][line[fold_idx]][line[sample_idx]].append(prediction) |
| 175 | + values_correct[line[repeat_idx]][line[fold_idx]][line[sample_idx]].append(correct) |
| 176 | + |
| 177 | + scores = [] |
| 178 | + for rep in values_predict.keys(): |
| 179 | + for fold in values_predict[rep].keys(): |
| 180 | + last_sample = len(values_predict[rep][fold]) - 1 |
| 181 | + y_pred = values_predict[rep][fold][last_sample] |
| 182 | + y_true = values_correct[rep][fold][last_sample] |
| 183 | + scores.append(sklearn_fn(y_true, y_pred, **kwargs)) |
| 184 | + return scores |
| 185 | + |
109 | 186 | def publish(self): |
110 | 187 | """Publish a run to the OpenML server. |
111 | 188 |
|
|
0 commit comments