---
# System prepended metadata

title: 異常検知

---

# 異常検知



## SN比

```julia=
using LinearAlgebra
using Statistics   # mean
using Distances    # sqmahalanobis
using DataFrames, CSV
combi(itr) = combi(identity, itr)
combi(n::Integer) = combi(1:n)
function combi(f, itr)    
    res = mapfoldl(
        f,
        (res,x) -> [res; (r -> [r; x]).(res)],
        itr,
        init=[[]]
    )
    filter(!isempty, res) # [] を取り除く
end
function a(y, dataset)
    μ = mean(dataset)
    Σ = mean(x -> (x - μ)*(x - μ)', dataset)
    sqmahalanobis(y, μ, inv(Σ))
end
a(y, safe_dataset, q) = a(y[q], [vec[q] for vec in safe_dataset])
SN(bad_dataset, safe_dataset, q) = 10*log10(mean(y -> a(y, safe_dataset, q)/length(q), bad_dataset))
function SN_list(x, label, id)
    list = []
    n,p = size(x)
    for ti = 1:n
        train = [i for i=1:n if i != ti]
        test = [ti]
        x_train = collect(eachrow(x[train,:]))
        x_test  = collect(eachrow(x[test,:]))
        append!(list,
                map( selected -> (SN(x_test,x_train, selected), label[selected], id[test]),
                combi(p) ))
    end
    list
end

data = DataFrame(CSV.File("かんくん.csv"))
x = Matrix(data[:, Not(1)])
label = names(data[:, Not(1)])
id = data[:, 1]

result = SN_list( x, label, id )

first(sort(result, rev=true), 5)
```
```
Out: 5-element Vector{Any}:
 (33.781083360629395, ["Rdc"], ["D9"])
 (33.144177503448915, ["Rtot", "Rdc"], ["D9"])
 (31.40072195457991, ["Rtot", "Rdc", "C'(Rdc)"], ["D9"])
 (31.089824848337145, ["Rdc", "C'(Rdc)"], ["D9"])
 (22.903631976175845, ["Rtot", "Rdc", "C'(Rdc)"], ["4"])
```

## グラフ
```julia=
using Distributions
using LinearAlgebra
using Statistics   # mean
using Distances    # sqmahalanobis
using DataFrames, CSV
using Plots
function a(y, dataset)
    μ = mean(dataset)
    Σ = mean(x -> (x - μ)*(x - μ)', dataset)
    sqmahalanobis(y, μ, inv(Σ))
end
a(y, safe_dataset, q) = a(y[q], [vec[q] for vec in safe_dataset])
threshold(n, M, q) = (M*(n+1))/(n-M) * quantile(FDist(M, n-M), q)

data = DataFrame(CSV.File("かんくん.csv"))   ###
x = Matrix(data[:, Not(1)])
label = names(data[:, Not(1)])
id = data[:, 1]
n, p = size(x)

selected = [1,3]      ### 変数の選択
test     = [5]        ### 異常の選択
train    = (1:n)[Not(test)]    ### 正常の選択

m = length(selected)
x_train = collect(eachrow(x[train,:]))


anormal_score = [a(x, x_train, selected) for x in eachrow(x)]
plot(id, log10.(anormal_score), st=:bar, title="anormality", legend=false )
plot!(x -> log10(threshold(n, m, 0.95)), 0:n)
plot!(x -> log10(threshold(n, m, 0.99)), 0:n)
```