Skip to content

Commit 71b8813

Browse files
authored
Add Time Series Block (#239)
1 parent 7b81003 commit 71b8813

File tree

16 files changed

+1057
-40
lines changed

16 files changed

+1057
-40
lines changed

.github/workflows/ci-fastmakie.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- 'FastTabular/**'
77
- 'FastText/**'
88
- 'FastVision/**'
9+
- 'FastTimeSeries/**'
910
- '*.md'
1011
jobs:
1112
test:

.github/workflows/ci-fasttabular.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- 'FastMakie/**'
77
- 'FastText/**'
88
- 'FastVision/**'
9+
- 'FastTimeSeries/**'
910
- '*.md'
1011
jobs:
1112
test:

.github/workflows/ci-fasttext.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- 'FastMakie/**'
77
- 'FastTabular/**'
88
- 'FastVision/**'
9+
- 'FastTimeSeries/**'
910
- '*.md'
1011
jobs:
1112
test:
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: CI - FastTimeSeries
2+
on:
3+
push:
4+
paths-ignore:
5+
- 'docs/**'
6+
- 'FastMakie/**'
7+
- 'FastTabular/**'
8+
- 'FastText/**'
9+
- 'FastVision/**'
10+
- '*.md'
11+
jobs:
12+
test:
13+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
version:
19+
- '1.6'
20+
os:
21+
- ubuntu-latest
22+
- macOS-latest
23+
- windows-latest
24+
arch:
25+
- x64
26+
27+
steps:
28+
- uses: actions/checkout@v2
29+
- uses: julia-actions/setup-julia@v1
30+
with:
31+
version: ${{ matrix.version }}
32+
arch: ${{ matrix.arch }}
33+
- uses: actions/cache@v1
34+
env:
35+
cache-name: cache-artifacts
36+
with:
37+
path: ~/.julia/artifacts
38+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
39+
restore-keys: |
40+
${{ runner.os }}-test-${{ env.cache-name }}-
41+
${{ runner.os }}-test-
42+
${{ runner.os }}-
43+
- name: Dev FastAI
44+
run: |
45+
julia --color=yes --project=./FastTimeSeries -e 'using Pkg; pkg"dev ."'
46+
shell: bash
47+
- name: Dev test dependencies
48+
run: |
49+
julia --color=yes --project=./FastTimeSeries/test -e 'using Pkg; pkg"dev . ./FastTimeSeries "'
50+
shell: bash
51+
- uses: julia-actions/julia-buildpkg@latest
52+
with:
53+
project: './FastTimeSeries/'
54+
- name: Run tests
55+
run: |
56+
julia --color=yes --depwarn=yes --project=./FastTimeSeries/test -e 'include("FastTimeSeries/test/runtests.jl")'
57+
continue-on-error: ${{ matrix.version == 'nightly' }}
58+
shell: bash

.github/workflows/ci-fastvision.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
- 'docs/**'
66
- 'FastTabular/**'
77
- 'FastText/**'
8+
- 'FastTimeSeries/**'
89
- '*.md'
910
pull_request:
1011
paths-ignore:

FastTabular/src/container.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,14 @@ Base.length(dataset::TableDataset{<:CSV.File}) = length(dataset.table)
9292
rm("test.csv")
9393
end
9494
end
95+
96+
@testset "TimeSeriesDataset" begin
97+
@testset "TimeSeriesDataset from TS" begin
98+
folderpath = datasetpath("atrial")
99+
filepath = joinpath(folderpath, "AtrialFibrillation_TRAIN.ts")
100+
tsd = TimeSeriesDataset(filepath)
101+
@test tsd isa TimeSeriesDataset{}
102+
@test size(getindex(tsd, 10)) == (2, 640)
103+
@test length(tsd) == 15
104+
end
105+
end

FastTimeSeries/Project.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name = "FastTimeSeries"
2+
uuid = "5337c758-7610-4451-a331-8357b11df7c6"
3+
authors = ["FluxML Community"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
FastAI = "5d0beca9-ade8-49ae-ad0b-a3cf890e669f"
8+
FilePathsBase = "48062228-2e41-5def-b9a4-89aafe57970f"
9+
InlineTest = "bd334432-b1e7-49c7-a2dc-dd9149e4ebd6"
10+
MLUtils = "f1d291b0-491e-4a28-83b9-f70985020b54"
11+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
12+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
13+
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
14+
15+
[compat]
16+
FastAI = "0.5"
17+
FilePathsBase = "0.9"
18+
InlineTest = "0.2"
19+
MLUtils = "0.2"
20+
UnicodePlots = "2, 3"
21+
julia = "1.6"

FastTimeSeries/src/FastTimeSeries.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module FastTimeSeries
2+
3+
4+
using FastAI
5+
using FastAI:
6+
# blocks
7+
Block, WrapperBlock, AbstractBlock, OneHotTensor, OneHotTensorMulti, Label,
8+
LabelMulti, wrapped, Continuous, getencodings, getblocks, encodetarget, encodeinput,
9+
# encodings
10+
Encoding, StatefulEncoding, OneHot,
11+
# visualization
12+
ShowText,
13+
# other
14+
Context, Training, Validation
15+
using FastAI.Datasets
16+
# for tests
17+
using ..FastAI: testencoding
18+
19+
# extending
20+
import FastAI:
21+
blockmodel, blockbackbone, blocklossfn, encode, decode, checkblock,
22+
encodedblock, decodedblock, showblock!, mockblock, setup
23+
24+
import MLUtils: MLUtils, eachobs, getobs, numobs
25+
26+
using FilePathsBase
27+
using InlineTest
28+
using Statistics
29+
using UnicodePlots
30+
31+
# Blocks
32+
include("blocks/timeseriesrow.jl")
33+
34+
# Encodings
35+
include("encodings/tspreprocessing.jl")
36+
37+
include("container.jl")
38+
include("recipes.jl")
39+
40+
const _tasks = Dict{String, Any}()
41+
include("tasks/classification.jl")
42+
43+
function __init__()
44+
_registerrecipes()
45+
foreach(values(_tasks)) do t
46+
if !haskey(FastAI.learningtasks(), t.id)
47+
push!(FastAI.learningtasks(), t)
48+
end
49+
end
50+
end
51+
52+
export
53+
TimeSeriesRow, TSClassificationSingle, TSPreprocessing
54+
end
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
TimeSeriesRow{M,N}() <: Block
3+
4+
[`Block`](#) for a M variate time series with N number of time steps. `obs` is valid for `TimeSeriesRow{M,N}()`
5+
if it is an (M,N) dimensional Matrix with number element type.
6+
7+
## Examples
8+
9+
Creating a block:
10+
11+
```julia
12+
TimeSeriesRow{1,51}() # Univariate time series with length 51.
13+
TimeSeriesRow{2,51}() # Multivariate time series with 2 variables and length 51.
14+
```
15+
16+
You can create a random observation using [`mockblock`](#):
17+
18+
{cell=main}
19+
```julia
20+
using FastAI
21+
FastAI.mockblock(TimeSeriesRow{1,10}())
22+
```
23+
24+
To visualize a time-series sample.
25+
26+
```julia
27+
showblock(TimeSeriesRow(1,10), rand(Float32, (1,10)))
28+
```
29+
30+
"""
31+
32+
struct TimeSeriesRow <: Block
33+
nfeatures::Int
34+
obslength::Union{Int, Colon}
35+
end
36+
37+
checkblock(row::TimeSeriesRow, obs::AbstractMatrix{<:Number}) = size(obs) == (row.nfeatures, row.obslength)
38+
39+
function mockblock(row::TimeSeriesRow)
40+
rand(Float64, (row.nfeatures, row.obslength))
41+
end
42+
43+
function setup(::Type{TimeSeriesRow}, data)
44+
nfeatures, obslength = size(getindex(data, 1))
45+
return TimeSeriesRow(nfeatures, obslength)
46+
end
47+
48+
# visualization
49+
50+
function showblock!(io, ::ShowText, block::TimeSeriesRow, obs)
51+
plot = UnicodePlots.lineplot(obs[1,:])
52+
for j=2:size(obs,1)
53+
UnicodePlots.lineplot!(plot, obs[j,:])
54+
end
55+
print(io, plot)
56+
end

0 commit comments

Comments
 (0)