Here’s an idea to simplify both the implementation of fit
and it’s use by developers and
end users. It is a variation of a suggestion already made by @CameronBieganek.
We have two fit methods: one to be implemented, raw_fit
, which is never called outside of the LearnAPI package, and one for calling by end users and developers, fit
, which is never overloaded.
Implementer does something like
raw_fit(strategy::MyStrategy, data...) = ... # `output`
params(::MyStrategy, output) = ... # `parameters` (just the learned ones)
predict(::MyStategy, parameters, newdata...) = ...
(Optionally, she can implement a report
method.)
In LearnAPI we have a type for wrapping the output of raw_fit
which becomes the output
of fit
, defined only in LearnAPI:
struct Model{S,O,P}
strategy::S
output::O # cleared out for serialization, ensembling, etc
params::P
end
function fit(strategy, data...)
output = raw_fit(strategy, data...)
params = LearnAPI.params(output)
return Model(strategy, output, params)
end
predict(model::Model, newdata...) = predict(model.strategy, model.params, newdata...)
I’m not stuck on Model
as the name for this wrapper.
The user or developer extending LearnAPI can do this:
model = fit(strategy, data...)
predict(model, newdata...)
And predict
still works if we clear out the full output
part of the
model
for serialization, ensembling, etc.
minimize(model::Model) = Model(model.strategy, nothing, model.params)
Otherwise, the full output is available for updating methods that need state.
Thoughts?