From cefad7d0462007dc143edfc26f86b05217348980 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Wed, 17 Nov 2021 11:39:24 +0100 Subject: [PATCH 01/15] Add R-square --- src/MLJBase.jl | 3 ++- src/measures/continuous.jl | 37 ++++++++++++++++++++++++++++++++++++- test/measures/continuous.jl | 1 + test/runtests.jl | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/MLJBase.jl b/src/MLJBase.jl index 21293ade..7e28a218 100644 --- a/src/MLJBase.jl +++ b/src/MLJBase.jl @@ -186,7 +186,8 @@ export mav, mae, mape, rms, rmsl, rmslp1, rmsp, l1, l2, log_cosh, RMS, rmse, RootMeanSquaredError, root_mean_squared_error, RootMeanSquaredLogError, RMSL, root_mean_squared_log_error, rmsl, rmsle, RootMeanSquaredLogProportionalError, rmsl1, RMSLP, - MAPE, MeanAbsoluteProportionalError, log_cosh_loss, LogCosh, LogCoshLoss + MAPE, MeanAbsoluteProportionalError, log_cosh_loss, LogCosh, LogCoshLoss, + RSquared, rsq, rsquared # measures/confusion_matrix.jl: export confusion_matrix, confmat, ConfusionMatrix diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index d1ae819c..aa815147 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -66,6 +66,41 @@ call(::RootMeanSquaredError, w::Arr{<:Real}) = (y .- ŷ).^2 .* w |> skipinvalid |> mean |> sqrt +# ------------------------------------------------------------------------- +# R-squared (coefficient of determination) + +struct RSquared <: Aggregated end + +metadata_measure(RSquared; + instances = ["rsq", "rsquared"], + target_scitype = InfiniteArrMissing, + prediction_type = :deterministic, + orientation = :loss, + aggregation = RSquared() +) + +const RSQ = RSquared +@create_aliases RSquared + +@create_docs(RSquared, +body= +""" +The R² (also known as R-squared or coefficient of determination) is very suitable for interpreting regression analysis (Chicco et al., [2021](https://doi.org/10.7717/peerj-cs.623)). +This is because R² is a percentage whereas MSE and RMSE have arbitrary ranges. + +Let ``\\overline{y}`` denote the mean of ``y``, then + +``\\text{R^2} = 1 - \\frac{∑ (\\hat{y} - y)^2}{∑ \\overline{y} - y)^2}.`` +""", +footer="") + +function call(::RSquared, ŷ::ArrMissing{<:Real}, y::ArrMissing{<:Real}) + num = (ŷ .- y).^2 |> skipinvalid |> sum + mean_y = mean(y) + denom = (mean_y .- y).^2 |> skipinvalid |> sum + return 1 - (num / denom) +end + # ------------------------------------------------------------------- # LP @@ -180,7 +215,7 @@ metadata_measure(RootMeanSquaredProportionalError; orientation = :loss, aggregation = RootMeanSquare()) - const RMSP = RootMeanSquaredProportionalError +const RMSP = RootMeanSquaredProportionalError @create_aliases RMSP @create_docs(RootMeanSquaredProportionalError, diff --git a/test/measures/continuous.jl b/test/measures/continuous.jl index 5f3a3164..3e645845 100644 --- a/test/measures/continuous.jl +++ b/test/measures/continuous.jl @@ -11,6 +11,7 @@ rng = StableRNG(666899) @test isapprox(mae(yhat, y, w), (1*3 + 2*1 + 4*1 + 3*3)/4) @test isapprox(rms(yhat, y), sqrt(5)) @test isapprox(rms(yhat, y, w), sqrt((1*3^2 + 2*1^2 + 4*1^2 + 3*3^2)/4)) + @test rsq(yhat, y) == -3 @test isapprox(mean(skipinvalid(l1(yhat, y))), 2) @test isapprox(mean(skipinvalid(l1(yhat, y, w))), mae(yhat, y, w)) @test isapprox(mean(skipinvalid(l2(yhat, y))), 5) diff --git a/test/runtests.jl b/test/runtests.jl index 110fbaba..feba4857 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,7 @@ using MLJBase if !MLJBase.TESTING error("To test MLJBase, the environment variable "* "`TEST_MLJBASE` must be set to `\"true\"`\n"* - "You can do this in the REPL with `ENV[\"TEST_MLJBASE\"]=\"true\"") + "You can do this in the REPL with `ENV[\"TEST_MLJBASE\"]=\"true\"`") end @info "nprocs() = $(nprocs())" From af9c0e8729a45c9cb4d393f47bd3ef4c4dacc029 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Wed, 17 Nov 2021 19:07:57 +0100 Subject: [PATCH 02/15] Add call with weights --- src/measures/continuous.jl | 16 ++++++++++++++-- test/resampling.jl | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index aa815147..87fb05bd 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -69,6 +69,8 @@ call(::RootMeanSquaredError, # ------------------------------------------------------------------------- # R-squared (coefficient of determination) +foo(x) = x + struct RSquared <: Aggregated end metadata_measure(RSquared; @@ -91,8 +93,7 @@ This is because R² is a percentage whereas MSE and RMSE have arbitrary ranges. Let ``\\overline{y}`` denote the mean of ``y``, then ``\\text{R^2} = 1 - \\frac{∑ (\\hat{y} - y)^2}{∑ \\overline{y} - y)^2}.`` -""", -footer="") +""") function call(::RSquared, ŷ::ArrMissing{<:Real}, y::ArrMissing{<:Real}) num = (ŷ .- y).^2 |> skipinvalid |> sum @@ -101,6 +102,17 @@ function call(::RSquared, ŷ::ArrMissing{<:Real}, y::ArrMissing{<:Real}) return 1 - (num / denom) end +function call(::RSquared, + ŷ::ArrMissing{<:Real}, + y::ArrMissing{<:Real}, + w::Arr{<:Real} + ) + num = (ŷ .- y).^2 .* w |> skipinvalid |> sum + mean_y = mean(y) + denom = (mean_y .- y).^2 |> skipinvalid |> sum + return 1 - (num / denom) +end + # ------------------------------------------------------------------- # LP diff --git a/test/resampling.jl b/test/resampling.jl index 35738ffb..cd856767 100644 --- a/test/resampling.jl +++ b/test/resampling.jl @@ -105,7 +105,7 @@ MLJBase.prediction_type(::typeof(dummy_measure_interval)) = :interval end @testset "_feature_dependencies_exist" begin - measures = Any[rms, log_loss, brier_score] + measures = Any[rms, rsq, log_loss, brier_score] @test !MLJBase._feature_dependencies_exist(measures) my_feature_dependent_loss(ŷ, X, y) = sum(abs.(ŷ - y) .* X.penalty)/sum(X.penalty); From 5543cf60f8d379a1486ad6d4631b702ac6c5cd77 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Wed, 17 Nov 2021 19:46:16 +0100 Subject: [PATCH 03/15] I have no idea what aggregation does --- src/measures/continuous.jl | 3 +-- test/resampling.jl | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index 87fb05bd..93786a5a 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -77,8 +77,7 @@ metadata_measure(RSquared; instances = ["rsq", "rsquared"], target_scitype = InfiniteArrMissing, prediction_type = :deterministic, - orientation = :loss, - aggregation = RSquared() + orientation = :loss ) const RSQ = RSquared diff --git a/test/resampling.jl b/test/resampling.jl index cd856767..f8c5737f 100644 --- a/test/resampling.jl +++ b/test/resampling.jl @@ -359,7 +359,7 @@ end for cache in [true, false] model = Models.DeterministicConstantRegressor() mach = machine(model, X, y, cache=cache) - result = evaluate!(mach, resampling=cv, measure=[rms, rmslp1], + result = evaluate!(mach, resampling=cv, measure=[rms, rsq, rmslp1], acceleration=accel, verbosity=verb) @test result.per_fold[1] ≈ [1/2, 3/4, 1/2, 3/4, 1/2] From 085af65114983666f6a610f0f7e4cbc599688125 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Wed, 17 Nov 2021 20:47:41 +0100 Subject: [PATCH 04/15] Update ci.yml (#680) --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 173e5b30..f3b2d158 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ jobs: test: name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} + timeout-minutes: 60 strategy: fail-fast: false matrix: From bfb32ad12e6a32029b5c31c625d087c165c1cf45 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Wed, 17 Nov 2021 21:02:04 +0100 Subject: [PATCH 05/15] Add w on another place --- src/measures/continuous.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index 93786a5a..65b2e865 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -69,8 +69,6 @@ call(::RootMeanSquaredError, # ------------------------------------------------------------------------- # R-squared (coefficient of determination) -foo(x) = x - struct RSquared <: Aggregated end metadata_measure(RSquared; @@ -108,7 +106,7 @@ function call(::RSquared, ) num = (ŷ .- y).^2 .* w |> skipinvalid |> sum mean_y = mean(y) - denom = (mean_y .- y).^2 |> skipinvalid |> sum + denom = (mean_y .- y).^2 .* w |> skipinvalid |> sum return 1 - (num / denom) end From 45c353aadc4926404812d0c24ac14f41b150c2d2 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Thu, 18 Nov 2021 09:57:46 +0100 Subject: [PATCH 06/15] Incorporate feedback --- src/measures/continuous.jl | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index 65b2e865..c423b5ea 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -75,8 +75,7 @@ metadata_measure(RSquared; instances = ["rsq", "rsquared"], target_scitype = InfiniteArrMissing, prediction_type = :deterministic, - orientation = :loss -) + orientation = :score) const RSQ = RSquared @create_aliases RSquared @@ -84,8 +83,7 @@ const RSQ = RSquared @create_docs(RSquared, body= """ -The R² (also known as R-squared or coefficient of determination) is very suitable for interpreting regression analysis (Chicco et al., [2021](https://doi.org/10.7717/peerj-cs.623)). -This is because R² is a percentage whereas MSE and RMSE have arbitrary ranges. +The R² (also known as R-squared or coefficient of determination) is suitable for interpreting linear regression analysis (Chicco et al., [2021](https://doi.org/10.7717/peerj-cs.623)). Let ``\\overline{y}`` denote the mean of ``y``, then @@ -99,17 +97,6 @@ function call(::RSquared, ŷ::ArrMissing{<:Real}, y::ArrMissing{<:Real}) return 1 - (num / denom) end -function call(::RSquared, - ŷ::ArrMissing{<:Real}, - y::ArrMissing{<:Real}, - w::Arr{<:Real} - ) - num = (ŷ .- y).^2 .* w |> skipinvalid |> sum - mean_y = mean(y) - denom = (mean_y .- y).^2 .* w |> skipinvalid |> sum - return 1 - (num / denom) -end - # ------------------------------------------------------------------- # LP From d6f6a026617bf740ed9ada44f7c686dbf1bd2141 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Thu, 18 Nov 2021 10:10:52 +0100 Subject: [PATCH 07/15] Add more info to the metadata_measure docstring --- src/measures/meta_utilities.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/measures/meta_utilities.jl b/src/measures/meta_utilities.jl index e38425b0..e7d16193 100644 --- a/src/measures/meta_utilities.jl +++ b/src/measures/meta_utilities.jl @@ -91,6 +91,12 @@ end metadata_measure(T; kw...) Helper function to write the metadata for a single measure. +The meaning of some of the keywords is as follows: +- `orientation`: Orientation of the metric. + Use `:loss` when lower is better (root mean square) and `:score` when higher is better. + For example, set `:loss` for root mean square and `:score` for area under the ROC curve. +- `aggregation`: Aggregation method for scores. + For example, when doing 3-fold cross-validation, the aggregation how to combine these scores. """ function metadata_measure(T; name::String="", human_name="", From 2470b8e12da9da9f3fc792f935f95b9279b620c4 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Thu, 18 Nov 2021 10:13:58 +0100 Subject: [PATCH 08/15] Fix typo --- src/measures/meta_utilities.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/measures/meta_utilities.jl b/src/measures/meta_utilities.jl index e7d16193..520c8e75 100644 --- a/src/measures/meta_utilities.jl +++ b/src/measures/meta_utilities.jl @@ -96,7 +96,8 @@ The meaning of some of the keywords is as follows: Use `:loss` when lower is better (root mean square) and `:score` when higher is better. For example, set `:loss` for root mean square and `:score` for area under the ROC curve. - `aggregation`: Aggregation method for scores. - For example, when doing 3-fold cross-validation, the aggregation how to combine these scores. + For example, when doing 3-fold cross-validation, the aggregation specifies how to combine + these scores. """ function metadata_measure(T; name::String="", human_name="", From 91449c727e95ef162d378d5d74bfbc1f88ea4ac5 Mon Sep 17 00:00:00 2001 From: Rik Huijzer Date: Thu, 18 Nov 2021 10:14:29 +0100 Subject: [PATCH 09/15] Fix another typo --- src/measures/meta_utilities.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/measures/meta_utilities.jl b/src/measures/meta_utilities.jl index 520c8e75..de370013 100644 --- a/src/measures/meta_utilities.jl +++ b/src/measures/meta_utilities.jl @@ -93,7 +93,7 @@ end Helper function to write the metadata for a single measure. The meaning of some of the keywords is as follows: - `orientation`: Orientation of the metric. - Use `:loss` when lower is better (root mean square) and `:score` when higher is better. + Use `:loss` when lower is better and `:score` when higher is better. For example, set `:loss` for root mean square and `:score` for area under the ROC curve. - `aggregation`: Aggregation method for scores. For example, when doing 3-fold cross-validation, the aggregation specifies how to combine From 7e101dc1435a3120f9fb697f295325f5c9e36fde Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 19 Nov 2021 09:54:23 +1300 Subject: [PATCH 10/15] fix supports_weights trait for RSqaured --- src/measures/continuous.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/measures/continuous.jl b/src/measures/continuous.jl index c423b5ea..e6997378 100644 --- a/src/measures/continuous.jl +++ b/src/measures/continuous.jl @@ -72,10 +72,11 @@ call(::RootMeanSquaredError, struct RSquared <: Aggregated end metadata_measure(RSquared; - instances = ["rsq", "rsquared"], - target_scitype = InfiniteArrMissing, - prediction_type = :deterministic, - orientation = :score) + instances = ["rsq", "rsquared"], + target_scitype = InfiniteArrMissing, + prediction_type = :deterministic, + orientation = :score, + supports_weights = false) const RSQ = RSquared @create_aliases RSquared From 313c0a266ccb0b43913dfbf63f34cb5451c6145d Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 19 Nov 2021 09:54:56 +1300 Subject: [PATCH 11/15] Add more to docstring of metadata_measure --- src/measures/measures.jl | 1 + src/measures/meta_utilities.jl | 75 ++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/measures/measures.jl b/src/measures/measures.jl index d172c085..9f00fde0 100644 --- a/src/measures/measures.jl +++ b/src/measures/measures.jl @@ -110,6 +110,7 @@ function call(measure::Unaggregated, yhat, y, weight_given_class::AbstractDict) return w .* unweighted end + # ## Top level function (measure::Measure)(args...) diff --git a/src/measures/meta_utilities.jl b/src/measures/meta_utilities.jl index de370013..ee8b1b96 100644 --- a/src/measures/meta_utilities.jl +++ b/src/measures/meta_utilities.jl @@ -90,14 +90,73 @@ end """ metadata_measure(T; kw...) -Helper function to write the metadata for a single measure. -The meaning of some of the keywords is as follows: -- `orientation`: Orientation of the metric. - Use `:loss` when lower is better and `:score` when higher is better. - For example, set `:loss` for root mean square and `:score` for area under the ROC curve. -- `aggregation`: Aggregation method for scores. - For example, when doing 3-fold cross-validation, the aggregation specifies how to combine - these scores. +Helper function to write the metadata (trait definitions) for a single +measure. + +### Compulsory keyword arguments + +- `target_scitype`: The allowed scientific type of `y` in `measure(ŷ, + y, ...)`. This is typically some abstract array. E.g, in single + target variable regression this is typically + `AbstractArray{<:Union{Missing,Continuous}}`. For a binary + classification metric insensitive to class order, this would + typically be `Union{AbstractArray{<:Union{Missing,Multiclass{2}}}, + AbstractArray{<:Union{Missing,OrderedFactor{2}}}}`, which has the + alias `FiniteArrMissing`. + +- `orientation`: Orientation of the measure. Use `:loss` when lower is + better and `:score` when higher is better. For example, set + `:loss` for root mean square and `:score` for area under the ROC + curve. + +- `prediction_type`: Refers to `ŷ` in `measure(ŷ, y, ...)` and should + be one of: `:deterministic` (`ŷ` has same type as `y`), + `:probabilistic` or `:interval`. + + +#### Optional keyword arguments + +The following have meaningful defaults but may still require +overloading: + +- `instances`: A vector of strings naming the built-in instances of + the measurement type provided by the implementation, which are + usually just common aliases for the default instance. E.g., for + `RSquared` has the `instances = ["rsq", "rsquared"]` which are both + defined as `RSquared()` in the implementation. `MulticlassFScore` + has the `instances = ["macro_f1score", "micro_f1score", + "multiclass_f1score"]`, where `micro_f1score = + MulticlassFScore(average=micro_avg)`, etc. Default is `String[]`. + +- `aggregation`: Aggregation method for measurements, typically + `Mean()` (for, e.g., mean absolute error) or `Sum()` (for number + of true positives). Default is `Mean()`. Must subtype + `StatisticalTraits.AggregationMode`. It is used to: + + - aggregrate measurements in resampling (eg, cross-validiation) + + - aggregating per-observation measurements returned by `single` in + the fallback definition of `call` for `Unaggregated` measures + (such as area under the ROC curve). + +- `supports_weights`: Whether the measure can be called with + per-observation weights `w`, as in `l2(ŷ, y, w)`. Default is `true`. + +- `supports_class_weights`: Whether the measure can be called with a + class weight dictionary `w`, as in `micro_f1score(ŷ, y, w)`. Default + is `true`. Default is `false`. + +- `human_name`: Ordinary name of measure. Used in the full + auto-generated docstring, which begins "A measure type for + $human_name ...". Eg, the `human_name` for `TruePositive` is `number + of true positives. Default is snake-case version of type name, with + underscores replaced by spaces; so `MeanAbsoluteError` becomes "mean + absolute error". + +- `docstring`: An abbreviated docstring, displayed by + `info(measure)`. Fallback uses `human_name` and lists the + `instances`. + """ function metadata_measure(T; name::String="", human_name="", From 02317cde8a5008b9cb411a3e79d54a9f2c2894d0 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 19 Nov 2021 09:58:14 +1300 Subject: [PATCH 12/15] Update measures/README.md --- src/measures/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/measures/README.md b/src/measures/README.md index 991fb303..5a9f3778 100644 --- a/src/measures/README.md +++ b/src/measures/README.md @@ -1,5 +1,9 @@ ## Adding new measures +This document assumes familiarity with the traits provided for +measures. For a summary, query the docstring for +`MLJBase.metadata_measures`. + A measure is ordinarily called on data directly, as in ```julia @@ -15,7 +19,7 @@ julia> m(ŷ, y) 0.019067038457889922 ``` -Recall that to call a measure without performing dimension or pool checks, one +To call a measure without performing dimension or pool checks, one uses `MLJBase.call` instead: ```julia From a8086859ff227706f04e8975d4318315758632e5 Mon Sep 17 00:00:00 2001 From: "Anthony Blaom, PhD" Date: Fri, 19 Nov 2021 17:37:46 +1300 Subject: [PATCH 13/15] Apply suggestions from code review Co-authored-by: Rik Huijzer --- src/measures/meta_utilities.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/measures/meta_utilities.jl b/src/measures/meta_utilities.jl index ee8b1b96..29407bdc 100644 --- a/src/measures/meta_utilities.jl +++ b/src/measures/meta_utilities.jl @@ -133,10 +133,10 @@ overloading: of true positives). Default is `Mean()`. Must subtype `StatisticalTraits.AggregationMode`. It is used to: - - aggregrate measurements in resampling (eg, cross-validiation) + - aggregate measurements in resampling (e.g., cross-validation) - aggregating per-observation measurements returned by `single` in - the fallback definition of `call` for `Unaggregated` measures + the fallback definition of `call` for `Unaggregated` measures (such as area under the ROC curve). - `supports_weights`: Whether the measure can be called with @@ -148,7 +148,7 @@ overloading: - `human_name`: Ordinary name of measure. Used in the full auto-generated docstring, which begins "A measure type for - $human_name ...". Eg, the `human_name` for `TruePositive` is `number + \$human_name ...". Eg, the `human_name` for `TruePositive` is `number of true positives. Default is snake-case version of type name, with underscores replaced by spaces; so `MeanAbsoluteError` becomes "mean absolute error". From 0a588c3739a070b5cbd1111717c26e3c6e93797e Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 21 Nov 2021 19:23:08 +0100 Subject: [PATCH 14/15] fix `@pipeline` when MLJ is not in `Main` The `Symbol` function returns a different value whether or not the module of the value is defined in the `Main` module. To circumvent this, one can use `nameof` to always get only the name. This allows `@pipeline` to be used in other modules without running `using MLJ` in `Main`. --- src/composition/models/from_network.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/composition/models/from_network.jl b/src/composition/models/from_network.jl index ad663c7e..f0689d63 100644 --- a/src/composition/models/from_network.jl +++ b/src/composition/models/from_network.jl @@ -36,7 +36,7 @@ _insert_subtyping(ex, subtype_ex) = # create the exported type symbol, e.g. abstract_type(T) == Unsupervised # would result in :UnsupervisedComposite -_exported_type(T::Model) = Symbol(abstract_type(T), :Composite) +_exported_type(T::Model) = Symbol(nameof(abstract_type(T)), :Composite) function eval_and_reassign(modl, ex) s = gensym() From e0bd988299cc1e68c1e96e2032c6285e93f82190 Mon Sep 17 00:00:00 2001 From: "Anthony Blaom, PhD" Date: Mon, 22 Nov 2021 10:16:48 +1300 Subject: [PATCH 15/15] bump 0.18.26 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 98e422ae..a4cf83e5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MLJBase" uuid = "a7f614a8-145f-11e9-1d2a-a57a1082229d" authors = ["Anthony D. Blaom "] -version = "0.18.25" +version = "0.18.26" [deps] CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"