文本分类需要CNN?No!fastText完美解决你的需求(前篇)

http://blog.csdn.net/weixin_36604953/article/details/78195462?locationNum=8&fps=1

文本分类需要CNN?No!fastText完美解决你的需求(前篇)

fastText是个啥?简单一点说,就是一种可以得到和深度学习结果准确率相同,但是速度快出几个世纪的文本分类算法。这个算法类似与CBOW,可爱的读着是不是要问CBOW又是个什么鬼?莫急,听小编给你慢慢到来,一篇文章,让你了解word2vec的原理,CBOW、Skip-gram模型,以及目前业界最流行的文本分类算法——fastText。 
2013年,Google的大牛Tomas Mikolov开源了word2vec算法,轰动一时(当然,托马斯大牛现在于FaceBook就职,16年中下旬开源了fastText算法,又在业界引起了轩然大波,没办法,速度太快了)。

为了更好地理解fastText,我们的介绍分为上下两篇,前篇,我们先来了解一下word2vec到底是啥,以及CBOW和Skip-gram;后篇,我们就来讲述fastText算法的思想和原理,有了前篇的铺垫,你会轻松的学会fastText。

你可以在这篇文章看到:word2vec的思想与实现,fastText算法的核心思想与创新,以及实现案例;你不会看到长篇的数学公式,高中数学就可以让你看懂这篇文章,通篇都会以最最简单直白的例子来说明,不会用让人看了就想吐的数学公式来刺激可爱的你。

本篇博文将从以下几个方面进行讲解

  • word2vec的思想与实现
  • fastText算法的核心思想与创新
  • 实现案例

word2vec思想

word2vec的核心是神经网络,采用 CBOW(Continuous Bag-Of-Words,即连续的词袋模型)和 Skip-Gram 两种模型,将词语映像到同一坐标系,输出为数值型向量的方法。简而言之,就是将人类才可以看懂的文字,转换为机器也可以识别、操作、处理的数值,将一串文字转化为一个数值型向量的过程。

Word2vec的产生是一个必然的过程,随着人类对非结构化数据(文字、语音、图像等)分析的需求,尤其是大量文本类数据的分析,必然需要一些让计算机“理解”文字的方法,最直接有效的自然就是将文字转化为数字;换言之,将全部的文本映射到数值空间中就是word2vec做的事情。这里需要引入一个概念——语言模型,我们不会在此深入的去探索语言模型,只是简单向读者介绍这个概念。

语言最大的特征就是上下文的联系,比如中文当中,两个特定的字会组成一个词语,若干词语和字组成句子,多个句子组成文章,如果文章中的全部文字都随机的打乱顺序排列,那么我想哪怕正在读文章的你是中文系的高材生,要完全看懂这篇文章也要费九牛二虎之力,请看下面这两段文字:

  • “自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。”
  • “与言将学处处方联及数言理语言信理各、语区工计系别这之和论切领所因人使中间究密的它有然的的与涉有自的要一言算语要效现体进的机融,语学究科科的计然行的学、但实又研是然。与重门能,究然常语域们语科是。自通人种日。言用领域机领域一智着机一人有即言用以言于能研方学的学它自重算向。算学自,计法此研个理一,语”

好吧,看到这里你可能要骂人了,第二段是人话么?答案是,第二段话就 
是第一段话,只是对第一段话随机打乱了顺序,这个不倒150字的段落,也许你用30分钟一个小时可以将它还原成“人话”,如果是长篇大论的呢?这里就看出了语言的逻辑性,词语前后关系的重要性。语言模型就是在做这样的事情,考察一个句子出现的可能性(也就是概率)。如果一个句子S由n个词w1~wn,那么S出现的概率就应该等于P(w1,w2,…,wn),用条件概率的公式即得到共识①如下:

P(S)=P(w1,w2,…,wn)=P(w1)P(w2│w1)…P(wn|w1,w2,…,w(n?1))

不懂这个公式丝毫不影响后面的学习,这个公式翻译成白话就是:词语wn出现的概率依赖于它前面n?1个词。当n很大时,P(wn│w1,w2,…,w(n?1))的计算是非常麻烦甚至无法估算,于是产生了一个叫做马尔科夫假设的概念并由此得到“二元模型”。马尔科夫假设的意思是“任意一个词w_k只与它前面的词即w(k?1)有关”。那么这样,公式①就可以写作下面的公式②的形式:

P(S)=P(w1)P(w2│w1)…P(wn|w(n?1))

语言模型正是为了考察句子,或者说由词a到词b存在在句子中的概率而存在的。如果将我们的语言模型即为f,那么word2vec就是去训练这个f,不关注这个模型是否完美,而是要获取模型产生的参数,对于word2vec,就是神经网络的权重参数,将这些参数作为句子S的替代,由这些参数组成的向量,就是我们所谓的“词向量”。这也就是word2vec的输出。

word2vec从大量文本语料中以无监督的方式学习语义信息,即通过一个嵌入空间使得语义上相似的单词在该空间内距离很近。比如“机器”和“机械”意思很相近,而“机器”和“猴子”的意思相差就很远了,那么由word2vec构建的这个数值空间中,“机器”和“机械”的距离较“机器”和“猴子”的距离而言是要近很多的。

Skip-gram 和 CBOW

不要被这两个看起来高大上的词吓到,其实很简单。由word2vec思想,即考察前后文的关联性产生了这两个模型:Skip-gram是通过一个词a去预测它周围的上下文;而CBOW相反,是通过上下文来预测其间的词。CBOW一般用于数据,而Skip-Gram通常用在数据量较大的情况。

图1

图1比较直接的展示了比较常规的CBOW和Skip-gram,图1左侧的CBOW给出了文本中一个词语wt左右各两个词,输出为wt。然后通过单隐藏层的神经网络去输出文本中每个词按照这个输入数据,输出为wt的概率。右侧的Skip-gram相反,用一个输入词wt去预测左右两个词语,同样输出概率值。

前文说过,word2vec输出是神经网络的权重值,用这些值组成词向量,它的输入就是我们文本中的词(将文本按一定颗粒度切分为词语和字),但是输入进计算机的文字依然是无法被计算机识别啊?该怎么进入这个过程呢?答案就是——one hot encoder。one hot encoder就是一个只含有1个1,其他都为0的值构成的向量。如果全世界的词一共有N个,为了简单起见,假设N是3,这3个词分别是“我”、“是”、“帅哥”(别骂我不要脸~~~),那么很显然,“我”就可以被编码为(1,0,0),“是”编码为(0,1,0),“帅哥”编码为(0,0,1)。这样的数值向量是完全可以被计算机识别和处理的。

言归正传,我们先来看一看Skip-gram模型。我们的输入已经明确了,再明确一下我们的输出:Skip-gram是一个单隐藏层的神经网络结构,那么我们要找的词向量其实就是输入层到第一个隐藏层的权重(也就是图1中Project层的权重值)。

这里,引入“窗口”和“skip-num”的概念,举个例子,比如有这么一句话:“中秋月亮比往常圆”,“中秋”、“月亮”、“比”、“往常”、“圆”作为6个独立的词,如果我们的输入是“月亮”,窗口设为2,skip-num也是2,那么我们会得到两组输入-输出:(月亮,中秋)和(月亮,比),假如先使用(月亮,中秋)作为神经网络的输入和输出进行训练,那么神经网络会输出整个文本中每个词作为“月亮”的输出的概率,也就是给定这组输入输出数据时,输入是“月亮”,输出结果是“中秋”的概率,即文本中每个词与输入值“月亮”相邻出现的概率(当然,这个例子没用对文本进行one hot encoder,是为了方便解释和理解,读着可以自行把它们假想为0-1向量,不想也没关系,小编觉得这样看得见摸得着不抽象的例子才能让大家都看懂)。

现在假设我们的Skip-gram是一个最简单的情况,用一个输入词去预测它相邻的一个词,如图2和图3所示(图3是图2的展开、细化模式)。那么请接着看图4,如果我们的词表中有10000个词,那么每个词进行one-hot编码后,就会是一个10000维的向量,其中9999个都是0,只有一个是1。从输入层到隐藏层没有使用激活函数,但在输出层中使用了softmax(不用怕,这个东西很简单,后面会介绍的,目前你只要把它简单理解成为类似逻辑回归中的logstic变换即可)。

图2

图3

图4

输出层理所当然也是10000维的向量,每个值就是按照输入的这个词,可以得到自己本身的概率,这个10000维的向量其实就是一个概率分布。

我们关注的点在隐藏层,如果我们想用将每个词表示为一个维度为100的向量,即每个词有100个特征,那么隐藏层就是一个10000行×100列的矩阵(也就是隐藏层有100个结点),这个10000×100的矩阵就是我们最后想要的结果,它会将10000个词中的每一个表示为一个100维的向量,有木有发现,10000维的词瞬间被降维到了100维,当然这个权重矩阵中的值就不是0-1了。输入是一个1×10000的向量,隐藏层是一个10000×100的矩阵,这两个矩阵做乘法运算看似需要耗费很多的计算资源,其实并没有,计算机根本没有在运算(也没有在偷懒哈),它只是做了一个“查表”的工作,也就是对权重矩阵做了一个“提取”的动作,只提识别1×10000的向量中那个不为0的值对应的索引,并且从10000×100的矩阵中提取该索引所对应的行。简单展示如下:

最终得到这个1×100的向量。在输出层通过softmax进行变换,使输出层每个结点将会输出一个0-1之间的值(概率),这些所有输出层结点的概率之和为1。

CBOW是同样的道理(如果按照最简单的情况,Skip-gram用一个输入词预测它后面的词,CBOW用一个输出词去预测它前面的一个词,其实是一模一样的套路)。

一点补充:理论部分的最后一点就是对前文的softmax进行一点简单的说明:softmax函数如下所示,zj是原始向量的某一个值,σ(z)j是它变换后的值,分母就是一个正则项,是对于每个z对应的e的z次幂求和,这样的变换会使得σ(z)j是一个属于(0,1)范围内的实数,也就是word2vec的神经网络输出层所输出的概率值。

Python实现word2vec

好了,到此为止,word2vec的原理相比读者已经了如指掌了,是不是有些蠢蠢欲动,摩拳擦掌了?那么我们用一个简单的小例子来实现一下word2vec吧~请读者自行搭建开发环境,小编使用的是Python3+加JupyterNotebook的环境,当然,读者可以使用Pycharm、Spyder等任何IDE进行练习~。请安装好jieba和gensim。在命令行使用pip install jieba和pip install genism即可安装。

好了,小编我选取的文本是小说《神雕侠侣》,其实网上有很多开源的语料,不过比较大,这里为了方便大家练习,故找了一个内容比较多且数据比较小的文本(当然,语料越充实,效果会越好),这个语料大家可以去网上随意搜索。语料如图5所示。

图5

import jieba

novel = open(‘E:/神雕侠侣.txt‘,‘r‘)
line = novel.readline()
novel_segmented = open(‘E:/神雕侠侣_segmented.txt‘,‘w‘)

while line:
    cutword = jieba.cut(line,cut_all=False)
    seg = ‘ ‘.join(cutword).replace(‘,‘,‘‘).replace(‘。‘,‘‘).replace(‘“‘,‘‘).replace(‘”‘,‘‘).replace(‘:‘,‘‘).replace(‘…‘,‘‘)            .replace(‘!‘,‘‘).replace(‘?‘,‘‘).replace(‘~‘,‘‘).replace(‘(‘,‘‘).replace(‘)‘,‘‘).replace(‘、‘,‘‘).replace(‘;‘,‘‘)
    print(seg,file=novel_segmented)

novel.close()
novel_segmented.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

首先,加载jieba库,对文本进行分词,以行为单位逐行读入文本,对每行(line)进行分词,cut_all=False为精确模式(默认情况也是精确模式),然后将文本中的标点符号替换为空,即去除标点符号,然后将分词结果存入novel_segmented中。

分词后的部分结果如图6所示。

图6

from gensim.models import word2vec

# 训练word2vec模型,生成词向量
s = word2vec.LineSentence(‘E:/神雕侠侣_segmented.txt‘)
model = word2vec.Word2Vec(s,size=20,window=5,min_count=5,workers=4)
model.save(‘E:result.txt‘)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

接下来,加载gensim.modelsword2vec,训练我们的模型,并生成词向量,将模型保存。我们的模型就是上面代码中的model啦~~~已经接近成功了!其中s使我们传入的分词后的文本,size就是前文中所说的词向量的维度,window即前文中引入的“窗口”概念,min_count是一个阈值,如果词语的频数少于这个阈值,将会从词表中删除或者说忽略该词(默认也是5),workers是控制并行数的参数,如果没有特殊需求,使用默认值一般就可以得到非常不错的效果。

好了,模型已经诞生了!那么来看看我们的模型可以带给我们哪些信息吧。首先,我们会有词表中每个词语的词向量表示,比如我的偶像杨过大侠,来看看“杨过”的词向量吧,图7中给出了一个20维(维度即size的值)的向量,这就是“杨过”的词向量。

图7

前文中提到过,word2vec表示的词语的词向量有这样的特征:经常一起出现的词,其词向量的相似度会高,那么我们来看看图8给出的杨过和一些主角的相似度吧!果然,杨过小龙女永远是珍爱啊!!!

图8

至此为止,fastText文本分类的前篇——word2vec的介绍就告一段落了,加下来,就要进入目前业界最流行最常用的快到起飞的文本分类算法fastText了。欲知后事如何,且听下回讲解!

时间: 2024-10-06 18:33:30

文本分类需要CNN?No!fastText完美解决你的需求(前篇)的相关文章

文本分类需要CNN?No!fastText完美解决你的需求(后篇)

http://blog.csdn.net/weixin_36604953/article/details/78324834 想必通过前一篇的介绍,各位小主已经对word2vec以及CBOW和Skip-gram有了比较清晰的了解.在这一篇中,小编带大家走进业内最新潮的文本分类算法,也就是fastText分类器.fastText与word2vec的提出者之所以会想到用fastText取代CNN(卷积神经网络)等深度学习模型,目的是为了在大数据情况下提高运算速度. 其实,文本的学习与图像的学习是不同的

用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践

转自https://zhuanlan.zhihu.com/p/25928551 近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文题目便是文本分类问题,趁此机会总结下文本分类领域特别是应用深度学习解决文本分类的相关的思路.做法和部分实践的经验. 业务问题描述: 淘宝商品的一个典型的例子见下图,图中商品的标题是"夏装雪纺条纹短袖t恤女春半袖衣服夏天中长款大码胖mm显瘦上衣夏".淘宝网后台是通过树形的多层的类目体系管理商品的,覆盖叶子类目数量达上万个,商品量也

CNN文本分类

CNN用于文本分类本就是一个不完美的解决方案,因为CNN要求输入都是一定长度的,而对于文本分类问题,文本序列是不定长的,RNN可以完美解决序列不定长问题, 因为RNN不要求输入是一定长度的.那么对于CNN用于解决文本分类问题而言,可以判断文本的长度范围,例如如果大多数文本长度在100以下,极少数在100以上,那就 可以设定文本长度是100,不足100的文本用padding补齐,多于100的文本则截断.具体过程如下图: 首先把分词之后的句子按照设定的维度展开,这里维度是9,每个单词都会有一个向量表

转:文本分类问题

作者:西瓜军团链接:https://www.zhihu.com/question/58863937/answer/166306236来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一.传统文本分类方法 文本分类问题算是自然语言处理领域中一个非常经典的问题了,相关研究最早可以追溯到上世纪50年代,当时是通过专家规则(Pattern)进行分类,甚至在80年代初一度发展到利用知识工程建立专家系统,这样做的好处是短平快的解决top问题,但显然天花板非常低,不仅费时费力,覆

文本分类:survey

作者:尘心链接:https://zhuanlan.zhihu.com/p/76003775 简述 文本分类在文本处理中是很重要的一个模块,它的应用也非常广泛,比如:垃圾过滤,新闻分类,词性标注等等.它和其他的分类没有本质的区别,核心方法为首先提取分类数据的特征,然后选择最优的匹配,从而分类.但是文本也有自己的特点,根据文本的特点,文本分类的一般流程为:1.预处理:2.文本表示及特征选择:3.构造分类器:4.分类. 通常来讲,文本分类任务是指在给定的分类体系中,将文本指定分到某个或某几个类别中.被

用于文本分类的RNN-Attention网络

用于文本分类的RNN-Attention网络 https://blog.csdn.net/thriving_fcl/article/details/73381217 Attention机制在NLP上最早是被用于seq2seq的翻译类任务中,如Neural Machine Translation by Jointly Learning to Align and Translate这篇文章所说. 之后在文本分类的任务中也用上Attention机制,这篇博客主要介绍Attention机制在文本分类任务

DL4J之CNN对今日头条文本分类

一.数据集介绍 数据来源:今日头条客户端 数据格式如下: 6551700932705387022_!_101_!_news_culture_!_京城最值得你来场文化之旅的博物馆_!_保利集团,马未都,中国科学技术馆,博物馆,新中国 6552368441838272771_!_101_!_news_culture_!_发酵床的垫料种类有哪些?哪种更好?_!_ 6552407965343678723_!_101_!_news_culture_!_上联:黄山黄河黄皮肤黄土高原.怎么对下联?_!_ 65

step by step带你fastText文本分类

本文参考原文-http://bjbsair.com/2020-03-25/tech-info/6300/ **写在前面 ** 今天的教程是基于FAIR的Bag of Tricks for Efficient Text Classification[1].也就是我们常说的fastText. 最让人欣喜的这篇论文配套提供了fasttext工具包.这个工具包代码质量非常高,论文结果一键还原,目前已经是包装地非常专业了,这是fastText官网和其github代码库,以及提供了python接口,可以直接

(转)完美解决 Android WebView 文本框获取焦点后自动放大有关问题

完美解决 Android WebView 文本框获取焦点后自动放大问题 前几天在写一个项目时,要求在项目中嵌入一个WebView 本来很快就完成了,测试也没有问题.但发给新加坡时,他们测试都会出现文本框聚焦时,网页面会放大(他们用三星手机测试的) 网上查了好久参考他的方法加上去测试 http://www.cppblog.com/guojingjia2006/archive/2012/12/18/196429.html 下面我将原文copy过来 **************************