热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【转】fastText原理及实践

本文转载自:https:zhuanlan.zhihu.comp32965521fastText是Facebook于2016年开源的一个词向量计算和文本分类工具

本文转载自:https://zhuanlan.zhihu.com/p/32965521

 

fastText是Facebook于2016年开源的一个词向量计算和文本分类工具,在学术上并没有太大创新。但是它的优点也非常明显,在文本分类任务中,fastText(浅层网络)往往能取得和深度网络相媲美的精度,却在训练时间上比深度网络快许多数量级。在标准的多核CPU上, 能够训练10亿词级别语料库的词向量在10分钟之内,能够分类有着30万多类别的50多万句子在1分钟之内。

 

本文首先会介绍一些预备知识,比如softmax、ngram等,然后简单介绍word2vec原理,之后来讲解fastText的原理,并着手使用keras搭建一个简单的fastText分类器,最后,我们会介绍fastText在达观数据的应用。

 

1. 预备知识


(1)Softmax回归

Softmax回归(Softmax Regression)又被称作多项逻辑回归(multinomial logistic regression),它是逻辑回归在处理多类别任务上的推广。

 

在逻辑回归中, 我们有m个被标注的样本: \left\{ (x^{(1)},y^{(1)}),..., (x^{(m)},y^{(m)}) \right\}

在Softmax回归中,类标是大于2的,因此在我们的训练集\left\{ \left( x^{(1)}, y^{(1)}\right),...,\left( x^{(m)}, y^{(m)}\right) \right\}

代价函数如下:

其中1{·}是指示函数,即1{true}=1,1{false}=0

 

既然我们说Softmax回归是逻辑回归的推广,那我们是否能够在代价函数上推导出它们的一致性呢?当然可以,于是:

可以看到,逻辑回归是softmax回归在K=2时的特例。

 

(2)分层Softmax

你可能也发现了,标准的Softmax回归中,要计算y=j时的Softmax概率: P(y=j)

树的结构是根据类标的频数构造的霍夫曼树。K个不同的类标组成所有的叶子节点,K-1个内部节点作为内部参数,从根节点到某个叶子节点经过的节点和边形成一条路径,路径长度被表示为 L(y_{j})

其中:

\sigma(·)

\theta_{n(y_{j},l)}

于是,从根节点走到叶子节点 y_{2}

输入层由目标词汇y的上下文单词 \left\{ x_{1},...,x_{c} \right\}

即:隐含层的输出是C个上下文单词向量的加权平均,权重为W

接着我们计算输出层的每个节点: u_{j}={v'}_{w_{j}}^{T}·h

(3)反向传播学习权重矩阵

在学习权重矩阵和过程中,我们首先随机产生初始值,然后feed训练样本到我们的模型,并观测我们期望输出和真实输出的误差。接着,我们计算误差关于权重矩阵的梯度,并在梯度的方向纠正它们。

 

首先定义损失函数,objective是最大化给定输入上下文,target单词的条件概率。因此,损失函数为:

这里, j^{*}

⟦j=j^* ⟧

于是, W_{ij}^{'}

如何更新权重W?

我们首先计算E关于隐含层节点的导数:

然后,E关于权重的导数为:

于是, w_{ki}

3. fastText分类

 

终于到我们的fastText出场了。这里有一点需要特别注意,一般情况下,使用fastText进行文本分类的同时也会产生词的embedding,即embedding是fastText分类的产物。除非你决定使用预训练的embedding来训练fastText分类模型,这另当别论。

 

(1)字符级别的n-gram

word2vec把语料库中的每个单词当成原子的,它会为每个单词生成一个向量。这忽略了单词内部的形态特征,比如:“apple” 和“apples”,“达观数据”和“达观”,这两个例子中,两个单词都有较多公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。

为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词。对于单词“apple”,假设n的取值为3,则它的trigram有

 

 

其中&#xff0c;<表示前缀&#xff0c;>表示后缀。于是&#xff0c;我们可以用这些trigram来表示“apple”这个单词&#xff0c;进一步&#xff0c;我们可以用这5个trigram的向量叠加来表示“apple”的词向量。

 

这带来两点好处&#xff1a;

1. 对于低频词生成的词向量效果会更好。因为它们的n-gram可以和其它词共享。

2. 对于训练词库之外的单词&#xff0c;仍然可以构建它们的词向量。我们可以叠加它们的字符级n-gram向量。

 

&#xff08;2&#xff09;模型架构

之前提到过&#xff0c;fastText模型架构和word2vec的CBOW模型架构非常相似。下面是fastText模型架构图&#xff1a;

 

注意&#xff1a;此架构图没有展示词向量的训练过程。可以看到&#xff0c;和CBOW一样&#xff0c;fastText模型也只有三层&#xff1a;输入层、隐含层、输出层&#xff08;Hierarchical Softmax&#xff09;&#xff0c;输入都是多个经向量表示的单词&#xff0c;输出都是一个特定的target&#xff0c;隐含层都是对多个词向量的叠加平均。不同的是&#xff0c;CBOW的输入是目标单词的上下文&#xff0c;fastText的输入是多个单词及其n-gram特征&#xff0c;这些特征用来表示单个文档&#xff1b;CBOW的输入单词被onehot编码过&#xff0c;fastText的输入特征是被embedding过&#xff1b;CBOW的输出是目标词汇&#xff0c;fastText的输出是文档对应的类标。

 

值得注意的是&#xff0c;fastText在输入时&#xff0c;将单词的字符级别的n-gram向量作为额外的特征&#xff1b;在输出时&#xff0c;fastText采用了分层Softmax&#xff0c;大大降低了模型训练时间。这两个知识点在前文中已经讲过&#xff0c;这里不再赘述。

 

fastText相关公式的推导和CBOW非常类似&#xff0c;这里也不展开了。

 

&#xff08;3&#xff09;核心思想

现在抛开那些不是很讨人喜欢的公式推导&#xff0c;来想一想fastText文本分类的核心思想是什么&#xff1f;

 

仔细观察模型的后半部分&#xff0c;即从隐含层输出到输出层输出&#xff0c;会发现它就是一个softmax线性多类别分类器&#xff0c;分类器的输入是一个用来表征当前文档的向量&#xff1b;模型的前半部分&#xff0c;即从输入层输入到隐含层输出部分&#xff0c;主要在做一件事情&#xff1a;生成用来表征文档的向量。那么它是如何做的呢&#xff1f;叠加构成这篇文档的所有词及n-gram的词向量&#xff0c;然后取平均。叠加词向量背后的思想就是传统的词袋法&#xff0c;即将文档看成一个由词构成的集合。

 

于是fastText的核心思想就是&#xff1a;将整篇文档的词及n-gram向量叠加平均得到文档向量&#xff0c;然后使用文档向量做softmax多分类。这中间涉及到两个技巧&#xff1a;字符级n-gram特征的引入以及分层Softmax分类。

 

&#xff08;4&#xff09;关于分类效果

还有个问题&#xff0c;就是为何fastText的分类效果常常不输于传统的非线性分类器&#xff1f;

 

假设我们有两段文本&#xff1a;

 

我 来到 达观数据

俺 去了 达而观信息科技

 

这两段文本意思几乎一模一样&#xff0c;如果要分类&#xff0c;肯定要分到同一个类中去。但在传统的分类器中&#xff0c;用来表征这两段文本的向量可能差距非常大。传统的文本分类中&#xff0c;你需要计算出每个词的权重&#xff0c;比如tfidf值&#xff0c; “我”和“俺” 算出的tfidf值相差可能会比较大&#xff0c;其它词类似&#xff0c;于是&#xff0c;VSM&#xff08;向量空间模型&#xff09;中用来表征这两段文本的文本向量差别可能比较大。但是fastText就不一样了&#xff0c;它是用单词的embedding叠加获得的文档向量&#xff0c;词向量的重要特点就是向量的距离可以用来衡量单词间的语义相似程度&#xff0c;于是&#xff0c;在fastText模型中&#xff0c;这两段文本的向量应该是非常相似的&#xff0c;于是&#xff0c;它们很大概率会被分到同一个类中。

 

使用词embedding而非词本身作为特征&#xff0c;这是fastText效果好的一个原因&#xff1b;另一个原因就是字符级n-gram特征的引入对分类效果会有一些提升 。

 

4. 手写一个fastText

 

keras是一个抽象层次很高的神经网络API&#xff0c;由python编写&#xff0c;底层可以基于Tensorflow、Theano或者CNTK。它的优点在于&#xff1a;用户友好、模块性好、易扩展等。所以下面我会用keras简单搭一个fastText的demo版&#xff0c;生产可用的fastText请移步https://github.com/facebookresearch/fastText。如果你弄懂了上面所讲的它的原理&#xff0c;下面的demo对你来讲应该是非常明了的。

 

为了简化我们的任务&#xff1a;

1. 训练词向量时&#xff0c;我们使用正常的word2vec方法&#xff0c;而真实的fastText还附加了字符级别的n-gram作为特征输入&#xff1b;

2. 我们的输出层使用简单的softmax分类&#xff0c;而真实的fastText使用的是Hierarchical Softmax。

 

首先定义几个常量&#xff1a;

 

VOCAB_SIZE &#61; 2000

EMBEDDING_DIM &#61;100

MAX_WORDS &#61; 500

CLASS_NUM &#61; 5

 

VOCAB_SIZE表示词汇表大小&#xff0c;这里简单设置为2000&#xff1b;

EMBEDDING_DIM表示经过embedding层输出&#xff0c;每个词被分布式表示的向量的维度&#xff0c;这里设置为100。比如对于“达观”这个词&#xff0c;会被一个长度为100的类似于[ 0.97860014, 5.93589592, 0.22342691, -3.83102846, -0.23053935, …]的实值向量来表示&#xff1b;

MAX_WORDS表示一篇文档最多使用的词个数&#xff0c;因为文档可能长短不一&#xff08;即词数不同&#xff09;&#xff0c;为了能feed到一个固定维度的神经网络&#xff0c;我们需要设置一个最大词数&#xff0c;对于词数少于这个阈值的文档&#xff0c;我们需要用“未知词”去填充。比如可以设置词汇表中索引为0的词为“未知词”&#xff0c;用0去填充少于阈值的部分&#xff1b;

CLASS_NUM表示类别数&#xff0c;多分类问题&#xff0c;这里简单设置为5。

 

模型搭建遵循以下步骤&#xff1a;

1. 添加输入层&#xff08;embedding层&#xff09;。Embedding层的输入是一批文档&#xff0c;每个文档由一个词汇索引序列构成。例如&#xff1a;[10, 30, 80, 1000] 可能表示“我 昨天 来到 达观数据”这个短文本&#xff0c;其中“我”、“昨天”、“来到”、“达观数据”在词汇表中的索引分别是10、30、80、1000&#xff1b;Embedding层将每个单词映射成EMBEDDING_DIM维的向量。于是&#xff1a;input_shape&#61;(BATCH_SIZE, MAX_WORDS), output_shape&#61;(BATCH_SIZE,
MAX_WORDS, EMBEDDING_DIM)&#xff1b;

2. 添加隐含层&#xff08;投影层&#xff09;。投影层对一个文档中所有单词的向量进行叠加平均。keras提供的GlobalAveragePooling1D类可以帮我们实现这个功能。这层的input_shape是Embedding层的output_shape&#xff0c;这层的output_shape&#61;( BATCH_SIZE, EMBEDDING_DIM)&#xff1b;

3. 添加输出层&#xff08;softmax层&#xff09;。真实的fastText这层是Hierarchical Softmax&#xff0c;因为keras原生并没有支持Hierarchical Softmax&#xff0c;所以这里用Softmax代替。这层指定了CLASS_NUM&#xff0c;对于一篇文档&#xff0c;输出层会产生CLASS_NUM个概率值&#xff0c;分别表示此文档属于当前类的可能性。这层的output_shape&#61;(BATCH_SIZE, CLASS_NUM)

4. 指定损失函数、优化器类型、评价指标&#xff0c;编译模型。损失函数我们设置为categorical_crossentropy&#xff0c;它就是我们上面所说的softmax回归的损失函数&#xff1b;优化器我们设置为SGD&#xff0c;表示随机梯度下降优化器&#xff1b;评价指标选择accuracy&#xff0c;表示精度。

 

用训练数据feed模型时&#xff0c;你需要&#xff1a;

1. 将文档分好词&#xff0c;构建词汇表。词汇表中每个词用一个整数&#xff08;索引&#xff09;来代替&#xff0c;并预留“未知词”索引&#xff0c;假设为0&#xff1b;

2. 对类标进行onehot化。假设我们文本数据总共有3个类别&#xff0c;对应的类标分别是1、2、3&#xff0c;那么这三个类标对应的onehot向量分别是[1, 0,
0]、[0, 1, 0]、[0, 0, 1]&#xff1b;

3. 对一批文本&#xff0c;将每个文本转化为词索引序列&#xff0c;每个类标转化为onehot向量。就像之前的例子&#xff0c;“我 昨天 来到 达观数据”可能被转化为[10, 30,
80, 1000]&#xff1b;它属于类别1&#xff0c;它的类标就是[1, 0, 0]。由于我们设置了MAX_WORDS&#61;500&#xff0c;这个短文本向量后面就需要补496个0&#xff0c;即[10, 30, 80, 1000, 0, 0, 0, …, 0]。因此&#xff0c;batch_xs的 维度为( BATCH_SIZE,MAX_WORDS)&#xff0c;batch_ys的维度为&#xff08;BATCH_SIZE, CLASS_NUM&#xff09;。

 

下面是构建模型的代码&#xff0c;数据处理、feed数据到模型的代码比较繁琐&#xff0c;这里不展示。

5. fastText在达观数据的应用

 

fastText作为诞生不久的词向量训练、文本分类工具&#xff0c;在达观得到了比较深入的应用。主要被用在以下两个系统&#xff1a;

1. 同近义词挖掘。Facebook开源的fastText工具也实现了词向量的训练&#xff0c;达观基于各种垂直领域的语料&#xff0c;使用其挖掘出一批同近义词&#xff1b;

2. 文本分类系统。在类标数、数据量都比较大时&#xff0c;达观会选择fastText 来做文本分类&#xff0c;以实现快速训练预测、节省内存的目的。

 

编者注&#xff1a;

如对文本挖掘领域的技术实践感兴趣&#xff0c;可前往下载达观研究院编写而成的《达观数据技术实践特刊》&#xff0c;该书集合了当下最热门的人工智能领域自然语言处理、个性化推荐、垂直搜索引擎三大方向的技术实践总结&#xff0c;融合了达观技术团队在服务华为、中兴、招行、平安、京东云等不同行业上百家企业后的技术感悟&#xff0c;是国内第一本系统介绍NLP、深度学习等AI技术实践应用的电子刊&#xff0c;欢迎各位技术爱好者前往下载。


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
author-avatar
无限的天空-空间
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有