refactor(app): refactor dictionary

This commit is contained in:
lxd1190 2018-11-07 14:57:17 +08:00
parent e831610019
commit 5faf04cf06
50 changed files with 336 additions and 257 deletions

View File

@ -1 +0,0 @@
__all__ = ["config", "controller", "dao", "model", "service", "utils"]

1
app/common/__init__.py Normal file
View File

@ -0,0 +1 @@
__all__ = ["common", "errorcode"]

View File

@ -8,6 +8,10 @@ https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
import traceback
from functools import wraps
from errorcode import *
DEFAULT_WINDOW = 180
INPUT_LEN_ENG_MAX = 32
INPUT_LEN_CH_MAX = 64
@ -17,3 +21,20 @@ VALUE_LEN_MAX = 50000
UPLOAD_FILE = '/tmp/tmpfile_%s.csv'
MARK_POSITIVE = 1
MARK_NEGATIVE = 2
def build_ret_data(ret_code, data=""):
return {"code": ret_code, "msg": ERR_CODE[ret_code], "data": data}
def exce_service(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
ret_code, ret_data = func(*args, **kwargs)
return_dict = build_ret_data(ret_code, ret_data)
except Exception as ex:
traceback.print_exc()
return_dict = build_ret_data(THROW_EXP, str(ex))
return return_dict
return wrapper

View File

@ -32,4 +32,4 @@ ERR_CODE = {
READ_FEATURE_FAILED: "读取特征数据失败",
TRAIN_ERR: "训练出错",
LACK_SAMPLE: "缺少正样本或负样本"
}
}

View File

@ -1 +0,0 @@
__all__ = ["database", "common", "errorcode"]

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import json
from functools import wraps
from django.shortcuts import render
from django.http import FileResponse
from common.render import render_json
from functools import wraps
from render import render_json
from app.service.time_series_detector.anomaly_service import *
from app.service.time_series_detector.sample_service import *
from app.service.time_series_detector.task_service import *
from app.service.time_series_detector.detect_service import *
from app.config.errorcode import *
from app.utils.utils import *
from app.common.errorcode import *
from app.common.common import *
def check_post(func):

View File

@ -1 +1 @@
__all__ = ["time_series_detector"]
__all__ = ["db_common", "time_series_detector"]

View File

@ -0,0 +1 @@
__all__ = ["database"]

View File

@ -1 +1 @@
__all__ = ["anomaly_op", "sample_op", "train_op"]
__all__ = ["anomaly_op", "sample_op", "train_op"]

View File

@ -8,13 +8,11 @@ https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
import time
import datetime
import MySQLdb
from app.config import database
from app.dao.db_common import database
from app.dao.time_series_detector.sample_op import *
from app.config.common import *
from app.config.errorcode import *
from app.common.common import *
from app.common.errorcode import *
class AbnormalOperation(object):

View File

@ -13,9 +13,9 @@ import uuid
import csv
import codecs
import MySQLdb
from app.config import database
from app.config.common import *
from app.config.errorcode import *
from app.dao.db_common import database
from app.common.common import *
from app.common.errorcode import *
class SampleOperation(object):

View File

@ -9,9 +9,9 @@ Unless required by applicable law or agreed to in writing, software distributed
"""
import MySQLdb
from app.config import database
from app.config.common import *
from app.config.errorcode import *
from app.dao.db_common import database
from app.common.common import *
from app.common.errorcode import *
class TrainOperation(object):

View File

@ -1 +0,0 @@
__all__ = ["time_series_detector"]

View File

@ -1 +1 @@
__all__ = ["time_series_detector"]
__all__ = ["time_series_detector"]

View File

@ -1 +1 @@
__all__ = ["algorithm", "feature", "anomaly_service", "sample_service", "task_service", "detect_service"]
__all__ = ["anomaly_service", "sample_service", "task_service", "detect_service"]

View File

@ -10,7 +10,6 @@ Unless required by applicable law or agreed to in writing, software distributed
import json
from app.dao.time_series_detector.anomaly_op import *
from app.utils.utils import *
class AnomalyService(object):

View File

@ -14,11 +14,12 @@ import threading
from app.dao.time_series_detector import anomaly_op
from app.dao.time_series_detector import sample_op
from app.dao.time_series_detector import train_op
from app.utils.utils import *
from app.service.time_series_detector.algorithm import isolation_forest, ewma, polynomial_interpolation, statistic, xgboosting
from app.config.errorcode import *
from app.config.common import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../../model/time_series_detector/')
from time_series_detector.algorithm import xgboosting
from time_series_detector import detect
from app.common.errorcode import *
from app.common.common import *
from time_series_detector.common.tsd_errorcode import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), './model/')
class DetectService(object):
@ -26,11 +27,7 @@ class DetectService(object):
def __init__(self):
self.sample_op_obj = sample_op.SampleOperation()
self.anomaly_op_obj = anomaly_op.AbnormalOperation()
self.iforest_obj = isolation_forest.IForest()
self.ewma_obj = ewma.Ewma()
self.polynomial_obj = polynomial_interpolation.PolynomialInterpolation()
self.statistic_obj = statistic.Statistic()
self.supervised_obj = xgboosting.XGBoosting()
self.detect_obj = detect.Detect()
def __generate_model(self, data, task_id):
"""
@ -125,62 +122,14 @@ class DetectService(object):
def __check_param(self, data):
if ("viewName" not in data.keys()) or ("attrId" not in data.keys()) or ("attrName" not in data.keys()) or ("time" not in data.keys()) or ("dataC" not in data.keys()) or ("dataB" not in data.keys()) or ("dataA" not in data.keys()):
return CHECK_PARAM_FAILED, "missing parameter"
if not data['dataA']:
return CHECK_PARAM_FAILED, "dataA can not be empty"
if not data['dataB']:
return CHECK_PARAM_FAILED, "dataB can not be empty"
if not data['dataC']:
return CHECK_PARAM_FAILED, "dataC can not be empty"
if not self.__list_is_digit(data['dataA'].split(',')):
return CHECK_PARAM_FAILED, "dataA contains illegal numbers"
if not self.__list_is_digit(data['dataB'].split(',')):
return CHECK_PARAM_FAILED, "dataB contains illegal numbers"
if not self.__list_is_digit(data['dataC'].split(',')):
return CHECK_PARAM_FAILED, "dataC contains illegal numbers"
if "window" in data:
window = data["window"]
else:
window = DEFAULT_WINDOW
if len(data['dataC'].split(',')) != (2 * window + 1):
return CHECK_PARAM_FAILED, "dataC length does not match"
if len(data['dataB'].split(',')) != (2 * window + 1):
return CHECK_PARAM_FAILED, "dataB length does not match"
if len(data['dataA'].split(',')) != (window + 1):
return CHECK_PARAM_FAILED, "dataA length does not match"
return OP_SUCCESS, ""
def value_predict(self, data):
"""
Predict the data
:param data: the time series to detect of
"""
ret_code, ret_data = self.__check_param(data)
if ret_code != OP_SUCCESS:
return build_ret_data(ret_code, ret_data)
if "taskId" in data and data["taskId"]:
model_name = MODEL_PATH + data["taskId"] + "_model"
else:
model_name = MODEL_PATH + "xgb_default_model"
combined_data = data["dataC"] + "," + data["dataB"] + "," + data["dataA"]
time_series = map(int, combined_data.split(','))
if "window" in data:
window = data["window"]
else:
window = DEFAULT_WINDOW
statistic_result = self.statistic_obj.predict(time_series)
ewma_result = self.ewma_obj.predict(time_series)
polynomial_result = self.polynomial_obj.predict(time_series, window)
iforest_result = self.iforest_obj.predict(time_series, window)
if statistic_result == 0 or ewma_result == 0 or polynomial_result == 0 or iforest_result == 0:
xgb_result = self.supervised_obj.predict(time_series, window, model_name)
res_value = xgb_result[0]
prob = xgb_result[1]
else:
res_value = 1
prob = 1
ret_data = {"ret": res_value, "p": str(prob)}
if ret_data["ret"] == 0:
ret_code, ret_data = self.detect_obj.value_predict(data)
if ret_code == TSD_OP_SUCCESS and ret_data["ret"] == 0:
anomaly_params = {
"view_id": data["viewId"],
"view_name": data["viewName"],
@ -192,18 +141,14 @@ class DetectService(object):
"data_a": data["dataA"]
}
self.anomaly_op_obj.insert_anomaly(anomaly_params)
return build_ret_data(OP_SUCCESS, ret_data)
return build_ret_data(ret_code, ret_data)
def rate_predict(self, data):
combined_data = data["dataC"] + "," + data["dataB"] + "," + data["dataA"]
time_series = map(float, combined_data.split(','))
statistic_result = self.statistic_obj.predict(time_series)
if statistic_result == 0:
prob = 0
else:
prob = 1
ret_data = {"ret": statistic_result, "p": str(prob)}
if ret_data["ret"] == 0:
ret_code, ret_data = self.__check_param(data)
if ret_code != OP_SUCCESS:
return build_ret_data(ret_code, ret_data)
ret_data, ret_data = self.detect_obj.rate_predict(data)
if ret_code == TSD_OP_SUCCESS and ret_data["ret"] == 0:
anomaly_params = {
"view_id": data["viewId"],
"view_name": data["viewName"],

View File

@ -12,9 +12,8 @@ import json
import traceback
import csv
from app.dao.time_series_detector.sample_op import *
from app.config.errorcode import *
from app.utils.utils import *
from app.config.common import *
from app.common.errorcode import *
from app.common.common import *
class SampleService(object):

View File

@ -10,8 +10,8 @@ Unless required by applicable law or agreed to in writing, software distributed
import json
from app.dao.time_series_detector.train_op import *
from app.config.errorcode import *
from app.utils.utils import *
from app.common.errorcode import *
from app.common.common import *
class TrainService(object):

View File

@ -1 +0,0 @@
__all__ = ["utils"]

View File

@ -137,7 +137,7 @@ python /data/Metis/app/controller/manage.py runserver {ip}:{port}
运行npm run build
将uweb目录下的custom文件夹复制到uweb目录下生成的dist文件夹中
将uweb目录下的custom文件夹复制到uweb目录下生成的dist文件夹中
将nginx配置文件中的root定位到uweb目录下的dist文件夹

View File

@ -1,25 +1,25 @@
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `train_task`
-- ----------------------------
DROP TABLE IF EXISTS `train_task`;
CREATE TABLE `train_task` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`task_id` char(255) DEFAULT NULL,
`sample_num` int(11) DEFAULT NULL,
`postive_sample_num` int(11) DEFAULT NULL,
`negative_sample_num` int(11) DEFAULT NULL,
`window` int(2) DEFAULT NULL,
`model_name` varchar(20) DEFAULT NULL,
`source` varchar(255) DEFAULT NULL,
`start_time` timestamp NULL DEFAULT NULL,
`end_time` timestamp NULL DEFAULT NULL,
`status` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of train_task
-- ----------------------------
INSERT INTO `train_task` VALUES ('1', '1535790960079', '90675', '45228', '45447', '180', 'xgb_default_model', 'Metis', '2018-09-01 16:36:00', '2018-09-01 16:45:40', 'complete');
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `train_task`
-- ----------------------------
DROP TABLE IF EXISTS `train_task`;
CREATE TABLE `train_task` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`task_id` char(255) DEFAULT NULL,
`sample_num` int(11) DEFAULT NULL,
`postive_sample_num` int(11) DEFAULT NULL,
`negative_sample_num` int(11) DEFAULT NULL,
`window` int(2) DEFAULT NULL,
`model_name` varchar(20) DEFAULT NULL,
`source` varchar(255) DEFAULT NULL,
`start_time` timestamp NULL DEFAULT NULL,
`end_time` timestamp NULL DEFAULT NULL,
`status` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of train_task
-- ----------------------------
INSERT INTO `train_task` VALUES ('1', '1535790960079', '90675', '45228', '45447', '180', 'xgb_default_model', 'Metis', '2018-09-01 16:36:00', '2018-09-01 16:45:40', 'complete');

View File

@ -0,0 +1 @@
__all__ = ["fixtures", "test_feature"]

View File

@ -9,8 +9,7 @@ Unless required by applicable law or agreed to in writing, software distributed
"""
from tests.fixtures import DataTestCase
from app.service.time_series_detector.feature.statistical_features import *
from time_series_detector.feature.statistical_features import *
class FeatureTestCase(DataTestCase):

View File

@ -0,0 +1 @@
__all__ = ["algorithm", "feature", "common", "detect"]

View File

@ -8,9 +8,9 @@ https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
from app.service.time_series_detector.algorithm import ewma
from app.service.time_series_detector.algorithm import polynomial_interpolation
from app.config.common import *
from time_series_detector.algorithm import ewma
from time_series_detector.algorithm import polynomial_interpolation
from time_series_detector.common.tsd_common import *
class EwmaAndPolynomialInterpolation(object):

View File

@ -13,13 +13,12 @@ import pickle
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.externals import joblib
from app.service.time_series_detector.feature import feature_service
from app.utils.utils import *
from app.config.errorcode import *
from app.config.common import *
from time_series_detector.feature import feature_service
from time_series_detector.common.tsd_common import *
from time_series_detector.common.tsd_errorcode import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../../../model/time_series_detector/')
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../model/')
DEFAULT_MODEL = MODEL_PATH + "gbdt_default_model"
@ -73,7 +72,7 @@ class Gbdt(object):
y_train = []
features = self.__calculate_features(data, window)
if features:
return LACK_SAMPLE
return TSD_LACK_SAMPLE
for index in features:
X_train.append(index[0])
y_train.append(index[1])
@ -85,8 +84,8 @@ class Gbdt(object):
model_name = MODEL_PATH + task_id + "_model"
joblib.dump(grd, model_name)
except Exception as ex:
return TRAIN_ERR, str(ex)
return OP_SUCCESS, ""
return TSD_TRAIN_ERR, str(ex)
return TSD_OP_SUCCESS, ""
def predict(self, X, window=DEFAULT_WINDOW, model_name=DEFAULT_MODEL):
"""

View File

@ -9,7 +9,7 @@ Unless required by applicable law or agreed to in writing, software distributed
"""
from sklearn.ensemble import IsolationForest
from app.config.common import *
from time_series_detector.common.tsd_common import *
class IForest(object):

View File

@ -12,7 +12,7 @@ import numpy as np
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from app.config.common import *
from time_series_detector.common.tsd_common import *
class PolynomialInterpolation(object):

View File

@ -10,11 +10,10 @@ Unless required by applicable law or agreed to in writing, software distributed
import os
import xgboost as xgb
from app.service.time_series_detector.feature import feature_service
from app.utils.utils import *
from app.config.errorcode import *
from app.config.common import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../../../model/time_series_detector/')
from time_series_detector.feature import feature_service
from time_series_detector.common.tsd_errorcode import *
from time_series_detector.common.tsd_common import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../model/')
DEFAULT_MODEL = MODEL_PATH + "xgb_default_model"
@ -76,7 +75,7 @@ class XGBoosting(object):
try:
f = open(feature_file_name, "w")
except Exception as ex:
return CAL_FEATURE_ERR, str(ex)
return TSD_CAL_FEATURE_ERR, str(ex)
times = 0
for temp in data:
if times > 0:
@ -86,7 +85,7 @@ class XGBoosting(object):
for x in result:
f.write(' ' + x)
times = times + 1
return OP_SUCCESS, ""
return TSD_OP_SUCCESS, ""
def __calculate_features(self, data, feature_file_name, window=DEFAULT_WINDOW):
"""
@ -106,7 +105,7 @@ class XGBoosting(object):
try:
ret_code, ret_data = self.__save_libsvm_format(features, feature_file_name)
except Exception as ex:
ret_code = CAL_FEATURE_ERR
ret_code = TSD_CAL_FEATURE_ERR
ret_data = str(ex)
return ret_code, ret_data
@ -121,12 +120,12 @@ class XGBoosting(object):
model_name = MODEL_PATH + task_id + "_model"
feature_file_name = MODEL_PATH + task_id + "_features"
ret_code, ret_data = self.__calculate_features(data, feature_file_name)
if ret_code != OP_SUCCESS:
if ret_code != TSD_OP_SUCCESS:
return ret_code, ret_data
try:
dtrain = xgb.DMatrix(feature_file_name)
except Exception as ex:
return READ_FEATURE_FAILED, str(ex)
return TSD_READ_FEATURE_FAILED, str(ex)
params = {
'max_depth': self.max_depth,
'eta': self.eta,
@ -143,8 +142,8 @@ class XGBoosting(object):
bst = xgb.train(params, dtrain, num_round)
bst.save_model(model_name)
except Exception as ex:
return TRAIN_ERR, str(ex)
return OP_SUCCESS, ""
return TSD_TRAIN_ERR, str(ex)
return TSD_OP_SUCCESS, ""
def predict(self, X, window=DEFAULT_WINDOW, model_name=DEFAULT_MODEL):
"""

View File

@ -0,0 +1 @@
__all__ = ["tsd_common", "tsd_errorcode"]

View File

@ -1,99 +1,80 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Tencent is pleased to support the open source community by making Metis available.
Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
import numpy as np
import traceback
from functools import wraps
from app.config.errorcode import *
from app.config.common import *
def is_standard_time_series(time_series, window=DEFAULT_WINDOW):
"""
Check the length of time_series. If window = 180, then the length of time_series should be 903.
The mean value of last window should be larger than 0.
:param time_series: the time series to check, like [data_c, data_b, data_a]
:type time_series: pandas.Series
:param window: the length of window
:return: True or False
:return type: boolean
"""
return bool(len(time_series) == 5 * window + 3 and np.mean(time_series[(4 * window + 2):]) > 0)
def split_time_series(time_series, window=DEFAULT_WINDOW):
"""
Spilt the time_series into five parts. Each has a length of window + 1
:param time_series: [data_c, data_b, data_a]
:param window: the length of window
:return: spilt list [[data_c_left], [data_c_right], [data_b_left], [data_b_right], [data_a]]
"""
data_c_left = time_series[0:(window + 1)]
data_c_right = time_series[window:(2 * window + 1)]
data_b_left = time_series[(2 * window + 1):(3 * window + 2)]
data_b_right = time_series[(3 * window + 1):(4 * window + 2)]
data_a = time_series[(4 * window + 2):]
split_time_series = [
data_c_left,
data_c_right,
data_b_left,
data_b_right,
data_a
]
return split_time_series
def normalize_time_series(split_time_series):
"""
Normalize the split_time_series.
:param split_time_series: [[data_c_left], [data_c_right], [data_b_left], [data_b_right], [data_a]]
:return: all list / mean(split_time_series)
"""
value = np.mean(split_time_series[4])
if value > 1:
normalized_data_c_left = list(split_time_series[0] / value)
normalized_data_c_right = list(split_time_series[1] / value)
normalized_data_b_left = list(split_time_series[2] / value)
normalized_data_b_right = list(split_time_series[3] / value)
normalized_data_a = list(split_time_series[4] / value)
else:
normalized_data_c_left = split_time_series[0]
normalized_data_c_right = split_time_series[1]
normalized_data_b_left = split_time_series[2]
normalized_data_b_right = split_time_series[3]
normalized_data_a = split_time_series[4]
normalized_split_time_series = [
normalized_data_c_left,
normalized_data_c_right,
normalized_data_b_left,
normalized_data_b_right,
normalized_data_a
]
return normalized_split_time_series
def build_ret_data(ret_code, data=""):
return {"code": ret_code, "msg": ERR_CODE[ret_code], "data": data}
def exce_service(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
ret_code, ret_data = func(*args, **kwargs)
return_dict = build_ret_data(ret_code, ret_data)
except Exception as ex:
traceback.print_exc()
return_dict = build_ret_data(THROW_EXP, str(ex))
return return_dict
return wrapper
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Tencent is pleased to support the open source community by making Metis available.
Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
import numpy as np
DEFAULT_WINDOW = 180
def is_standard_time_series(time_series, window=DEFAULT_WINDOW):
"""
Check the length of time_series. If window = 180, then the length of time_series should be 903.
The mean value of last window should be larger than 0.
:param time_series: the time series to check, like [data_c, data_b, data_a]
:type time_series: pandas.Series
:param window: the length of window
:return: True or False
:return type: boolean
"""
return bool(len(time_series) == 5 * window + 3 and np.mean(time_series[(4 * window + 2):]) > 0)
def split_time_series(time_series, window=DEFAULT_WINDOW):
"""
Spilt the time_series into five parts. Each has a length of window + 1
:param time_series: [data_c, data_b, data_a]
:param window: the length of window
:return: spilt list [[data_c_left], [data_c_right], [data_b_left], [data_b_right], [data_a]]
"""
data_c_left = time_series[0:(window + 1)]
data_c_right = time_series[window:(2 * window + 1)]
data_b_left = time_series[(2 * window + 1):(3 * window + 2)]
data_b_right = time_series[(3 * window + 1):(4 * window + 2)]
data_a = time_series[(4 * window + 2):]
split_time_series = [
data_c_left,
data_c_right,
data_b_left,
data_b_right,
data_a
]
return split_time_series
def normalize_time_series(split_time_series):
"""
Normalize the split_time_series.
:param split_time_series: [[data_c_left], [data_c_right], [data_b_left], [data_b_right], [data_a]]
:return: all list / mean(split_time_series)
"""
value = np.mean(split_time_series[4])
if value > 1:
normalized_data_c_left = list(split_time_series[0] / value)
normalized_data_c_right = list(split_time_series[1] / value)
normalized_data_b_left = list(split_time_series[2] / value)
normalized_data_b_right = list(split_time_series[3] / value)
normalized_data_a = list(split_time_series[4] / value)
else:
normalized_data_c_left = split_time_series[0]
normalized_data_c_right = split_time_series[1]
normalized_data_b_left = split_time_series[2]
normalized_data_b_right = split_time_series[3]
normalized_data_a = split_time_series[4]
normalized_split_time_series = [
normalized_data_c_left,
normalized_data_c_right,
normalized_data_b_left,
normalized_data_b_right,
normalized_data_a
]
return normalized_split_time_series

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Tencent is pleased to support the open source community by making Metis available.
Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
TSD_OP_SUCCESS = 0
TSD_THROW_EXP = 1000
TSD_CHECK_PARAM_FAILED = 1002
TSD_FILE_FORMAT_ERR = 1003
TSD_CAL_FEATURE_ERR = 2001
TSD_READ_FEATURE_FAILED = 2002
TSD_TRAIN_ERR = 2003
TSD_LACK_SAMPLE = 2004
ERR_CODE = {
TSD_OP_SUCCESS: "操作成功",
TSD_THROW_EXP: "抛出异常",
TSD_CHECK_PARAM_FAILED: "参数检查失败",
TSD_FILE_FORMAT_ERR: "文件格式有误",
TSD_CAL_FEATURE_ERR: "特征计算出错",
TSD_READ_FEATURE_FAILED: "读取特征数据失败",
TSD_TRAIN_ERR: "训练出错",
TSD_LACK_SAMPLE: "缺少正样本或负样本"
}

View File

@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Tencent is pleased to support the open source community by making Metis available.
Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/BSD-3-Clause
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"""
import os
from time_series_detector.algorithm import isolation_forest, ewma, polynomial_interpolation, statistic, xgboosting
from time_series_detector.common.tsd_errorcode import *
from time_series_detector.common.tsd_common import *
MODEL_PATH = os.path.join(os.path.dirname(__file__), './model/')
class Detect(object):
def __init__(self):
self.iforest_obj = isolation_forest.IForest()
self.ewma_obj = ewma.Ewma()
self.polynomial_obj = polynomial_interpolation.PolynomialInterpolation()
self.statistic_obj = statistic.Statistic()
self.supervised_obj = xgboosting.XGBoosting()
def __list_is_digit(self, data):
for index in data:
try:
float(index)
except ValueError:
return False
return True
def __check_param(self, data):
if ("viewName" not in data.keys()) or ("attrId" not in data.keys()) or ("attrName" not in data.keys()) or ("time" not in data.keys()) or ("dataC" not in data.keys()) or ("dataB" not in data.keys()) or ("dataA" not in data.keys()):
return TSD_CHECK_PARAM_FAILED, "missing parameter"
if not data['dataA']:
return TSD_CHECK_PARAM_FAILED, "dataA can not be empty"
if not data['dataB']:
return TSD_CHECK_PARAM_FAILED, "dataB can not be empty"
if not data['dataC']:
return TSD_CHECK_PARAM_FAILED, "dataC can not be empty"
if not self.__list_is_digit(data['dataA'].split(',')):
return TSD_CHECK_PARAM_FAILED, "dataA contains illegal numbers"
if not self.__list_is_digit(data['dataB'].split(',')):
return TSD_CHECK_PARAM_FAILED, "dataB contains illegal numbers"
if not self.__list_is_digit(data['dataC'].split(',')):
return TSD_CHECK_PARAM_FAILED, "dataC contains illegal numbers"
if "window" in data:
window = data["window"]
else:
window = DEFAULT_WINDOW
if len(data['dataC'].split(',')) != (2 * window + 1):
return TSD_CHECK_PARAM_FAILED, "dataC length does not match"
if len(data['dataB'].split(',')) != (2 * window + 1):
return TSD_CHECK_PARAM_FAILED, "dataB length does not match"
if len(data['dataA'].split(',')) != (window + 1):
return TSD_CHECK_PARAM_FAILED, "dataA length does not match"
return TSD_OP_SUCCESS, ""
def value_predict(self, data):
"""
Predict the data
:param data: the time series to detect of
"""
ret_code, ret_data = self.__check_param(data)
if ret_code != TSD_OP_SUCCESS:
return ret_code, ret_data
if "taskId" in data and data["taskId"]:
model_name = MODEL_PATH + data["taskId"] + "_model"
else:
model_name = MODEL_PATH + "xgb_default_model"
combined_data = data["dataC"] + "," + data["dataB"] + "," + data["dataA"]
time_series = map(int, combined_data.split(','))
if "window" in data:
window = data["window"]
else:
window = DEFAULT_WINDOW
statistic_result = self.statistic_obj.predict(time_series)
ewma_result = self.ewma_obj.predict(time_series)
polynomial_result = self.polynomial_obj.predict(time_series, window)
iforest_result = self.iforest_obj.predict(time_series, window)
if statistic_result == 0 or ewma_result == 0 or polynomial_result == 0 or iforest_result == 0:
xgb_result = self.supervised_obj.predict(time_series, window, model_name)
res_value = xgb_result[0]
prob = xgb_result[1]
else:
res_value = 1
prob = 1
ret_data = {"ret": res_value, "p": str(prob)}
return TSD_OP_SUCCESS, ret_data
def rate_predict(self, data):
"""
Predict the data
:param data: the time series to detect of
"""
combined_data = data["dataC"] + "," + data["dataB"] + "," + data["dataA"]
time_series = map(float, combined_data.split(','))
statistic_result = self.statistic_obj.predict(time_series)
if statistic_result == 0:
prob = 0
else:
prob = 1
ret_data = {"ret": statistic_result, "p": str(prob)}
return TSD_OP_SUCCESS, ret_data

View File

@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed
import statistical_features
import classification_features
import fitting_features
from app.utils import utils
from time_series_detector.common import tsd_common
def extract_features(time_series, window):
@ -25,15 +25,15 @@ def extract_features(time_series, window):
:return: the value of features
:return type: list with float
"""
if not utils.is_standard_time_series(time_series, window):
if not tsd_common.is_standard_time_series(time_series, window):
# add your report of this error here...
return []
# spilt time_series
split_time_series = utils.split_time_series(time_series, window)
split_time_series = tsd_common.split_time_series(time_series, window)
# nomalize time_series
normalized_split_time_series = utils.normalize_time_series(split_time_series)
normalized_split_time_series = tsd_common.normalize_time_series(split_time_series)
s_features = statistical_features.get_statistical_features(normalized_split_time_series[4])
f_features = fitting_features.get_fitting_features(normalized_split_time_series)
c_features = classification_features.get_classification_features(normalized_split_time_series[0] + normalized_split_time_series[1][1:] + normalized_split_time_series[2] + normalized_split_time_series[3][1:] + normalized_split_time_series[4])

View File

@ -9,7 +9,7 @@ Unless required by applicable law or agreed to in writing, software distributed
"""
import numpy as np
from app.config.common import *
from time_series_detector.common.tsd_common import *
def time_series_moving_average(x):