Skip to content

Commit

Permalink
Merge pull request #423 from alan-turing-institute/dev
Browse files Browse the repository at this point in the history
For a 0.15.2 release
  • Loading branch information
ablaom authored Sep 4, 2020
2 parents 8ea3d48 + 7a4920c commit 5e5d1cd
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MLJBase"
uuid = "a7f614a8-145f-11e9-1d2a-a57a1082229d"
authors = ["Anthony D. Blaom <[email protected]>"]
version = "0.15.1"
version = "0.15.2"

[deps]
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"
Expand Down
2 changes: 1 addition & 1 deletion src/MLJBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export orientation, reports_each_observation,
spports_weights, prediction_type

# measures/continuous.jl:
export mav, mae, mape, rms, rmsl, rmslp1, rmsp, l1, l2
export mav, mae, mape, rms, rmsl, rmslp1, rmsp, l1, l2, log_cosh

# measures/confusion_matrix.jl:
export confusion_matrix, confmat
Expand Down
30 changes: 30 additions & 0 deletions src/measures/continuous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,33 @@ function (m::MAPE)(ŷ::Vec{<:Real}, y::Vec{<:Real})
end
return ret / count
end

struct LogCosh <: Measure end

"""
log_cosh(ŷ, y)
Log-Cosh per-observation loss:
``\\text{Log-Cosh Loss} = log(cosh(ŷᵢ-yᵢ))``
where `yᵢ` is the target and `ŷᵢ` is the output.
For more information, run `info(log_cosh)`.
"""
const log_cosh = LogCosh()

metadata_measure(LogCosh;
name = "log_cosh",
target_scitype = Union{Vec{Continuous},Vec{Count}},
prediction_type = :deterministic,
orientation = :loss,
reports_each_observation = true,
is_feature_dependent = false,
supports_weights = false,
docstring = "log cosh loss; aliases: `log_cosh`.")

function (log_cosh::LogCosh)(ŷ::Vec{<:Real}, y::Vec{<:Real})
check_dimensions(ŷ, y)
return log.(cosh.(ŷ-y))
end
63 changes: 31 additions & 32 deletions src/univariate_finite/arrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ for func in [:pdf, :logpdf]
u::AbstractArray{UnivariateFinite{S,V,R,P},N},
C::AbstractVector{<:Union{V, CategoricalValue{V,R}}}) where {S,V,R,P,N}

ret = Array{P,N+1}(undef, size(u)..., length(C))
#ret = Array{P,N+1}(undef, size(u)..., length(C))
ret = zeros(P, size(u)..., length(C))
for i in eachindex(C)
ret[fill(:,N)...,i] = broadcast($func, u, C[i])
ret[fill(:,N)...,i] .= broadcast($func, u, C[i])
end
return ret
end
Expand Down Expand Up @@ -129,8 +130,13 @@ function Base.Broadcast.broadcasted(
cv::CategoricalValue) where {S,V,R,P,N}

cv in classes(u) || _err_missing_class(cv)

return get(u.prob_given_ref, int(cv), zeros(P, size(u)))

f() = zeros(P, size(u)) #default caller function

return Base.Broadcast.Broadcasted(
identity,
(get(f, u.prob_given_ref, int(cv)),)
)
end

# pdf.(u, v)
Expand Down Expand Up @@ -162,41 +168,33 @@ function Base.Broadcast.broadcasted(
raw::Union{V,AbstractArray{V,N}}) where {S,V,R,P,N}

cat = transform(classes(u), raw)
return broadcast(pdf, u, cat)
return Base.Broadcast.broadcasted(pdf, u, cat)
end

# logpdf.(u::UniFinArr{S,V,R,P,N}, cv::CategoricalValue)
# logpdf.(u::UniFinArr{S,V,R,P,N}, v::AbstractArray{<:CategoricalValue{V,R},N})
# logpdf.(u::UniFinArr{S,V,R,P,N}, raw::V)
# logpdf.(u::UniFinArr{S,V,R,P,N}, raw::AbstractArray{V,N})
# logpdf.(u::UniFinArr{S,V,R,P,N}, raw::AbstractArray{V,N})
# logpdf.(u::UniFinArr{S,V,R,P,N}, raw::V)
for typ in (:CategoricalValue,
:(AbstractArray{<:CategoricalValue{V,R},N}),
:(AbstractArray{<:CategoricalValue{V,R},N}),
:V,
:(AbstractArray{V,N}))
if typ == :CategoricalValue || typ == :V
eval(quote
function Base.Broadcast.broadcasted(
::typeof(logpdf),
u::UniFinArr{S,V,R,P,N},
c::$typ) where {S,V,R,P,N}

# Start with the pdf array
pdf_arr = pdf.(u, c)

# Create an uninitialized array similar to pdf_arr
# this avoids mutating the initial pdf_arr
result = similar(pdf_arr)

# Take the log of each entry in-place
@simd for j in eachindex(result)
@inbounds result[j] = log(pdf_arr[j])
end

return result
end
end)
else
if typ == :CategoricalValue || typ == :V
eval(quote
function Base.Broadcast.broadcasted(
::typeof(logpdf),
u::UniFinArr{S,V,R,P,N},
c::$typ) where {S,V,R,P,N}

# Start with the pdf array
# take advantage of loop fusion
result = log.(pdf.(u, c))
return result
end
end)

else
eval(quote
function Base.Broadcast.broadcasted(
::typeof(logpdf),
u::UniFinArr{S,V,R,P,N},
Expand All @@ -213,7 +211,8 @@ for typ in (:CategoricalValue,
return result
end
end)
end
end

end

## PERFORMANT BROADCASTING OF mode:
Expand Down
1 change: 1 addition & 0 deletions test/measures/continuous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ rng = StableRNG(666899)
@test isapprox(mean(l1(yhat, y, w)), mae(yhat, y, w))
@test isapprox(mean(l2(yhat, y)), 5)
@test isapprox(mean(l2(yhat, y, w)), rms(yhat, y, w)^2)
@test isapprox(mean(log_cosh(yhat, y)), 1.3715546675)

yhat = y .+ 1
@test isapprox(rmsl(yhat, y),
Expand Down

0 comments on commit 5e5d1cd

Please sign in to comment.