|
1 | | -""" |
| 1 | +r""" |
2 | 2 | Stopping criteria for value computations. |
3 | 3 |
|
4 | | -This module provides a basic set of stopping criteria, like [MaxUpdates][pydvl.value.stopping.MaxUpdates], |
5 | | -[MaxTime][pydvl.value.stopping.MaxTime], or [HistoryDeviation][pydvl.value.stopping.HistoryDeviation] among others. |
6 | | -These can behave in different ways depending on the context. |
7 | | -For example, [MaxUpdates][pydvl.value.stopping.MaxUpdates] limits |
| 4 | +This module provides a basic set of stopping criteria, like |
| 5 | +[MaxUpdates][pydvl.value.stopping.MaxUpdates], |
| 6 | +[MaxTime][pydvl.value.stopping.MaxTime], or |
| 7 | +[HistoryDeviation][pydvl.value.stopping.HistoryDeviation] among others. These |
| 8 | +can behave in different ways depending on the context. For example, |
| 9 | +[MaxUpdates][pydvl.value.stopping.MaxUpdates] limits |
8 | 10 | the number of updates to values, which depending on the algorithm may mean a |
9 | 11 | different number of utility evaluations or imply other computations like solving |
10 | 12 | a linear or quadratic program. |
11 | 13 |
|
12 | | -## Creating stopping criteria |
13 | | -
|
14 | | -The easiest way is to declare a function implementing the interface |
15 | | -[StoppingCriterionCallable][pydvl.value.stopping.StoppingCriterionCallable] and |
16 | | -wrap it with [make_criterion()][pydvl.value.stopping.make_criterion]. This |
17 | | -creates a [StoppingCriterion][pydvl.value.stopping.StoppingCriterion] object |
18 | | -that can be composed with other stopping criteria. |
19 | | -
|
20 | | -Alternatively, and in particular if reporting of completion is required, one can |
21 | | -inherit from this class and implement the abstract methods |
22 | | -[_check][pydvl.value.stopping.StoppingCriterion._check] and |
23 | | -[completion][pydvl.value.stopping.StoppingCriterion.completion]. |
| 14 | +Stopping criteria are callables that are evaluated on a |
| 15 | +[ValuationResult][pydvl.value.result.ValuationResult] and return a |
| 16 | +[Status][pydvl.utils.status.Status] object. They can be combined using boolean |
| 17 | +operators. |
| 18 | +
|
| 19 | +## How convergence is determined |
| 20 | +
|
| 21 | +Most stopping criteria keep track of the convergence of each index separately |
| 22 | +but make global decisions based on the overall convergence of some fraction of |
| 23 | +all indices. For example, if we have a stopping criterion that checks whether |
| 24 | +the standard error of 90% of values is below a threshold, then methods will keep |
| 25 | +updating **all** indices until 90% of them have converged, irrespective of the |
| 26 | +quality of the individual estimates, and *without freezing updates* for indices |
| 27 | +along the way as values individually attain low standard error. |
| 28 | +
|
| 29 | +This has some practical implications, because some values do tend to converge |
| 30 | +sooner than others. For example, assume we use the criterion |
| 31 | +`AbsoluteStandardError(0.02) | MaxUpdates(1000)`. Then values close to 0 might |
| 32 | +be marked as "converged" rather quickly because they fulfill the first |
| 33 | +criterion, say after 20 iterations, despite being poor estimates. Because other |
| 34 | +indices take much longer to have low standard error and the criterion is a |
| 35 | +global check, the "converged" ones keep being updated and end up being good |
| 36 | +estimates. In this case, this has been beneficial, but one might not wish for |
| 37 | +converged values to be updated, if one is sure that the criterion is adequate |
| 38 | +for individual values. |
| 39 | +
|
| 40 | +[Semi-value methods][pydvl.value.semivalues] include a parameter |
| 41 | +`skip_converged` that allows to skip the computation of values that have |
| 42 | +converged. The way to avoid doing this too early is to use a more stringent |
| 43 | +check, e.g. `AbsoluteStandardError(1e-3) | MaxUpdates(1000)`. With |
| 44 | +`skip_converged=True` this check can still take less time than the first one, |
| 45 | +despite requiring more iterations for some indices. |
24 | 46 |
|
25 | | -## Composing stopping criteria |
26 | | -
|
27 | | -Objects of type [StoppingCriterion][pydvl.value.stopping.StoppingCriterion] can |
28 | | -be composed with the binary operators `&` (*and*), and `|` (*or*), following the |
29 | | -truth tables of [Status][pydvl.utils.status.Status]. The unary operator `~` |
30 | | -(*not*) is also supported. See |
31 | | -[StoppingCriterion][pydvl.value.stopping.StoppingCriterion] for details on how |
32 | | -these operations affect the behavior of the stopping criteria. |
33 | 47 |
|
34 | 48 | ## Choosing a stopping criterion |
35 | 49 |
|
|
40 | 54 | [AbsoluteStandardError][pydvl.value.stopping.AbsoluteStandardError]. The former |
41 | 55 | will ensure that the computation does not run for too long, while the latter |
42 | 56 | will try to achieve results that are stable enough. Note however that if the |
43 | | -thresholds too strict, one will always end up running until a maximum number of |
44 | | -iterations or time. |
| 57 | +threshold is too strict, one will always end up running until a maximum number |
| 58 | +of iterations or time. Also keep in mind that different values converge at |
| 59 | +different times, so you might want to use tight thresholds and `skip_converged` |
| 60 | +as described above for semi-values. |
45 | 61 |
|
46 | 62 |
|
47 | 63 | ??? Example |
|
67 | 83 |
|
68 | 84 | !!! Warning |
69 | 85 | Be careful not to reuse the same stopping criterion for different |
70 | | - computations. The object has state and will not be reset between calls. |
| 86 | + computations. The object has state and will not be reset between calls to |
| 87 | + value computation methods. If you need to reuse the same criterion, you |
| 88 | + should create a new instance. |
| 89 | +
|
| 90 | +
|
| 91 | +## Creating stopping criteria |
| 92 | +
|
| 93 | +The easiest way is to declare a function implementing the interface |
| 94 | +[StoppingCriterionCallable][pydvl.value.stopping.StoppingCriterionCallable] and |
| 95 | +wrap it with [make_criterion()][pydvl.value.stopping.make_criterion]. This |
| 96 | +creates a [StoppingCriterion][pydvl.value.stopping.StoppingCriterion] object |
| 97 | +that can be composed with other stopping criteria. |
| 98 | +
|
| 99 | +Alternatively, and in particular if reporting of completion is required, one can |
| 100 | +inherit from this class and implement the abstract methods `_check` and |
| 101 | +[completion][pydvl.value.stopping.StoppingCriterion.completion]. |
| 102 | +
|
| 103 | +## Combining stopping criteria |
| 104 | +
|
| 105 | +Objects of type [StoppingCriterion][pydvl.value.stopping.StoppingCriterion] can |
| 106 | +be combined with the binary operators `&` (*and*), and `|` (*or*), following the |
| 107 | +truth tables of [Status][pydvl.utils.status.Status]. The unary operator `~` |
| 108 | +(*not*) is also supported. See |
| 109 | +[StoppingCriterion][pydvl.value.stopping.StoppingCriterion] for details on how |
| 110 | +these operations affect the behavior of the stopping criteria. |
71 | 111 |
|
72 | 112 |
|
73 | 113 | ## References |
|
0 commit comments