Skip to content

Commit 195e502

Browse files
committed
add timeseries mlflow tracking.
1 parent ac31514 commit 195e502

File tree

3 files changed

+204
-3
lines changed

3 files changed

+204
-3
lines changed

AutoAD/src/AutoAD.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ include("carettspredictor.jl")
4646
using .CaretTSPredictors
4747
export CaretTSPredictor, carettsdriver
4848

49+
include("automlflowtsprediction.jl")
50+
using .AutoMLFlowTSPredictions
51+
export AutoMLFlowTSPrediction
52+
export mlftsdriver
53+
4954
end # module AutoAD

AutoAD/src/automlflowanomalydetection.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function (obj::AutoMLFlowAnomalyDetection)(; args...)
6666
return obj
6767
end
6868

69-
function fit!(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame, Y::Vector)
69+
function fit!(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame, Y::Vector=[])::Nothing
7070
# start experiment run
7171
setupautofit!(mlfad)
7272
# automate anomaly detection
@@ -79,9 +79,10 @@ function fit!(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame, Y::Vector)
7979
MLF.log_metric("votepercent", autoad.model[:votepercent])
8080
# log artifacts and end experiment run
8181
logmlartifact(mlfad)
82+
return nothing
8283
end
8384

84-
function fit(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame, Y::Vector)
85+
function fit(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame, Y::Vector=[])::Nothing
8586
mlfcopy = deepcopy(mlfad)
8687
fit!(mlfcopy, X, Y)
8788
return mlfcopy
@@ -142,9 +143,9 @@ function transform(mlfad::AutoMLFlowAnomalyDetection, X::DataFrame)
142143
end
143144

144145
function mlfaddriver()
145-
url = "http://localhost:8081"
146146
url = "http://mlflow.home"
147147
url = "http://mlflow.isiath.duckdns.org:8082"
148+
url = "http://localhost:8081"
148149

149150
X = CSV.read("./data/node_cpu_ratio_rate_5m_1d_1m.csv",DataFrame;header=false)
150151

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
module AutoMLFlowTSPredictions
2+
using PDFmerger: append_pdf!
3+
using Plots
4+
using Statistics
5+
using Serialization
6+
import PythonCall
7+
const PYC = PythonCall
8+
using CSV
9+
10+
using DataFrames: DataFrame
11+
using Random
12+
using ..AbsTypes
13+
using ..Utils
14+
using ..CaretTSPredictors
15+
16+
import ..AbsTypes: fit, fit!, transform, transform!
17+
export fit, fit!, transform, transform!
18+
export mlftsdriver, AutoMLFlowTSPrediction
19+
20+
const MLF = PYC.pynew()
21+
const REQ = PYC.pynew()
22+
23+
function __init__()
24+
PYC.pycopy!(MLF, PYC.pyimport("mlflow"))
25+
PYC.pycopy!(REQ, PYC.pyimport("requests"))
26+
end
27+
28+
include("./mlflowutils.jl")
29+
30+
mutable struct AutoMLFlowTSPrediction <: Workflow
31+
name::String
32+
model::Dict{Symbol,Any}
33+
34+
function AutoMLFlowTSPrediction(args=Dict())
35+
default_args = Dict(
36+
:name => "AutoTSPredictions",
37+
:projectname => "AutoTSPredictions",
38+
:url => "http://localhost:8080",
39+
:description => "Automated Timeseries Prediction",
40+
:projecttype => "tsprediction",
41+
:artifact_name => "AutoTSPredictionModel.bin",
42+
:impl_args => Dict(
43+
:name => "autots",
44+
:learner=>"auto",
45+
:forecast_horizon=>10
46+
)
47+
)
48+
cargs = nested_dict_merge(default_args, args)
49+
initmlflowcargs!(cargs)
50+
cargs[:automodel] = CaretTSPredictor(cargs[:impl_args])
51+
new(cargs[:name], cargs)
52+
end
53+
end
54+
55+
function AutoMLFlowTSPrediction(name::String, args::Dict)
56+
AutoMLFlowTSPrediction(Dict(:name => name, args...))
57+
end
58+
59+
function AutoMLFlowTSPrediction(name::String; args...)
60+
AutoMLFlowTSPrediction(Dict(Dict(pairs(args))...))
61+
end
62+
63+
function (obj::AutoMLFlowTSPrediction)(; args...)
64+
model = obj.model
65+
cargs = nested_dict_merge(model, Dict(pairs(args)))
66+
obj.model = cargs
67+
return obj
68+
end
69+
70+
function fit!(mlfas::AutoMLFlowTSPrediction, X::DataFrame, Y::Vector=[])::Nothing
71+
# start experiment run
72+
setupautofit!(mlfas)
73+
# automate prediction
74+
autots = mlfas.model[:automodel]
75+
tsoutput = fit_transform!(autots, X, Y)
76+
# save model in memory
77+
mlfas.model[:automodel] = autots
78+
# log info to mlflow
79+
MLF.log_param("TSOutput", tsoutput)
80+
MLF.log_metric("ForecastHorizon", autots.model[:forecast_horizon])
81+
# log artifacts and end experiment run
82+
logmlartifact(mlfas)
83+
return nothing
84+
end
85+
86+
function fit(mlfas::AutoMLFlowTSPrediction, X::DataFrame, Y::Vector=[])::Nothing
87+
mlfcopy = deepcopy(mlfas)
88+
fit!(mlfcopy, X, Y)
89+
return mlfcopy
90+
end
91+
92+
function plottroutput(mlfas::AutoMLFlowTSPrediction, Y::Union{Vector,DataFrame})
93+
data = Y
94+
votepercent = mlfas.model[:automodel].model[:votepercent]
95+
tmpdir = tempdir()
96+
println(tmpdir)
97+
artifact_plot = joinpath(tmpdir, "plots.pdf")
98+
artifact_allplots = joinpath(tmpdir, "allplots.pdf")
99+
rm(artifact_allplots, force=true)
100+
if votepercent == 0.0
101+
for ndx in 0.1:0.1:1.0
102+
strndx = string(ndx)
103+
coldata = data[:, strndx]
104+
ndx = findall(x -> x == true, coldata)
105+
Plots.plot(data[:,1], label="tsdata", title="TS Prediction")
106+
xlabel!("X")
107+
ylabel!("Y")
108+
plp = scatter!(ndx, data[:,1][ndx], label="prediction")
109+
savefig(plp, artifact_plot)
110+
append_pdf!(artifact_allplots, artifact_plot, cleanup=true)
111+
end
112+
else
113+
strndx = string(votepercent)
114+
coldata = data[:, strndx]
115+
ndx = findall(x -> x == true, coldata)
116+
Plots.plot(data[:,1], label="tsdata", title="TS Prediction")
117+
xlabel!("X")
118+
ylabel!("Y")
119+
scatter!(ndx, data[:,1][ndx], label="prediction")
120+
savefig(artifact_allplots)
121+
end
122+
MLF.log_artifact(artifact_allplots)
123+
end
124+
125+
function transform!(mlfas::AutoMLFlowTSPrediction, X::DataFrame)
126+
# start experiment run
127+
Y = autotransform!(mlfas, X)
128+
# create plots and save them as mlfow artifacts
129+
# plottroutput(mlfas, Y)
130+
# end run
131+
MLF.end_run()
132+
return Y
133+
end
134+
135+
function transform(mlfas::AutoMLFlowTSPrediction, X::DataFrame)
136+
mlfasc = deepcopy(mlfas)
137+
return transform!(mlfasc, X)
138+
end
139+
140+
function mlftsdriver()
141+
url = "http://mlflow.home"
142+
url = "http://mlflow.isiath.duckdns.org:8082"
143+
url = "http://localhost:8081"
144+
145+
X = CSV.read("./data/node_cpu_ratio_rate_5m_1d_1m.csv",DataFrame;header=false)
146+
147+
#X = vcat(5 * cos.(-10:10), sin.(-30:30), 3 * cos.(-10:10), 2 * tan.(-10:10), sin.(-30:30)) |> x -> DataFrame([x], :auto)
148+
149+
# test all voting percent
150+
mlfas = AutoMLFlowTSPrediction(Dict(:url => url))
151+
fit!(mlfas, X)
152+
#println(Yc |> x -> first(x, 5))
153+
154+
# # test specific votepercent
155+
# mlvad = AutoMLFlowTSPrediction(Dict(:url => url, :impl_args => Dict(:votepercent => 0.3)))
156+
# Yc = fit_transform!(mlvad, X)
157+
# println(Yc |> x -> first(x, 5))
158+
#
159+
# # override default votepercent
160+
# mlfas = AutoMLFlowTSPrediction(Dict(:url => url))
161+
# mlfas.model[:automodel](; votepercent=0.5)
162+
# Yc = fit_transform!(mlfas, X)
163+
# println(Yc |> x -> first(x, 5))
164+
#
165+
#
166+
# mlfas = AutoMLFlowTSPrediction(Dict(:url => url))
167+
# mlfas.model[:automodel](; votepercent=0.0)
168+
# Yc = fit_transform!(mlfas, X)
169+
# println(Yc |> x -> first(x, 5))
170+
#
171+
# ## test prediction using exisiting trained model from artifacts
172+
# #### alternative 1 to use trained model for transform
173+
# mlvad = AutoMLFlowTSPrediction(Dict(:url => url))
174+
# Yc = fit_transform!(mlvad, X)
175+
# run_id = mlvad.model[:run_id]
176+
# newmlad = AutoMLFlowTSPrediction(Dict(:run_id => run_id, :url => url, :impl_args => Dict(:votepercent => 0.5)))
177+
# newmlad.model[:automodel](; votepercent=0.2)
178+
# Yn = transform!(newmlad, X)
179+
# println(Yn |> x -> first(x, 5))
180+
#
181+
# ## alternative 2 to use trained model for transform
182+
# mlvad = AutoMLFlowTSPrediction(Dict(:url => url))
183+
# Yc = fit_transform!(mlvad, X)
184+
# run_id = mlvad.model[:run_id]
185+
# votepercent = 0.3
186+
# newmlad = AutoMLFlowTSPrediction(Dict(:url => url))
187+
# newmlad(; run_id)
188+
# newmlad.model[:automodel](; votepercent)
189+
# Yn = transform!(newmlad, X)
190+
# println(Yn |> x -> first(x, 5))
191+
192+
return nothing
193+
end
194+
195+
end

0 commit comments

Comments
 (0)