Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log Transforms #104

Merged
merged 8 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "FeatureTransforms"
uuid = "8fd68953-04b8-4117-ac19-158bf6de9782"
authors = ["Invenia Technical Computing Corporation"]
version = "0.3.10"
version = "0.3.11"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
2 changes: 2 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ Power
Periodic
MeanStdScaling
IdentityScaling
InverseHyperbolicSine
LinearCombination
LogTransform
OneHotEncoding
```

Expand Down
2 changes: 2 additions & 0 deletions src/FeatureTransforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ using Tables
export Transform, transform, transform!
export HoD, LinearCombination, OneHotEncoding, Periodic, Power
export AbstractScaling, IdentityScaling, MeanStdScaling
export LogTransform, InverseHyperbolicSine

include("utils.jl")
include("traits.jl")
Expand All @@ -16,6 +17,7 @@ include("apply.jl")

# Transform implementations
include("linear_combination.jl")
include("log.jl")
include("one_hot_encoding.jl")
include("periodic.jl")
include("power.jl")
Expand Down
33 changes: 33 additions & 0 deletions src/log.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
LogTransform <: Transform

Logarithmically transform the data through: sign(x) * log(|x| + 1).

This allows transformations of all real numbers, not just positive ones.
"""
struct LogTransform <: Transform end
cardinality(::LogTransform) = OneToOne()

_logtransform(x) = sign(x) * log(abs(x) + one(x))
_invlogtransform(x) = sign(x) * (exp(sign(x) * x) - one(x))

function _apply(A::AbstractArray, transform::LogTransform; inverse=false, kwargs...)
inverse && return _invlogtransform.(A)
return _logtransform.(A)
end


"""
InverseHyperbolicSine <: Transform

Logarithmically transform the data through: log(x + √(x² + 1)).

This is the inverse hyperbolic sine.
"""
struct InverseHyperbolicSine <: Transform end
cardinality(::InverseHyperbolicSine) = OneToOne()

function _apply(A::AbstractArray, transform::InverseHyperbolicSine; inverse=false, kwargs...)
inverse && return sinh.(A)
return asinh.(A)
end
46 changes: 46 additions & 0 deletions test/log.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@testset "log" begin

V1 = [1; -2; 3; 4; 0; -6]
V2 = -V1
M = [1 1 0.5; 0.0 1.0 2.0]

@testset "LogTransform" begin

logV1 = [log(2); -log(3); log(4); log(5); log(1); -log(7)]
logV2 = -logV1
logM = [log(2) log(2) log(1.5); log(1) log(2) log(3)]

@testset "simple" for x in (V1, V2, M)
transform = LogTransform()
@test cardinality(transform) == OneToOne()
@test transform isa Transform
end

@testset "Apply" for (x, y) in ((V1, logV1), (V2, logV2), (M, logM))
f = LogTransform()
transformed = FeatureTransforms.apply(x, f)
@test transformed ≈ y atol=1e-5
@test FeatureTransforms.apply(transformed, f; inverse=true) ≈ x atol=1e-5
end
mzgubic marked this conversation as resolved.
Show resolved Hide resolved
end

@testset "InverseHyperbolicSine" begin

logV1 = asinh.(V1)
logV2 = asinh.(V2)
logM = asinh.(M)

@testset "simple" for x in (V1, V2, M)
transform = InverseHyperbolicSine()
@test cardinality(transform) == OneToOne()
@test transform isa Transform
end

@testset "Apply" for (x, y) in ((V1, logV1), (V2, logV2), (M, logM))
f = InverseHyperbolicSine()
transformed = FeatureTransforms.apply(x, f)
@test transformed ≈ y atol=1e-5
@test FeatureTransforms.apply(transformed, f; inverse=true) ≈ x atol=1e-5
end
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ using TimeZones
Sys.WORD_SIZE == 64 && v"1.6" <= VERSION < v"1.7" && doctest(FeatureTransforms)

include("linear_combination.jl")
include("log.jl")
include("one_hot_encoding.jl")
include("periodic.jl")
include("power.jl")
Expand Down