見出し画像

ログ分析ツールのためにTFIDFパッケージの改善

今朝は4時から開発開始です。
GO言語のTFIDFパッケージ


をログ分析ツール


に組み込みための改善の続きです。

で扱っているサンプルデータのTFIDFを計算して、同じ結果が得られるようにしました。それをテストに組み込みました。

func TestGetTFIDF(t *testing.T) {
	docs := []string{
		"犬 可愛い 犬 大きい",
		"猫 小さい 猫 可愛い 可愛い",
		"虫 小さい 可愛くない",
	}
	f := New()
	f.AddDocs(docs...)
	dc := f.GetDocumentCount()
	if dc != 3 {
		t.Fatalf("failed GetDocumentCount=%v", dc)
	}
	dup := f.GetDupCount()
	if dup != 0 {
		t.Fatalf("failed GetDupCount=%v", dc)
	}
	at := f.GetAllTerms()
	if len(at) != 7 || at[6] != "虫" {
		t.Fatalf("failed GetAllTerms=%v", at)
	}
	v := f.GetTFIDF(docs...)
	if len(v) != 3 || len(v[0]) != 7 || v[0][0] != 0.3513662770270411 {
		t.Fatalf("failed GetTFIDF=%v", v)
	}
	fmt.Println(f.GetAllTerms())
	for _, e := range v {
		fmt.Println(e)
	}
}

実行すると

同じ値が得られます。
これで、ドキュメントの行単位でベクトルデータを作成することができるようになったので、TFTIDFパッケージの稀なログ検知プログラムに異常検知のアルゴリズムを組み込んでみることにしました。
ログ分析ツールで使っているIsolation ForestとLocal Outlier Factorです。
比較的簡単にできました。スコアの計算を置き換えるだけです。

		vectors := f.GetTFIDF(lines...)
		samples := lof.GetSamplesFromFloat64s(vectors)
		lofGetter := lof.NewLOF(5)
		if err := lofGetter.Train(samples); err != nil {
			log.Fatalf("LOF err=%v", err)
		}
		for i, s := range samples {
			s := lofGetter.GetLOF(s, "fast")
			logs = append(logs, logEnt{
				Pos:   i,
				Score: s,
			})
		}

前に試したログで実行する

 % go run . -a lof -t log -g  ~/prj/lesson/tfidf/twsnmp/test.log
Score	Log
2.081	Jun  3 07:14:01 minipc CRON[10234]: (root) CMD (/usr/sbin/mon.sh)
1.977	Jun  3 07:14:01 minipc loadmon:  07:14:01 up 209 days, 23:56,  1 user,  load average: 0.99, 0.91, 0.92
1.930	Jun  3 07:14:01 minipc memmon: Mem:        7987020      743760      171064      465844     7072196     6467548
1.167	Jun  3 07:14:22 minipc snmpd[23595]: Connection from UDP: [192.168.1.250]:64336->[192.168.1.210]:161
1.036	Jun  3 07:13:57 minipc gravwell_simple_relay[550]: <12>1 2023-06-03T07:13:57.05767+09:00 minipc simplerelay - ingest/muxer.go:1402 [gw@1 indexer="pipe:///opt/gravwell/comms/pipe" ingester="simplerelay" ingesteruuid="cd6c92b5-8fdb-4b84-a87f-1cab42c0033e" error="dial unix /opt/gravwell/comms/pipe: connect: no such file or directory"] connection error
1.032	Jun  3 07:13:48 minipc snmpd[23595]: Connection from UDP: [192.168.1.4]:57885->[192.168.1.210]:161
1.032	Jun  3 07:13:48 minipc snmpd[23595]: Connection from UDP: [192.168.1.4]:57885->[192.168.1.210]:161
1.032	Jun  3 07:13:48 minipc snmpd[23595]: Connection from UDP: [192.168.1.4]:57885->[192.168.1.210]:161
1.026	Jun  3 07:13:48 minipc snmpd[23595]: Connection from UDP: [192.168.1.4]:57885->[192.168.1.210]:161
1.008	Jun  3 07:13:57 minipc gravwell_simple_relay[550]: <14>1 2023-06-03T07:13:57.057382+09:00 minipc simplerelay - ingest/muxer.go:1394 [gw@1 indexer="pipe:///opt/gravwell/comms/pipe" ingester="simplerelay" ingesteruuid="cd6c92b5-8fdb-4b84-a87f-1cab42c0033e"] initializing connection

のような感じで稀なログが上位に来るようになります。
ログファイルのサイズが小さい場合は問題ないですが、サイズの大きなものを実行するとメモリを沢山使うようなので、もう少し改善が必要です。
でも、今朝は時間切れです。

明日に続く

いいなと思ったら応援しよう!

twsnmp
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。