BERT的几个可能的应用

??BERT是谷歌公司于2018年11月发布的一款新模型,它一种预训练语言表示的方法,在大量文本语料(维基百科)上训练了一个通用的“语言理解”模型,然后用这个模型去执行想做的NLP任务。一经公布,它便引爆了整个NLP界,其在11个主流NLP任务中都取得优异的结果,因此成为NLP领域最吸引人的一个模型。简单来说,BERT就是在训练了大量的文本语料(无监督)之后,能够在对英语中的单词(或中文的汉字)给出一个向量表示,使得该单词(或汉字)具有一定的语义表示能力,因此,BERT具有一定的先验知识,在NLP任务中表现十分抢眼。
??在文章利用bert-serving-server搭建bert词向量服务(一) 中,作者简洁明了地介绍了如何利用bert-serving-server来获取中文汉字的词向量,这大大降低了一般从业者使用BERT的门槛。
??结合笔者这段时间的工作体会以及思考,笔者尝试着给出BERT的几个可能的应用,如下:

  • NLP基本任务
  • 查找相似词语
  • 提取文本中的实体
  • 问答中的实体对齐

由于笔者才疏学浅且撰写文章时间仓促,文章中有不足之处,请读者多多批评指正!

NLP基本任务

??BERT公布已经半年多了,现在已经成为NLP中的深度学习模型中必不可少的工具,一般会加载在模型中的Embedding层。由于篇幅原因,笔者不再介绍自己的BERT项目,而是介绍几个BERT在基本任务中的Github项目:

可以看到,BERT已经广泛应用于NLP基本任务中,在开源项目中导出可以见到它的身影,并且这些项目的作者也写了非常细致的代码工程,便于上手。



??在具体讲述下面的三个应用前,我们先了解下BERT应用的项目结构,如下:

其中,bert_client_lmj.py为调用BERT词向量服务,具体可参考文章利用bert-serving-server搭建bert词向量服务(一) ,完整的Python代码如下:

# -*- coding:utf-8 -*-
from bert_serving.client import BertClient
from sklearn.metrics.pairwise import cosine_similarity

class Encoding(object):
    def __init__(self):
        self.server_ip = "127.0.0.1"
        self.bert_client = BertClient(ip=self.server_ip)

    def encode(self, query):
        tensor = self.bert_client.encode([query])
        return tensor

    def query_similarity(self, query_list):
        tensors = self.bert_client.encode(query_list)
        return cosine_similarity(tensors)[0][1]

if __name__ == "__main__":
    ec = Encoding()
    print(ec.encode("中国").shape)
    print(ec.encode("美国").shape)
    print("中国和美国的向量相似度:", ec.query_similarity(["中国", "美国"]))

查找相似词语

??利用词向量可以查找文章中与指定词语最相近的几个词语。具体的做法为:现将文章分词,对分词后的每个词,查询其与指定词语的相似度,最后按相似度输出词语即可。我们的示例文章为老舍的《养花》,内容如下:

我爱花,所以也爱养花。我可还没成为养花专家,因为没有工夫去研究和试验。我只把养花当做生活中的一种乐趣,花开得大小好坏都不计较,只要开花,我就高兴。在我的小院子里,一到夏天满是花草,小猫只好上房去玩,地上没有它们的运动场。
花虽然多,但是没有奇花异草。珍贵的花草不易养活,看着一棵好花生病要死,是件难过的事。北京的气候,对养花来说不算很好,冬天冷,春天多风,夏天不是干旱就是大雨倾盆,秋天最好,可是会忽然闹霜冻。在这种气候里,想把南方的好花养活,我还没有那么大的本事。因此,我只养些好种易活、自己会奋斗的花草。
不过,尽管花草自己会奋斗,我若是置之不理,任其自生自灭,大半还是会死的。我得天天照管它们,像好朋友似的关心它们。一来二去,我摸着一些门道:有的喜阴,就别放在太阳地里;有的喜干,就别多浇水。摸着门道,花草养活了,而且三年五载老活着、开花,多么有意思啊!不是乱吹,这就是知识呀!多得些知识决不是坏事。
我不是有腿病吗,不但不利于行,也不利于久坐。我不知道花草们受我的照顾,感谢我不感谢;我可得感谢它们。我工作的时候,我总是写一会儿就到院中去看看,浇浇这棵,搬搬那盆,然后回到屋里再写一会儿,然后再出去。如此循环,让脑力劳动和体力劳动得到适当的调节,有益身心,胜于吃药。要是赶上狂风暴雨或天气突变,就得全家动员,抢救花草,十分紧张。几百盆花,都要很快地抢到屋里去,使人腰酸腿疼,热汗直流。第二天,天气好了,又得把花都搬出去,就又一次腰酸腿疼,热汗直流。可是,这多么有意思呀!不劳动,连棵花也养不活,这难道不是真理吗?
送牛奶的同志进门就夸“好香”,这使我们全家都感到骄傲。赶到昙花开放的时候,约几位朋友来看看,更有秉烛夜游的味道——昙花总在夜里开放。花分根了,一棵分为几棵,就赠给朋友们一些。看着友人拿走自己的劳动果实,心里自然特别欢喜。
当然,也有伤心的时候,今年夏天就有这么一回。三百棵菊秧还在地上(没到移入盆中的时候),下了暴雨,邻家的墙倒了,菊秧被砸死三十多种,一百多棵。全家人几天都没有笑容。
有喜有忧,有笑有泪,有花有果,有香有色,既须劳动,又长见识,这就是养花的乐趣。

指定词语为“开心”,查询《养花》一文中与“开心”最为接近的5个词语,完整的Python代码如下:(find_similar_words.py)

# -*- coding:utf-8 -*-
import jieba
from bert_client_lmj import Encoding
from operator import itemgetter

# 读取文章
with open('./doc.txt', 'r', encoding='utf-8') as f:
    content = f.read().replace('\n', '')

ec = Encoding()
similar_word_dict = {}

# 查找文章中与'开心'的最接近的词语
words = list(jieba.cut(content))
for word in words:
    print(word)
    if word not in similar_word_dict.keys():
        similar_word_dict[word] = ec.query_similarity([word, '开心'])

# 按相似度从高到低排序
sorted_dict = sorted(similar_word_dict.items(), key=itemgetter(1), reverse=True)

print('与%s最接近的5个词语及相似度如下:' % '开心')
for _ in sorted_dict[:5]:
    print(_)

输出的结果如下:

与开心最接近的5个词语及相似度如下:
('难过', 0.9070794)
('高兴', 0.89517105)
('乐趣', 0.89260685)
('骄傲', 0.87363803)
('我爱花', 0.86954254)

提取文本中的实体

??在事件抽取中,我们往往需要抽取一些指定的元素,比如在下面的句子中,

巴基斯坦当地时间2014年12月16日早晨,巴基斯坦塔利班运动武装分子袭击了西北部白沙瓦市一所军人子弟学校,打死141人,其中132人为12岁至16岁的学生。

我们需要抽取袭击者,也就是恐怖组织这个元素。
??直接从句法分析,也许可以得到一定的效果,但由于事件描述方式多变,句法分析会显得比较复杂且效果不一定能保证。这时候,我们尝试BERT词向量,它在一定程度上可以作为补充策略,帮助我们定位到事件的元素。具体的想法如下:

  • 指定事件元素模板
  • 句子分词,对词语做n-gram
  • 查询每个n-gram与模板的相似度
  • 按相似度对n-gram排序,取相似度最高的n-gram

在这里,我们的事件元素为恐怖组织,指定的模板为“伊斯兰组织”,完整的Python程序如下(find_similar_entity_in_sentence.py):

# -*- coding:utf-8 -*-

import jieba
from operator import itemgetter
from bert_client_lmj import Encoding

# 创建n-gram
def compute_ngrams(sequence, n):
    lst = list(zip(*[sequence[index:] for index in range(n)]))
    for i in range(len(lst)):
        lst[i] = ''.join(lst[i])
    return lst

# 模板
template = '伊斯兰组织'
# 示例句子
doc = "巴基斯坦当地时间2014年12月16日早晨,巴基斯坦塔利班运动武装分子袭击了西北部白沙瓦市一所军人子弟学校,打死141人,其中132人为12岁至16岁的学生。"

words = list(jieba.cut(doc))
all_lst = []
for j in range(1, 5):
    all_lst.extend(compute_ngrams(words, j))

ec = Encoding()
similar_word_dict = {}

# 查找文章中与template的最接近的词语
for word in all_lst:
    print(word)
    if word not in similar_word_dict.keys():
        similar_word_dict[word] = ec.query_similarity([word, template])

# 按相似度从高到低排序
sorted_dict = sorted(similar_word_dict.items(), key=itemgetter(1), reverse=True)

print('与%s最接近的实体是: %s,相似度为 %s.' %(template, sorted_dict[0][0], sorted_dict[0][1]))

输出的结果如下:

与伊斯兰组织最接近的实体是: 塔利班运动武装分子,相似度为 0.8953854.

可以看到,该算法成功地帮助我们定位到了恐怖组织:塔利班运动武装分子,效果很好,但是由于是无监督产生的词向量,效果不一定可控,而且该算法运行速度较慢,这点可以从工程上加以改进。

问答中的实体对齐

??在智能问答中,我们往往会采用知识图谱或者数据库存储实体,其中一个难点就是实体对齐。举个例子,我们在数据库中储存的实体如下:(entities.txt)

094型/晋级
052C型(旅洋Ⅱ级)
辽宁舰/瓦良格/Varyag
杰拉尔德·R·福特号航空母舰
052D型(旅洋III级)
054A型
CVN-72/林肯号/Lincoln

这样的实体名字很复杂,如果用户想查询实体“辽宁舰”,就会碰到困难,但是由于实体以储存在数据库或知识图谱中,实体不好直接修改。一种办法是通过关键字匹配定位实体,在这里,我们可以借助BERT词向量来实现,完整的Python代码如下:(Entity_Alignment.py)

# -*- coding:utf-8 -*-
from bert_client_lmj import Encoding
from operator import itemgetter

with open('entities.txt', 'r', encoding='utf-8') as f:
    entities = [_.strip() for _ in f.readlines()]

ec = Encoding()

def entity_alignment(query):

    similar_word_dict = {}

    # 查找已有实体中与query最接近的实体
    for entity in entities:
        if entity not in similar_word_dict.keys():
            similar_word_dict[entity] = ec.query_similarity([entity, query])

    # 按相似度从高到低排序
    sorted_dict = sorted(similar_word_dict.items(), key=itemgetter(1), reverse=True)

    return sorted_dict[0]

query = '辽宁舰'
result = entity_alignment(query)
print('查询实体:%s,匹配实体:%s 。' %(query, result))

query = '林肯号'
result = entity_alignment(query)
print('查询实体:%s,匹配实体:%s 。' %(query, result))

输出的结果如下:

查询实体:辽宁舰,匹配实体:('辽宁舰/瓦良格/Varyag', 0.8534695) 。
查询实体:林肯号,匹配实体:('CVN-72/林肯号/Lincoln', 0.8389378) 。

??在这里,查询的速度应该不是困难,因为我们可以将已储存的实体以离线的方式查询其词向量并储存,这样进来一个查询到实体,只查询一次词向量,并计算其与离线的词向量的相似度。这种方法也存在缺陷,主要是由于词向量的无监督,实体对齐有时候不会很准,但作为一种补充策略,也许可以考虑。

总结

??本文介绍了笔者这段时间所思考的BERT词向量的几个应用,由于能力有限,文章中会存在考虑不当的地方,还请读者多多批评指正。
??另外,笔者将会持续调研词向量方面的技术,比如腾讯词向量,百度词向量等,欢迎大家关注~

注意:不妨了解下笔者的微信公众号: Python爬虫与算法(微信号为:easy_web_scrape), 欢迎大家关注~

原文地址:https://www.cnblogs.com/jclian91/p/10987841.html

时间: 2024-10-10 01:42:43

BERT的几个可能的应用的相关文章

Attention is all you need及其在TTS中的应用Close to Human Quality TTS with Transformer和BERT

论文地址:Attention is you need 序列编码 深度学习做NLP的方法,基本都是先将句子分词,然后每个词转化为对应的的词向量序列,每个句子都对应的是一个矩阵\(X=(x_1,x_2,...,x_t)\),其中\(x_i\)都代表着第\(i\)个词向量,维度为d维,故\(x\in R^{n×d}\) 第一个基本的思路是RNN层,递归式进行: \[ y_t=f(y_{t-1},x_t) \] RNN结构本身比较简单,也适合序列建模,但RNN明显缺点之一在于无法并行,因而速度较慢,而且

BERT的开源实现的使用

参考这篇文章: 小数据福音!BERT在极小数据下带来显著提升的开源实现 https://mp.weixin.qq.com/s?__biz=MzIwMTc4ODE0Mw==&mid=2247493161&idx=1&sn=58ddcd071602c42dda93275289311bb3&chksm=96ea39a9a19db0bf15df95cc9961064a3bab4e4a0b8d25a9bfb45c154942330b9cdb0abe0f4b&mpshare=1

BERT模型介绍

前不久,谷歌AI团队新发布的BERT模型,在NLP业内引起巨大反响,认为是NLP领域里程碑式的进步.BERT模型在机器阅读理解顶级水平测试SQuAD1.1中表现出惊人的成绩:全部两个衡量指标上全面超越人类,并且还在11种不同NLP测试中创出最佳成绩,包括将GLUE基准推至80.4%(绝对改进7.6%),MultiNLI准确度达到86.7%(绝对改进率5.6%)等.BERT模型是以Transformer编码器来表示,本文在详细介绍BERT模型,Transformer编码器的原理可以参考(). 论文

最强NLP模型-BERT

简介: BERT,全称Bidirectional Encoder Representations from Transformers,是一个预训练的语言模型,可以通过它得到文本表示,然后用于下游任务,比如文本分类,问答系统,情感分析等任务.BERT像是word2vec的加强版,同样是预训练得到词级别或者句子级别的向量表示,word2vec是上下文无关的(Context-Free),而BERT是上下问有关的(Contextual).意思就是,word2vec只是具有词本身的语义信息,而没有包含文本

一文读懂BERT中的WordPiece

1. 前言 2018年最火的论文要属google的BERT,不过今天我们不介绍BERT的模型,而是要介绍BERT中的一个小模块WordPiece. 2. WordPiece原理 现在基本性能好一些的NLP模型,例如OpenAI GPT,google的BERT,在数据预处理的时候都会有WordPiece的过程.WordPiece字面理解是把word拆成piece一片一片,其实就是这个意思. WordPiece的一种主要的实现方式叫做BPE(Byte-Pair Encoding)双字节编码. BPE

BERT模型在多类别文本分类时的precision, recall, f1值的计算

BERT预训练模型在诸多NLP任务中都取得最优的结果.在处理文本分类问题时,即可以直接用BERT模型作为文本分类的模型,也可以将BERT模型的最后层输出的结果作为word embedding导入到我们定制的文本分类模型中(如text-CNN等).总之现在只要你的计算资源能满足,一般问题都可以用BERT来处理,此次针对公司的一个实际项目--一个多类别(61类)的文本分类问题,其就取得了很好的结果. 我们此次的任务是一个数据分布极度不平衡的多类别文本分类(有的类别下只有几个或者十几个样本,有的类别下

深度双向Transformer预训练【BERT第一作者分享】

目录 NLP中的预训练 语境表示 语境表示相关研究 存在的问题 BERT的解决方案 任务一:Masked LM 任务二:预测下一句 BERT 输入表示 模型结构--Transformer编码器 Transformer vs. LSTM 模型细节 在不同任务上进行微调 GLUE SQuAD 1.1 SQuAD 2.0 SWAG 分析 预训练的影响 方向与训练时间的影响 模型规模的影响 遮罩策略的影响 多语言BERT(机器翻译) 生成训练数据(机器阅读理解) 常见问题 结论 翻译自Jacob Dev

Perseus-BERT——业内性能极致优化的BERT训练方案

[作者] 笋江(林立翔) 驭策(龚志刚) 蜚廉(王志明) 昀龙(游亮) 一,背景--横空出世的BERT全面超越人类2018年在自然语言处理(NLP)领域最具爆炸性的一朵"蘑菇云"莫过于Google Research提出的BERT(Bidirectional Encoder Representations from Transformers)模型.作为一种新型的语言表示模型,BERT以"摧枯拉朽"之势横扫包括语言问答.理解.预测等各项NLP锦标的桂冠,见图1和图2.

chinese multiple class classification using BERT

Steps: git clone https://github.com/google-research/bert prepare data, download pre-trained models modify code in run_classifier.py add a new processor ? ? add the processor in main function ? ? ? ? Train and predict train python run_classifier.py --

为什么BERT有3个嵌入层,它们都是如何实现的

目录 引言 概览 Token Embeddings 作用 实现 Segment Embeddings 作用 实现 Position Embeddings 作用 实现 合成表示 结论 参考文献 本文翻译自Why BERT has 3 Embedding Layers and Their Implementation Details 引言 ? 本文将阐述BERT中嵌入层的实现细节,包括token embeddings.segment embeddings, 和position embeddings.