Skip to content

Commit

Permalink
Merge pull request #134 from JuliaAI/dev
Browse files Browse the repository at this point in the history
For a 1.3.5 release
  • Loading branch information
ablaom authored Jan 3, 2022
2 parents 597e2dd + 2a77b27 commit 824e05c
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 10 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
matrix:
version:
- '1.0'
- '1.6'
- '1'
os:
- ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MLJModelInterface"
uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea"
authors = ["Thibaut Lienart and Anthony Blaom"]
version = "1.3.4"
version = "1.3.5"

[deps]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand Down
2 changes: 1 addition & 1 deletion src/MLJModelInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ end

# data operations
export matrix, int, classes, decoder, table,
nrows, selectrows, selectcols, select, info
nrows, selectrows, selectcols, select, info, scitype

# equality
export is_same_except, isrepresented
Expand Down
44 changes: 40 additions & 4 deletions src/data_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,41 @@ classes(x) = classes(get_interface_mode(), x)

classes(::LightInterface, x) = errlight("classes")

# ------------------------------------------------------------------------
# scitype

"""
scitype(X)
The scientific type (interpretation) of `X`, distinct from its
machine type.
### Examples
```julia
julia> scitype(3.14)
Continuous
julia> scitype([1, 2, missing])
AbstractVector{Union{Missing, Count}}
julia> scitype((5, "beige"))
Tuple{Count, Textual}
julia> using CategoricalArrays
julia> X = (gender = categorical(['M', 'M', 'F', 'M', 'F']),
ndevices = [1, 3, 2, 3, 2]);
julia> scitype(X)
Table{Union{AbstractVector{Count}, AbstractVector{Multiclass{2}}}}
```
"""
scitype(X) = scitype(get_interface_mode(), vtrait(X, "scitype"), X)

function scitype(::LightInterface, m, X)
return errlight("scitype")
end

# ------------------------------------------------------------------------
# schema

Expand Down Expand Up @@ -187,14 +222,15 @@ istable(::Mode, ::Val{:table}) = true
# decoder

"""
d = decoder(x)
decoder(x)
A callable object for decoding the integer representation of a
Return a callable object for decoding the integer representation of a
`CategoricalString` or `CategoricalValue` sharing the same pool as
`x`. (Here `x` is of one of these two types.) Specifically, one has
`d(int(y)) == y` for all `y in classes(x)`. One can also call `d` on
integer arrays, in which case `d` is broadcast over all elements.
`decoder(x)(int(y)) == y` for all `y in classes(x)`. One can also call `decoder(x)` on
integer arrays, in which case `decoder(x)` is broadcast over all elements.
### Examples
```julia
julia> v = categorical(["c", "b", "c", "a"])
4-element CategoricalArrays.CategoricalArray{String,1,UInt32}:
Expand Down
47 changes: 43 additions & 4 deletions test/data_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
x = 1:5
@test_throws M.InterfaceError M.categorical(x)
end

@testset "cat-full" begin
setfull()
M.categorical(::FI, a...; kw...) = categorical(a...; kw...)
x = 1:5
@test M.categorical(x) == categorical(x)
end

# ------------------------------------------------------------------------
@testset "matrix-light" begin
setlight()
Expand All @@ -25,18 +27,21 @@ end
X = (a=[1, 2, 3], b=[1, 2, 3])
@test_throws M.InterfaceError matrix(X)
end

@testset "matrix-full" begin
setfull()
M.matrix(::FI, ::Val{:table}, X; kw...) = Tables.matrix(X; kw...)
X = (a=[1, 2, 3], b=[1, 2, 3])
@test matrix(X) == hcat([1, 2, 3], [1, 2, 3])
end

# ------------------------------------------------------------------------
@testset "int-light" begin
setlight()
x = categorical([1, 2, 3])
@test_throws M.InterfaceError int(x)
end

@testset "int-full" begin
setfull()
M.int(::FI, x::CategoricalValue) = CategoricalArrays.refcode(x)
Expand All @@ -61,6 +66,31 @@ end
x = categorical(['a','b','a'])
@test classes(x[1]) == ['a', 'b']
end

# ------------------------------------------------------------------------
@testset "scitype-light" begin
# throw error for any input anyway
setlight()

ary = rand(10, 3)
@test_throws M.InterfaceError M.scitype(ary)

df = DataFrame(rand(10, 3), :auto)
@test_throws M.InterfaceError M.scitype(df)
end

@testset "scitype-full" begin
setfull()
M.scitype(::FI, v, X) = ScientificTypes.scitype(X)

ary = rand(10, 3)
@test M.scitype(ary) == AbstractArray{Continuous, 2}

df = DataFrame(A = rand(10), B = categorical(rand('a':'c', 10)))
sch = M.scitype(df)
@test sch <: Table(Continuous, Multiclass)
end

# ------------------------------------------------------------------------
@testset "schema-light" begin
# throw error for any input anyway
Expand All @@ -70,14 +100,14 @@ end
df = DataFrame(rand(10, 3), :auto)
@test_throws M.InterfaceError M.schema(df)
end

@testset "schema-full" begin
setfull()
M.schema(::FI, v, X) = ScientificTypes.schema(X)

ary = rand(10, 3)
M.schema(::FI, ::Val{:table}, X; kw...) =
ScientificTypes.schema(X; kw...)
M.schema(::FI, ::Val{:other}, X; kw...) = nothing
@test_throws ArgumentError M.schema(ary)

@test M.schema(ary) === nothing
df = DataFrame(A = rand(10), B = categorical(rand('a':'c', 10)))
sch = M.schema(df)
@test sch.names == (:A, :B)
Expand All @@ -86,6 +116,7 @@ end
@test sch.scitypes[1] <: Continuous
@test sch.scitypes[2] <: Multiclass
end

# ------------------------------------------------------------------------
@testset "istable" begin
# Nothing stops someone from implementing a Tables.jl
Expand All @@ -106,24 +137,28 @@ end
X = DataFrame(A=rand(10))
@test M.istable(X)
end

# ------------------------------------------------------------------------
@testset "decoder-light" begin
setlight()
x = 5
@test_throws M.InterfaceError decoder(x)
end

@testset "decoder-full" begin
setfull()
# toy test because I don't want to copy the decoder logic here
M.decoder(::FI, x) = 0
@test decoder(nothing) == 0
end

# ------------------------------------------------------------------------
@testset "table-light" begin
setlight()
X = ones(3, 2)
@test_throws M.InterfaceError table(X)
end

@testset "table-full" begin
setfull()
function M.table(::FI, A::AbstractMatrix; names=nothing)
Expand All @@ -135,13 +170,15 @@ end
@test Tables.istable(T)
@test Tables.matrix(T) == X
end

# ------------------------------------------------------------------------
@testset "nrows-light" begin
setlight()
X = (a=[4, 2, 1], b=[3, 2, 1])
@test_throws M.InterfaceError nrows(X)
@test nrows(nothing) == 0
end

@testset "nrows-full" begin
setfull()
X = ones(5)
Expand All @@ -157,6 +194,7 @@ end
X = (a=[4, 2, 1], b=[3, 2, 1])
@test nrows(X) == 3
end

# ------------------------------------------------------------------------
@testset "select-light" begin
setlight()
Expand All @@ -179,6 +217,7 @@ end
@test_throws M.InterfaceError selectcols(X, 1)
@test_throws M.InterfaceError select(X, 1, 1)
end

@testset "select-full" begin
setfull()

Expand Down

0 comments on commit 824e05c

Please sign in to comment.