草庐IT

人工智能算法小白实战-你真的了解词向量吗?

恒生LIGHT云社区 2023-03-28 原文
作者:刘算法

来源:恒生LIGHT云社区

你真的了解词向量吗

笔者在上一篇文章《自然语言处理工程化全景图解析》详细阐述了NLP工程化过程中常见的技术环节。这篇文章将基于其中常见的一个技术点:词向量展开讨论,希望对读者今后的学习和实践有一定的指导意义。

文章将从词向量的应用场景,词向量的训练,词向量的加载和代码实践4个环节展开描述。

一、词向量有哪些常见应用

1、自然语言的数学表达

词向量的存在完美的实现了自然语言中文字向数学表达的转变,不同维度的词向量可以充分刻画词语的含义,让词语与词语之间的计算成为可能。 以下代码描述了常见词汇的词向量数学表达及词向量维度:

词语的数学表达:

语句的数学表达:

2、相似词与相对词:

既然词语可以通过向量表示,显而易见,词语之间的相似和相对都可以通过数学的方式来实现。以下代码描述了基于词向量的相似词和相对(反)词查找:

计算词语之间的相似度:

查找跟目标词相似的前top n个词:

在一定范围内查找相似词:

在一定范围内查找相对词: (相反词)

3、特征表达

自然语言处理里面提到的词向量维度常见的分布在50-300之间,每个维度的值刻画了该词在该维度上的特征值。当前的技术中,对词向量的计算多是通过轻型神经网络训练所得,神经网络训练的不可解释性也导致词向量在特定维度上的值不可解释。尽管不可解释,词向量依然是自然语言处理中非常重要的特征表达形式。常见的应用场景有:句向量sentence2vec, 文档向量doc2vec,而在深度学习训练过程中,词向量也是非常重要“配料”,如下图所示:

二、如何训练词向量?

从选型的角度,常见的词向量训练模型有word2vec,fasttext,glove等。

Fast text由face book研发,该算法模型以大量语料上的快速分类而著称。针对文本分类任务,该算法模型完全可以不需要提前训练词向量,而直接输出文本分类结果。Word2vec和glove 都是基于语言模型中词共现信息来建模的。

算法原理上,Word2vec具备两种建模方法:CBOW和Skip-Gram,CBOW通过上下文的词语预测中心词;Skip-Gram利用中心词预测上下文的词。Word2vec以预测词为建模目标,却在训练中间阶段生成了词向量,这一“副产品”。Glove 通过构建词汇的共现矩阵统计每个词在上下文本内容中出现的频率,进而构建词向量和共现矩阵的近似关系,最后通过对损失函数的求解学习获得词向量表征。

从训练词向量的性能上看,二则模型差距不大,但glove更容易并行化,因此在处理大语料方面更节省时间。

从实现的代码难度上看,上述的几种方法在实现上都可以通过调用Python包来实现,因此难度不大,重要的是训练过程中应该注意哪些问题,下面结合个人经验提出几点思考:

1 如何选择语料

自然语言处理领域对词的语义理解更多的要依赖于词语所在语言环境,相同的词在不同的语言环境中则表现出不同的语义。针对特定任务场景中样本的特点,需采集跟该任务场景极其相关的样本作为训练语料,并且在保证“样本纯度”的情况下,希望训练语料“尽量多”。比如,需要对新闻类文本实现分类,则需要搜集足够纯度的新闻类文本作为词向量训练语料,而不应采集像人类对话类文本等样本作为训练语料。在语料准备方面,语料“纯度”的考虑应该放在首位,数量放在次位。“纯度”保障模型针对特定问题更加聚焦,“数量”保障词向量表征更具泛化能力。而一些科研机构或公司也会追求大而全的词向量,进而在尽量多的全文语料上做词向量的训练,比如腾讯AI实验室公开的16G词向量文件。

2 如何选择模型

下游任务的不同一定程度上决定我们选择模型的方向。像一般的自然语言处理任务,不涉及深层语言特性理解等复杂任务的情况下,优先选择简单模型,比如word2vec的skip-gram。在满足需求的情况下,训练简单模型可以节省更多的时间和空间开销。对于深层语言特性理解等较为复杂的任务,需要模型学习更多的特征,挖掘深层次的语言含义,则需选择较为复杂的模型训练词向量。

3 如何选择特征维度

业界将词向量的特征维度一般定义在50到300之间不等。针对某个特定的任务场景具体选择多少维度并没有明确的定论,维度的选择更多的依靠算法工程师的经验。结合前人经验和个人实践总结,词向量特征维度选择需要考虑的因素跟模型选择方面有些类似。一般任务下,50到100维度的词向量如果能够满足要求的前提下,优先选择低维度词向量。该种词向量的训练更快,即便下游任务中用到词向量的计算,低维度向量的计算相比高纬度可以节省计算开销。特定复杂任务下,需要选择高维度词向量来支撑,这时的词向量训练更耗时也更消耗资源。

4 如何评价训练词向量的好坏

自然语言处理中的词向量训练一般是一个经典NLP任务中的重要环节,因此对词向量训练的评价不能单纯地评价一个训练任务,而应该结合下游任务一起评价。假如当前任务是分类任务,下游分类任务的性能好坏则可以反映出词向量训练性能的好坏,并指导下一步词向量训练策略。

三、词向量的加载问题

要完成上述基于词向量的应用,代码实践过程中首先需要将词向量加载到内存中。对于巨型词向量文件的加载一般需要消耗太多的时间。如何能够提升该文件的加载速度,作者以腾讯公开的16G的词向量文件为例,从以下几个方法尝试和对比了不同方法下的时间消耗:

1.常规方法直接读取源文件,比较消耗时

2.先将源文件转写成pkl格式再加载,可大幅降低时间。

除了上述方法,作者还尝试了其他多种方法的实现,由于篇幅所限不再一一列举,直接说结论。通过代码对比可以看出,将原始的词向量txt文件转成pkl文件后再通过pickle加载文件明显可以大幅减低加载时间。

四、代码实践

Faiss是facebook公开的快速搜索匹配算法,其中包含多个搜索算法及工作模式。公开的资源中均可查询到其算法原理及使用说明。作者仅以其中一种算法为例实践关键词搜索匹配功能。

1、代码实践

下面代码展示了Faiss中一种基于IndexFlatL2的快速匹配算法过程。代码中函数的接口及返回值已在注释中说明,在此不再赘述。

函数调用时,假设查询数据库中词的数量是10万,待查询的词的数量为1千,代码如下图:

执行faiss_labels_match函数后得到待查询结果,需要说明的是,函数调用时设定k=2,所以函数返回结果中每个词会返回两个相似词结果,具体如图:

2、性能对比

下面的代码对比了faiss 搜索和普通搜索之间的时间消耗。作者假设带查询的数据库中的词数量总数为10万,更改待查询的词序列长度从1 到1000不等,统计了两种算法的时间消耗,统计数据已在图中通过箭头部分指出。

通过对比可以看出普通搜索的时间消耗随着待查询词序列长度的增加呈线性增长,而faiss在数据量增加的情况下搜索效果则更具优势。

五、总结

以上从自然语言处理领域中常见的词向量这一技术点出发,提出了几点经验和思考,希望对大家今后的工作和学习中能提供帮助。

有关人工智能算法小白实战-你真的了解词向量吗?的更多相关文章

  1. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  2. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  3. ruby-on-rails - 我真的需要在 Rails 中使用 csv gem 吗? - 2

    我的问题很简单:我是否必须在使用RubyonRails的类上require'csv'?如果我打开一个railsconsole并尝试使用CSVgem它可以工作,但我必须在文件中这样做吗? 最佳答案 CSVlibrary是ruby​​标准库的一部分;它不是gem(即第三方库)。与所有标准库(与核心库不同)一样,csv不会由ruby​​解释器自动加载。所以是的,在您的应用程序中某处您确实需要要求它:irb(main):001:0>CSVNameError:uninitializedconstantCSVfrom(irb):1from/Us

  4. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  5. ruby-on-rails - 如何测试自己对 Ruby/ROR 的了解? - 2

    是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby​​和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T

  6. ruby-on-rails - 了解 "attribute_will_change!"方法 - 2

    我想覆盖store_accessor的getter。可以查到here.代码在这里:#Fileactiverecord/lib/active_record/store.rb,line74defstore_accessor(store_attribute,*keys)keys=keys.flatten_store_accessors_module.module_evaldokeys.eachdo|key|define_method("#{key}=")do|value|write_store_attribute(store_attribute,key,value)enddefine_met

  7. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

  8. ruby-on-rails - ruby 真的是一种完全面向对象的语言吗? - 2

    Ruby是完全面向对象的语言。在ruby​​中,一切都是对象,因此属于某个类。例如5属于Objectclass1.9.3p194:001>5.class=>Fixnum1.9.3p194:002>5.class.superclass=>Integer1.9.3p194:003>5.class.superclass.superclass=>Numeric1.9.3p194:005>5.class.superclass.superclass.superclass=>Object1.9.3p194:006>5.class.superclass.superclass.superclass.su

  9. 100个python算法超详细讲解:画直线 - 2

    1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva

  10. 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一) - 2

    前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型

随机推荐