Skip to content

Commit 52bde1a

Browse files
committed
add autoanomalydetector
1 parent ce126f8 commit 52bde1a

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

AutoAI/src/AutoAI.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,8 @@ include("automlflowregression.jl")
4040
using .AutoMLFlowRegressions
4141
export mlfregdriver
4242

43+
include("autoanomalydetector.jl")
44+
using .AutoAnomalyDetectors
45+
export autoaddriver
46+
4347
end # module AutoAI

AutoAI/src/autoanomalydetector.jl

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
module AutoAnomalyDetectors
2+
# classification search blocks
3+
4+
5+
using Distributed
6+
using AutoMLPipeline
7+
using DataFrames: DataFrame, nrow, rename!
8+
using AutoMLPipeline: score
9+
using Random
10+
using Statistics
11+
using ..AbsTypes
12+
using ..Utils
13+
using ..CaretAnomalyDetectors
14+
import ..CaretAnomalyDetectors.caretadlearner_dict
15+
using ..SKAnomalyDetectors
16+
17+
import ..AbsTypes: fit, fit!, transform, transform!
18+
export fit, fit!, transform, transform!
19+
export AutoAnomalyDetector, autoaddriver
20+
21+
# define customized type
22+
mutable struct AutoAnomalyDetector <: Workflow
23+
name::String
24+
model::Dict{Symbol,Any}
25+
26+
function AutoAnomalyDetector(args=Dict())
27+
default_args = Dict(
28+
:name => "autoad",
29+
:votepercent => 0.3,
30+
:impl_args => Dict()
31+
)
32+
cargs = nested_dict_merge(default_args, args)
33+
cargs[:name] = cargs[:name] * "_" * randstring(3)
34+
new(cargs[:name], cargs)
35+
end
36+
end
37+
38+
function fit!(autodt::AutoAnomalyDetector, X::DataFrame, Y::Vector)
39+
return nothing
40+
end
41+
42+
function fit(clfb::AutoAnomalyDetector, X::DataFrame, Y::Vector)
43+
return nothing
44+
end
45+
46+
function transform!(autodt::AutoAnomalyDetector, X::DataFrame)
47+
# detect anomalies using caret
48+
dfres1 = DataFrame()
49+
for learner in keys(caretadlearner_dict)
50+
model = CaretAnomalyDetector(learner)
51+
res = fit_transform!(model, X)
52+
mname = string(learner)
53+
dfres1 = hcat(dfres1, DataFrame(mname => res; makeunique=true))
54+
end
55+
56+
#detect anomalies using scikitlearn
57+
iso = SKAnomalyDetector("IsolationForest")
58+
eli = SKAnomalyDetector("EllipticEnvelope")
59+
osvm = SKAnomalyDetector("OneClassSVM")
60+
lcl = SKAnomalyDetector("LocalOutlierFactor")
61+
isores = fit_transform!(iso, X)
62+
elires = fit_transform!(eli, X)
63+
osvmres = fit_transform!(osvm, X)
64+
lclres = fit_transform!(lcl, X)
65+
dfres2 = DataFrame(iso=isores, eli=elires, osvm=osvmres, lcl=lclres)
66+
67+
# combine results and get mean anomaly for each row
68+
mdf = hcat(dfres1, dfres2)
69+
mdfm = hcat(mdf, DataFrame(admean=mean.(eachrow(mdf))))
70+
# filter anomalies based on mean cut-off
71+
# cutoff = autodt.model[:votepercent]
72+
dfad = DataFrame()
73+
for cutoff in 0.1:0.1:1.0
74+
ndx = map(x -> x >= cutoff, mdfm.admean)
75+
dfad = hcat(dfad, DataFrame(n=ndx); makeunique=true)
76+
end
77+
names = map(x -> string(x), 0.1:0.1:1.0)
78+
rename!(dfad, names)
79+
return dfad
80+
end
81+
82+
function transform(autodt::AutoAnomalyDetector, X::DataFrame)
83+
end
84+
85+
function autoaddriver()
86+
autoaddt = AutoAnomalyDetector(Dict(:votepercent => 0.1))
87+
X = vcat(5 * cos.(-10:10), sin.(-30:30), 3 * cos.(-10:10), 2 * tan.(-10:10), sin.(-30:30)) |> x -> DataFrame([x], :auto)
88+
fit_transform!(autoaddt, X)
89+
end
90+
91+
92+
end

AutoAI/src/lightwood.jl

Whitespace-only changes.

0 commit comments

Comments
 (0)