Passed
Pull Request — master (#414)
by Osma
02:32
created

HyperparameterOptimizer._objective()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
"""Hyperparameter optimization functionality for backends"""
2
3
import abc
4
import collections
5
import optuna
6
from .backend import AnnifBackend
7
from annif import logger
8
from logging import DEBUG
9
10
11
HPRecommendation = collections.namedtuple('HPRecommendation', 'lines score')
12
13
14
class HyperparameterOptimizer:
15
    """Base class for hyperparameter optimizers"""
16
17
    def __init__(self, backend, corpus, metric):
18
        self._backend = backend
19
        self._corpus = corpus
20
        self._metric = metric
21
22
    def _prepare(self):
23
        """Prepare the optimizer for hyperparameter evaluation"""
24
        pass  # pragma: no cover
25
26
    @abc.abstractmethod
27
    def _objective(self, trial):
28
        """Objective function to optimize"""
29
        pass  # pragma: no cover
30
31
    @abc.abstractmethod
32
    def _postprocess(self, study):
33
        """Convert the study results into hyperparameter recommendations"""
34
        pass  # pragma: no cover
35
36
    def optimize(self, n_trials):
37
        """Find the optimal hyperparameters by testing up to the given number
38
        of hyperparameter combinations"""
39
40
        self._prepare()
41
        study = optuna.create_study(direction='maximize')
42
        study.optimize(self._objective,
43
                       n_trials=n_trials,
44
                       gc_after_trial=False,
45
                       show_progress_bar=True)
46
        return self._postprocess(study)
47
48
49
class AnnifHyperoptBackend(AnnifBackend):
50
    """Base class for Annif backends that can perform hyperparameter
51
    optimization"""
52
53
    @abc.abstractmethod
54
    def get_hp_optimizer(self, corpus, metric):
55
        """Get a HyperparameterOptimizer object that can look for
56
        optimal hyperparameter combinations for the given corpus,
57
        measured using the given metric"""
58
59
        pass  # pragma: no cover
60