mirror of
https://github.com/Tencent/Metis.git
synced 2025-12-25 19:52:49 +00:00
refactor(app): refactor dictionary
This commit is contained in:
parent
e831610019
commit
5faf04cf06
|
|
@ -1 +0,0 @@
|
|||
__all__ = ["config", "controller", "dao", "model", "service", "utils"]
|
||||
|
|
@ -0,0 +1 @@
|
|||
__all__ = ["common", "errorcode"]
|
||||
|
|
@ -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
|
||||
|
|
@ -32,4 +32,4 @@ ERR_CODE = {
|
|||
READ_FEATURE_FAILED: "读取特征数据失败",
|
||||
TRAIN_ERR: "训练出错",
|
||||
LACK_SAMPLE: "缺少正样本或负样本"
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
__all__ = ["database", "common", "errorcode"]
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__all__ = ["time_series_detector"]
|
||||
__all__ = ["db_common", "time_series_detector"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
__all__ = ["database"]
|
||||
|
|
@ -1 +1 @@
|
|||
__all__ = ["anomaly_op", "sample_op", "train_op"]
|
||||
__all__ = ["anomaly_op", "sample_op", "train_op"]
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__all__ = ["time_series_detector"]
|
||||
|
|
@ -1 +1 @@
|
|||
__all__ = ["time_series_detector"]
|
||||
__all__ = ["time_series_detector"]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__all__ = ["algorithm", "feature", "anomaly_service", "sample_service", "task_service", "detect_service"]
|
||||
__all__ = ["anomaly_service", "sample_service", "task_service", "detect_service"]
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__all__ = ["utils"]
|
||||
|
|
@ -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文件夹
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
@ -0,0 +1 @@
|
|||
__all__ = ["fixtures", "test_feature"]
|
||||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
__all__ = ["algorithm", "feature", "common", "detect"]
|
||||
|
|
@ -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):
|
||||
|
|
@ -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):
|
||||
"""
|
||||
|
|
@ -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):
|
||||
|
|
@ -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):
|
||||
|
|
@ -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):
|
||||
"""
|
||||
|
|
@ -0,0 +1 @@
|
|||
__all__ = ["tsd_common", "tsd_errorcode"]
|
||||
|
|
@ -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
|
||||
|
|
@ -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: "缺少正样本或负样本"
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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])
|
||||
|
|
@ -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):
|
||||
Loading…
Reference in New Issue