JCC-DeepOD/testbed/testbed_unsupervised_tsad.py

137 lines
4.9 KiB
Python

# -*- coding: utf-8 -*-
"""
testbed of unsupervised time series anomaly detection
@Author: Hongzuo Xu <hongzuoxu@126.com, xuhongzuo13@nudt.edu.cn>
"""
import os
import argparse
import getpass
import yaml
import time
import importlib as imp
import numpy as np
import utils
dataset_root = f'/home/{getpass.getuser()}/dataset/5-TSdata/_processed_data/'
parser = argparse.ArgumentParser()
parser.add_argument("--runs", type=int, default=5,
help="how many times we repeat the experiments to obtain the average performance")
parser.add_argument("--output_dir", type=str, default='@records/',
help="the output file path")
parser.add_argument("--dataset", type=str,
default='ASD,SMAP,MSL',
)
parser.add_argument("--entities", type=str,
default='FULL',
help='FULL represents all the csv file in the folder, or a list of entity names split by comma'
)
parser.add_argument("--entity_combined", type=int, default=1)
parser.add_argument("--model", type=str, default='AnomalyTransformer', help="")
parser.add_argument('--silent_header', action='store_true')
parser.add_argument("--flag", type=str, default='')
parser.add_argument("--note", type=str, default='')
parser.add_argument('--seq_len', type=int, default=30)
parser.add_argument('--stride', type=int, default=10)
args = parser.parse_args()
module = imp.import_module('deepod.models.time_series')
model_class = getattr(module, args.model)
path = 'configs.yaml'
with open(path) as f:
d = yaml.safe_load(f)
try:
model_configs = d[args.model]
except KeyError:
print(f'config file does not contain default parameter settings of {args.model}')
model_configs = {}
model_configs['seq_len'] = args.seq_len
model_configs['stride'] = args.stride
print(f'Model Configs: {model_configs}')
# # setting result file/folder path
cur_time = time.strftime("%m-%d %H.%M.%S", time.localtime())
os.makedirs(args.output_dir, exist_ok=True)
result_file = os.path.join(args.output_dir, f'{args.model}.{args.flag}.csv')
# # print header in the result file
if not args.silent_header:
f = open(result_file, 'a')
print('\n---------------------------------------------------------', file=f)
print(f'model: {args.model}, dataset: {args.dataset}, '
f'{args.runs}runs, {cur_time}', file=f)
for k in model_configs.keys():
print(f'Parameters,\t [{k}], \t\t {model_configs[k]}', file=f)
print(f'Note: {args.note}', file=f)
print(f'---------------------------------------------------------', file=f)
print(f'data, adj_auroc, std, adj_ap, std, adj_f1, std, adj_p, std, adj_r, std, time, model', file=f)
f.close()
dataset_name_lst = args.dataset.split(',')
for dataset in dataset_name_lst:
# # import data
data_pkg = utils.import_ts_data_unsupervised(dataset_root,
dataset, entities=args.entities,
combine=args.entity_combined)
train_lst, test_lst, label_lst, name_lst = data_pkg
entity_metric_lst = []
entity_metric_std_lst = []
for train_data, test_data, labels, dataset_name in zip(train_lst, test_lst, label_lst, name_lst):
entries = []
t_lst = []
for i in range(args.runs):
start_time = time.time()
print(f'\nRunning [{i+1}/{args.runs}] of [{args.model}] on Dataset [{dataset_name}]')
t1 = time.time()
clf = model_class(**model_configs, random_state=42+i)
clf.fit(train_data)
scores = clf.decision_function(test_data)
t = time.time() - t1
eval_metrics = utils.get_metrics(labels, scores)
adj_eval_metrics = utils.get_metrics(labels, utils.adjust_scores(labels, scores))
# print single results
txt = f'{dataset_name},'
txt += ', '.join(['%.4f' % a for a in eval_metrics]) + \
', pa, ' + \
', '.join(['%.4f' % a for a in adj_eval_metrics])
txt += f', model, {args.model}, time, {t:.1f} s, runs, {i+1}/{args.runs}'
print(txt)
entries.append(adj_eval_metrics)
t_lst.append(t)
avg_entry = np.average(np.array(entries), axis=0)
std_entry = np.std(np.array(entries), axis=0)
entity_metric_lst.append(avg_entry)
entity_metric_std_lst.append(std_entry)
f = open(result_file, 'a')
txt = '%s, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, ' \
'%.4f, %.4f, %.4f, %.4f, %.1f, %s ' % \
(dataset_name,
avg_entry[0], std_entry[0], avg_entry[1], std_entry[1],
avg_entry[2], std_entry[2], avg_entry[3], std_entry[3],
avg_entry[4], std_entry[4],
np.average(t_lst), args.model)
print(txt)
print(txt, file=f)
f.close()