Example #1
0
def load_vec_data(db, cameo=""):
    """
    传入事件cameo号,到cameo号对应的列表中加载所有事件短句向量
    :param cameo:(str)事件cameo号
    """
    # 游标对象
    cursor = db.cursor()
    # 定义好sql语句,%s是字符串的占位符
    if cameo and cameo is not None:
        sql = f"select * from event_vec_table where cameo='{cameo}'"
    else:
        sql = "select * from event_vec_table"
    # 数据向量字典
    data = {}
    try:
        # 执行sql语句
        cursor.execute(sql)
        # 获取所有结果集
        results = cursor.fetchall()
        for once in results:
            # 将读取到的字节流转化为ndarray数组
            try:
                numArr = np.array(json.loads(bytes.decode(bytes(once[2], encoding="utf-8"))), dtype=np.float32)
            except:
                numArr = np.array(json.loads(bytes.decode(bytes(once[2], encoding="gbk"))), dtype=np.float32)
            data[once[1]] = numArr
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        raise trace

    finally:
        cursor.close()

    return data
def get_event_cameo(cameo_model, events: list):
    """
    传入事件cameo模型和事件列表,判断每个事件的cameo,并添加到事件列表中
    :param cameo_model:事件cameo模型
    :param events:(list) 事件列表
    :return:events(list)事件列表
    :raise:TypeError 事件列表类型
    """
    if not isinstance(events, list):
        logger.error("用于预测事件cameo的事件列表类型错误!")
        raise TypeError

    # 遍历事件列表
    with cameo_sess.as_default():
        with cameo_sess.graph.as_default():
            for event in events:
                # 使用将主、谓、宾、否定词拼接为事件短句,预测事件cameo
                short_sentence = "".join([event["subject"], event["negative_word"], event["verb"], event["object"]])
                # 使用bert分字器对事件短句进行分字并ids化
                token_ids, segment_ids = TOKENIZER.encode(first_text=short_sentence)
                # 转化为数组,模型预测需要ndarray
                token_ids, segment_ids = np.array([token_ids]), np.array([segment_ids])
                # 获取cameo预测值 [[0.001,0.002,0.005,0.2,0.100,0.51]]
                event_cameo = cameo_model.predict([token_ids, segment_ids])
                # 获取cameo的id [cameo_id]
                event_cameo = np.argmax(event_cameo, axis=1)
                event_id = event_cameo[0]
                # 根据cameo_id获取cameo
                event["cameo"] = ID2CAMEO[f"{event_id}"]

    return events
Example #3
0
def load_vec_data(cameo: str):
    """
    传入事件cameo号,到cameo号对应的列表中加载所有事件短句向量
    :param cameo:(str)事件cameo号
    :return:data(dict){事件id:向量}
    :raise:TypeError FileNotFoundError
    """
    # 需要读取向量的文件路径
    read_file_path = cat_path(pre_config.vec_data_dir, f"{cameo}.npy")

    data = {}
    # 判断文件是否存在,不存在则返回空值
    if not os.path.exists(read_file_path):
        return data
    # 如果字典文件缺失则报错
    elif not os.path.exists(pre_config.cameo2id_path):
        logger.error("cameo映射事件向量的字典文件缺失!")
        raise FileNotFoundError

    else:
        # cameo2id 字典 {cameo:[]}
        cameo2id = comm.read_cameo2id(pre_config.cameo2id_path)

        # 读取文件中的向量
        x = comm.read_np(read_file_path)

        for key, value in zip(cameo2id[cameo], x):
            data[key] = value

        return data
Example #4
0
    def evaluate(sentence):
        """
        传入句子,调用模型对句子中的事件进行抽取,并添加实体信息。
        :param sentence: (str)待抽取事件的句子
        :return: results(list)事件列表
        :raise:TypeError
        """
        if not isinstance(sentence, str) or not sentence:
            logger.error("待抽取事件的句子格式错误,应该使用字符串格式且不能为空!")
            raise TypeError

        # 传入模型和句子进行事件抽取
        events = extract_items(sentence, state_model, trigger_model, object_model, subject_model, loc_model,
                               time_model,
                               negative_model)

        results = []
        for event in events:
            if not event['subject'] and not event['object']:
                continue
            else:
                results.append(event)
        # 对得到的事件列表进行实体信息补充
        results = get_ners_lac(results)

        return results
def generate_trained_model_path(trained_model_dir: str,
                                trained_model_name: str):
    """
    传入模型保存文件夹,和训练后模型名称,按照日期生成模型保存文件夹,并生成模型保存路径,返回模型保存路径
    :param trained_model_dir: (str)模型保存文件夹
    :param trained_model_name: (str)模型名称
    :return: trained_model_path(str)模型保存路径
    :raise:ValueError 文件夹不存在或者模型命名不以.h5结尾
    """
    # 判断保存训练后模型的文主文件夹是否存在,不存在则报错
    if not os.path.exists(trained_model_dir) or not os.path.isdir(
            trained_model_dir):
        logger.error(f"{trained_model_dir} is wrong!")
        raise ValueError
    # 模型不以.h5结尾则报错
    if not trained_model_name.endswith(".h5"):
        logger.error(f"{trained_model_name} must end with .h5")
        raise ValueError
    # 按照当前时间年月日生成文件夹,构建训练后模型的保存位置
    trained_model_dir = cat_path(
        trained_model_dir,
        time.strftime('%Y-%m-%d', time.localtime(time.time())))
    trained_model_path = cat_path(trained_model_dir, trained_model_name)
    # 如果文件夹不存在则生成
    if not os.path.exists(trained_model_dir):
        os.mkdir(trained_model_dir)

    return trained_model_path
Example #6
0
def worker():
    """
    预测模块,对主队列传入的文本进行处理及事件匹配预测,通过子队列将结果返回
    :return: None
    """
    try:
        from jdqd.a01.event_match.algor.predict.execute import load_match_model, get_events, get_predict_result

        # 加载事件匹配模型
        model = load_match_model()
        # 获取事件列表
        event_list = get_events()
    except:
        trac = traceback.format_exc()
        logger.error(trac)
        raise trac

    while True:

        # 获取数据和子队列
        logger.info("从主队列获取信息。。。")
        content, sample_type, sub_queue = main_queue.get()
        try:
            logger.info("开始进行事件识别。。。")
            content_pred = get_predict_result(model, event_list, content,
                                              sample_type)

            sub_queue.put((True, content_pred))
        except:
            # 通过子队列发送异常信息
            trace = traceback.format_exc()
            sub_queue.put((False, trace))

            continue
Example #7
0
def vev_delete():
    """
    事件向量化接口,从前端接收事件id,将事件从事件cameo字典以及npy文件中删除。
    :return: 删除状态
    :raise:事件id为空--ValueError
    """
    if request.method == "GET":
        # 事件id
        event_id = request.args.get("event_id", type=str, default=None)
    else:
        # 事件id
        event_id = request.form.get("event_id", type=str, default=None)

    try:
        # 判断短句是否为空
        judge("event_id", event_id)
        # 删除事件id以及对应的向量
        delete_vec.execute_delete(DB, event_id)
        # 删除向量字典中的向量
        del VEC_DATA[event_id]
        for cameo in CAMEO2ID:
            if event_id in CAMEO2ID[cameo]:
                CAMEO2ID[cameo].remove(event_id)

        return jsonify(status="success", message="success")
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        jsonify(status="failed", message=str(trace))
def get_abstract(content: str, n=3):
    """
    传入清洗后的文章内容,分别使用text rank 和mmr方法提取文章摘要,返回摘要语句列表
    :param content: (str)清洗后的文本字符串
    :return: summary_sentences(list) 摘要句子列表
    :raise: TypeError
    """
    if not isinstance(content, str):
        logger.error("待抽取摘要的内容格式错误!")
        raise TypeError

    # 摘要句子列表
    summary_sentences = []
    # 使用mmr方式抽取的摘要句子列表
    mmr_summary_sentences = mmr_subtract(content, n)
    # 使用text rank抽取的摘要句子列表
    text_rank_summary_sentences = text_rank_subtract(content, n)

    summary_sentences.extend(mmr_summary_sentences)
    summary_sentences.extend(text_rank_summary_sentences)

    # 将句子中的空格剔除
    summary_sentences = [
        once.replace(" ", "") for once in summary_sentences if once
    ]
    summary_sentences = list(set(summary_sentences))

    return summary_sentences
Example #9
0
def model_predict():
    """
    模型预测接口。该接口完成了三个主要步骤:构建数据集、模型预测。
    1、构建数据集。获取数据库中指定的预测数据,并且对数据集进行转换;
    2、模型预测。使用指定的模型及数据集进行预测,预测结果记录到数据库。
    返回数据,如:{"status":"success"}
    """
    task_id = request.form.get("task_id")
    logger.info(f"开始根据模型预测id<{task_id}>数据进行预测")
    try:
        # 查询t_event_task表,获取模型任务信息,该方法返回的是EventTask实体
        event_task = query_teventtask_by_id(task_id)
        # 1、构建数据集。获取数据库中指定的预测数据,并且对数据集进行转换;
        dates, data = combine_data(event_task.tables_name)
        data = data.values
        events_set, events_p_oh = get_event(dates, event_task.event_type)
        # 2、模型预测。使用指定的模型及数据集进行预测,预测结果记录到数据库。
        update_task_status(task_id, ModelStatus.PROCESSING.value)   # 任务状态修改为运行中
        last_date_data_pred = predict_by_model(event_task.model_id, data, dates, events_set, task_id,
                                               event_task.sample_start_date, event_task.model_type, event_task.event)
        predict_task_finish(task_id, last_date_data_pred, ModelStatus.SUCCESS.value)    # 任务状态修改为完成/成功
        logger.info(f"模型id<{event_task.model_id}>的预测完成")
        return {"success": True}
    except Exception as e:
        logger.error(f"表 id {task_id} 预测发生异常:{traceback.format_exc()}")
        predict_task_finish(task_id, "", ModelStatus.FAILD.value)   # 任务状态修改为失败
        return {"success": False, "exception": e}
    finally:
        K.clear_session()
Example #10
0
def load_cameo_dict(db):
    """
    传入数据库连接,获取数据库中的向量,获取其中所有的cameo,id用于构造cameo2id字典
    :return:data(dict){cameo:[event_id]}
    """
    # 游标对象
    cursor = db.cursor()
    # 定义好sql语句,%s是字符串的占位符
    sql = "select * from event_vec_table"
    # 数据向量字典
    data = {}
    try:
        # 执行sql语句
        cursor.execute(sql)
        # 获取所有结果集
        results = cursor.fetchall()
        for once in results:
            event_ids = data.setdefault(once[0], [])
            event_ids.append(once[1])
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        raise trace
    finally:
        cursor.close()

    return data
Example #11
0
def read_cameo2id(file_path: str):
    """
    传入json文件路径,读取文件内容,返回json解析后的数据。
    :param file_path: (str)json文件路径
    :return: data 读取得到的文章内容
    :raise: ValueError 如果不是json文件则报错
    """
    # 判断文件是否为.json文件
    if not os.path.exists(file_path) or os.path.isdir(
            file_path) or not file_path.endswith(".json"):
        logger.error(f"{file_path} 文件错误!")
        raise ValueError

    # 因为多线程,所有循环读取字典内容
    while True:

        try:
            with open(file_path, "r", encoding="utf-8") as file:
                content = file.read()
        except TypeError:
            with open(file_path, "r", encoding="gbk") as file:
                content = file.read()

        # 读取到内容则跳出循环
        if content and content is not None:
            try:
                data = json.loads(content)
            except:
                continue
            break

    return data
Example #12
0
def test_loguru():
    os.environ['LOGURU_LEVEL'] = "INFO"
    from loguru import logger

    logger.debug(f"调试 {datetime.datetime.now()}")
    logger.info(f"信息提示 {datetime.datetime.now()}")
    logger.warning(f"警告 =======  {datetime.datetime.now()}")
    logger.error(f"错误 !!!!!!  {datetime.datetime.now()}")
Example #13
0
def execute(raw_dir, target_dir):
    """
    传入原始标注数据文件夹路径和解析后文件存放的路径,按照时间生成json文件名称,将解析好的数据保存到目标文件夹
    :param raw_dir: 存放原始标注数据的文件夹
    :param target_dir: 存放解析后数据的文件夹
    :return: status--解析状态, corpus_num--数据量
    """
    # 存放所有解析后的数据
    all_datas = []
    # 语料中的句子数量
    all_sentence_num = 0
    # 语料中的事件数量
    all_event_num = 0

    try:
        # 判断数据路径是否正确
        if valid_dir(raw_dir):
            # 判断目标文件夹路径是否存在,不存在则创建
            if not valid_dir(target_dir):
                os.makedirs(target_dir)
            file_name = f"{time.strftime('%Y-%m-%d', time.localtime(time.time()))}.json"
            target_file_path = cat_path(target_dir, file_name)
            # 获取文件夹下所有文件的名称
            file_names = os.listdir(raw_dir)
            file_names = list(
                set(file_name.split(".")[0] for file_name in file_names))
            # 遍历文件进行解析
            for file_name in tqdm(file_names):
                file_path = os.path.join(raw_dir, file_name)
                # 判断两个文件是否都同时存在
                if valid_file(f"{file_path}.ann") and valid_file(
                        f"{file_path}.txt"):

                    # 解析文件获取事件和文件中的句子以及事件数量
                    data, sentence_num, event_num = data_process(file_path)
                    all_datas.extend(data)
                    all_sentence_num += sentence_num
                    all_event_num += event_num

            logger.info(f"总共有句子:{all_sentence_num},总共有事件:{all_event_num}")
            # 将解析后的数据保存到目标文件
            save_json(all_datas, target_file_path)

            return {
                "status": "success",
                "results": {
                    "sentences": all_sentence_num,
                    "events": all_event_num
                }
            }

        else:
            logger.error(f"存放原始标注数据的文件夹:{raw_dir}没有找到")
            raise FileNotFoundError
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        return {"status": "failed", "results": trace}
Example #14
0
def judge(name, data):
    """
    传入数据,判断是否为空
    :param name: 数据名称
    :param data: 数据
    :return: None
    """
    if not data or data is None:
        logger.error(f"{name} is None!")
        raise ValueError
Example #15
0
def test_mylog():
    os.environ['HR_RUN_PROD'] = "y"
    os.environ['HR_LOG_FILE'] = "/tmp/logger-test.log"
    os.environ['HR_LOG_FILE_LEVEL'] = "ERROR"
    os.environ['HR_LOG_CONSOLE'] = "y"
    from feedwork.utils import logger

    logger.debug(f"调试 {datetime.datetime.now()}")
    logger.info(f"信息提示 {datetime.datetime.now()}")
    logger.warning(f"警告 =======  {datetime.datetime.now()}")
    logger.error(f"错误 !!!!!!  {datetime.datetime.now()}")
def translate_any_2_anyone(article, target="en"):
    """
    临时用的,将任意语言的文章翻译为英文

    :param article: String.文章
    :param target: String.可选值有en、zh等

    """
    url = config.translate_url
    article_t = ""
    try:
        article_detect = detect(article)
        if article_detect == 'ja' or article_detect == 'zh-cn':
            article_array = article.split("。")
            for sentence in article_array:
                data = {
                    "from": "auto",
                    "to": target,
                    "apikey": config.translate_user_key,
                    "src_text": sentence
                }
                cur_time = date_util.sys_date("%Y-%m-%d %H:%M:%S")
                logger.info(f"-----------翻译句子开始----------- : {cur_time}")
                res = http_post(data, url)
                cur_time = date_util.sys_date("%Y-%m-%d %H:%M:%S")
                logger.info(f"-----------翻译句子结束----------- : {cur_time}")
                res_dict = json.loads(res)
                if "tgt_text" in res_dict:
                    content = res_dict['tgt_text']
                    article_t += content + ". "
        else:
            article_array = article.split(".")
            for sentence in article_array:
                data = {
                    "from": "auto",
                    "to": target,
                    "apikey": config.translate_user_key,
                    "src_text": sentence
                }
                cur_time = date_util.sys_date("%Y-%m-%d %H:%M:%S")
                logger.info(f"-----------翻译句子开始----------- : {cur_time}")
                res = http_post(data, url)
                cur_time = date_util.sys_date("%Y-%m-%d %H:%M:%S")
                logger.info(f"-----------翻译句子结束----------- : {cur_time}")
                res_dict = json.loads(res)
                if "tgt_text" in res_dict:
                    content = res_dict['tgt_text']
                    article_t += content + ". "
        return article_t
    except HTTPError as e:
        logger.error('翻译时发生的错误:', e)
        return ''
Example #17
0
    def coref_(query: str):
        """
        对传入的英文字符串进行指代消解,并返回消解后的文本
        指代消解--翻译--中文
        :param query:(str)待消解的英文字符串
        :return:spacy_data(str)指代消解后并翻译成中文的字符串
        :raise:TypeError
        """
        if not isinstance(query, str) or not query:
            logger.error("待消解的内容格式错误,应该是字符串格式,且不能为空!")
            raise TypeError

        # 消除朝鲜和韩国的指代消歧问题,对两个国家进行指代符替换
        # 防止指代消解因朝鲜韩国出现问题,提前将二者替换为NK SK,如果二者同时存在则只替换一个
        if "North Korea" in query:
            query = query.replace("North Korea", "NK")
        elif "South Korea" in query:
            query = query.replace("South Korea", "SK")

        # 指代消解
        spacy_data = coref_spacy.coref_data(nlp, query)

        # 限制字符翻译
        temp = ''
        data = []
        for once in nlp(spacy_data).sents:
            if len(temp) + len(str(once)) < 2000:
                temp = f"{temp} {str(once)}"
            else:
                # 使用免费接口进行翻译,报错则使用收费接口
                trans = free_transform_any_2_zh(temp)
                if type(trans) != str:
                    trans = transform_any_2_zh(temp)
                data.append(trans)
                temp = str(once)

        # 使用免费接口进行翻译,报错则使用收费接口
        trans = free_transform_any_2_zh(temp)
        if type(trans) != str:
            trans = transform_any_2_zh(temp)
        data.append(trans)

        # 将翻译内容拼接为字符串
        spacy_data = "".join(data)

        if "SK" in spacy_data:
            spacy_data = spacy_data.replace("SKn", "韩国").replace("SK", "韩国")
        elif "NK" in spacy_data:
            spacy_data = spacy_data.replace("NKn", "朝鲜").replace("NK", "朝鲜")

        return spacy_data
Example #18
0
def get_data(train_data_path: str, dev_data_path: str, label2id_path: str, id2label_path: str):
    """
    传入训练集、验证集、标签字典路径,读取json文件内容,训练集、验证集数据以及标签字典。
    :param train_data_path:(str)训练集数据路径
    :param dev_data_path:(str)验证集数据路径
    :param label2id_path:(str)label2id字典路径
    :param id2label_path:(str)id2label字典路径
    :return:train_data(list)、dev_data(list)、label2id(dict)、id2label(dict)
    """
    if not valid_file(train_data_path):
        logger.error(f"训练数据{train_data_path} 路径错误!")
    elif not valid_file(dev_data_path):
        logger.error(f"验证数据{dev_data_path} 路径错误!")
    elif not valid_file(label2id_path):
        logger.error(f"cameo2id文件{label2id_path} 路径错误!")
    elif not valid_file(id2label_path):
        logger.error(f"id2cameo文件{id2label_path} 路径错误!")

    # 加载训练数据集
    train_data = read_json(train_data_path)
    # 加载验证集
    dev_data = read_json(dev_data_path)
    # 加载标签字典
    label2id = read_json(label2id_path)
    id2label = read_json(id2label_path)
    # 构造模型训练数据集[(sentence, cameo), ]
    train_data = [(data, label2id[label]) for data, label in list(train_data.items())]
    # 构造模型验证数据集[(sentence, cameo), ]
    dev_data = [(data, label2id[label]) for data, label in list(dev_data.items())]

    return train_data, dev_data, label2id, id2label
Example #19
0
def event_match():
    """
    事件匹配,从前端获取事件短句、cameo编号、相似度阈值
    :return: 匹配结果给前端
    :raise:ValueError如果短句为空
    """
    if request.method == "GET":
        # 事件短句,由主语、谓语、否定词、宾语组成
        short_sentence = request.args.get("short_sentence",
                                          type=str,
                                          default=None)
        # 事件cameo号
        cameo = request.args.get("cameo", type=str, default=None)
        # 相似度阈值
        threshold = request.args.get("threshold", type=float, default=0.5)
    else:
        # 事件短句,由主语、谓语、否定词、宾语组成
        short_sentence = request.form.get("short_sentence",
                                          type=str,
                                          default=None)
        # 事件cameo号
        cameo = request.form.get("cameo", type=str, default=None)
        # 相似度阈值
        threshold = request.form.get("threshold", type=float, default=0.5)

    # 默认阈值为0.5
    if not threshold or threshold is None:
        threshold = 0.5

    try:
        # 判断短句是否为空
        judge("short_sentence", short_sentence)
        # 短句向量化
        main_vec = load_model.generate_vec(TOKENIZER, BERT_MODEL,
                                           short_sentence)
        # 最终的结果
        results = []
        for once in CAMEO2ID[cameo]:
            score = load_model.vec_match(main_vec, VEC_DATA[once], MATCH_MODEL)
            if score >= threshold:
                results.append({"event_id": once, "score": float(score)})
        # 对输出的结果按照降序排序
        results.sort(key=lambda x: x["score"], reverse=True)
        return jsonify(status="success", result=results)
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        return jsonify(status="failed", result=trace)
Example #20
0
def coref_data(nlp, line: str):
    """
    传入nlp模型和待消解的英文字符串,对英文文本进行指代消解,返回消解后的字符串。
    :param nlp: 指代消解模型对象
    :param line: (str)待消解的文本
    :return: res(str)消解后的文本
    """
    if not isinstance(line, str):
        logger.error("The type of content for coreference must be string!")
        raise TypeError
    # 调用模型传入待消解的文本
    doc = nlp(line)
    # 调用指代消解方法,得到指代消解后的文本内容
    res = doc._.coref_resolved

    return res
Example #21
0
def save_json(content, file_path: str):
    """
    传入需要保存的数据,将数据转换为json字符串保存到指定路径file_path
    :param content: 需要保存的数据
    :param file_path: (str)指定路径
    :return: None 无返回值
    :raise: ValueError 如果不是json文件则报错
    """
    # 判断是否保存为.json
    if not file_path.endswith(".json"):
        logger.error(f"{file_path} 需保存为.json文件")
        raise ValueError

    # 将列表或者字典处理成json字符串
    content = json.dumps(content, ensure_ascii=False, indent=4)
    with open(file_path, "w", encoding="utf-8") as file:
        file.write(content)
Example #22
0
def load_vec_data(vector_data_dir: str):
    """
    传入向量数据保存的文件夹,加载所有的向量数据到内存中。
    :param vector_data_dir: (str)向量数据保存的文件夹
    :return: vec_data(dict)向量数据字典
    :raise:ValueError 保存向量的文件夹路径不是文件夹或者不存在
    """
    if not os.path.exists(vector_data_dir) or os.path.isfile(vector_data_dir):
        logger.error(f"{vector_data_dir}向量保存文件夹错误!")
        raise ValueError
    # 将所有向量加载到内存中
    vec_data = {}
    file_list = os.listdir(vector_data_dir)
    for file in file_list:
        vec_data["{}".format(file)] = np.load(cat_path(vector_data_dir, file))

    return vec_data
Example #23
0
def event_vectorization():
    """
    事件向量化接口,从前端接收短句、cameo编号、事件id,将事件向量化保存到文件中。
    :return: 保存状态
    :raise:事件短句、事件id为空--ValueError
    """
    if request.method == "GET":
        # 事件短句,由主语、谓语、否定词、宾语组成
        short_sentence = request.args.get("short_sentence",
                                          type=str,
                                          default=None)
        # 事件cameo号
        cameo = request.args.get("cameo", type=str, default=None)
        # 事件id
        event_id = request.args.get("event_id", type=str, default=None)
    else:
        # 事件短句,由主语、谓语、否定词、宾语组成
        short_sentence = request.form.get("short_sentence",
                                          type=str,
                                          default=None)
        # 事件cameo号
        cameo = request.form.get("cameo", type=str, default=None)
        # 事件id
        event_id = request.form.get("event_id", type=str, default=None)

    try:
        # 判断短句是否为空
        judge("short_sentence", short_sentence)
        # 判断cameo是否为空
        judge("cameo", cameo)
        # 判断事件id是否为空
        judge("event_id", event_id)
        # 事件短句向量化
        main_vec = load_model.generate_vec(TOKENIZER, BERT_MODEL,
                                           short_sentence)
        # 向量保存
        save_vec.save_vec_data(DB, cameo, event_id, main_vec)
        # 加载到向量字典中
        VEC_DATA[event_id] = main_vec
        event_ids = CAMEO2ID.setdefault(cameo, [])
        event_ids.append(event_id)
        return jsonify(status="success", message="success")
    except:
        trace = traceback.format_exc()
        logger.error(trace)
        return jsonify(status="failed", message=str(trace))
Example #24
0
def get_bert_tokenizer(dict_path: str):
    """
    传入字典路径,读取字典内容,并使用字典初始化分字器,返回分字器对象
    :param dict_path: (str)字典路径
    :return: tokenizer(object)分字器
    :raise: ValueError 如果字典文件不存在或者字典文件不是.txt文件
    """
    if not os.path.exists(dict_path) or os.path.isdir(
            dict_path) or not dict_path.endswith(".txt"):
        logger.error(f"{dict_path} bert 字典文件损坏!")
        raise ValueError

    # 加载bert字典
    token_dict = get_token_dict(dict_path)
    # 构建tokenizer类
    tokenizer = OurTokenizer(token_dict)

    return tokenizer
Example #25
0
def file_list_indir(root_dir, index_mdfile):
    # root_dir目录下必须存在被检查的索引文件
    if not os.path.isfile(os.path.join(root_dir, index_mdfile)):
        logger.error(f"{index_mdfile} is not real file")
        return None

    file_list = []
    for cur_root_dir, sub_dirs, filenames in os.walk(root_dir):
        #    for file in glob.glob(f"{root_dir}/*"):
        for filename in filenames:
            if filename == index_mdfile:
                continue
            cur_file = os.path.join(cur_root_dir,
                                    filename)  # 每个文件名,都是 root_dir 开头的

            file_list.append(os.path.join(cur_root_dir, filename))
            logger.info(f"file={filename}")
    return file_list
def get_ners_lac(events: list):
    """
    传入事件列表,将事件论元拼接为字符串,使用lac抽取事件中的实体名词,补充到事件列表中
    :param events: (list)事件列表
    :return: events (list)补充实体成分后的事件字典列表
    :raise:TypeError 事件列表类型错误
    """
    if not isinstance(events, list):
        logger.error("用于抽取实体的事件列表类型错误!")
        raise TypeError

    # 遍历事件列表
    for event in events:
        # 获取事件所有论元,拼接成事件句子
        sentence = ''.join([event[i] for i in event.keys() if i != 'state' and i != 'triggerloc_index'])
        # 使用hanlp对事件句子进行实体识别
        words = lac.run(sentence)
        # 在事件字典中加入namedentity
        event["namedentity"] = {'organization': [], 'location': [], 'person': []}

        # 遍历实体识别后的词
        for word, ner in zip(words[0], words[1]):
            # 判断是否为地点实体
            if ner == "LOC":
                if str(word) in event["namedentity"]["location"]:
                    pass
                else:
                    event["namedentity"]["location"].append(str(word))
            # 判断是否为人物实体
            elif ner == "PER":
                if str(word) in event["namedentity"]["person"]:
                    pass
                else:
                    event["namedentity"]["person"].append(str(word))
            # 判断是否为机构实体
            elif ner == "ORG":
                if str(word) in event["namedentity"]["organization"]:
                    pass
                else:
                    event["namedentity"]["organization"].append(str(word))

    return events
Example #27
0
def load_data(file_path: str):
    """
    传入文件路径,按行读取文件内容,去除换行符,返回数据列表
    :param file_path: (str)数据保存路径
    :return: data(list)数据列表
    :raise:ValueError
    """
    if not os.path.exists(file_path) or os.path.isdir(file_path):
        logger.error(f"{file_path} 文件路径错误!")
        raise ValueError
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            data = f.readlines()
    except TypeError:
        with open(file_path, "r", encoding="gbk") as f:
            data = f.readlines()
    # 按行读取样本
    data = [once.replace("\n", "") for once in data if once]

    return data
Example #28
0
def reload_model():
    """
    从前端接收模型路径,重新加载模型
    :return: status 加载状态
    """
    # 模型路径字典
    model_path = {"extract": "", "cameo": "", "state": ""}

    if request.method == "POST":
        model_path["extract"] = request.form.get("extract", type=str, default=None)
        model_path["cameo"] = request.form.get("cameo", type=str, default=None)
        model_path["state"] = request.form.get("state", type=str, default=None)
        model_version = request.form.get("version", type=str, default=None)
        model_id = request.form.get("model_id", type=str, default=None)
    else:
        model_path["extract"] = request.args.get("extract", type=str, default=None)
        model_path["cameo"] = request.args.get("cameo", type=str, default=None)
        model_path["state"] = request.args.get("state", type=str, default=None)
        model_version = request.args.get("version", type=str, default=None)
        model_id = request.args.get("model_id", type=str, default=None)

    try:
        logger.info("开始重载模型参数。。。")
        for model_type in model_path:
            if model_path[model_type] != None and not model_path[model_type]:
                if os.path.exists(model_path[model_type]):
                    exec(
                        f"model_path[{model_type}] = cat_path(model_path[{model_type}], {model_type}_model_{model_version}_{model_id}.h5)")
                    exec(f"PredictConfig.event_{model_type}_model_path = model_path[{model_type}]")
                    exec(f"get_{model_type}_model()")
                else:
                    logger.error(f"{model_type}模型路径:{model_path[model_type]}错误,请重新传入!")
                    raise ValueError
        logger.info("模型参数重载完成!")
        return jsonify(status="success")

    except:
        trace = traceback.format_exc()
        logger.error(trace)

        return jsonify(status="error", message=trace)
Example #29
0
def generate_vec(tokenizer, bert_model, sentence: str):
    """
    传入bert分词器、bert模型对象、待向量化的中文句子,对句子进行编码,然后使用bert进行向量化。
    :param tokenizer:分字器
    :param bert_model:模型对象
    :param sentence:(str)待向量化的句子
    :return:x(ndarray)句子向量(768,)
    :raise: TypeError
    """
    if not isinstance(sentence, str):
        logger.error("待向量化的句子格式错误,应该使用字符串格式!")
        raise TypeError

    # 句子编码, 按照最大长度切分
    token_ids, segment_ids = tokenizer.encode(first_text=sentence[:pre_config.maxlen])
    with SESS_1.as_default():
        with SESS_1.graph.as_default():
            # 句子向量
            x = bert_model.predict([np.array([token_ids]), np.array([segment_ids])])[0][0]

    return x
Example #30
0
def get_token_dict(dict_path: str):
    """
    传入bert字典路径,按行读取文件内容,返回字典
    :param dict_path: (str)字典文件路径
    :return: token_dict(dict)模型字典
    """
    if not os.path.exists(dict_path) or os.path.isdir(
            dict_path) or not dict_path.endswith(".txt"):
        logger.error(f"{dict_path} bert 字典文件损坏!")
        raise ValueError

    token_dict = {}
    # 加载模型对应的字典
    with codecs.open(dict_path, 'r', 'utf8') as reader:
        # 遍历读取文件内容的每一行
        for line in reader:
            token = line.strip()
            # 将字典的长度作为字符的id
            token_dict[token] = len(token_dict)

    return token_dict