Skip to content

Commit 5ed45c9

Browse files
committed
alpha
add a README typo polish readme
0 parents  commit 5ed45c9

File tree

8 files changed

+347
-0
lines changed

8 files changed

+347
-0
lines changed

.github/workflows/TagBot.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: TagBot
2+
on:
3+
issue_comment:
4+
types:
5+
- created
6+
workflow_dispatch:
7+
jobs:
8+
TagBot:
9+
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: JuliaRegistries/TagBot@v1
13+
with:
14+
token: ${{ secrets.GITHUB_TOKEN }}
15+
ssh: ${{ secrets.DOCUMENTER_KEY }}

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
- dev
7+
push:
8+
branches:
9+
- master
10+
- dev
11+
tags: '*'
12+
jobs:
13+
test:
14+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
version:
20+
- '1.0'
21+
- '1'
22+
os:
23+
- ubuntu-latest
24+
arch:
25+
- x64
26+
steps:
27+
- uses: actions/checkout@v2
28+
- uses: julia-actions/setup-julia@v1
29+
with:
30+
version: ${{ matrix.version }}
31+
arch: ${{ matrix.arch }}
32+
- uses: actions/cache@v1
33+
env:
34+
cache-name: cache-artifacts
35+
with:
36+
path: ~/.julia/artifacts
37+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
38+
restore-keys: |
39+
${{ runner.os }}-test-${{ env.cache-name }}-
40+
${{ runner.os }}-test-
41+
${{ runner.os }}-
42+
- uses: julia-actions/julia-buildpkg@v1
43+
- uses: julia-actions/julia-runtest@v1
44+
- uses: julia-actions/julia-processcoverage@v1
45+
- uses: codecov/codecov-action@v1
46+
with:
47+
file: lcov.info

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/Manifest.toml
2+
/docs/Manifest.toml
3+
.ipynb_checkpoints
4+
*~
5+
#*
6+
.#*
7+
*.bu
8+
.DS_Store
9+
sandbox/
10+
docs/build

LICENCE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
The MLJ.jl package is licensed under the MIT "Expat" License:
2+
3+
> Copyright (c) 2019: Anthony Blaom, Thibaut Lienart, Franz J Király
4+
> and contributors.
5+
>
6+
> Permission is hereby granted, free of charge, to any person obtaining a copy
7+
> of this software and associated documentation files (the "Software"), to deal
8+
> in the Software without restriction, including without limitation the rights
9+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
> copies of the Software, and to permit persons to whom the Software is
11+
> furnished to do so, subject to the following conditions:
12+
>
13+
> The above copyright notice and this permission notice shall be included in all
14+
> copies or substantial portions of the Software.
15+
>
16+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
> SOFTWARE.
23+
>

Project.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name = "StatTraits"
2+
uuid = "64bff920-2084-43da-a3e6-9bb72801c0c9"
3+
authors = ["Anthony D. Blaom <[email protected]>"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
ScientificTypes = "321657f4-b219-11e9-178b-2701a2544e81"
8+
9+
[compat]
10+
ScientificTypes = "^1"
11+
12+
[extras]
13+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
14+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
15+
16+
[targets]
17+
test = ["Test", "SparseArrays"]

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# StatTraits.jl
2+
3+
| Linux | Coverage |
4+
| :-----------: | :------: |
5+
| [![Build status](https://github.com/alan-turing-institute/StatTraits.jl/workflows/CI/badge.svg)](https://github.com/alan-turing-institute/StatTraits.jl/actions)| [![codecov.io](http://codecov.io/github/alan-turing-institute/StatTraits.jl/coverage.svg?branch=master)](http://codecov.io/github/alan-turing-institute/StatTraits.jl?branch=master) |
6+
7+
A light-weight package defining fall-back implementations for a
8+
collection of "traits" possessed by statistical objects. Here are two
9+
examples, which apply to both statistical models and loss functions:
10+
11+
```julia
12+
target_scitype(::Type) = Unknown
13+
prediction_type(::Type) = :unknown # also :probablistic, :deterministic, :interval
14+
```
15+
16+
Here `Unknown` is a type defined in the light-weight package
17+
[`ScientificTypes.jl`](https://github.com/alan-turing-institute/ScientificTypes.jl),
18+
the only dependency of StatsTraits.jl.
19+
20+
Refer to [source code](src/StatTraits.jl) for a complete list.
21+
22+
The traits defined here are overloaded by assorted model types and
23+
measure types in the
24+
[MLJ](https://github.com/alan-turing-institute/MLJ.jl) universe
25+
(examples of measures are loss functions and scoring rules). However,
26+
this small package might be of independent interest.
27+
28+
A planned StatisticalMeasures.jl package, to contain measures
29+
currently in
30+
[MLJBase.jl](https://github.com/alan-turing-institute/MLJBase.jl),
31+
will have this package as a dependency, allowing it to be independent
32+
of the MLJ packages.
33+

src/StatTraits.jl

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
module StatTraits
2+
3+
using ScientificTypes
4+
5+
6+
## CONSTANTS
7+
8+
const TRAITS = [
9+
:input_scitype,
10+
:output_scitype,
11+
:target_scitype,
12+
:is_pure_julia,
13+
:package_name,
14+
:package_license,
15+
:load_path,
16+
:package_uuid,
17+
:package_url,
18+
:is_wrapper,
19+
:supports_weights,
20+
:supports_online,
21+
:docstring,
22+
:name,
23+
:is_supervised,
24+
:prediction_type,
25+
:hyperparameters,
26+
:hyperparameter_types,
27+
:hyperparameter_ranges]
28+
29+
30+
## EXPORT
31+
32+
for trait in TRAITS
33+
eval(:(export $trait))
34+
end
35+
36+
37+
## HELPERS
38+
39+
"""
40+
41+
typename(T::Type)
42+
43+
Return a symbol corresponding to the name of the type `T`, stripped of
44+
any type-parameters and module qualifications. For example:
45+
46+
_typename(MLJBase.Machine{MLJModels.ConstantRegressor,true})
47+
48+
returns `:Machine`. Where this does not make sense (eg, instances of
49+
`Union`) `Symbol(string(M))` is returned.
50+
51+
"""
52+
function typename(M)
53+
if isdefined(M, :name)
54+
return M.name.name
55+
elseif isdefined(M, :body)
56+
return _typename(M.body)
57+
else
58+
return Symbol(string(M))
59+
end
60+
end
61+
62+
63+
## TRAITS
64+
65+
# The following can return any scientific type, that is, any type
66+
# defined in the package ScientificTypes.jl, and any ordinary type
67+
# that functions as a scientific type (eg, `Missing`). Here "target"
68+
# is a synonym for "labels", as in supervised learning; "input" is a
69+
# synonym for "features":
70+
71+
input_scitype(::Type) = Unknown
72+
output_scitype(::Type) = Unknown
73+
target_scitype(::Type) = Unknown
74+
75+
# The following refer to properties of the package defining a type,
76+
# for use in, say, a registry of machine learning models. All but the
77+
# first must return a string:
78+
79+
is_pure_julia(::Type) = false # must be `true` or `false`
80+
package_name(::Type) = "unknown"
81+
package_license(::Type) = "unknown"
82+
load_path(::Type) = "unknown"
83+
package_uuid(::Type) = "unknown"
84+
package_url(::Type) = "unknown"
85+
86+
# Below "weights" means "per-observation weights":
87+
88+
supports_weights(::Type) = false
89+
supports_class_weights(::Type) = false
90+
91+
# Possible values of the following are `:deterministic`, `:probabilistic`,
92+
# `:interval`, or `:unknown`:
93+
94+
prediction_type(::Type) = :unknown # used for measures too
95+
96+
# Miscellaneous:
97+
98+
is_wrapper(::Type) = false # or `true`
99+
supports_online(::Type) = false # or `true`
100+
docstring(M::Type) = string(M) # some `String`
101+
is_supervised(::Type) = false # or `true`
102+
103+
# Returns a tuple, with one entry per field of `T` (the type of some
104+
# statistical model, for example). Each entry is `nothing` or defines
105+
# some kind of default "search range" for the corresponding field (as
106+
# ordered in `fieldnames(T)`).
107+
108+
hyperparameter_ranges(T::Type) = Tuple(fill(nothing, length(fieldnames(T))))
109+
110+
# Not really traits (you would not ordinarily overload them) but
111+
# included here as they are often grouped with true traits:
112+
113+
name(M::Type) = string(typename(M))
114+
hyperparameters(M::Type) = fieldnames(M)
115+
hyperparameter_types(M::Type) = string.(fieldtypes(M))
116+
117+
118+
## MAKE TRAITS ACT ON INSTANCES AS WELL AS TYPES
119+
120+
for trait in TRAITS
121+
ex = quote
122+
$trait(x) = $trait(typeof(x))
123+
end
124+
eval(ex)
125+
end
126+
127+
end # module

test/runtests.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using Test
2+
using StatTraits
3+
using ScientificTypes
4+
import SparseArrays
5+
6+
module Fruit
7+
8+
struct Apple end
9+
10+
end
11+
12+
import .Fruit
13+
14+
15+
## HELPERS
16+
17+
@testset "typename" begin
18+
@test StatTraits.typename(Nothing) == :Nothing
19+
@test StatTraits.typename(UnionAll) == :UnionAll
20+
@test StatTraits.typename(Union{Char,Int}) == Symbol("Union{Char, Int64}")
21+
T = SparseArrays.sparse([1,2], [1,3], [0.5, 0.6]) |> typeof
22+
@test StatTraits.typename(T) == :SparseMatrixCSC
23+
end
24+
25+
26+
## TRAITS WITH NON-CONSTANT FALL-BACK
27+
28+
struct Foo
29+
x::Int
30+
y::Char
31+
end
32+
33+
@testset "docstring" begin
34+
@test docstring(Foo(1,'x')) == "Foo"
35+
@test docstring(Fruit.Apple()) == "Main.Fruit.Apple"
36+
end
37+
38+
@testset "hyperparameter_ranges" begin
39+
@test hyperparameter_ranges(Foo(1, 'x')) == (nothing, nothing)
40+
@test hyperparameter_ranges(Fruit.Apple()) == ()
41+
end
42+
43+
@testset "name" begin
44+
@test name(Float64) == "Float64"
45+
@test name(Fruit.Apple) == "Apple"
46+
@test name(Fruit.Apple()) == "Apple"
47+
end
48+
49+
@testset "hyperparameters" begin
50+
@test hyperparameters(Foo(1, 'x')) == (:x, :y)
51+
@test hyperparameters(Fruit.Apple()) == ()
52+
end
53+
54+
@testset "hyperparameter_types" begin
55+
@test hyperparameter_types(Foo(1, 'x')) == ("Int64", "Char")
56+
@test hyperparameter_types(Fruit.Apple()) == ()
57+
end
58+
59+
60+
## TRAITS WITH CONSTANT FALL-BACK
61+
62+
const NONCONSTANT = [:docstring,
63+
:hyperparameter_ranges,
64+
:name,
65+
:hyperparameters,
66+
:hyperparameter_types]
67+
68+
@testset "traits with constant fall-back" begin
69+
for trait in setdiff(StatTraits.TRAITS, NONCONSTANT)
70+
ex = quote
71+
@test $trait(Fruit.Apple()) == $trait(Foo(1, 'x'))
72+
end
73+
Main.eval(ex)
74+
end
75+
end

0 commit comments

Comments
 (0)