diff --git a/docs/src/anatomy_of_an_implementation.md b/docs/src/anatomy_of_an_implementation.md index 754bf94d..ee097e4f 100644 --- a/docs/src/anatomy_of_an_implementation.md +++ b/docs/src/anatomy_of_an_implementation.md @@ -106,7 +106,7 @@ Note that we also include `learner` in the struct, for it must be possible to re The core implementation of `fit` looks like this: ```@example anatomy -function LearnAPI.fit(learner::Ridge, data; verbosity=1) +function LearnAPI.fit(learner::Ridge, data; verbosity=LearnAPI.default_verbosity()) X, y = data @@ -397,7 +397,7 @@ methods - one to handle "regular" input, and one to handle the pre-processed dat (observations) which appears first below: ```@example anatomy2 -function LearnAPI.fit(learner::Ridge, observations::RidgeFitObs; verbosity=1) +function LearnAPI.fit(learner::Ridge, observations::RidgeFitObs; verbosity=LearnAPI.default_verbosity()) lambda = learner.lambda diff --git a/docs/src/fit_update.md b/docs/src/fit_update.md index 2e2c0858..08f5067a 100644 --- a/docs/src/fit_update.md +++ b/docs/src/fit_update.md @@ -3,8 +3,8 @@ ### Training ```julia -fit(learner, data; verbosity=1) -> model -fit(learner; verbosity=1) -> static_model +fit(learner, data; verbosity=LearnAPI.default_verbosity()) -> model +fit(learner; verbosity=LearnAPI.default_verbosity()) -> static_model ``` A "static" algorithm is one that does not generalize to new observations (e.g., some @@ -15,8 +15,8 @@ clustering algorithms); there is no training data and the algorithm is executed ### Updating ``` -update(model, data; verbosity=1, param1=new_value1, param2=new_value2, ...) -> updated_model -update_observations(model, new_data; verbosity=1, param1=new_value1, ...) -> updated_model +update(model, data; verbosity=..., param1=new_value1, param2=new_value2, ...) -> updated_model +update_observations(model, new_data; verbosity=..., param1=new_value1, ...) -> updated_model update_features(model, new_data; verbosity=1, param1=new_value1, ...) -> updated_model ``` @@ -101,18 +101,18 @@ See also [Density Estimation](@ref). Exactly one of the following must be implemented: -| method | fallback | -|:--------------------------------------------|:---------| -| [`fit`](@ref)`(learner, data; verbosity=1)` | none | -| [`fit`](@ref)`(learner; verbosity=1)` | none | +| method | fallback | +|:-----------------------------------------------------------------------|:---------| +| [`fit`](@ref)`(learner, data; verbosity=LearnAPI.default_verbosity())` | none | +| [`fit`](@ref)`(learner; verbosity=LearnAPI.default_verbosity())` | none | ### Updating | method | fallback | compulsory? | |:-------------------------------------------------------------------------------------|:---------|-------------| -| [`update`](@ref)`(model, data; verbosity=1, hyperparameter_updates...)` | none | no | -| [`update_observations`](@ref)`(model, data; verbosity=1, hyperparameter_updates...)` | none | no | -| [`update_features`](@ref)`(model, data; verbosity=1, hyperparameter_updates...)` | none | no | +| [`update`](@ref)`(model, data; verbosity=..., hyperparameter_updates...)` | none | no | +| [`update_observations`](@ref)`(model, data; verbosity=..., hyperparameter_updates...)` | none | no | +| [`update_features`](@ref)`(model, data; verbosity=..., hyperparameter_updates...)` | none | no | There are some contracts governing the behaviour of the update methods, as they relate to a previous `fit` call. Consult the document strings for details. @@ -124,4 +124,5 @@ fit update update_observations update_features +LearnAPI.default_verbosity ``` diff --git a/src/LearnAPI.jl b/src/LearnAPI.jl index c1564e06..5d31ce93 100644 --- a/src/LearnAPI.jl +++ b/src/LearnAPI.jl @@ -1,7 +1,8 @@ module LearnAPI -include("tools.jl") include("types.jl") +include("verbosity.jl") +include("tools.jl") include("predict_transform.jl") include("fit_update.jl") include("target_weights_features.jl") diff --git a/src/fit_update.jl b/src/fit_update.jl index 39a662a9..4d9c9e2e 100644 --- a/src/fit_update.jl +++ b/src/fit_update.jl @@ -1,8 +1,8 @@ # # FIT """ - fit(learner, data; verbosity=1) - fit(learner; verbosity=1) + fit(learner, data; verbosity=LearnAPI.default_verbosity()) + fit(learner; verbosity=LearnAPI.default_verbosity()) Execute the machine learning or statistical algorithm with configuration `learner` using the provided training `data`, returning an object, `model`, on which other methods, such @@ -17,26 +17,27 @@ model = fit(learner, (X, y)) ŷ = predict(model, Xnew) ``` -The signature `fit(learner; verbosity=1)` (no `data`) is provided by learners that do not -generalize to new observations (called *static algorithms*). In that case, +The signature `fit(learner; verbosity=...)` (no `data`) is provided by learners that do +not generalize to new observations (called *static algorithms*). In that case, `transform(model, data)` or `predict(model, ..., data)` carries out the actual algorithm execution, writing any byproducts of that operation to the mutable object `model` returned by `fit`. Use `verbosity=0` for warnings only, and `-1` for silent training. -See also [`predict`](@ref), [`transform`](@ref), [`inverse_transform`](@ref), -[`LearnAPI.functions`](@ref), [`obs`](@ref). +See also [`LearnAPI.default_verbosity`](@ref), [`predict`](@ref), [`transform`](@ref), +[`inverse_transform`](@ref), [`LearnAPI.functions`](@ref), [`obs`](@ref). # Extended help # New implementations Implementation of exactly one of the signatures is compulsory. If `fit(learner; -verbosity=1)` is implemented, then the trait [`LearnAPI.is_static`](@ref) must be +verbosity=...)` is implemented, then the trait [`LearnAPI.is_static`](@ref) must be overloaded to return `true`. -The signature must include `verbosity`. +The signature must include `verbosity` with [`LearnAPI.default_verbosity()`](@ref) as +default. If `data` encapsulates a *target* variable, as defined in LearnAPI.jl documentation, then [`LearnAPI.target(data)`](@ref) must be overloaded to return it. If [`predict`](@ref) or @@ -59,7 +60,7 @@ function fit end # # UPDATE AND COUSINS """ - update(model, data; verbosity=1, hyperparam_replacements...) + update(model, data; verbosity=LearnAPI.default_verbosity(), hyperparam_replacements...) Return an updated version of the `model` object returned by a previous [`fit`](@ref) or `update` call, but with the specified hyperparameter replacements, in the form `p1=value1, @@ -98,7 +99,12 @@ See also [`LearnAPI.clone`](@ref) function update end """ - update_observations(model, new_data; verbosity=1, parameter_replacements...) + update_observations( + model, + new_data; + parameter_replacements..., + verbosity=LearnAPI.default_verbosity(), + ) Return an updated version of the `model` object returned by a previous [`fit`](@ref) or `update` call given the new observations present in `new_data`. One may additionally @@ -134,7 +140,12 @@ See also [`LearnAPI.clone`](@ref). function update_observations end """ - update_features(model, new_data; verbosity=1, parameter_replacements...) + update_features( + model, + new_data; + parameter_replacements..., + verbosity=LearnAPI.default_verbosity(), + ) Return an updated version of the `model` object returned by a previous [`fit`](@ref) or `update` call given the new features encapsulated in `new_data`. One may additionally diff --git a/src/verbosity.jl b/src/verbosity.jl new file mode 100644 index 00000000..4f77e659 --- /dev/null +++ b/src/verbosity.jl @@ -0,0 +1,26 @@ +const DEFAULT_VERBOSITY = Ref(1) + +""" + LearnAPI.default_verbosity() + LearnAPI.default_verbosity(level::Int) + +Respectively return, or set, the default `verbosity` level for LearnAPI.jl methods that +support it, which includes [`fit`](@ref), [`update`](@ref), +[`update_observations`](@ref), and [`update_features`](@ref). The effect in a top-level +call is generally: + + + +| `level` | behaviour | +|:--------|:----------------------------------| +| 1 | informational | +| 0 | warnings only | +| -1 | silent | + + +Methods consuming `verbosity` generally call other verbosity-supporting methods +at one level lower, so increasing `verbosity` beyond `1` may be useful. + +""" +default_verbosity() = DEFAULT_VERBOSITY[] +default_verbosity(level) = (DEFAULT_VERBOSITY[] = level) diff --git a/test/runtests.jl b/test/runtests.jl index 8a255c83..056fa491 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,7 @@ using Test test_files = [ "tools.jl", + "verbosity.jl", "traits.jl", "clone.jl", "predict_transform.jl", diff --git a/test/verbosity.jl b/test/verbosity.jl new file mode 100644 index 00000000..72ce29c8 --- /dev/null +++ b/test/verbosity.jl @@ -0,0 +1,7 @@ +using Test + +@test LearnAPI.default_verbosity() ==1 +LearnAPI.default_verbosity(42) +@test LearnAPI.default_verbosity() == 42 + +true