Expected error reduction query strategy. References: Roy and McCallum, 2001 (http://groups.csail.mit.edu/rrg/papers/icml01.pdf) Args: learner: The ActiveLearner object for which the expected error is to be estimated. X: The samples. loss: Th
(learner: ActiveLearner, X: modALinput, loss: str = 'binary',
p_subsample: np.float = 1.0, n_instances: int = 1,
random_tie_break: bool = False)
| 16 | |
| 17 | |
| 18 | def expected_error_reduction(learner: ActiveLearner, X: modALinput, loss: str = 'binary', |
| 19 | p_subsample: np.float = 1.0, n_instances: int = 1, |
| 20 | random_tie_break: bool = False) -> np.ndarray: |
| 21 | """ |
| 22 | Expected error reduction query strategy. |
| 23 | |
| 24 | References: |
| 25 | Roy and McCallum, 2001 (http://groups.csail.mit.edu/rrg/papers/icml01.pdf) |
| 26 | |
| 27 | Args: |
| 28 | learner: The ActiveLearner object for which the expected error |
| 29 | is to be estimated. |
| 30 | X: The samples. |
| 31 | loss: The loss function to be used. Can be 'binary' or 'log'. |
| 32 | p_subsample: Probability of keeping a sample from the pool when |
| 33 | calculating expected error. Significantly improves runtime |
| 34 | for large sample pools. |
| 35 | n_instances: The number of instances to be sampled. |
| 36 | random_tie_break: If True, shuffles utility scores to randomize the order. This |
| 37 | can be used to break the tie when the highest utility score is not unique. |
| 38 | |
| 39 | |
| 40 | Returns: |
| 41 | The indices of the instances from X chosen to be labelled. |
| 42 | The expected error metric of the chosen instances; |
| 43 | """ |
| 44 | |
| 45 | assert 0.0 <= p_subsample <= 1.0, 'p_subsample subsampling keep ratio must be between 0.0 and 1.0' |
| 46 | assert loss in ['binary', 'log'], 'loss must be \'binary\' or \'log\'' |
| 47 | |
| 48 | expected_error = np.zeros(shape=(data_shape(X)[0],)) |
| 49 | possible_labels = np.unique(learner.y_training) |
| 50 | |
| 51 | try: |
| 52 | X_proba = learner.predict_proba(X) |
| 53 | except NotFittedError: |
| 54 | # TODO: implement a proper cold-start |
| 55 | return np.array([0]) |
| 56 | |
| 57 | cloned_estimator = clone(learner.estimator) |
| 58 | |
| 59 | for x_idx, x in enumerate_data(X): |
| 60 | # subsample the data if needed |
| 61 | if np.random.rand() <= p_subsample: |
| 62 | X_reduced = drop_rows(X, x_idx) |
| 63 | # estimate the expected error |
| 64 | for y_idx, y in enumerate(possible_labels): |
| 65 | X_new = add_row(learner.X_training, x) |
| 66 | y_new = data_vstack((learner.y_training, np.array(y).reshape(1,))) |
| 67 | |
| 68 | cloned_estimator.fit(X_new, y_new) |
| 69 | refitted_proba = cloned_estimator.predict_proba(X_reduced) |
| 70 | if loss is 'binary': |
| 71 | nloss = _proba_uncertainty(refitted_proba) |
| 72 | elif loss is 'log': |
| 73 | nloss = _proba_entropy(refitted_proba) |
| 74 | |
| 75 | expected_error[x_idx] += np.sum(nloss)*X_proba[x_idx, y_idx] |
nothing calls this directly
no test coverage detected
searching dependent graphs…