異常検知でGo!
こんにちは。ちょびえです。4日めですがいかがお過ごしでしょうか?
今日はGoで異常検知を試してみましたのでレポートしてみたいと思います。
異常検知の世界
ふつうのWebプログラマーの私がデータマイニングによる異常検知読んで、機械学習ってなんて便利なんだろう!?と驚いたと共に機械学習の魅力に引き込まれていきました。
https://github.com/muddydixon/fluent-plugin-anomalydetect のSDAR部分を再実装したものです。私は高校をドロップアウトしてるので線形代数周りの理解・実装でだいぶ難儀しましたが、良き実装があればなんとかなるもんだなぁ、、、とw
anomalydetectorはChangeFinder部分のスムージングなどの実装は含んでいないのでこんな感じで作ってみてください。
package main
import (
"fmt"
"bufio"
"strconv"
"os"
"strings"
anomalydetector "github.com/chobie/go-anomalydetector"
)
type ChangeFinder struct {
O *anomalydetector.AnomalyDetector
S *anomalydetector.AnomalyDetector
Smooth int
Last float64
LastScore float64
Buffer []float64
Buffer2 []float64
}
func sum(array *[]float64) float64 {
sum := 0.0
for _, value := range *array {
sum += value
}
return sum
}
func (finder *ChangeFinder) Update(v float64) float64 {
var score float64 = 0.0
if v == finder.Last && finder.LastScore < 3.0 {
score = finder.LastScore
} else {
r := finder.O.Update(v)
finder.Buffer = append(finder.Buffer, r)
if len(finder.Buffer) > finder.Smooth {
finder.Buffer = finder.Buffer[1:]
}
score = finder.S.Update(sum(&finder.Buffer) / float64(len(finder.Buffer)))
}
finder.Last = v
finder.LastScore = score
return finder.LastScore
}
func NewChangePoint(outlier_term int, outlier_discount float64, score_term int, score_discount float64, smooth_term int) *ChangeFinder {
v := ChangeFinder{}
v.O = anomalydetector.NewAnomalyDetector(outlier_term, outlier_discount)
v.S = anomalydetector.NewAnomalyDetector(score_term, score_discount)
v.Smooth = smooth_term
return &v
}
func main() {
p, err := os.Open("go.tsv")
if err != nil {
panic(err)
}
defer p.Close()
cp := NewChangePoint(12, 0.0275, 6, 0.1, 12)
scanner := bufio.NewScanner(p)
for scanner.Scan() {
args := strings.Split(scanner.Text(), "\t")
result, err := strconv.ParseFloat(args[1], 64)
if err != nil {
panic(err)
}
score := cp.Update(result)
fmt.Printf("%s\t%f\t%f\n", args[0], result, score)
}
}
Google TrendでGolangを検索した結果を下記にはりつけておきます。ダウンロードしてgo.tsvで保存して置いてください。
https://gist.github.com/chobie/16b15c35f8452ed8d59f
それでは実行結果をExcelでPlotしてみたいと思います。スコアはそのままだと小さくて読みづらいのでなんとなく自乗しときました。
2008/9は記憶にありませんが、2009/11といえばコレですね
それじゃ、Happy Hacking