Closed azev77 closed 4 years ago
Regarding EvoTrees, could you precise the versions used for MLJ and EvoTres. I couldn't reproduce with the latest versions: MLJ v0.10.3 and EvoTrees v0.4.6:
using MLJ
X, y = @load_boston;
train, test = partition(eachindex(y), .7, rng=333);
@load EvoTreeRegressor
mdl = EvoTreeRegressor()
mach = machine(mdl, X, y)
fit!(mach, rows=train, verbosity=1)
(MLJtest) pkg> st
Status `~/Evovest/MLJtest/Project.toml`
[f6006082] EvoTrees v0.4.6
[add582a8] MLJ v0.10.3
I see the issue:
before I ran the code I deleted all my Julia libraries & downloaded MLJ EvoTrees etc from scratch.
I have EvoTrees v0.3.0
Next I manually downloaded the latest EvoTrees:
add https://github.com/Evovest/EvoTrees.jl
and things now work.
I've had this type of issue before, when installing one package doesn't allow me to install the latest version of another package.
To avoid those kind of package versioning bottlenecks, I think it's a good practice to create julia projects for every project. For example:
shell> mkdir MyProject
shell> cd MyProject
] activate .
Doing so will isolate the package within the given project and will minimize being exposed to potential dependencies conflicts.
@azev77 Can we close this now?
Yes. Yesterday they released EvoTrees 0.4.7 which fixed this.
@ablaom Question:
What is the advantage to a mutating function: fit!(m, rows=train)
As opposed to: res = fit(m, rows=train)
From upcoming design paper:
MLJ provides a basic fit/update/predict
interface to be implemented
by new supervised models. For unsupervised models predict
is
replaced with transform
and an optional inverse_transform
method. These methods operate on models which are mutable structs
storing hyper-parameters, and nothing else. This model interface is
purely functional for maximum flexibility. Presently the general MLJ
user is encouraged to interact through a machine interface sitting
on top. See more on this below.
In MLJ a model is just a struct storing the hyper-parameters
associated with some learning algorithm suggested by the struct name
(e.g., DecisionTreeClassifier
), and that is all. In the low-level,
functional-style, model interface learned parameters are not stored,
only passed around. Learned parameters are stored in machines (which
additionally point to the hyperparameters stored in a model); see
below. The separation of hyper-parameters and learned parameters is
essential to flexible model composition.
For supervised models the fit
method has this signature:
fit(model, verbosity, X, y)
where X
is training input and y
the training target. The method
outputs a triple, typically denoted (fitresult, cache, report)
.
The fitresult
stores the learned parameters, which must
include everything needed by predict
to make predictions, apart
from model
and new input data:
predict(model, fitresult, X)
The purpose of cache
is to pass on "state" not included in the
fitresult
to an update
method that the model implementer may
optionally overload:
update(model, verbosity, fitresult, cache, X, y)
This method is to be called instead of fit
(and passed the
fitresult
and cache
returned by the fit
call) when retraining
using identical data. (The data X
, y
, are included for implementer
convenience.) It provides an opportunity for the model implementer to
avoid unnecessary repetition of code execution. The three main
use-cases are:
Iterative models. If the only change to a random forest model is an increase in the number of trees by ten, for example, then not all trees need to be retrained; only ten new trees need to be trained. If a "self-tuning" model has been fit (i.e., tuned) using 70 iterations of Tree Parzen optimization, then adding 20 more iterations should build on the existing surrogate objective function, not ignore the existing tuning history.
Data preprocessing. Avoid overheads associated with data preprocessing, such as coercion of data into an algorithm-specific type.
Smart training of composite models. When tuning a simple
transformer-predictor pipeline model using a holdout set, for
example, it is unecessary to retrain the transformer if only the
predictor hyper-parameters change. MLJ implements "smart" retraining
of composite models like this by defining appropriate update
methods.
In the future MLJ will add an update_data
method to support
models that can cary out on-line learning.
The general MLJ user trains models through its machine interface. This makes some work-flows more convenient, but more significantly, introduces a syntax closely aligned with that for model composition (see below).
A machine is a mutable struct that binds a model to data at construction
mach = machine(model, X, y)
When the user calls fit!(mach, rows=...)
the fitresult
, cache
and report
variables generated by lower-level calls to fit
or
update
, are stored or updated in the machine struct, mach
, with
the training being optionally restricted to the specified rows of
data. To retrain with new hyper-parameters, the user simply mutates
model
and repeats the fit!
call.
Syntax for predicting using a machine is predict(mach, Xnew)
.
First I will train a model that works
LGBMRegressor
, then two that don't: ARDRegressor (breaks @ fit(), "PyError", which you're aware of) EvoTreeRegressor (breaks @ machine(), "MethodError") @jeremiedb