Source code for skquery.oracle.TripletOracle

from ..exceptions import EmptyBudgetError, NoAnswerError


[docs] class TripletOracle: """ Oracle for triplet queries. Inspired from the formalization in [1]. Parameters ---------- budget : int, default=10 Maximum number of queries the oracle will answer. truth : array-like, default=None Ground truth labeling that emulates a human oracle. Attributes ---------- queries : int Number of queries answered by the oracle so far. budget : int Maximum number of queries the oracle will answer. truth : array-like, default=None Ground truth labeling that emulates a human oracle. References ---------- [1] Xiong, S., Pei, Y., Rosales, R., Fern, X. Z. Active Learning from Relative Comparisons, IEEE Transactions on Knowledge and Data Engineering, vol. 27, nᵒ 12, p. 3166‑3175, dec. 2015, doi: 10.1109/TKDE.2015.2462365. """ def __init__(self, budget=10, truth=None): self.queries = 0 self.budget = budget self.truth = truth
[docs] def query(self, i, j, k): """ Query the oracle on the relation between a triplet of points. Parameters ---------- i : int Index of first data point, the reference. j : int Index of second data point, the assumed positive example. k : int Index of third data point, the assumed negative example. Returns ------- answer : bool Answer to the query. Raises ------ NoAnswerError If the oracle doesn't give an answer, i.e. they don't know what to answer. """ if self.queries < self.budget: self.queries += 1 if self.truth is not None: if self.truth[i] == self.truth[j] and self.truth[i] != self.truth[k]: return True elif self.truth[i] != self.truth[j] and self.truth[i] == self.truth[k]: return False else: raise NoAnswerError answer = input(f"Is {i} more similar to {j} than to {k} ? (yes (y)/no (n)/pass (p)) ").strip().lower() if answer == "p": # "don't know" answer raise NoAnswerError else: return answer == "y" else: raise EmptyBudgetError