Skip to content

Latest commit

 

History

History
171 lines (121 loc) · 7.33 KB

README.md

File metadata and controls

171 lines (121 loc) · 7.33 KB

概述

在NLP的序列标注任务里面,NER是基础的上游任务,也就意味着,业界许多垂直领域的NLP项目,NER是绕不开的任务。今天的这篇博客,笔者不想涉及深入的算法和数学知识,仅就在代码实现层面,对有监督的NER训练,做一些介绍。对于NER一知半解的读者,可以移步笔者的另一篇博文——《命名实体识别概述》

技能要求

  1. Python 3
  2. Keras框架
  3. Log、Matplotlib、TensorFlow等辅助工具

项目目标

  1. 根据已经标记的NER数据集,训练得到NER模型;
  2. 用NER模型,预测新数据;

项目目录

➜  Keras-NER tree
.
├── __init__.py
├── config.py # 配置文件,项目的常量和超参数
├── keras_run.py # 项目的执行文件
├── log # 日志
│   ├── __pycache__
│   │   └── log.cpython-36.pyc
│   ├── log.py
│   └── logging.log
├── model # 训练好的模型权重
│   └── best.model.weight
├── model.py # 模型,提供训练、预测
├── resource # 数据集
│   ├── predict.txt
│   ├── predict_label.txt
│   ├── source.txt
│   ├── source_vocb.txt
│   ├── target.txt
│   └── tgt_vocb.txt
└── utils.py

5 directories, 18 files

项目

数据集

  1. 训练的原始数据
新华社 北京 六月 十日  中宣部教育部团中央  全国学联 近日 联合 发出通知决定 今年 暑期 继续 深入开展 大中学生 志愿者 文化科技卫生三下乡活动三年  先后  亲友  六个    过事 几个 还是   两三层  关系  办成 去年 春天职工 何新荣 9   孩子   白血病家里 负担 不起  女子 53 公斤  比赛 广东 选手 郭惠冰 4  成人 世界纪录令人叹服 。
......
  1. 原始数据对应的标记数据:
B-ORG B-LOC B-TIME I-TIME O B-ORG O B-ORG O B-ORG O B-ORG B-TIME O O O O B-TIME I-TIME O O B-ROLE I-ROLE O O O O O O O O O O
B-TIME I-TIME O O B-TIME O B-ROLE O B-ROLE I-ROLE O O O O O O O O O O O O O O O O
B-TIME I-TIME O B-ROLE B-PER O O O O O O O O B-LOC O O O O
O O O O O O O O B-LOC B-ROLE B-PER O O O O O O O
......
  1. 预测的原始数据:
进一步 研究 已经 发现  有关 这个钥匙 功能 及其 薄弱环节韩国  开始 实施 初步  紧缩 政策决定  1998  预算 削减 10以上 拟定  金融 改革方案取消  外汇资本 流通  利率  所有 管制逐步 允许 外国 金融机构 接管  收购 部分 韩国 金融机构         应有尽有 我们 望而生畏 。
.....

模型搭建

    def __build_model__(self):
        model = Sequential()
        emb = layers.Embedding(input_dim=MAX_FEATURE, output_dim=embedding_size, input_length=MAX_LEN)
        bdr = Bidirectional(layers.LSTM(64, return_sequences=True))
        crf = CRF(get_label_counts() + 1, sparse_target=True)

        model.add(emb)
        model.add(bdr)
        model.add(crf)

        model.summary()
        model.compile(optimizer='adam', loss=crf.loss_function, metrics=[crf.accuracy])
        return model

这里要特别注意:

  1. Embedding的三个参数,input_dim是指Embedding层要接收的特征维度,比如,在本项目中就是要输入的前MAX_FEATURE个出现频率较高的词汇。output_dim是输出给下层的维度,input_length则是对于每个sample,截取前MAX_LEN个词汇作为输入,不足的会用0填充(也可以自己指定其他数字,默认是0)。
  2. CRF的算法没有在keras「原装包」中,需要另外导入keras-contrib包。第一个接受的参数是输出的类型数量,这里+1的是因为在对数据进行填充(padding)的时候,额外引进了填充的类别。
  3. 损失函数和指标都选用了CRF自带的函数。

生成数据

def generate_data():
    with open(src_file, 'r') as f:
        sentences = f.readlines()

    tk = Tokenizer(num_words=MAX_FEATURE, filters=' \n')
    tk.fit_on_texts(sentences)
    sen_sqc = tk.texts_to_sequences(sentences)

    sen_sqc_pad = pad_sequences(sen_sqc, maxlen=MAX_LEN)

    with open(source_vocb_path, 'w') as f:
        f.write(str(tk.index_word))

    with open(tgt_file, 'r') as f:
        tgt = f.readlines()

    tk_tgt = Tokenizer(num_words=MAX_FEATURE, filters=' \n')
    tk_tgt.fit_on_texts(tgt)
    tgt_sqc = tk_tgt.texts_to_sequences(tgt)
    tgt_sqc_pad = pad_sequences(tgt_sqc, maxlen=MAX_LEN)
    with open(tgt_vocb_path, 'w') as f:
        f.write(str(tk_tgt.index_word))

    if is_dev():
        sen_sqc_pad = sen_sqc_pad[:MAX_SAMPLE]
        tgt_sqc_pad = tgt_sqc_pad[:MAX_SAMPLE]

    log.i('sen shape: {}, tgt shape:{}'.format(sen_sqc_pad.shape, tgt_sqc_pad.shape))

    # tgt_sqc_pad = np.expand_dims(tgt_sqc_pad, 2)
    tgt_sqc_pad = tgt_sqc_pad.reshape((tgt_sqc_pad.shape[0], tgt_sqc_pad.shape[1], 1))
    X_train, X_test, y_train, y_test = train_test_split(sen_sqc_pad, tgt_sqc_pad, test_size=0.2)
    log.i('generate data finish')

    return X_train, X_test, y_train, y_test

最主要的地方是利用了KerasTokenizer,对词汇进行唯一标识。

项目成果

  1. 训练准确度:

    准确度损失值

  2. 预测结果:

['进一步(o)', '研究(o)', '已经(o)', '发现(o)', '了(o)', '有关(o)', '这个(o)', '“(o)', '钥匙(o)', '”(o)', '的(o)', '功能(o)', '及其(o)', '薄弱环节(o)', '。(o)']

['韩国(b-loc)', '已(o)', '开始(o)', '实施(o)', '初步(o)', '的(o)', '紧缩(o)', '政策(o)', ',(o)', '决定(o)', '把(o)', '1998(b-time)', '年(i-time)', '预算(o)', '削减(o)', '10(o)', '%(o)', '以上(o)', ',(o)', '并(o)', '拟定(o)', '出(o)', '金融(o)', '改革方案(o)', ',(o)', '取消(o)', '对(o)', '外汇(o)', '、(o)', '资本(o)', '流通(o)', '和(o)', '利率(o)', '的(o)', '所有(o)', '管制(o)', ',(o)', '逐步(o)', '允许(o)', '外国(o)', '金融机构(o)', '接管(o)', '和(o)', '收购(o)', '部分(o)', '韩国(b-loc)', '金融机构(o)', '。(o)']

['甜(o)', '的(o)', '咸(o)', '的(o)', ',(o)', '干(o)', '的(o)', '稀(o)', '的(o)', ',(o)', '素(o)', '的(o)', '荤(o)', '的(o)', ',(o)', '应有尽有(o)', ',(o)', '让(o)', '我们(o)', '望而生畏(o)', '。(o)']

['在(o)', '这种(o)', '心理(o)', '的(o)', '趋动(o)', '下(o)', ',(o)', '敢(o)', '冒风险(o)', '的(o)', '股民(o)', '越来越(o)', '多(o)', '。(o)']

['当年(o)', '全县(o)', '上下(o)', '一盘棋(o)', ',(o)', '从(o)', '抓(o)', '计划生育(o)', '着眼(o)', '促进(o)', '经济(o)', '发展(o)', '入手(o)', ',(o)', '成效显著(o)', '。(o)']

['傅全有(b-per)', '说(o)', ',(o)', '领导(o)', '方法(o)', '“(o)', '十六(o)', '字(o)', '”(o)', '方针(o)', ',(o)', '是(o)', '新形势下(o)', '加强(o)', '党委(o)', '建设(o)', '的(o)', '根本(o)', '指导方针(o)', '。(o)']
......