TargetEncoder reuses the first level's shrinkage factor for all levels when m > 0
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- machine-learning
Research direction
Start in target_encoder_fit, especially the per-level loop inside the feature_mapper closure, and read the existing TargetEncoder tests. Add regression coverage for finite m and m = :auto, checking that each level gets its own shrinkage factor. Done means the reproduced level encodings match the per-level expected values and the existing tests still pass.
Written by the indexing model from the issue text.
Description
TargetEncoder with m > 0 (or m = :auto) is supposed to compute the shrinkage factor λ = n_i / (m + n_i) separately for every level, but only the first level of the first encoded column gets its own λ. Every other level (and every other column) reuses that same value.
To reproduce
using MLJBase, MLJTransforms, CategoricalArrays, Statistics
X = (A = categorical(["a", "a", "b", "b", "b", "b", "b", "b"]),)
y = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
mach = fit!(machine(TargetEncoder(m = 2), X, y), verbosity = 0)
Xt = MLJBase.transform(mach, X)
println("encoded A: ", Xt.A)
prior = mean(y)
for lvl in ("a", "b")
t = y[X.A .== lvl]
λ = length(t) / (2 + length(t))
println(lvl, ": n=", length(t), " λ=", λ, " expected=", λ * mean(t) + (1 - λ) * prior)
end
Output:
encoded A: [3.0, 3.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]
a: n=2 λ=0.5 expected=3.0
b: n=6 λ=0.75 expected=5.25
Level "b" should be encoded as 0.75 * 5.5 + 0.25 * 4.5 = 5.25, but it gets 5.0, which is what you get with level "a"'s λ = 0.5. Same thing with m = :auto: the m estimated for the first level is reused for all the others (for the data above but with y = [1, 2, 3, 5, 8, 13, 21, 34], level "b" comes out as 10.8985 instead of 13.5697). Binary and multiclass targets are affected the same way.
Cause
In target_encoder_fit, the per-level loop inside the feature_mapper closure assigns back to the captured outer variables:
m == :auto && (m = compute_m_auto(task, targets_for_level; y_var = y_var))
lambda = compute_shrinkage(targets_for_level; m = m, λ = lambda)
After the first level, lambda is no longer 1.0, so compute_shrinkage treats it as a user-supplied λ and just returns it. With m = :auto, m is overwritten by a number on the first level so it is never re-estimated. The existing tests only use m = Inf, where λ is 0 for every level anyway, so they don't catch this.
Versions
- Julia 1.13.3
- MLJTransforms 0.2.1 (current
dev, 1f79daf) - MLJBase 1.15.0, CategoricalArrays 1.1.1
- Dominant language
- Julia
- Stars
- 1
- Forks
- 5
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 8
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from JuliaAI/MLJTransforms.jl
-
Add a `Transformer` wrapper for models that supervised that transformMay be free again @ablaom claimed this 217 days ago, and no pull request is open. Openenhancement
JuliaAI/MLJTransforms.jl#52 · 3 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
JuliaAI/MLJTransforms.jl#39 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
JuliaAI/MLJTransforms.jl#21 · 13 comments ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 38/100
JuliaAI/MLJTransforms.jl#46 · 7 comments ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 3/5 1-2 days Newbie friendliness 48/100
JuliaAI/MLJTransforms.jl#44 · 2 comments ·
Maintainers usually reply within 1 day
All issues in JuliaAI/MLJTransforms.jl
Similar issues
-
release preparation spack
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
30-minutes algorithm any-language codewars dart easy elixir hackerrank hacktoberfest haskell help wanted interview-prep julia leetcode lua open-source r scala students zig
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Huerte/algo-solutions-python#163 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
QuantumSavory/QuantumClifford.jl#853 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
JuliaPackaging/Yggdrasil#15441 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 78/100
JuliaSmoothOptimizers/Penelopt.jl#260 ·
Maintainers usually reply within 1 day