From 8824893b1586d79f8c6a89f7e05663499ddac183 Mon Sep 17 00:00:00 2001 From: Simon Let Date: Tue, 24 Sep 2019 01:51:47 +0200 Subject: [PATCH] evaluate: add dynamic/tf-idf record distance strategy --- evaluate/resh-evaluate-plot.py | 2 +- evaluate/resh-evaluate.go | 20 +++-- evaluate/strategy-dynamic-record-distance.go | 85 ++++++++++++++++++++ 3 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 evaluate/strategy-dynamic-record-distance.go diff --git a/evaluate/resh-evaluate-plot.py b/evaluate/resh-evaluate-plot.py index 7568800..4ffea19 100755 --- a/evaluate/resh-evaluate-plot.py +++ b/evaluate/resh-evaluate-plot.py @@ -502,7 +502,7 @@ def plot_strategies_charsRecalled_prefix(plot_size=50, selected_strategies=[]): plot_strategies_matches(20) plot_strategies_charsRecalled(20) -plot_strategies_charsRecalled_prefix(20) +# plot_strategies_charsRecalled_prefix(20) # graph_cmdSequences(node_count=33, edge_minValue=0.048) diff --git a/evaluate/resh-evaluate.go b/evaluate/resh-evaluate.go index 3fdd45a..8a7ea08 100644 --- a/evaluate/resh-evaluate.go +++ b/evaluate/resh-evaluate.go @@ -114,12 +114,22 @@ func main() { directory.init() strategies = append(strategies, &directory) + dynamicDist := strategyDynamicRecordDistance{ + maxDepth: 3000, + distParams: common.DistParams{Pwd: 10, RealPwd: 10, SessionID: 1, Time: 1}, + label: "10*pwd,10*realpwd,session,time", + } + dynamicDist.init() + strategies = append(strategies, &dynamicDist) + + distanceStaticBest := strategyRecordDistance{ + maxDepth: 3000, + distParams: common.DistParams{Pwd: 10, RealPwd: 10, SessionID: 1, Time: 1}, + label: "10*pwd,10*realpwd,session,time", + } + strategies = append(strategies, &distanceStaticBest) + if *slow { - distanceStaticBest := strategyRecordDistance{ - distParams: common.DistParams{SessionID: 1, Pwd: 10, RealPwd: 10, Time: 1}, - label: "10*pwd,10*realpwd,1*session,time", - } - strategies = append(strategies, &distanceStaticBest) markovCmd := strategyMarkovChainCmd{order: 1} markovCmd.init() diff --git a/evaluate/strategy-dynamic-record-distance.go b/evaluate/strategy-dynamic-record-distance.go new file mode 100644 index 0000000..a7ffbe7 --- /dev/null +++ b/evaluate/strategy-dynamic-record-distance.go @@ -0,0 +1,85 @@ +package main + +import ( + "math" + "sort" + "strconv" + + "github.com/curusarn/resh/common" +) + +type strategyDynamicRecordDistance struct { + history []common.EnrichedRecord + distParams common.DistParams + pwdHistogram map[string]int + realPwdHistogram map[string]int + maxDepth int + label string +} + +type strDynDistEntry struct { + cmdLine string + distance float64 +} + +func (s *strategyDynamicRecordDistance) init() { + s.history = nil + s.pwdHistogram = map[string]int{} + s.realPwdHistogram = map[string]int{} +} + +func (s *strategyDynamicRecordDistance) GetTitleAndDescription() (string, string) { + return "dynamic record distance (depth:" + strconv.Itoa(s.maxDepth) + ";" + s.label + ")", "Use TF-IDF record distance to recommend commands" +} + +func (s *strategyDynamicRecordDistance) idf(count int) float64 { + return math.Log(float64(len(s.history)) / float64(count)) +} + +func (s *strategyDynamicRecordDistance) GetCandidates() []string { + if len(s.history) == 0 { + return nil + } + var prevRecord common.EnrichedRecord + prevRecord = s.history[0] + prevRecord.SetCmdLine("") + prevRecord.SetBeforeToAfter() + var mapItems []strDynDistEntry + for i, record := range s.history { + if s.maxDepth != 0 && i > s.maxDepth { + break + } + distParams := common.DistParams{ + Pwd: s.distParams.Pwd * s.idf(s.pwdHistogram[prevRecord.PwdAfter]), + RealPwd: s.distParams.RealPwd * s.idf(s.realPwdHistogram[prevRecord.RealPwdAfter]), + Time: s.distParams.Time, + SessionID: s.distParams.SessionID, + } + distance := record.DistanceTo(prevRecord, distParams) + mapItems = append(mapItems, strDynDistEntry{record.CmdLine, distance}) + } + sort.SliceStable(mapItems, func(i int, j int) bool { return mapItems[i].distance < mapItems[j].distance }) + var hist []string + histSet := map[string]bool{} + for _, item := range mapItems { + if histSet[item.cmdLine] { + continue + } + histSet[item.cmdLine] = true + hist = append(hist, item.cmdLine) + } + return hist +} + +func (s *strategyDynamicRecordDistance) AddHistoryRecord(record *common.EnrichedRecord) error { + // append record to front + s.history = append([]common.EnrichedRecord{*record}, s.history...) + s.pwdHistogram[record.Pwd]++ + s.realPwdHistogram[record.RealPwd]++ + return nil +} + +func (s *strategyDynamicRecordDistance) ResetHistory() error { + s.init() + return nil +}