文档章节

用深度神经网络处理NER命名实体识别问题

Airship
 Airship
发布于 2017/08/11 21:51
字数 1576
阅读 21
收藏 0
点赞 0
评论 0

本文结构:

  1. 什么是命名实体识别(NER)
  2. 怎么识别?

cs224d Day 7: 项目2-用DNN处理NER问题
课程项目描述地址

什么是NER?

命名实体识别(NER)是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。命名实体识别是信息提取、问答系统、句法分析、机器翻译等应用领域的重要基础工具,作为结构化信息提取的重要步骤。摘自BosonNLP

怎么识别?

先把解决问题的逻辑说一下,然后解释主要的代码,有兴趣的话,完整代码请去这里看
代码是在 Tensorflow 下建立只有一个隐藏层的 DNN 来处理 NER 问题。

1.问题识别:

NER 是个分类问题。

给一个单词,我们需要根据上下文判断,它属于下面四类的哪一个,如果都不属于,则类别为0,即不是实体,所以这是一个需要分成 5 类的问题:

• Person (PER)
• Organization (ORG)
• Location (LOC)
• Miscellaneous (MISC)

我们的训练数据有两列,第一列是单词,第二列是标签。

EU    ORG
rejects    O
German    MISC
Peter    PER
BRUSSELS    LOC

2.模型:

接下来我们用深度神经网络对其进行训练。

模型如下:

输入层的 x^(t) 为以 x_t 为中心的窗口大小为3的上下文语境,x_t 是 one-hot 向量,x_t 与 L 作用后就是相应的词向量,词向量的长度为 d = 50 :

我们建立一个只有一个隐藏层的神经网络,隐藏层维度是 100,y^ 就是得到的预测值,维度是 5:

用交叉熵来计算误差:

J 对各个参数进行求导:

得到如下求导公式:

在 TensorFlow 中求导是自动实现的,这里用Adam优化算法更新梯度,不断地迭代,使得loss越来越小直至收敛。

3.具体实现

def test_NER() 中,我们进行 max_epochs 次迭代,每次,用 training data 训练模型 得到一对 train_loss, train_acc,再用这个模型去预测 validation data,得到一对 val_loss, predictions,我们选择最小的 val_loss,并把相应的参数 weights 保存起来,最后我们是要用这些参数去预测 test data 的类别标签:

def test_NER():

  config = Config()
  with tf.Graph().as_default():
    model = NERModel(config)   # 最主要的类

    init = tf.initialize_all_variables()
    saver = tf.train.Saver()

    with tf.Session() as session:
      best_val_loss = float('inf')  # 最好的值时,它的 loss 它的 迭代次数 epoch
      best_val_epoch = 0

      session.run(init)
      for epoch in xrange(config.max_epochs):
        print 'Epoch {}'.format(epoch)
        start = time.time()
        ###
        train_loss, train_acc = model.run_epoch(session, model.X_train,
                                                model.y_train)   # 1.把 train 数据放进迭代里跑,得到 loss 和 accuracy
        val_loss, predictions = model.predict(session, model.X_dev, model.y_dev)   # 2.用这个model去预测 dev 数据,得到loss 和 prediction
        print 'Training loss: {}'.format(train_loss)
        print 'Training acc: {}'.format(train_acc)
        print 'Validation loss: {}'.format(val_loss)
        if val_loss < best_val_loss:            # 用 val 数据的loss去找最小的loss
          best_val_loss = val_loss
          best_val_epoch = epoch
          if not os.path.exists("./weights"):
            os.makedirs("./weights")

          saver.save(session, './weights/ner.weights')   # 把最小的 loss 对应的 weights 保存起来
        if epoch - best_val_epoch > config.early_stopping:
          break
        ###
        confusion = calculate_confusion(config, predictions, model.y_dev)  # 3.把 dev 的lable数据放进去,计算prediction的confusion
        print_confusion(confusion, model.num_to_tag)
        print 'Total time: {}'.format(time.time() - start)

      saver.restore(session, './weights/ner.weights')    # 再次加载保存过的 weights,用 test 数据做预测,得到预测结果
      print 'Test'
      print '=-=-='
      print 'Writing predictions to q2_test.predicted'
      _, predictions = model.predict(session, model.X_test, model.y_test)
      save_predictions(predictions, "q2_test.predicted")    # 把预测结果保存起来

if __name__ == "__main__":
  test_NER()

4.模型是怎么训练的呢?

  • 首先导入数据 training,validation,test:
# Load the training set
docs = du.load_dataset('data/ner/train')

# Load the dev set (for tuning hyperparameters)
docs = du.load_dataset('data/ner/dev')

# Load the test set (dummy labels only)
docs = du.load_dataset('data/ner/test.masked')
  • 把单词转化成 one-hot 向量后,再转化成词向量:
  def add_embedding(self):
    # The embedding lookup is currently only implemented for the CPU
    with tf.device('/cpu:0'):

      embedding = tf.get_variable('Embedding', [len(self.wv), self.config.embed_size])    # assignment 中的 L    
      window = tf.nn.embedding_lookup(embedding, self.input_placeholder)                # 在 L 中直接把window大小的context的word vector搞定
      window = tf.reshape(
        window, [-1, self.config.window_size * self.config.embed_size])

      return window
  • 建立神经层,包括用 xavier 去初始化第一层, L2 正则化和用 dropout 来减小过拟合的处理:
  def add_model(self, window):

    with tf.variable_scope('Layer1', initializer=xavier_weight_init()) as scope:        # 用initializer=xavier去初始化第一层
      W = tf.get_variable(                                                                # 第一层有 W,b1,h
          'W', [self.config.window_size * self.config.embed_size,
                self.config.hidden_size])
      b1 = tf.get_variable('b1', [self.config.hidden_size])
      h = tf.nn.tanh(tf.matmul(window, W) + b1)
      if self.config.l2:                                                                # L2 regularization for W
          tf.add_to_collection('total_loss', 0.5 * self.config.l2 * tf.nn.l2_loss(W))    # 0.5 * self.config.l2 * tf.nn.l2_loss(W)

    with tf.variable_scope('Layer2', initializer=xavier_weight_init()) as scope:
      U = tf.get_variable('U', [self.config.hidden_size, self.config.label_size])
      b2 = tf.get_variable('b2', [self.config.label_size])
      y = tf.matmul(h, U) + b2
      if self.config.l2:
          tf.add_to_collection('total_loss', 0.5 * self.config.l2 * tf.nn.l2_loss(U))
    output = tf.nn.dropout(y, self.dropout_placeholder)                                    # 返回 output,两个variable_scope都带dropout

    return output

关于 L2正则化 和 dropout 是什么, 如何减小过拟合问题的,可以看这篇博客,总结的简单明了。

  • 用 cross entropy 来计算 loss:
  def add_loss_op(self, y):

    cross_entropy = tf.reduce_mean(                                                        # 1.关键步骤:loss是用cross entropy定义的
        tf.nn.softmax_cross_entropy_with_logits(y, self.labels_placeholder))                # y是模型预测值,计算cross entropy
    tf.add_to_collection('total_loss', cross_entropy)            # Stores value in the collection with the given name.
                                                                # collections are not sets, it is possible to add a value to a collection several times.
    loss = tf.add_n(tf.get_collection('total_loss'))            # Adds all input tensors element-wise. inputs: A list of Tensor with same shape and type

    return loss
  • 接着用 Adam Optimizer 把loss最小化:
  def add_training_op(self, loss):

    optimizer = tf.train.AdamOptimizer(self.config.lr)
    global_step = tf.Variable(0, name='global_step', trainable=False)
    train_op = optimizer.minimize(loss, global_step=global_step)    # 2.关键步骤:用 AdamOptimizer 使 loss 达到最小,所以更关键的是 loss

    return train_op

每一次训练后,得到了最小化 loss 相应的 weights。

这样,NER 这个分类问题就搞定了,当然为了提高精度等其他问题,还是需要查阅文献来学习的。下一次先实现个 RNN。

[cs224d]

Day 1. 深度学习与自然语言处理 主要概念一览
Day 2. TensorFlow 入门
Day 3. word2vec 模型思想和代码实现
Day 4. 怎样做情感分析
Day 5. CS224d-Day 5: RNN快速入门
Day 6. 一文学会用 Tensorflow 搭建神经网络
Day 7. 用深度神经网络处理NER命名实体识别问题
Day 8. 用 RNN 训练语言模型生成文本
Day 9. RNN与机器翻译
Day 10. 用 Recursive Neural Networks 得到分析树
Day 11. RNN的高级应用

我是 不会停的蜗牛 Alice
85后全职主妇
喜欢人工智能,行动派
创造力,思考力,学习力提升修炼进行中
欢迎您的喜欢,关注和评论!



作者:不会停的蜗牛
链接:http://www.jianshu.com/p/581832f2c458
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文转载自:http://www.jianshu.com/p/581832f2c458

共有 人打赏支持
Airship
粉丝 34
博文 852
码字总数 18996
作品 0
南京
高级程序员
机器学习 人工智能 博文链接汇总

115 [入门问题] [TensorFlow] [深度学习] [好玩儿的算法应用实例] [聊天机器人] [神经网络] [机器学习] [机器学习算法应用实例] [自然语言处理] [数据科学] [Python] [Java] [机器学习--初...

aliceyangxi1987
2017/05/13
0
0
基于神经网络的实体识别和关系抽取联合学习 | PaperWeekly #54

最近,研究者们在基于神经网络方法上进行实体识别和关系抽取联合学习,我阅读了一些相关工作,在此和大家一起分享学习(本文中引用了一些论文作者 Suncong Zheng 的 PPT 报告)。 引言 本文关...

技术小能手
2017/12/04
0
0
NLP 专题论文解读:从 Chatbot 到 NER | PaperDaily #11

对话系统 1. 论文动机 论文来自华为诺亚方舟实验室。 都说人工智能要有情感,能体会到人的喜怒哀乐,今天就来介绍一篇带有情绪的 chatbot。在以往的研究中,大部分对话系统都只关注生成对话的...

技术小能手
2017/11/09
0
0
学界 | 回望2017,基于深度学习的NLP研究大盘点

  AI 科技评论按:本文是一篇发布于 tryolabs 的文章,作者 Javier Couto 针对 2017 年基于深度学习的自然语言处理研究进行了大盘点。AI 科技评论根据原文进行了编译。   在过去的几年里...

AI科技评论
01/01
0
0
Github一周项目总结:Python库spaCy最热

  【IT168 资讯】过去一周,Github上最热门的项目当属自然语言处理Python库spaCy,该项目最近更新到了2.0版本。SpaCy是一个基于自然语言处理研究创建的开源项目,目的是最终将其用于真实的...

it168网站
2017/11/21
0
0
ACL 2018 | 利用Lattice LSTM的最优中文命名实体识别方法

  选自arXiv   作者:Yue Zhang、Jie Yang   机器之心编译   参与:路、王淑婷      近日,来自新加坡科技设计大学的研究者在 arXiv 上发布了一篇论文,介绍了一种新型中文命名实...

机器之心
06/30
0
0
一文学会用 Tensorflow 搭建神经网络

cs224d-Day 6: 快速入门 Tensorflow 本文是学习这个视频课程系列的笔记,课程链接是 youtube 上的, 讲的很好,浅显易懂,入门首选, 而且在github有代码, 想看视频的也可以去他的优酷里的频...

aliceyangxi1987
2017/04/26
0
0
中文词法分析解决方案 - LAC

中文词法分析(LAC) 中文分词(Word Segmentation)是将连续的自然语言文本,切分出具有语义合理性和完整性的词汇序列的过程。因为在汉语中,词是承担语义的最基本单位,切词是文本分类、情感...

匿名
前天
0
0
阿里AAAI2018论文解读:轻量网络训练框架、GAN中文命名实体识别、英俄翻译等

1. 火箭发射:一种有效的轻量网络训练框架《Rocket Launching: A Universal and Efficient Framework for Training Well-performing Light Net》 【团队名称】阿里妈妈事业部 【作者】周国睿...

技术小能手
2017/12/29
0
0
命名实体识别从数据集到算法实现

命名实体识别(Named Entity Recognition, NER)是 NLP 的基础任务,指从文本中识别出命名性指称项,为关系抽取等任务做铺垫。狭义上,是识别出人名、地名和组织机构名这三类命名实体(时间、...

技术小能手
06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

10.28 rsync工具介绍 , rsync常用选项, rsync通过ssh同步

rsync远程同步 重点!重点!!重点!!! 例子 • rsync -av /etc/passwd /tmp/1.txt • rsync -av /tmp/1.txt 192.168.188.128:/tmp/2.txt rsync格式 • rsync [OPTION] … SRC DEST • rs......

Linux_老吴
9分钟前
0
0
iis php 环境搭建,非常详细的教程

准备篇 一、环境说明: 操作系统:Windows Server 2016 PHP版本:php 7.1.0 MySQL版本:MySQL 5.7.17.0 二、相关软件下载: 1、PHP下载地址: http://windows.php.net/downloads/releases/ph...

T_star
11分钟前
0
0
Day35 rsync通过服务同步

rsync通过服务同步 rsyncd.conf配置文件详解 port:指定在哪个端口启动rsyncd服务,默认是873端口。 log file:指定日志文件。 pid file:指定pid文件,这个文件的作用涉及服务的启动、停止等...

杉下
16分钟前
0
0
【最新最全】为 iOS 和 Android 的真机和模拟器编译 Luajit 库

编译 Luajit 库,的确是一个挑战。因为官网的教程,在当前版本的 Xcode 和 NDK 环境中,已经不适用了。以前只是编译了适用于真机的 Luajit 库。最近在尝试编译模拟器 Luajit 库,就顺便梳理了...

ios122
16分钟前
0
0
rsync至ssh同步

rsync: 文件同步工具,可实现“增量拷贝”;使用yum安装rsync包 常用选项:-a=-rtplgoD (-r同步目录,-t保持文件的时间属性,-p保持文件的权限属性,-l保持软连接,-g保持文件的属组,-o保持...

ZHENG-JY
22分钟前
0
0
TradingView 学习笔记

#前言 公司最后需要使用TradingView展示K线图走势。由于之前没接触过,拿到文档时一脸蒙逼。还好找到二篇文章+Demo代码,直接改改就行了。 #被批 由于上面的懵懂,有个问题困扰4个小时没解决...

hihubs
22分钟前
0
0
10.28 rsync工具介绍~10.31 rsync通过ssh同步

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而...

洗香香
24分钟前
1
0
php如何使用JSON-RPC查找以太坊中的最新块哈希hash值?

我用PHP中开发了一个以太坊块资源管理器,并成功地与我的服务器Geth节点建立了JSON-RPC通信。然而,当我试图找出最后一个区块时,我陷入了困境。我在https://ethereum.gitbooks.io/frontier...

智能合约
30分钟前
1
0
卷积为什么要旋转180度

参考《最容易理解的对卷积(convolution)的解释》 https://blog.csdn.net/bitcarmanlee/article/details/54729807 这篇博客详细讲解了“卷积”,提及了为什么要反转180度,我简述下。 1.卷积的...

datadev_sh
33分钟前
0
0
【2018.07.18学习笔记】【linux高级知识 20.23-20.26】

20.23/20.24/20.25 告警系统邮件引擎 20.26 运行告警系统

lgsxp
38分钟前
16
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部