|
|
from util.data import get_attack_interval
|
|
|
import time
|
|
|
from datetime import datetime
|
|
|
from pytz import utc, timezone
|
|
|
from util.time import timestamp2str
|
|
|
import json
|
|
|
import argparse
|
|
|
import numpy as np
|
|
|
|
|
|
def printsep():
|
|
|
print('='*40+'\n')
|
|
|
|
|
|
def save_attack_infos(f1_scores, total_err_scores, labels, names, save_path, dataset, config):
|
|
|
slide_win=config['slide_win']
|
|
|
down_len=config['down_len']
|
|
|
|
|
|
|
|
|
if dataset == 'wadi' or dataset == 'wadi2':
|
|
|
s = '09/10/2017 18:00:00'
|
|
|
elif dataset == 'swat':
|
|
|
s = '28/12/2015 10:00:00'
|
|
|
start_s = int(time.mktime(datetime.strptime(s, "%d/%m/%Y %H:%M:%S").timetuple()))
|
|
|
cst8 = timezone('Asia/Shanghai')
|
|
|
fmt = '%m/%d %H:%M:%S'
|
|
|
|
|
|
attack_inters = get_attack_interval(labels)
|
|
|
|
|
|
save_infos = {
|
|
|
'total_best_f1_score': f1_scores[0],
|
|
|
'total_best_f1_score_topk': f1_scores[1],
|
|
|
'total_best_f1_score_all': f1_scores[2],
|
|
|
'attacks': []
|
|
|
}
|
|
|
|
|
|
indices_map = names
|
|
|
|
|
|
indices = np.argmax(total_err_scores, axis=0).tolist()
|
|
|
anomaly_sensors = [ indices_map[index] for index in indices ]
|
|
|
|
|
|
topk = 5
|
|
|
topk_indices = np.argpartition(total_err_scores, -topk, axis=0)[-topk:]
|
|
|
topk_indices = np.transpose(topk_indices)
|
|
|
|
|
|
topk_anomaly_sensors = []
|
|
|
topk_err_score_map=[]
|
|
|
for i, indexs in enumerate(topk_indices):
|
|
|
|
|
|
topk_anomaly_sensors.append([indices_map[index] for index in indexs])
|
|
|
|
|
|
item = {}
|
|
|
for sensor, index in zip(topk_anomaly_sensors[i],indexs):
|
|
|
if sensor not in item:
|
|
|
item[sensor] = total_err_scores[index, i]
|
|
|
|
|
|
topk_err_score_map.append(item)
|
|
|
|
|
|
|
|
|
for head, end in attack_inters:
|
|
|
attack_infos = {}
|
|
|
topk_attack_infos = {}
|
|
|
|
|
|
head_t = timestamp2str(start_s+(head+slide_win)*down_len, fmt, cst8)
|
|
|
end_t = timestamp2str(start_s+(end+slide_win)*down_len, fmt, cst8)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(head, end):
|
|
|
|
|
|
t = timestamp2str(start_s+(i+slide_win)*down_len, fmt, cst8)
|
|
|
max_sensor = anomaly_sensors[i]
|
|
|
topk_sensors = topk_anomaly_sensors[i]
|
|
|
|
|
|
if max_sensor not in attack_infos:
|
|
|
attack_infos[max_sensor] = 0
|
|
|
attack_infos[max_sensor] += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for anomaly_sensor in topk_sensors:
|
|
|
if anomaly_sensor not in topk_attack_infos:
|
|
|
topk_attack_infos[anomaly_sensor] = 0
|
|
|
topk_attack_infos[anomaly_sensor] += topk_err_score_map[i][anomaly_sensor]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sorted_attack_infos = {k: v for k, v in sorted(attack_infos.items(), reverse=True, key=lambda item: item[1])}
|
|
|
sorted_topk_attack_infos = {k: v for k, v in sorted(topk_attack_infos.items(), reverse=True, key=lambda item: item[1])}
|
|
|
|
|
|
|
|
|
|
|
|
save_infos['attacks'].append({
|
|
|
'start': head_t,
|
|
|
'end': end_t,
|
|
|
'sensors': list(sorted_attack_infos),
|
|
|
'topk_sensors': list(sorted_topk_attack_infos),
|
|
|
'topk_scores': list(sorted_topk_attack_infos.values())
|
|
|
})
|
|
|
|
|
|
with open(save_path, 'w+') as outfile:
|
|
|
json.dump(save_infos, outfile, indent=4)
|
|
|
|