精华内容
下载资源
问答
  • 关于向量的一篇好的入门文章

    万次阅读 2017-07-13 15:46:42
    作者:Scofield ... 来源:知乎 著作权归作者所有。...很好,正好可借此机会介绍向量、word2vec以及DeepNLP整套相关的东西: 文章很长,是从CSDN上写好复制过来的,亦可直接跳到博客观看: 深度学
    作者:Scofield
    链接:https://www.zhihu.com/question/53354714/answer/155313446
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    很好,正好可借此机会介绍词向量、word2vec以及DeepNLP整套相关的东西:

    文章很长,是从CSDN上写好复制过来的,亦可直接跳到博客观看:

    深度学习(Deep Learning)·自然语言处理(NLP)·表示(Representation)

    here we go.

    ·············································border··············································

    From RxNLP.Scofield转载注明出处。·············································Header··············································

    《DeepNLP的表示学习·词嵌入来龙去脉·深度学习(Deep Learning)·自然语言处理(NLP)·表示(Representation)》

    ·············································border··············································

    Indexing:

    〇、序

    一、DeepNLP的核心关键:语言表示(Representation)

    二、NLP词的表示方法类型

    1、词的独热表示one-hot representation

    2、词的分布式表示distributed representation

    三、NLP语言模型

    四、词的分布式表示

    1. 基于矩阵的分布表示

    2. 基于聚类的分布表示

    3. 基于神经网络的分布表示,词嵌入( word embedding)

    五、词嵌入( word embedding)

    1、概念

    2、理解

    六、神经网络语言模型与word2vec

    1、神经网络语言模型

    2.word2vec与CBOW、Skip-gram

    3.个人对word embedding的理解

    七、后言

    References

    ·············································border··············································

    〇、序 之前一段时间,在结合深度学习做NLP的时候一直有思考一些问题,其中有一个问题算是最核心一个:究竟深度网络是怎么做到让各种NLP任务解决地如何完美呢?到底我的数据在NN中发什么了什么呢?

    并且,不少的terms like: 词向量、word embedding、分布式表示、word2vec、glove等等,这一锅粥的名词术语分别代表什么,他们具体的关系是什么,他们是否处于平级关系?

    出于对知识结构追求完整梳理的强迫症的老毛病,于是不停地查资料、思考、keep revolving……

    然后就感觉有一点小进展了。想到,不如将个人对其的理解,无论对错,先拿出来跟peer分享下,或许能交换出更有意义的东西呢?

    整篇文章的构架是按照属于概念在逻辑上的先后大小顺序,一层一层一级一级地往下剖析、比较、说明。

    另外说明下,here整篇文字内容相对是比较入门,甚至有的点可能描述的不太客观正确,限于当前的认知水平……还请您海涵,希望您在评论中指正!

    一、DeepNLP的核心关键:语言表示(Representation) 最近有一个新名词:Deep Learning + NLP = DeepNLP。当常规的机器学习Machine Learning升级发展到了一定的阶段后,慢慢的被后起的深度学习Deep Learning夺势而去,并如火如荼地引领了一波新高潮,因为Deep Learning有machinelearning过而不及之处!那当Deep Learning进入NLP领域,自然是要横扫ACL一批paper才是。事实也是这样的。

    先提下数据特征表示问题。数据表示是机器学习的核心问题,在过去的Machine Learning阶段,大量兴起特征工程,人工设计大量的特征解决数据的有效表示问题。而到了Deep Learning,想都别想,end-2-end,一步到位,hyper-parameter自动帮你选择寻找关键的特征参数。

    那么,Deep Learning如何能在NLP中发挥出应有的real power呢?很明显,先不提如何设计出很强势的网络结构,不提如何在NLP中引入基于NN的解决例如情感分析、实体识别、机器翻译、文本生成这些高级任务,咱们首先得把语言表示这一关过了——如何让语言表示成为NN能够处理的数据类型。

    我们看看图像和语音是怎么表示数据的:


    <img src="https://pic2.zhimg.com/v2-79c5bc427f8d337a45534d226e83ee4d_b.jpg" data-rawwidth="857" data-rawheight="324" class="origin_image zh-lightbox-thumb" width="857" data-original="https://pic2.zhimg.com/v2-79c5bc427f8d337a45534d226e83ee4d_r.jpg">

    在语音中,用音频频谱序列向量所构成的matrix作为前端输入喂给NN进行处理,good;在图像中,用图片的像素构成的matrix展平成vector后组成的vector序列喂给NN进行处理,good;那在自然语言处理中呢?噢你可能知道或者不知道,将每一个词用一个向量表示出来!想法是挺简单的,对,事实上就是这么简单,然而真有这么简单吗?可能没这么简单。

    有人提到,图像、语音属于比较自然地低级数据表示形式,在图像和语音领域,最基本的数据是信号数据,我们可以通过一些距离度量,判断信号是否相似,在判断两幅图片是否相似时,只需通过观察图片本身就能给出回答。而语言作为人类在进化了几百万年所产生的一种高层的抽象的思维信息表达的工具,其具有高度抽象的特征,文本是符号数据,两个词只要字面不同,就难以刻画它们之间的联系,即使是“麦克风”和“话筒”这样的同义词,从字面上也难以看出这两者意思相同(语义鸿沟现象),可能并不是简单地一加一那么简单就能表示出来,而判断两个词是否相似时,还需要更多的背景知识才能做出回答。

    那么据上是不是可以自信地下一个结论呢:如何有效地表示出语言句子是决定NN能发挥出强大拟合计算能力的关键前提!

    二、NLP词的表示方法类型 接下来将按照上面的思路,引出各种词的表示方法。按照现今目前的发展,词的表示分为独热表示one-hot、分布式表示distributed。

    1、词的独热表示one-hot representation NLP 中最直观,也是到目前为止最常用的词表示方法是 One-hot Representation,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。关于one-hot编码的资料很多,街货,这里简单举个栗子说明:

    “话筒”表示为 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ...] “麦克”表示为 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...]

    每个词都是茫茫 0 海中的一个 1。这种 One-hot Representation 如果采用稀疏方式存储,会是非常的简洁:也就是给每个词分配一个数字 ID。比如刚才的例子中,话筒记为 3,麦克记为 8(假设从 0 开始记)。如果要编程实现的话,用 Hash 表给每个词分配一个编号就可以了。这么简洁的表示方法配合上最大熵、SVM、CRF 等等算法已经很好地完成了 NLP 领域的各种主流任务。

    现在我们分析他的不当处。1、向量的维度会随着句子的词的数量类型增大而增大;2、任意两个词之间都是孤立的,根本无法表示出在语义层面上词语词之间的相关信息,而这一点是致命的。

    2、词的分布式表示distributed representation 传统的独热表示( one-hot representation)仅仅将词符号化,不包含任何语义信息。如何将语义融入到词表示中?Harris 在 1954 年提出的分布假说( distributional hypothesis)为这一设想提供了理论基础:上下文相似的词,其语义也相似。Firth 在 1957 年对分布假说进行了进一步阐述和明确:词的语义由其上下文决定( a word is characterized by thecompany it keeps)。

    到目前为止,基于分布假说的词表示方法,根据建模的不同,主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示。尽管这些不同的分布表示方法使用了不同的技术手段获取词表示,但由于这些方法均基于分布假说,它们的核心思想也都由两部分组成:一、选择一种方式描述上下文;二、选择一种模型刻画某个词(下文称“目标词”)与其上下文之间的关系。

    三、NLP语言模型 在详细介绍词的分布式表示之前,需要将NLP中的一个关键概念描述清楚:语言模型。语言模型包括文法语言模型和统计语言模型。一般我们指的是统计语言模型。之所以要将语言模型摆在词表示方法之前,是因为后面的表示方法马上要用到这一概念。

    统计语言模型: 统计语言模型把语言(词的序列)看作一个随机事件,并赋予相应的概率来描述其属于某种语言集合的可能性。给定一个词汇集合 V,对于一个由 V 中的词构成的序列S = ⟨w1, · · · , wT ⟩ ∈ Vn,统计语言模型赋予这个序列一个概率P(S),来衡量S 符合自然语言的语法和语义规则的置信度。

    用一句简单的话说,就语言模型就是计算一个句子的概率大小的这种模型。有什么意义呢?一个句子的打分概率越高,越说明他是更合乎人说出来的自然句子。

    就是这么简单。常见的统计语言模型有N元文法模型(N-gram Model),最常见的是unigram model、bigram model、trigram model等等。形式化讲,统计语言模型的作用是为一个长度为 m 的字符串确定一个概率分布 P(w1; w2; :::; wm),表示其存在的可能性,其中 w1 到 wm 依次表示这段文本中的各个词。一般在实际求解过程中,通常采用下式计算其概率值:


    <img src="https://pic4.zhimg.com/v2-d27151ddaec2cd19f907bc41820cddc7_b.png" data-rawwidth="478" data-rawheight="75" class="origin_image zh-lightbox-thumb" width="478" data-original="https://pic4.zhimg.com/v2-d27151ddaec2cd19f907bc41820cddc7_r.png">

    同时通过这些方法均也可以保留住一定的词序信息,这样就能把一个词的上下文信息capture住。

    具体的语言模型详情属于街货,详细请自行搜索。

    四、词的分布式表示

    1. 基于矩阵的分布表示 基于矩阵的分布表示通常又称为分布语义模型,在这种表示下,矩阵中的一行,就成为了对应词的表示,这种表示描述了该词的上下文的分布。由于分布假说认为上下文相似的词,其语义也相似,因此在这种表示下,两个词的语义相似度可以直接转化为两个向量的空间距离。

    常见到的Global Vector 模型( GloVe模型)是一种对“词-词”矩阵进行分解从而得到词表示的方法,属于基于矩阵的分布表示。

    2. 基于聚类的分布表示 基于聚类的分布表示我也还不是太清楚,所以就不做具体描述。

    3. 基于神经网络的分布表示,词嵌入( word embedding)

    基于神经网络的分布表示一般称为词向量、词嵌入( word embedding)或分布式表示( distributed representation)。这正是我们的主角today。

    神经网络词向量表示技术通过神经网络技术对上下文,以及上下文与目标词之间的关系进行建模。由于神经网络较为灵活,这类方法的最大优势在于可以表示复杂的上下文。在前面基于矩阵的分布表示方法中,最常用的上下文是词。如果使用包含词序信息的 n-gram 作为上下文,当 n 增加时, n-gram 的总数会呈指数级增长,此时会遇到维数灾难问题。而神经网络在表示 n-gram 时,可以通过一些组合方式对 n 个词进行组合,参数个数仅以线性速度增长。有了这一优势,神经网络模型可以对更复杂的上下文进行建模,在词向量中包含更丰富的语义信息。

    五、词嵌入( word embedding)

    1、概念 基于神经网络的分布表示又称为词向量、词嵌入,神经网络词向量模型与其它分布表示方法一样,均基于分布假说,核心依然是上下文的表示以及上下文与目标词之间的关系的建模。

    前面提到过,为了选择一种模型刻画某个词(下文称“目标词”)与其上下文之间的关系,我们需要在词向量中capture到一个词的上下文信息。同时,上面我们恰巧提到了统计语言模型正好具有捕捉上下文信息的能力。那么构建上下文与目标词之间的关系,最自然的一种思路就是使用语言模型。从历史上看,早期的词向量只是神经网络语言模型的副产品。

    2001年, Bengio 等人正式提出神经网络语言模型( Neural Network Language Model ,NNLM),该模型在学习语言模型的同时,也得到了词向量。所以请注意一点:词向量可以认为是神经网络训练语言模型的副产品

    2、理解 前面提过,one-hot表示法具有维度过大的缺点,那么现在将vector做一些改进:1、将vector每一个元素由整形改为浮点型,变为整个实数范围的表示;2、将原来稀疏的巨大维度压缩嵌入到一个更小维度的空间。如图示:


    <img src="https://pic2.zhimg.com/v2-d652e78ec0a60ce27e3ad3057c1ad4c5_b.png" data-rawwidth="468" data-rawheight="392" class="origin_image zh-lightbox-thumb" width="468" data-original="https://pic2.zhimg.com/v2-d652e78ec0a60ce27e3ad3057c1ad4c5_r.png">

    这也是词向量又名词嵌入的缘由了。

    六、神经网络语言模型与word2vec 好了,到目前为止我们已经对的分布式表示以及词嵌入的概念的层级关系有了个理性的认识了,那这跟word2vec有什么联系?

    1、神经网络语言模型 上面说,通过神经网络训练语言模型可以得到词向量,那么,究竟有哪些类型的神经网络语言模型呢?个人所知,大致有这么些个:

    a) Neural Network Language Model ,NNLMb) Log-Bilinear Language Model, LBLc) Recurrent Neural Network based Language Model,RNNLMd) Collobert 和 Weston 在2008 年提出的 C&W 模型e) Mikolov 等人提出了 CBOW( Continuous Bagof-Words)和 Skip-gram 模型

    到这,估计有人看到了两个熟悉的term:CBOW、skip-gram,有看过word2vec的同学应该对此有所了解。我们继续。

    2.word2vec与CBOW、Skip-gram 现在我们正式引出最火热的另一个term:word2vec。

    上面提到的5个神经网络语言模型,只是个在逻辑概念上的东西,那么具体我们得通过设计将其实现出来,而实现CBOW( Continuous Bagof-Words)和 Skip-gram 语言模型的工具正是well-known word2vec!另外,C&W 模型的实现工具是SENNA。

    所以说,分布式词向量并不是word2vec的作者发明的,他只是提出了一种更快更好的方式来训练语言模型罢了。分别是:连续词袋模型Continous Bag of Words Model(CBOW)和Skip-Gram Model,这两种都是可以训练出词向量的方法,再具体代码操作中可以只选择其一,不过据论文说CBOW要更快一些。

    顺便说说这两个语言模型。统计语言模型statistical language model就是给你几个词,在这几个词出现的前提下来计算某个词出现的(事后)概率。CBOW也是统计语言模型的一种,顾名思义就是根据某个词前面的C个词或者前后C个连续的词,来计算某个词出现的概率。Skip-Gram Model相反,是根据某个词,然后分别计算它前后出现某几个词的各个概率。

    以“我爱北京天安门”这句话为例。假设我们现在关注的词是“爱”,C=2时它的上下文分别是“我”,“北京天安门”。CBOW模型就是把“我” “北京天安门” 的one hot表示方式作为输入,也就是C个1xV的向量,分别跟同一个VxN的大小的系数矩阵W1相乘得到C个1xN的隐藏层hidden layer,然后C个取平均所以只算一个隐藏层。这个过程也被称为线性激活函数(这也算激活函数?分明就是没有激活函数了)。然后再跟另一个NxV大小的系数矩阵W2相乘得到1xV的输出层,这个输出层每个元素代表的就是词库里每个词的事后概率。输出层需要跟ground truth也就是“爱”的one hot形式做比较计算loss。这里需要注意的就是V通常是一个很大的数比如几百万,计算起来相当费时间,除了“爱”那个位置的元素肯定要算在loss里面,word2vec就用基于huffman编码的Hierarchical softmax筛选掉了一部分不可能的词,然后又用nagetive samping再去掉了一些负样本的词所以时间复杂度就从O(V)变成了O(logV)。Skip gram训练过程类似,只不过输入输出刚好相反。

    补充下,Word embedding的训练方法大致可以分为两类:一类是无监督或弱监督的预训练;一类是端对端(end to end)的有监督训练。无监督或弱监督的预训练以word2vec和auto-encoder为代表。这一类模型的特点是,不需要大量的人工标记样本就可以得到质量还不错的embedding向量。不过因为缺少了任务导向,可能和我们要解决的问题还有一定的距离。因此,我们往往会在得到预训练的embedding向量后,用少量人工标注的样本去fine-tune整个模型。

    相比之下,端对端的有监督模型在最近几年里越来越受到人们的关注。与无监督模型相比,端对端的模型在结构上往往更加复杂。同时,也因为有着明确的任务导向,端对端模型学习到的embedding向量也往往更加准确。例如,通过一个embedding层和若干个卷积层连接而成的深度神经网络以实现对句子的情感分类,可以学习到语义更丰富的词向量表达。

    3.个人对word embedding的理解 现在,词向量既能够降低维度,又能够capture到当前词在本句子中上下文的信息(表现为前后距离关系),那么我们对其用来表示语言句子词语作为NN的输入是非常自信与满意的。

    另外一点很实用的建议,在你做某一项具体的NLP任务时如你要用到词向量,那么我建议你:要么1、选择使用别人训练好的词向量,注意,得使用相同语料内容领域的词向量;要么2、自己训练自己的词向量。我建议是前者,因为……坑太多了。


    七、后言

    说到这里,其实我并没有想继续说下去的打算了,即并没有打算将word2vec的数学原理、详解啥的统统来一顿讲了,因为我发现网上关于讲解word2vec的文章实在是太多了,多到几乎所有的文章都是一样的。所以我也没有必要再copy一份过来咯。

    所以,要详细了解word2vec、cbow、skip-gram细节的请您仔细搜索。我相信,在了解了这一系列的前提上下文知识的背景下,你再去读word2vec相关的细节文章时,一定不会感到有多吃力。

    另外这也反映出来了一个更大的问题,即网络文章缺少critical思维的原创性。

    网上随便一搜“word2vec”、“词向量”,然后一大堆的关于word2vec、cbow、skip-gram数学公式的讲解,并且还都是千篇一律的东西……但最让人无法理解的是,基本上没有人去详细地提一提这些东西他的出现他的存在的上下文、他的发展的过程、他在整个相关技术框架的所处位置等等。这让我很郁闷……

    其实顺便分享下,在我个人的方法论思维中,一个带有完整上下文以及结构构建良好的知识框架,在某种程度上,比一些细枝末节的详细知识点来的重要的多了!因为,一旦构建了一个完备的知识结构框架,那么剩下你要做的是将一些零零碎碎的细节进行填补而已;而反过来却根本不行,知识堆砌只会让你思维混乱,走不了多远。

    所以here我也呼吁各位blogger,大家能充分发挥自己的能动性,主动去创造一些没有的东西,分享一些独有的思维见解,也算是对中国网络blog以及CS事业的推动贡献啊!I mean,即便是copy别人的原来的东西,也最好是咀嚼咀嚼,消化后加上自己的东西再share啊!



    References:《How to Generate a Good Word Embedding?》,Siwei Lai, Kang Liu, Liheng Xu, Jun Zhao《基于神经网络的词和文档语义向量表示方法研究》,来斯惟《面向自然语言处理的分布式表示学习》,邱锡鹏《Deep Learning 实战之 word2vec》

    展开全文
  • 神经网络——最易懂最清晰的一篇文章

    万次阅读 多人点赞 2018-08-24 15:43:20
    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法... 神经网络是种模拟人脑的神经网络以期能够实现类人工智能的机器学习技...

    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法,同时也可以更好地帮助你理解深度学习技术。

      本文以一种简单的,循序的方式讲解神经网络。适合对神经网络了解不多的同学。本文对阅读没有一定的前提要求,但是懂一些机器学习基础会更好地帮助理解本文。

      神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。人脑中的神经网络是一个非常复杂的组织。成人的大脑中估计有1000亿个神经元之多。

    图1 人脑神经网络

     

      那么机器学习中的神经网络是如何实现这种模拟的,并且达到一个惊人的良好效果的?通过本文,你可以了解到这些问题的答案,同时还能知道神经网络的历史,以及如何较好地学习它。

      由于本文较长,为方便读者,以下是本文的目录:

      一.前言

      二.神经元

      三.单层神经网络(感知器)

      四.两层神经网络(多层感知器)

      五.多层神经网络(深度学习)

      六.回顾

      七.展望

      八.总结

      九.后记

      十.备注

     

    一. 前言

      让我们来看一个经典的神经网络。这是一个包含三个层次的神经网络。红色的是输入层,绿色的是输出层,紫色的是中间层(也叫隐藏层)。输入层有3个输入单元,隐藏层有4个单元,输出层有2个单元。后文中,我们统一使用这种颜色来表达神经网络的结构。

    图2 神经网络结构图

     

      在开始介绍前,有一些知识可以先记在心里:

    1. 设计一个神经网络时,输入层与输出层的节点数往往是固定的,中间层则可以自由指定;
    2. 神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;
    3. 结构图里的关键不是圆圈(代表“神经元”),而是连接线(代表“神经元”之间的连接)。每个连接线对应一个不同的权重(其值称为权值),这是需要训练得到的。  

      除了从左到右的形式表达的结构图,还有一种常见的表达形式是从下到上来表示一个神经网络。这时候,输入层在图的最下方。输出层则在图的最上方,如下图:

    图3 从下到上的神经网络结构图 

     

      从左到右的表达形式以Andrew Ng和LeCun的文献使用较多,Caffe里使用的则是从下到上的表达。在本文中使用Andrew Ng代表的从左到右的表达形式。

      下面从简单的神经元开始说起,一步一步介绍神经网络复杂结构的形成。

     

    二. 神经元

      1.引子 

      对于神经元的研究由来已久,1904年生物学家就已经知晓了神经元的组成结构。

      一个神经元通常具有多个树突,主要用来接受传入信息;而轴突只有一条,轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接,从而传递信号。这个连接的位置在生物学上叫做“突触”。

      人脑中的神经元形状可以用下图做简单的说明:

    图4 神经元

     

       1943年,心理学家McCulloch和数学家Pitts参考了生物神经元的结构,发表了抽象的神经元模型MP。在下文中,我们会具体介绍神经元模型。

       

    图5 Warren McCulloch(左)和 Walter Pitts(右)  

      2.结构 

      神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。

      下图是一个典型的神经元模型:包含有3个输入,1个输出,以及2个计算功能。

      注意中间的箭头线。这些线称为“连接”。每个上有一个“权值”。

    图6 神经元模型 

     

      连接是神经元中最重要的东西。每一个连接上都有一个权重。

      一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。

      我们使用a来表示输入,用w来表示权值。一个表示连接的有向箭头可以这样理解:在初端,传递的信号大小仍然是a,端中间有加权参数w,经过这个加权后的信号会变成a*w,因此在连接的末端,信号的大小就变成了a*w。

      在其他绘图模型里,有向箭头可能表示的是值的不变传递。而在神经元模型里,每个有向箭头表示的是值的加权传递。

    图7 连接(connection)  

     

      如果我们将神经元图中的所有变量用符号表示,并且写出输出的计算公式的话,就是下图。

    图8 神经元计算  

     

      可见z是在输入和权值的线性加权和叠加了一个函数g的值。在MP模型里,函数g是sgn函数,也就是取符号函数。这个函数当输入大于0时,输出1,否则输出0。

      下面对神经元模型的图进行一些扩展。首先将sum函数与sgn函数合并到一个圆圈里,代表神经元的内部计算。其次,把输入a与输出z写到连接线的左上方,便于后面画复杂的网络。最后说明,一个神经元可以引出多个代表输出的有向箭头,但值都是一样的。

      神经元可以看作一个计算与存储单元。计算是神经元对其的输入进行计算功能。存储是神经元会暂存计算结果,并传递到下一层。

    图9 神经元扩展 

     

      当我们用“神经元”组成网络以后,描述网络中的某个“神经元”时,我们更多地会用“单元”(unit)来指代。同时由于神经网络的表现形式是一个有向图,有时也会用“节点”(node)来表达同样的意思。 

      3.效果 

      神经元模型的使用可以这样理解:

      我们有一个数据,称之为样本。样本有四个属性,其中三个属性已知,一个属性未知。我们需要做的就是通过三个已知属性预测未知属性。

      具体办法就是使用神经元的公式进行计算。三个已知属性的值是a1,a2,a3,未知属性的值是z。z可以通过公式计算出来。

      这里,已知的属性称之为特征,未知的属性称之为目标。假设特征与目标之间确实是线性关系,并且我们已经得到表示这个关系的权值w1,w2,w3。那么,我们就可以通过神经元模型预测新样本的目标。

      4.影响

      1943年发布的MP模型,虽然简单,但已经建立了神经网络大厦的地基。但是,MP模型中,权重的值都是预先设置的,因此不能学习。

      1949年心理学家Hebb提出了Hebb学习率,认为人脑神经细胞的突触(也就是连接)上的强度上可以变化的。于是计算科学家们开始考虑用调整权值的方法来让机器学习。这为后面的学习算法奠定了基础。

    图10 Donald Olding Hebb 

     

      尽管神经元模型与Hebb学习律都已诞生,但限于当时的计算机能力,直到接近10年后,第一个真正意义的神经网络才诞生。

     

    三. 单层神经网络(感知器)

      1.引子  

      1958年,计算科学家Rosenblatt提出了由两层神经元组成的神经网络。他给它起了一个名字--“感知器”(Perceptron)(有的文献翻译成“感知机”,下文统一用“感知器”来指代)。

      感知器是当时首个可以学习的人工神经网络。Rosenblatt现场演示了其学习识别简单图像的过程,在当时的社会引起了轰动。

      人们认为已经发现了智能的奥秘,许多学者和科研机构纷纷投入到神经网络的研究中。美国军方大力资助了神经网络的研究,并认为神经网络比“原子弹工程”更重要。这段时间直到1969年才结束,这个时期可以看作神经网络的第一次高潮。

    图11 Rosenblat与感知器 

      2.结构

      下面来说明感知器模型。

      在原来MP模型的“输入”位置添加神经元节点,标志其为“输入单元”。其余不变,于是我们就有了下图:从本图开始,我们将权值w1, w2, w3写到“连接线”的中间。

    图12 单层神经网络 

     

      在“感知器”中,有两个层次。分别是输入层和输出层。输入层里的“输入单元”只负责传输数据,不做计算。输出层里的“输出单元”则需要对前面一层的输入进行计算。

      我们把需要计算的层次称之为“计算层”,并把拥有一个计算层的网络称之为“单层神经网络”。有一些文献会按照网络拥有的层数来命名,例如把“感知器”称为两层神经网络。但在本文里,我们根据计算层的数量来命名。

      假如我们要预测的目标不再是一个值,而是一个向量,例如[2,3]。那么可以在输出层再增加一个“输出单元”。

      下图显示了带有两个输出单元的单层神经网络,其中输出单元z1的计算公式如下图。

    图13 单层神经网络(Z1)

     

      可以看到,z1的计算跟原先的z并没有区别。

      我们已知一个神经元的输出可以向多个神经元传递,因此z2的计算公式如下图。

    图14 单层神经网络(Z2)

     

      可以看到,z2的计算中除了三个新的权值:w4,w5,w6以外,其他与z1是一样的。

      整个网络的输出如下图。

    图15 单层神经网络(Z1和Z2)

     

      目前的表达公式有一点不让人满意的就是:w4,w5,w6是后来加的,很难表现出跟原先的w1,w2,w3的关系。

      因此我们改用二维的下标,用wx,y来表达一个权值。下标中的x代表后一层神经元的序号,而y代表前一层神经元的序号(序号的顺序从上到下)。

      例如,w1,2代表后一层的第1个神经元与前一层的第2个神经元的连接的权值(这种标记方式参照了Andrew Ng的课件)。根据以上方法标记,我们有了下图。

    图16 单层神经网络(扩展)

     

      如果我们仔细看输出的计算公式,会发现这两个公式就是线性代数方程组。因此可以用矩阵乘法来表达这两个公式。

      例如,输入的变量是[a1,a2,a3]T(代表由a1,a2,a3组成的列向量),用向量a来表示。方程的左边是[z1,z2]T,用向量z来表示。

      系数则是矩阵W(2行3列的矩阵,排列形式与公式中的一样)。

      于是,输出公式可以改写成:

    g(W * a) = z;

     

      这个公式就是神经网络中从前一层计算后一层的矩阵运算。

      3.效果

      与神经元模型不同,感知器中的权值是通过训练得到的。因此,根据以前的知识我们知道,感知器类似一个逻辑回归模型,可以做线性分类任务。

      我们可以用决策分界来形象的表达分类的效果。决策分界就是在二维的数据平面中划出一条直线,当数据的维度是3维的时候,就是划出一个平面,当数据的维度是n维时,就是划出一个n-1维的超平面。

      下图显示了在二维平面中划出决策分界的效果,也就是感知器的分类效果。

    图17 单层神经网络(决策分界)

      

      4.影响 

      感知器只能做简单的线性分类任务。但是当时的人们热情太过于高涨,并没有人清醒的认识到这点。于是,当人工智能领域的巨擘Minsky指出这点时,事态就发生了变化。

      Minsky在1969年出版了一本叫《Perceptron》的书,里面用详细的数学证明了感知器的弱点,尤其是感知器对XOR(异或)这样的简单分类任务都无法解决。

      Minsky认为,如果将计算层增加到两层,计算量则过大,而且没有有效的学习算法。所以,他认为研究更深层的网络是没有价值的。(本文成文后一个月,即2016年1月,Minsky在美国去世。谨在本文中纪念这位著名的计算机研究专家与大拿。)

       

    图18 Marvin Minsky

      

      由于Minsky的巨大影响力以及书中呈现的悲观态度,让很多学者和实验室纷纷放弃了神经网络的研究。神经网络的研究陷入了冰河期。这个时期又被称为“AI winter”。

      接近10年以后,对于两层神经网络的研究才带来神经网络的复苏。

     

    四. 两层神经网络(多层感知器)

      1.引子

      两层神经网络是本文的重点,因为正是在这时候,神经网络开始了大范围的推广与使用。

      Minsky说过单层神经网络无法解决异或问题。但是当增加一个计算层以后,两层神经网络不仅可以解决异或问题,而且具有非常好的非线性分类效果。不过两层神经网络的计算是一个问题,没有一个较好的解法。

      1986年,Rumelhar和Hinton等人提出了反向传播(Backpropagation,BP)算法,解决了两层神经网络所需要的复杂计算量问题,从而带动了业界使用两层神经网络研究的热潮。目前,大量的教授神经网络的教材,都是重点介绍两层(带一个隐藏层)神经网络的内容。 

      这时候的Hinton还很年轻,30年以后,正是他重新定义了神经网络,带来了神经网络复苏的又一春。

            

    图19 David Rumelhart(左)以及 Geoffery Hinton(右)

     

      2.结构

      两层神经网络除了包含一个输入层,一个输出层以外,还增加了一个中间层。此时,中间层和输出层都是计算层。我们扩展上节的单层神经网络,在右边新加一个层次(只含有一个节点)。

      现在,我们的权值矩阵增加到了两个,我们用上标来区分不同层次之间的变量。

      例如ax(y)代表第y层的第x个节点。z1,z2变成了a1(2),a2(2)。下图给出了a1(2),a2(2)的计算公式。

    图20 两层神经网络(中间层计算)

     

      计算最终输出z的方式是利用了中间层的a1(2),a2(2)和第二个权值矩阵计算得到的,如下图。

    图21 两层神经网络(输出层计算)

     

      假设我们的预测目标是一个向量,那么与前面类似,只需要在“输出层”再增加节点即可。

      我们使用向量和矩阵来表示层次中的变量。a(1),a(2),z是网络中传输的向量数据。W(1)和W(2)是网络的矩阵参数。如下图。

    图22 两层神经网络(向量形式)

     

      使用矩阵运算来表达整个计算公式的话如下:

      g(W(1) * a(1)) = a(2); 

    g(W(2) * a(2)) = z;

     

      由此可见,使用矩阵运算来表达是很简洁的,而且也不会受到节点数增多的影响(无论有多少节点参与运算,乘法两端都只有一个变量)。因此神经网络的教程中大量使用矩阵运算来描述。

      需要说明的是,至今为止,我们对神经网络的结构图的讨论中都没有提到偏置节点(bias unit)。事实上,这些节点是默认存在的。它本质上是一个只含有存储功能,且存储值永远为1的单元。在神经网络的每个层次中,除了输出层以外,都会含有这样一个偏置单元。正如线性回归模型与逻辑回归模型中的一样。

      偏置单元与后一层的所有节点都有连接,我们设这些参数值为向量b,称之为偏置。如下图。

    图23 两层神经网络(考虑偏置节点)

     

      可以看出,偏置节点很好认,因为其没有输入(前一层中没有箭头指向它)。有些神经网络的结构图中会把偏置节点明显画出来,有些不会。一般情况下,我们都不会明确画出偏置节点。 

      在考虑了偏置以后的一个神经网络的矩阵运算如下:

      g(W(1) * a(1) + b(1)) = a(2); 

    g(W(2) * a(2) + b(2)) = z;

     

      需要说明的是,在两层神经网络中,我们不再使用sgn函数作为函数g,而是使用平滑函数sigmoid作为函数g。我们把函数g也称作激活函数(active function)。

      事实上,神经网络的本质就是通过参数与激活函数来拟合特征与目标之间的真实函数关系。初学者可能认为画神经网络的结构图是为了在程序中实现这些圆圈与线,但在一个神经网络的程序中,既没有“线”这个对象,也没有“单元”这个对象。实现一个神经网络最需要的是线性代数库。

      3.效果

      与单层神经网络不同。理论证明,两层神经网络可以无限逼近任意连续函数。

      这是什么意思呢?也就是说,面对复杂的非线性分类任务,两层(带一个隐藏层)神经网络可以分类的很好。

      下面就是一个例子(此两图来自colah的博客),红色的线与蓝色的线代表数据。而红色区域和蓝色区域代表由神经网络划开的区域,两者的分界线就是决策分界。

    图24 两层神经网络(决策分界)

      

      可以看到,这个两层神经网络的决策分界是非常平滑的曲线,而且分类的很好。有趣的是,前面已经学到过,单层网络只能做线性分类任务。而两层神经网络中的后一层也是线性分类层,应该只能做线性分类任务。为什么两个线性分类任务结合就可以做非线性分类任务?

      我们可以把输出层的决策分界单独拿出来看一下。就是下图。

    图25 两层神经网络(空间变换)

     

      可以看到,输出层的决策分界仍然是直线。关键就是,从输入层到隐藏层时,数据发生了空间变换。也就是说,两层神经网络中,隐藏层对原始的数据进行了一个空间变换,使其可以被线性分类,然后输出层的决策分界划出了一个线性分类分界线,对其进行分类。

      这样就导出了两层神经网络可以做非线性分类的关键--隐藏层。联想到我们一开始推导出的矩阵公式,我们知道,矩阵和向量相乘,本质上就是对向量的坐标空间进行一个变换。因此,隐藏层的参数矩阵的作用就是使得数据的原始坐标空间从线性不可分,转换成了线性可分。

      两层神经网络通过两层的线性模型模拟了数据内真实的非线性函数。因此,多层的神经网络的本质就是复杂函数拟合。

      下面来讨论一下隐藏层的节点数设计。在设计一个神经网络时,输入层的节点数需要与特征的维度匹配,输出层的节点数要与目标的维度匹配。而中间层的节点数,却是由设计者指定的。因此,“自由”把握在设计者的手中。但是,节点数设置的多少,却会影响到整个模型的效果。如何决定这个自由层的节点数呢?目前业界没有完善的理论来指导这个决策。一般是根据经验来设置。较好的方法就是预先设定几个可选值,通过切换这几个值来看整个模型的预测效果,选择效果最好的值作为最终选择。这种方法又叫做Grid Search(网格搜索)。

      了解了两层神经网络的结构以后,我们就可以看懂其它类似的结构图。例如EasyPR字符识别网络架构(下图)。

    图26 EasyPR字符识别网络

     

      EasyPR使用了字符的图像去进行字符文字的识别。输入是120维的向量。输出是要预测的文字类别,共有65类。根据实验,我们测试了一些隐藏层数目,发现当值为40时,整个网络在测试集上的效果较好,因此选择网络的最终结构就是120,40,65。

      4.训练

      下面简单介绍一下两层神经网络的训练。

      在Rosenblat提出的感知器模型中,模型中的参数可以被训练,但是使用的方法较为简单,并没有使用目前机器学习中通用的方法,这导致其扩展性与适用性非常有限。从两层神经网络开始,神经网络的研究人员开始使用机器学习相关的技术进行神经网络的训练。例如用大量的数据(1000-10000左右),使用算法进行优化等等,从而使得模型训练可以获得性能与数据利用上的双重优势。

      机器学习模型训练的目的,就是使得参数尽可能的与真实的模型逼近。具体做法是这样的。首先给所有参数赋上随机值。我们使用这些随机生成的参数值,来预测训练数据中的样本。样本的预测目标为yp,真实目标为y。那么,定义一个值loss,计算公式如下。

    loss = (yp - y)2

     

      这个值称之为损失(loss),我们的目标就是使对所有训练数据的损失和尽可能的小。

      如果将先前的神经网络预测的矩阵公式带入到yp中(因为有z=yp),那么我们可以把损失写为关于参数(parameter)的函数,这个函数称之为损失函数(loss function)。下面的问题就是求:如何优化参数,能够让损失函数的值最小。

      此时这个问题就被转化为一个优化问题。一个常用方法就是高等数学中的求导,但是这里的问题由于参数不止一个,求导后计算导数等于0的运算量很大,所以一般来说解决这个优化问题使用的是梯度下降算法。梯度下降算法每次计算参数在当前的梯度,然后让参数向着梯度的反方向前进一段距离,不断重复,直到梯度接近零时截止。一般这个时候,所有的参数恰好达到使损失函数达到一个最低值的状态。

      在神经网络模型中,由于结构复杂,每次计算梯度的代价很大。因此还需要使用反向传播算法。反向传播算法是利用了神经网络的结构进行的计算。不一次计算所有参数的梯度,而是从后往前。首先计算输出层的梯度,然后是第二个参数矩阵的梯度,接着是中间层的梯度,再然后是第一个参数矩阵的梯度,最后是输入层的梯度。计算结束以后,所要的两个参数矩阵的梯度就都有了。

      反向传播算法可以直观的理解为下图。梯度的计算从后往前,一层层反向传播。前缀E代表着相对导数的意思。

    图27 反向传播算法

     

      反向传播算法的启示是数学中的链式法则。在此需要说明的是,尽管早期神经网络的研究人员努力从生物学中得到启发,但从BP算法开始,研究者们更多地从数学上寻求问题的最优解。不再盲目模拟人脑网络是神经网络研究走向成熟的标志。正如科学家们可以从鸟类的飞行中得到启发,但没有必要一定要完全模拟鸟类的飞行方式,也能制造可以飞天的飞机。

      优化问题只是训练中的一个部分。机器学习问题之所以称为学习问题,而不是优化问题,就是因为它不仅要求数据在训练集上求得一个较小的误差,在测试集上也要表现好。因为模型最终是要部署到没有见过训练数据的真实场景。提升模型在测试集上的预测效果的主题叫做泛化(generalization),相关方法被称作正则化(regularization)。神经网络中常用的泛化技术有权重衰减等。

      5.影响

      两层神经网络在多个地方的应用说明了其效用与价值。10年前困扰神经网络界的异或问题被轻松解决。神经网络在这个时候,已经可以发力于语音识别,图像识别,自动驾驶等多个领域。

      历史总是惊人的相似,神经网络的学者们再次登上了《纽约时报》的专访。人们认为神经网络可以解决许多问题。就连娱乐界都开始受到了影响,当年的《终结者》电影中的阿诺都赶时髦地说一句:我的CPU是一个神经网络处理器,一个会学习的计算机。

      但是神经网络仍然存在若干的问题:尽管使用了BP算法,一次神经网络的训练仍然耗时太久,而且困扰训练优化的一个问题就是局部最优解问题,这使得神经网络的优化较为困难。同时,隐藏层的节点数需要调参,这使得使用不太方便,工程和研究人员对此多有抱怨。

      90年代中期,由Vapnik等人发明的SVM(Support Vector Machines,支持向量机)算法诞生,很快就在若干个方面体现出了对比神经网络的优势:无需调参;高效;全局最优解。基于以上种种理由,SVM迅速打败了神经网络算法成为主流。

    图28 Vladimir Vapnik

     

      神经网络的研究再次陷入了冰河期。当时,只要你的论文中包含神经网络相关的字眼,非常容易被会议和期刊拒收,研究界那时对神经网络的不待见可想而知。

     

    五. 多层神经网络(深度学习)

      1.引子  

      在被人摒弃的10年中,有几个学者仍然在坚持研究。这其中的棋手就是加拿大多伦多大学的Geoffery Hinton教授。

      2006年,Hinton在《Science》和相关期刊上发表了论文,首次提出了“深度信念网络”的概念。与传统的训练方式不同,“深度信念网络”有一个“预训练”(pre-training)的过程,这可以方便的让神经网络中的权值找到一个接近最优解的值,之后再使用“微调”(fine-tuning)技术来对整个网络进行优化训练。这两个技术的运用大幅度减少了训练多层神经网络的时间。他给多层神经网络相关的学习方法赋予了一个新名词--“深度学习”。

       很快,深度学习在语音识别领域暂露头角。接着,2012年,深度学习技术又在图像识别领域大展拳脚。Hinton与他的学生在ImageNet竞赛中,用多层的卷积神经网络成功地对包含一千类别的一百万张图片进行了训练,取得了分类错误率15%的好成绩,这个成绩比第二名高了近11个百分点,充分证明了多层神经网络识别效果的优越性。

      在这之后,关于深度神经网络的研究与应用不断涌现。

    图29 Geoffery Hinton 

     

      由于篇幅原因,本文不介绍CNN(Conventional Neural Network,卷积神经网络)与RNN(Recurrent Neural Network,递归神经网络)的架构,下面我们只讨论普通的多层神经网络。

      2.结构

      我们延续两层神经网络的方式来设计一个多层神经网络。

      在两层神经网络的输出层后面,继续添加层次。原来的输出层变成中间层,新加的层次成为新的输出层。所以可以得到下图。

    图30 多层神经网络

     

      依照这样的方式不断添加,我们可以得到更多层的多层神经网络。公式推导的话其实跟两层神经网络类似,使用矩阵运算的话就仅仅是加一个公式而已。

      在已知输入a(1),参数W(1),W(2),W(3)的情况下,输出z的推导公式如下:

         g(W(1) * a(1)) = a(2); 

        g(W(2) * a(2)) = a(3);

    g(W(3) * a(3)) = z;

     

      多层神经网络中,输出也是按照一层一层的方式来计算。从最外面的层开始,算出所有单元的值以后,再继续计算更深一层。只有当前层所有单元的值都计算完毕以后,才会算下一层。有点像计算向前不断推进的感觉。所以这个过程叫做“正向传播”。

      下面讨论一下多层神经网络中的参数。

      首先我们看第一张图,可以看出W(1)中有6个参数,W(2)中有4个参数,W(3)中有6个参数,所以整个神经网络中的参数有16个(这里我们不考虑偏置节点,下同)。

    图31 多层神经网络(较少参数)

     

      假设我们将中间层的节点数做一下调整。第一个中间层改为3个单元,第二个中间层改为4个单元。

      经过调整以后,整个网络的参数变成了33个。

    图32 多层神经网络(较多参数)

     

      虽然层数保持不变,但是第二个神经网络的参数数量却是第一个神经网络的接近两倍之多,从而带来了更好的表示(represention)能力。表示能力是多层神经网络的一个重要性质,下面会做介绍。

      在参数一致的情况下,我们也可以获得一个“更深”的网络。

    图33 多层神经网络(更深的层次)

     

      上图的网络中,虽然参数数量仍然是33,但却有4个中间层,是原来层数的接近两倍。这意味着一样的参数数量,可以用更深的层次去表达。

      3.效果

      与两层层神经网络不同。多层神经网络中的层数增加了很多。

      增加更多的层次有什么好处?更深入的表示特征,以及更强的函数模拟能力。

      更深入的表示特征可以这样理解,随着网络的层数增加,每一层对于前一层次的抽象表示更深入。在神经网络中,每一层神经元学习到的是前一层神经元值的更抽象的表示。例如第一个隐藏层学习到的是“边缘”的特征,第二个隐藏层学习到的是由“边缘”组成的“形状”的特征,第三个隐藏层学习到的是由“形状”组成的“图案”的特征,最后的隐藏层学习到的是由“图案”组成的“目标”的特征。通过抽取更抽象的特征来对事物进行区分,从而获得更好的区分与分类能力。

      关于逐层特征学习的例子,可以参考下图。

    图34 多层神经网络(特征学习)

     

      更强的函数模拟能力是由于随着层数的增加,整个网络的参数就越多。而神经网络其实本质就是模拟特征与目标之间的真实关系函数的方法,更多的参数意味着其模拟的函数可以更加的复杂,可以有更多的容量(capcity)去拟合真正的关系。

      通过研究发现,在参数数量一样的情况下,更深的网络往往具有比浅层的网络更好的识别效率。这点也在ImageNet的多次大赛中得到了证实。从2012年起,每年获得ImageNet冠军的深度神经网络的层数逐年增加,2015年最好的方法GoogleNet是一个多达22层的神经网络。

      在最新一届的ImageNet大赛上,目前拿到最好成绩的MSRA团队的方法使用的更是一个深达152层的网络!关于这个方法更多的信息有兴趣的可以查阅ImageNet网站。

      4.训练

      在单层神经网络时,我们使用的激活函数是sgn函数。到了两层神经网络时,我们使用的最多的是sigmoid函数。而到了多层神经网络时,通过一系列的研究发现,ReLU函数在训练多层神经网络时,更容易收敛,并且预测性能更好。因此,目前在深度学习中,最流行的非线性函数是ReLU函数。ReLU函数不是传统的非线性函数,而是分段线性函数。其表达式非常简单,就是y=max(x,0)。简而言之,在x大于0,输出就是输入,而在x小于0时,输出就保持为0。这种函数的设计启发来自于生物神经元对于激励的线性响应,以及当低于某个阈值后就不再响应的模拟。

      在多层神经网络中,训练的主题仍然是优化和泛化。当使用足够强的计算芯片(例如GPU图形加速卡)时,梯度下降算法以及反向传播算法在多层神经网络中的训练中仍然工作的很好。目前学术界主要的研究既在于开发新的算法,也在于对这两个算法进行不断的优化,例如,增加了一种带动量因子(momentum)的梯度下降算法。 

      在深度学习中,泛化技术变的比以往更加的重要。这主要是因为神经网络的层数增加了,参数也增加了,表示能力大幅度增强,很容易出现过拟合现象。因此正则化技术就显得十分重要。目前,Dropout技术,以及数据扩容(Data-Augmentation)技术是目前使用的最多的正则化技术。

      5.影响

      目前,深度神经网络在人工智能界占据统治地位。但凡有关人工智能的产业报道,必然离不开深度学习。神经网络界当下的四位引领者除了前文所说的Ng,Hinton以外,还有CNN的发明人Yann Lecun,以及《Deep Learning》的作者Bengio。

      前段时间一直对人工智能持谨慎态度的马斯克,搞了一个OpenAI项目,邀请Bengio作为高级顾问。马斯克认为,人工智能技术不应该掌握在大公司如Google,Facebook的手里,更应该作为一种开放技术,让所有人都可以参与研究。马斯克的这种精神值得让人敬佩。

       

    图35 Yann LeCun(左)和 Yoshua Bengio(右)

     

      多层神经网络的研究仍在进行中。现在最为火热的研究技术包括RNN,LSTM等,研究方向则是图像理解方面。图像理解技术是给计算机一幅图片,让它用语言来表达这幅图片的意思。ImageNet竞赛也在不断召开,有更多的方法涌现出来,刷新以往的正确率。

     

    六. 回顾

      1.影响  

      我们回顾一下神经网络发展的历程。神经网络的发展历史曲折荡漾,既有被人捧上天的时刻,也有摔落在街头无人问津的时段,中间经历了数次大起大落。

      从单层神经网络(感知器)开始,到包含一个隐藏层的两层神经网络,再到多层的深度神经网络,一共有三次兴起过程。详见下图。

    图36 三起三落的神经网络

     

      上图中的顶点与谷底可以看作神经网络发展的高峰与低谷。图中的横轴是时间,以年为单位。纵轴是一个神经网络影响力的示意表示。如果把1949年Hebb模型提出到1958年的感知机诞生这个10年视为落下(没有兴起)的话,那么神经网络算是经历了“三起三落”这样一个过程,跟“小平”同志类似。俗话说,天将降大任于斯人也,必先苦其心志,劳其筋骨。经历过如此多波折的神经网络能够在现阶段取得成功也可以被看做是磨砺的积累吧。

      历史最大的好处是可以给现在做参考。科学的研究呈现螺旋形上升的过程,不可能一帆风顺。同时,这也给现在过分热衷深度学习与人工智能的人敲响警钟,因为这不是第一次人们因为神经网络而疯狂了。1958年到1969年,以及1985年到1995,这两个十年间人们对于神经网络以及人工智能的期待并不现在低,可结果如何大家也能看的很清楚。

      因此,冷静才是对待目前深度学习热潮的最好办法。如果因为深度学习火热,或者可以有“钱景”就一窝蜂的涌入,那么最终的受害人只能是自己。神经网络界已经两次有被人们捧上天了的境况,相信也对于捧得越高,摔得越惨这句话深有体会。因此,神经网络界的学者也必须给这股热潮浇上一盆水,不要让媒体以及投资家们过分的高看这门技术。很有可能,三十年河东,三十年河西,在几年后,神经网络就再次陷入谷底。根据上图的历史曲线图,这是很有可能的。

      2.效果  

      下面说一下神经网络为什么能这么火热?简而言之,就是其学习效果的强大。随着神经网络的发展,其表示性能越来越强。

      从单层神经网络,到两层神经网络,再到多层神经网络,下图说明了,随着网络层数的增加,以及激活函数的调整,神经网络所能拟合的决策分界平面的能力。

    图37 表示能力不断增强

     

      可以看出,随着层数增加,其非线性分界拟合能力不断增强。图中的分界线并不代表真实训练出的效果,更多的是示意效果。

      神经网络的研究与应用之所以能够不断地火热发展下去,与其强大的函数拟合能力是分不开关系的。

      3.外因  

      当然,光有强大的内在能力,并不一定能成功。一个成功的技术与方法,不仅需要内因的作用,还需要时势与环境的配合。神经网络的发展背后的外在原因可以被总结为:更强的计算性能,更多的数据,以及更好的训练方法。只有满足这些条件时,神经网络的函数拟合能力才能得已体现,见下图。

    图38 发展的外在原因

     

      之所以在单层神经网络年代,Rosenblat无法制作一个双层分类器,就在于当时的计算性能不足,Minsky也以此来打压神经网络。但是Minsky没有料到,仅仅10年以后,计算机CPU的快速发展已经使得我们可以做两层神经网络的训练,并且还有快速的学习算法BP。

      但是在两层神经网络快速流行的年代。更高层的神经网络由于计算性能的问题,以及一些计算方法的问题,其优势无法得到体现。直到2012年,研究人员发现,用于高性能计算的图形加速卡(GPU)可以极佳地匹配神经网络训练所需要的要求:高并行性,高存储,没有太多的控制需求,配合预训练等算法,神经网络才得以大放光彩。

      互联网时代,大量的数据被收集整理,更好的训练方法不断被发现。所有这一切都满足了多层神经网络发挥能力的条件。

      “时势造英雄”,正如Hinton在2006年的论文里说道的

      “... provided that computers were fast enough, data sets were big enough, and the initial weights were close enough to a good solution. All three conditions are now satisfied.”,

     

      外在条件的满足也是神经网络从神经元得以发展到目前的深度神经网络的重要因素。

      除此以外,一门技术的发扬没有“伯乐”也是不行的。在神经网络漫长的历史中,正是由于许多研究人员的锲而不舍,不断钻研,才能有了现在的成就。前期的Rosenblat,Rumelhart没有见证到神经网络如今的流行与地位。但是在那个时代,他们为神经网络的发展所打下的基础,却会永远流传下去,不会退色。

     

    七. 展望

      1.量子计算

      回到我们对神经网络历史的讨论,根据历史趋势图来看,神经网络以及深度学习会不会像以往一样再次陷入谷底?作者认为,这个过程可能取决于量子计算机的发展。

      根据一些最近的研究发现,人脑内部进行的计算可能是类似于量子计算形态的东西。而且目前已知的最大神经网络跟人脑的神经元数量相比,仍然显得非常小,仅不及1%左右。所以未来真正想实现人脑神经网络的模拟,可能需要借助量子计算的强大计算能力。

      各大研究组也已经认识到了量子计算的重要性。谷歌就在开展量子计算机D-wave的研究,希望用量子计算来进行机器学习,并且在前段时间有了突破性的进展。国内方面,阿里和中科院合作成立了量子计算实验室,意图进行量子计算的研究。

      如果量子计算发展不力,仍然需要数十年才能使我们的计算能力得以突飞猛进的发展,那么缺少了强大计算能力的神经网络可能会无法一帆风顺的发展下去。这种情况可以类比为80-90年时期神经网络因为计算能力的限制而被低估与忽视。假设量子计算机真的能够与神经网络结合,并且助力真正的人工智能技术的诞生,而且量子计算机发展需要10年的话,那么神经网络可能还有10年的发展期。直到那时期以后,神经网络才能真正接近实现AI这一目标。

    图39 量子计算

     

      2.人工智能

      最后,作者想简单地谈谈对目前人工智能的看法。虽然现在人工智能非常火热,但是距离真正的人工智能还有很大的距离。就拿计算机视觉方向来说,面对稍微复杂一些的场景,以及易于混淆的图像,计算机就可能难以识别。因此,这个方向还有很多的工作要做。

      就普通人看来,这么辛苦的做各种实验,以及投入大量的人力就是为了实现一些不及孩童能力的视觉能力,未免有些不值。但是这只是第一步。虽然计算机需要很大的运算量才能完成一个普通人简单能完成的识图工作,但计算机最大的优势在于并行化与批量推广能力。使用计算机以后,我们可以很轻易地将以前需要人眼去判断的工作交给计算机做,而且几乎没有任何的推广成本。这就具有很大的价值。正如火车刚诞生的时候,有人嘲笑它又笨又重,速度还没有马快。但是很快规模化推广的火车就替代了马车的使用。人工智能也是如此。这也是为什么目前世界上各著名公司以及政府都对此热衷的原因。

      目前看来,神经网络要想实现人工智能还有很多的路要走,但方向至少是正确的,下面就要看后来者的不断努力了。

    图40 人工智能

     

    八 总结

      本文回顾了神经网络的发展历史,从神经元开始,历经单层神经网络,两层神经网络,直到多层神经网络。在历史介绍中穿插讲解神经网络的结构,分类效果以及训练方法等。本文说明了神经网络内部实际上就是矩阵计算,在程序中的实现没有“点”和“线”的对象。本文说明了神经网络强大预测能力的根本,就是多层的神经网络可以无限逼近真实的对应函数,从而模拟数据之间的真实关系。除此之外,本文回顾了神经网络发展的历程,分析了神经网络发展的外在原因,包括计算能力的增强,数据的增多,以及方法的创新等。最后,本文对神经网络的未来进行了展望,包括量子计算与神经网络结合的可能性,以及探讨未来人工智能发展的前景与价值。

     

    九. 后记

      本篇文章可以视为作者一年来对神经网络的理解与总结,包括实验的体会,书籍的阅读,以及思考的火花等。神经网络虽然重要,但学习并不容易。这主要是由于其结构图较为难懂,以及历史发展的原因,导致概念容易混淆,一些介绍的博客与网站内容新旧不齐。本篇文章着眼于这些问题,没有太多的数学推导,意图以一种简单的,直观的方式对神经网络进行讲解。在2015年最后一天终于写完。希望本文可以对各位有所帮助。

     

     

      作者很感谢能够阅读到这里的读者。如果看完觉得好的话,还请轻轻点一下赞,你们的鼓励就是作者继续行文的动力。本文的备注部分是一些对神经网络学习的建议,供补充阅读与参考。

      

      目前为止,EasyPR的1.4版已经将神经网络(ANN)训练的模块加以开放,开发者们可以使用这个模块来进行自己的字符模型的训练。有兴趣的可以下载

     

    十. 备注

      神经网络虽然很重要,但是对于神经网络的学习,却并不容易。这些学习困难主要来自以下三个方面:概念,类别,教程。下面简单说明这三点。

      1.概念

      对于一门技术的学习而言,首先最重要的是弄清概念。只有将概念理解清楚,才能顺畅的进行后面的学习。由于神经网络漫长的发展历史,经常会有一些概念容易混淆,让人学习中产生困惑。这里面包括历史的术语,不一致的说法,以及被遗忘的研究等。 

      历史的术语

      这个的代表就是多层感知器(MLP)这个术语。起初看文献时很难理解的一个问题就是,为什么神经网络又有另一个名称:MLP。其实MLP(Multi-Layer Perceptron)的名称起源于50-60年代的感知器(Perceptron)。由于我们在感知器之上又增加了一个计算层,因此称为多层感知器。值得注意的是,虽然叫“多层”,MLP一般都指的是两层(带一个隐藏层的)神经网络。

      MLP这个术语属于历史遗留的产物。现在我们一般就说神经网络,以及深度神经网络。前者代表带一个隐藏层的两层神经网络,也是EasyPR目前使用的识别网络,后者指深度学习的网络。

      不一致的说法

      这个最明显的代表就是损失函数loss function,这个还有两个说法是跟它完全一致的意思,分别是残差函数error function,以及代价函数cost function。loss function是目前深度学习里用的较多的一种说法,caffe里也是这么叫的。cost function则是Ng在coursera教学视频里用到的统一说法。这三者都是同一个意思,都是优化问题所需要求解的方程。虽然在使用的时候不做规定,但是在听到各种讲解时要心里明白。

      再来就是权重weight和参数parameter的说法,神经网络界由于以前的惯例,一般会将训练得到的参数称之为权重,而不像其他机器学习方法就称之为参数。这个需要记住就好。不过在目前的使用惯例中,也有这样一种规定。那就是非偏置节点连接上的值称之为权重,而偏置节点上的值称之为偏置,两者统一起来称之为参数。

      另外一个同义词就是激活函数active function和转移函数transfer function了。同样,他们代表一个意思,都是叠加的非线性函数的说法。

      被遗忘的研究

      由于神经网络发展历史已经有70年的漫长历史,因此在研究过程中,必然有一些研究分支属于被遗忘阶段。这里面包括各种不同的网络,例如SOM(Self-Organizing Map,自组织特征映射网络),SNN(Synergetic Neural Network,协同神经网络),ART(Adaptive Resonance Theory,自适应共振理论网络)等等。所以看历史文献时会看到许多没见过的概念与名词。

      有些历史网络甚至会重新成为新的研究热点,例如RNN与LSTM就是80年代左右开始的研究,目前已经是深度学习研究中的重要一门技术,在语音与文字识别中有很好的效果。 

      对于这些易于混淆以及弄错的概念,务必需要多方参考文献,理清上下文,这样才不会在学习与阅读过程中迷糊。

      2.类别

      下面谈一下关于神经网络中的不同类别。

      其实本文的名字“神经网络浅讲”并不合适,因为本文并不是讲的是“神经网络”的内容,而是其中的一个子类,也是目前最常说的前馈神经网络。根据下图的分类可以看出。

    图41 神经网络的类别

     

      神经网络其实是一个非常宽泛的称呼,它包括两类,一类是用计算机的方式去模拟人脑,这就是我们常说的ANN(人工神经网络),另一类是研究生物学上的神经网络,又叫生物神经网络。对于我们计算机人士而言,肯定是研究前者。

      在人工神经网络之中,又分为前馈神经网络和反馈神经网络这两种。那么它们两者的区别是什么呢?这个其实在于它们的结构图。我们可以把结构图看作是一个有向图。其中神经元代表顶点,连接代表有向边。对于前馈神经网络中,这个有向图是没有回路的。你可以仔细观察本文中出现的所有神经网络的结构图,确认一下。而对于反馈神经网络中,结构图的有向图是有回路的。反馈神经网络也是一类重要的神经网络。其中Hopfield网络就是反馈神经网络。深度学习中的RNN也属于一种反馈神经网络。

      具体到前馈神经网络中,就有了本文中所分别描述的三个网络:单层神经网络,双层神经网络,以及多层神经网络。深度学习中的CNN属于一种特殊的多层神经网络。另外,在一些Blog中和文献中看到的BP神经网络是什么?其实它们就是使用了反向传播BP算法的两层前馈神经网络。也是最普遍的一种两层神经网络。

      通过以上分析可以看出,神经网络这种说法其实是非常广义的,具体在文章中说的是什么网络,需要根据文中的内容加以区分。

      3.教程

      如何更好的学习神经网络,认真的学习一门课程或者看一本著作都是很有必要的。

      说到网络教程的话,这里必须说一下Ng的机器学习课程。对于一个初学者而言,Ng的课程视频是非常有帮助的。Ng一共开设过两门机器学习公开课程:一个是2003年在Standford开设的,面向全球的学生,这个视频现在可以在网易公开课上找到;另一个是2010年专门为Coursera上的用户开设的,需要登陆Coursera上才能学习。

      但是,需要注意点是,这两个课程对待神经网络的态度有点不同。早些的课程一共有20节课,Ng花了若干节课去专门讲SVM以及SVM的推导,而当时的神经网络,仅仅放了几段视频,花了大概不到20分钟(一节课60分钟左右)。而到了后来的课程时,总共10节的课程中,Ng给了完整的两节给神经网络,详细介绍了神经网络的反向传播算法。同时给SVM只有一节课,并且没有再讲SVM的推导过程。下面两张图分别是Ng介绍神经网络的开篇,可以大致看出一些端倪。

    图42 Ng与神经网络

     

      为什么Ng对待神经网络的反应前后相差那么大?事实上就是深度学习的原因。Ng实践了深度学习的效果,认识到深度学习的基础--神经网络的重要性。这就是他在后面重点介绍神经网络的原因。总之,对于神经网络的学习而言,我更推荐Coursera上的。因为在那个时候,Ng才是真正的把神经网络作为一门重要的机器学习方法去传授。你可以从他上课的态度中感受到他的重视,以及他希望你能学好的期望。

     

    版权说明:

      本文中的所有文字,图片,代码的版权都是属于作者和博客园共同所有。欢迎转载,但是务必注明作者与出处。任何未经允许的剽窃以及爬虫抓取都属于侵权,作者和博客园保留所有权利。

      

    参考文献:

      1.Neural Networks

      2.Andrew Ng Neural Networks 

      3.神经网络简史

      4.中科院 史忠植 神经网络 讲义

      5.深度学习 胡晓林

     

     

     这是转发博客园的一篇文章,博主:计算机的潜意识,目前是南大的人工智能方向的在读博士。博客里写了一些机器学习入门的内容,以及分享了他在github上的一个开源项目EasyPR,车牌识别系统。能为初学者提供非常大的帮助,有兴趣的朋友请务必移步前往,一看究竟。

    原文链接:https://www.cnblogs.com/subconscious/p/5058741.html

    展开全文
  • Elasticsearch学习,请先看这一篇

    万次阅读 多人点赞 2016-08-18 21:08:36
    题记:Elasticsearch研究有段时间了,现特将Elasticsearch相关核心知识、原理从初学者认知、学习的角度,从以下9个方面进行详细梳理。欢迎讨论……0. 带着问题上路——ES是如何产生的?(1)思考:大规模数据如何...

    Elasticsearch 最少必要知识实战教程直播回放

    题记:

    Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识、原理从初学者认知、学习的角度,从以下9个方面进行详细梳理。欢迎讨论…

    0. 带着问题上路——ES是如何产生的?

    (1)思考:大规模数据如何检索?

    如:当系统数据量上了10亿、100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:
    1)用什么数据库好?(mysql、sybase、oracle、达梦、神通、mongodb、hbase…)
    2)如何解决单点故障;(lvs、F5、A10、Zookeep、MQ)
    3)如何保证数据安全性;(热备、冷备、异地多活)
    4)如何解决检索难题;(数据库代理中间件:mysql-proxy、Cobar、MaxScale等;)
    5)如何解决统计分析问题;(离线、近实时)

    (2)传统数据库的应对解决方案

    对于关系型数据,我们通常采用以下或类似架构去解决查询瓶颈和写入瓶颈:
    解决要点:
    1)通过主从备份解决数据安全性问题;
    2)通过数据库代理中间件心跳监测,解决单点故障问题;
    3)通过代理中间件将查询语句分发到各个slave节点进行查询,并汇总结果
    这里写图片描述

    (3)非关系型数据库的解决方案

    对于Nosql数据库,以mongodb为例,其它原理类似:
    解决要点:
    1)通过副本备份保证数据安全性;
    2)通过节点竞选机制解决单点问题;
    3)先从配置库检索分片信息,然后将请求分发到各个节点,最后由路由节点合并汇总结果
    这里写图片描述

    另辟蹊径——完全把数据放入内存怎么样?

    我们知道,完全把数据放在内存中是不可靠的,实际上也不太现实,当我们的数据达到PB级别时,按照每个节点96G内存计算,在内存完全装满的数据情况下,我们需要的机器是:1PB=1024T=1048576G
    节点数=1048576/96=10922个
    实际上,考虑到数据备份,节点数往往在2.5万台左右。成本巨大决定了其不现实!

    从前面讨论我们了解到,把数据放在内存也好,不放在内存也好,都不能完完全全解决问题。
    全部放在内存速度问题是解决了,但成本问题上来了。
    为解决以上问题,从源头着手分析,通常会从以下方式来寻找方法:
    1、存储数据时按有序存储;
    2、将数据和索引分离;
    3、压缩数据;
    这就引出了Elasticsearch。

    1. ES 基础一网打尽

    1.1 ES定义

    ES=elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
    Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

    1.2 Lucene与ES关系?

    1)Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

    2)Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

    1.3 ES主要解决问题:

    1)检索相关数据;
    2)返回统计结果;
    3)速度要快。

    1.4 ES工作原理

    当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,如果用户更改了配置)寻找集群中的其它节点,并与之建立连接。这个过程如下图所示:
    这里写图片描述

    1.5 ES核心概念

    1)Cluster:集群。

    ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

    2)Node:节点。

    形成集群的每个服务器称为节点。

    3)Shard:分片。

    当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。
    当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

    4)Replia:副本。

    为提高查询吞吐量或实现高可用性,可以使用分片副本。
    副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。
    当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

    5)全文检索。

    全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。
    全文索引就是把内容根据词的意义进行分词,然后分别创建索引,例如”你们的激情是因为什么事情来的” 可能会被分词成:“你们“,”激情“,“什么事情“,”来“ 等token,这样当你搜索“你们” 或者 “激情” 都会把这句搜出来。

    1.6 ES数据架构的主要概念(与关系数据库Mysql对比)

    这里写图片描述
    (1)关系型数据库中的数据库(DataBase),等价于ES中的索引(Index)
    (2)一个数据库下面有N张表(Table),等价于1个索引Index下面有N多类型(Type),
    (3)一个数据库表(Table)下的数据由多行(ROW)多列(column,属性)组成,等价于1个Type由多个文档(Document)和多Field组成。
    (4)在一个关系型数据库里面,schema定义了表、每个表的字段,还有表和字段之间的关系。 与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
    (5)在数据库中的增insert、删delete、改update、查search操作等价于ES中的增PUT/POST、删Delete、改_update、查GET.

    1.7 ELK是什么?

    ELK=elasticsearch+Logstash+kibana
    elasticsearch:后台分布式存储以及全文检索
    logstash: 日志加工、“搬运工”
    kibana:数据可视化展示。
    ELK架构为数据分布式存储、可视化查询和日志解析创建了一个功能强大的管理链。 三者相互配合,取长补短,共同完成分布式大数据处理工作。

    2. ES特点和优势

    1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。
    2)实时分析的分布式搜索引擎。
    分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作;
    负载再平衡和路由在大多数情况下自动完成。
    3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试)
    4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。

    3、ES性能

    3.1 性能结果展示

    (1)硬件配置:
    CPU 16核 AuthenticAMD
    内存 总量:32GB
    硬盘 总量:500GB 非SSD

    (2)在上述硬件指标的基础上测试性能如下:
    1)平均索引吞吐量: 12307docs/s(每个文档大小:40B/docs)
    2)平均CPU使用率: 887.7%(16核,平均每核:55.48%)
    3)构建索引大小: 3.30111 GB
    4)总写入量: 20.2123 GB
    5)测试总耗时: 28m 54s.

    3.2 性能esrally工具(推荐)

    使用参考:http://blog.csdn.net/laoyang360/article/details/52155481

    4、为什么要用ES?

    4.1 ES国内外使用优秀案例

    1) 2013年初,GitHub抛弃了Solr,采取ElasticSearch 来做PB级的搜索。 “GitHub使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码”。

    2)维基百科:启动以elasticsearch为基础的核心搜索架构。
    3)SoundCloud:“SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务”。
    4)百度:百度目前广泛使用ElasticSearch作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据。

    4.2 我们也需要

    实际项目开发实战中,几乎每个系统都会有一个搜索的功能,当搜索做到一定程度时,维护和扩展起来难度就会慢慢变大,所以很多公司都会把搜索单独独立出一个模块,用ElasticSearch等来实现。

    近年ElasticSearch发展迅猛,已经超越了其最初的纯搜索引擎的角色,现在已经增加了数据聚合分析(aggregation)和可视化的特性,如果你有数百万的文档需要通过关键词进行定位时,ElasticSearch肯定是最佳选择。当然,如果你的文档是JSON的,你也可以把ElasticSearch当作一种“NoSQL数据库”, 应用ElasticSearch数据聚合分析(aggregation)的特性,针对数据进行多维度的分析。

    【知乎:热酷架构师潘飞】ES在某些场景下替代传统DB
    个人以为Elasticsearch作为内部存储来说还是不错的,效率也基本能够满足,在某些方面替代传统DB也是可以的,前提是你的业务不对操作的事性务有特殊要求;而权限管理也不用那么细,因为ES的权限这块还不完善。
    由于我们对ES的应用场景仅仅是在于对某段时间内的数据聚合操作,没有大量的单文档请求(比如通过userid来找到一个用户的文档,类似于NoSQL的应用场景),所以能否替代NoSQL还需要各位自己的测试。
    如果让我选择的话,我会尝试使用ES来替代传统的NoSQL,因为它的横向扩展机制太方便了。

    5. ES的应用场景是怎样的?

    5.1 通常我们面临问题有两个:

    1)新系统开发尝试使用ES作为存储和检索服务器;
    2)现有系统升级需要支持全文检索服务,需要使用ES。
    以上两种架构的使用,以下链接进行详细阐述。
    http://blog.csdn.net/laoyang360/article/details/52227541

    5.2 一线公司ES使用场景:

    1)新浪ES 如何分析处理32亿条实时日志 http://dockone.io/article/505
    2)阿里ES 构建挖财自己的日志采集和分析体系 http://afoo.me/columns/tec/logging-platform-spec.html
    3)有赞ES 业务日志处理 http://tech.youzan.com/you-zan-tong-ri-zhi-ping-tai-chu-tan/
    4)ES实现站内搜索 http://www.wtoutiao.com/p/13bkqiZ.html

    6. 如何部署ES?

    6.1 ES部署(无需安装)

    1)零配置,开箱即用
    2)没有繁琐的安装配置
    3)java版本要求:最低1.7
    我使用的1.8
    [root@laoyang config_lhy]# echo $JAVA_HOME
    /opt/jdk1.8.0_91
    4)下载地址:
    https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/zip/elasticsearch/2.3.5/elasticsearch-2.3.5.zip
    5)启动
    cd /usr/local/elasticsearch-2.3.5
    ./bin/elasticsearch
    bin/elasticsearch -d(后台运行)

    6.2 ES必要的插件

    必要的Head、kibana、IK(中文分词)、graph等插件的详细安装和使用。
    http://blog.csdn.net/column/details/deep-elasticsearch.html

    6.3 ES windows下一键安装

    自写bat脚本实现windows下一键安装。
    1)一键安装ES及必要插件(head、kibana、IK、logstash等)
    2)安装后以服务形式运行ES。
    3)比自己摸索安装节省至少2小时时间,效率非常高。
    脚本说明:
    http://blog.csdn.net/laoyang360/article/details/51900235

    7. ES对外接口(开发人员关注)

    1)JAVA API接口

    http://www.ibm.com/developerworks/library/j-use-elasticsearch-java-apps/index.html

    2)RESTful API接口

    常见的增、删、改、查操作实现:
    http://blog.csdn.net/laoyang360/article/details/51931981

    8.ES遇到问题怎么办?

    1)国外:https://discuss.elastic.co/
    2)国内:http://elasticsearch.cn/

    参考:

    [1] http://www.tuicool.com/articles/7fueUbb
    [2] http://zhaoyanblog.com/archives/495.html
    [3]《Elasticsearch服务器开发》
    [4]《实战Elasticsearch、Logstash、Kibana》
    [5]《Elasticsearch In Action》
    [6]《某ES大牛PPT》

    9、还有吗?

    《死磕 Elasticsearch 方法论》:普通程序员高效精进的 10 大狠招!(免费完整版)
    https://blog.csdn.net/laoyang360/article/details/79293493
    ——————————————————————————————————
    更多ES相关实战干货经验分享,请扫描下方【铭毅天下】微信公众号二维码关注。
    (每周至少更新一篇!)

    这里写图片描述
    和你一起,死磕Elasticsearch
    ——————————————————————————————————

    2016-08-18 21:10 思于家中床前

    作者:铭毅天下
    转载请标明出处,原文地址:
    http://blog.csdn.net/laoyang360/article/details/52244917
    如果感觉本文对您有帮助,请点击‘顶’支持一下,您的支持是我坚持写作最大的动力,谢谢!

    展开全文
  • fastText原理和文本分类实战,看这一篇就够了

    万次阅读 多人点赞 2019-03-19 11:19:48
    fastText原理 、fastText简介 fastText是个快速文本分类算法,与基于神经网络的分类算法相比有两大优点: 1、fastText在保持高精度的情况下加快了训练速度和测试速度 2、fastText不需要预训练好的向量,...

    前言:若需获取本文全部的手书版原稿资料,扫码关注公众号,回复: FastText 即可获取。

    原创不易,转载请告知并注明出处!扫码关注公众号【机器学习与自然语言处理】,定期发布知识图谱,自然语言处理、机器学习等知识,添加微信号【17865190919】进讨论群,加好友时备注来自CSDN。
    机器学习与自然语言处理

    Word2vec, Fasttext, Glove, Elmo, Bert, Flair pre-train Word Embedding源码+数据Github网址: 词向量预训练实现Github


    fastText原理篇

    一、fastText简介

    fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点:
    1、fastText在保持高精度的情况下加快了训练速度和测试速度
    2、fastText不需要预训练好的词向量,fastText会自己训练词向量
    3、fastText两个重要的优化:Hierarchical Softmax、N-gram

    二、fastText模型架构

    fastText模型架构和word2vec中的CBOW很相似, 不同之处是fastText预测标签而CBOW预测的是中间词,即模型架构类似但是模型的任务不同。下面我们先看一下CBOW的架构:
    在这里插入图片描述
    word2vec将上下文关系转化为多分类任务,进而训练逻辑回归模型,这里的类别数量|V|词库大小。通常的文本数据中,词库少则数万,多则百万,在训练中直接训练多分类逻辑回归并不现实。word2vec中提供了两种针对大规模多分类问题的优化手段, negative sampling 和hierarchical softmax。在优化中,negative sampling 只更新少量负面类,从而减轻了计算量。hierarchical softmax 将词库表示成前缀树,从树根到叶子的路径可以表示为一系列二分类器,一次多分类计算的复杂度从|V|降低到了树的高度

    fastText模型架构:其中x1,x2,…,xN−1,xN表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的cbow相似,cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别
    在这里插入图片描述

    三、层次softmax

    softmax函数常在神经网络输出层充当激活函数,目的就是将输出层的值归一化到0-1区间,将神经元输出构造成概率分布,主要就是起到将神经元输出值进行归一化的作用,下图展示了softmax函数对于输出值z1=3,z2=1,z3=-3的归一化映射过程
    在这里插入图片描述
    在标准的softmax中,计算一个类别的softmax概率时,我们需要对所有类别概率做归一化,在这类别很大情况下非常耗时,因此提出了分层softmax(Hierarchical Softmax),思想是根据类别的频率构造霍夫曼树来代替标准softmax,通过分层softmax可以将复杂度从N降低到logN,下图给出分层softmax示例:
    在这里插入图片描述
    在层次softmax模型中,叶子结点的词没有直接输出的向量,而非叶子节点都有响应的输在在模型的训练过程中,通过Huffman编码,构造了一颗庞大的Huffman树,同时会给非叶子结点赋予向量。我们要计算的是目标词w的概率,这个概率的具体含义,是指从root结点开始随机走,走到目标词w的概率。因此在途中路过非叶子结点(包括root)时,需要分别知道往左走和往右走的概率。例如到达非叶子节点n的时候往左边走和往右边走的概率分别是:
    在这里插入图片描述
    以上图中目标词为w2为例,
    在这里插入图片描述
    到这里可以看出目标词为w的概率可以表示为:
    在这里插入图片描述
    其中θn(w,j)是非叶子结点n(w,j)的向量表示(即输出向量);h是隐藏层的输出值,从输入词的向量中计算得来;sign(x,j)是一个特殊函数定义
    在这里插入图片描述
    此外,所有词的概率和为1,即
    在这里插入图片描述
    最终得到参数更新公式为:
    在这里插入图片描述

    四、N-gram特征

    n-gram是基于语言模型的算法,基本思想是将文本内容按照子节顺序进行大小为N的窗口滑动操作,最终形成窗口为N的字节片段序列。而且需要额外注意一点是n-gram可以根据粒度不同有不同的含义,有字粒度的n-gram和词粒度的n-gram,下面分别给出了字粒度和词粒度的例子:
    在这里插入图片描述
    在这里插入图片描述
    对于文本句子的n-gram来说,如上面所说可以是字粒度或者是词粒度,同时n-gram也可以在字符级别工作,例如对单个单词matter来说,假设采用3-gram特征,那么matter可以表示成图中五个3-gram特征,这五个特征都有各自的词向量,五个特征的词向量和即为matter这个词的向其中“<”和“>”是作为边界符号被添加,来将一个单词的ngrams与单词本身区分开来:
    在这里插入图片描述
    从上面来看,使用n-gram有如下优点
    1、为罕见的单词生成更好的单词向量:根据上面的字符级别的n-gram来说,即是这个单词出现的次数很少,但是组成单词的字符和其他单词有共享的部分,因此这一点可以优化生成的单词向量
    2、在词汇单词中,即使单词没有出现在训练语料库中,仍然可以从字符级n-gram中构造单词的词向量
    3、n-gram可以让模型学习到局部单词顺序的部分信息, 如果不考虑n-gram则便是取每个单词,这样无法考虑到词序所包含的信息,即也可理解为上下文信息,因此通过n-gram的方式关联相邻的几个词,这样会让模型在训练的时候保持词序信息

    但正如上面提到过,随着语料库的增加,内存需求也会不断增加,严重影响模型构建速度,针对这个有以下几种解决方案:
    1、过滤掉出现次数少的单词
    2、使用hash存储
    3、由采用字粒度变化为采用词粒度



    fastText实战篇

    fastText实战篇来自对fastText官方文档的翻译,官网网址为:fasttext学习官网,英文阅读能力好的强烈建议直接读原文,下面翻译可以提供给不想读英文文档的读者,翻译能力有限,有错请指正!

    一、Fasttext介绍

    1、什么是fastText

    fastText是一个高效学习单词表示和句子分类

    2、fastText环境要求

    fastText需要运行在Mac OS或Linux上,因为fastText使用了C++11,因此需要很好支持C++11的编译器,支持的编译器包括:
    (1) gcc-4.6.3 或者更新版本
    (2) clang-3.3 或者更新版本

    编译是使用Makefile执行的,因此你需要有一个工作的make,对于单词相似度评估脚本则需要如下环境:
    (1) python2.6 或者更新
    (2) numpy 和 spicy

    3、在本地快速搭建fastText

    为了搭建fastText,打开命令窗口依次执行以下命令:

    $ git clone https://github.com/facebookresearch/fastText.git
    $ cd fastText
    $ make
    

    上述命令将为所有类和主二进制fastText生成目标文件,如果你不打算使用默认的系统范围编译器,可以更新Makefile(CC和include)开头定义的两个宏

    二、fastText教程-文本分类

    文本分类对许多应用来说都是一个核心问题,例如:垃圾邮件分类、情感分析以及智能问答等。在此教程中,详细阐述通过fastText如何搭建一个文本分类模型

    1、什么是文本分类

    文本分类的目的是将文档(例如电子邮件、帖子、文本消息,产品评论等)分给一个或多个类别,表示这些类别可以是评价分数,垃圾邮件、非垃圾邮件,或者是文档所用的语言。目前,构建此类分类器最主要的方法是机器学习,机器学习方法从实例中学习分类规则,为了构建分类器,我们需要带标签的数据,标签数据指的数据包括文档和此文档所对应的类别(或称标记或标签),例如,我们可以构建一个分类器,该分类器将cooking自动分为几个标签如:pot、bowl、baking

    2、安装fastText

    首先我们需要做的便是安装搭建fastText,需要系统支持c++ 11的c++编译器,先从GitHub上下载fastText到本地(版本在更新,可以到GitHub上查看最近版本进行下载):

    $ wget https://github.com/facebookresearch/fastText/archive/v0.1.0.zip
    

    然后将下载的zip文件夹进行解压,解压后进入目录对fastText项目执行make命令进行编译(因此这里便需要你的系统有支持c++11的编译器)

    $ unzip v0.1.0.zip
    $ cd fastText-0.1.0
    $ make
    

    在根目录下运行名为fasttext的二进制文件,便会打印出fastText支持的各种不同的命令,如:supervised进行模型训练,quantize量化模型以减少内存使用,test进行模型测试,predict预测最可能的标签等,运行结果如下所示:

    >> ./fasttext
    usage: fasttext <command> <args>
    
    The commands supported by fasttext are:
    
      supervised              train a supervised classifier
      quantize                quantize a model to reduce the memory usage
      test                    evaluate a supervised classifier
      predict                 predict most likely labels
      predict-prob            predict most likely labels with probabilities
      skipgram                train a skipgram model
      cbow                    train a cbow model
      print-word-vectors      print word vectors given a trained model
      print-sentence-vectors  print sentence vectors given a trained model
      nn                      query for nearest neighbors
      analogies               query for analogies
      
    
    上述的命令包括:
    supervised: 训练一个监督分类器
    quantize:量化模型以减少内存使用量
    test:评估一个监督分类器
    predict:预测最有可能的标签 
    predict-prob:用概率预测最可能的标签
    skipgram:训练一个 skipgram 模型
    cbow:训练一个 cbow 模型
    print-word-vectors:给定一个训练好的模型,打印出所有的单词向量
    print-sentence-vectors:给定一个训练好的模型,打印出所有的句子向量
    nn:查询最近邻居
    analogies:查找所有同类词
    

    在本节fastText文本分类中,我们主要使用SUPERVISED、TEST和PREDICT命令,在下一小节中我们主要介绍FASTTEXT关于学习单词向量的模型

    3、获取数据及数据预处理

    正如上面所说,我们需要带有标签的数据去训练我们的监督学习的分类器,本教程中,我们使用cooking相关数据构建我们的分类器,因此首先我们下载数据,数据网址为stackexchange,进行如下命令操作:

    >> wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz
    >> tar xvzf cooking.stackexchange.tar.gz
    >> head cooking.stackexchange.txt
    

    通过head命令便可看到文档形式,文档的每一行都包含一个标签,标签后面跟着相应的单词短语,所有的标签都以__label__前缀开始,这事fastText便是标签和单词短语的方式,训练的模型便是预测文档中给定单词短语预测其对应的标签

    在训练分类器之前,我们需要将数据分割成训练集和验证集,我们将使用验证集来评估学习到的分类器对新数据的性能好坏,先通过下面命令来查看文档中总共含有多少数据:

    >> wc cooking.stackexchange.txt 
       15404  169582 1401900 cooking.stackexchange.txt
    

    可以看到我们数据中总共包含了15404个示例,我们把文档分成一个包含12404个示例的训练集和一个包含3000个示例的验证集,执行如下命令:

    >> head -n 12404 cooking.stackexchange.txt > cooking.train
    >> tail -n 3000 cooking.stackexchange.txt > cooking.valid
    
    4、使用fastText快速搭建分类器

    上面数据已经准备好了,接下来我们便开始训练我们的模型,首先执行如下命令进行模型的训练:

    >> ./fasttext supervised -input cooking.train -output model_cooking
    Read 0M words
    Number of words:  14598
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 75109  lr: 0.000000  loss: 5.708354  eta: 0h0m 
    

    -input命令选项指示训练数据,-output选项指示的是保存的模型的位置,在训练结束后,文件model_cooking.bin是在当前目录中创建的,model_cooking.bin便是我们保存训练模型的文件

    模型训练好之后,我们可以交互式测试我们的分类器,即单独测试某一个句子所属的类别,可以通过以下命令进行交互式测试:

    >> ./fasttext predict model_cooking.bin -
    

    输入以上命令后,命令行会提示你输入句子,然后我们可以进行如下句子测试:

    Which baking dish is best to bake a banana bread ?

    上面句子可以得到预测的标签是baking,显然这个预测结果是正确的,我们再进行尝试

    Why not put knives in the dishwasher?

    上面句子预测的标签是food-safety,可以看出是不相关的,显然预测的不正确,为了验证学习到的分类模型的好坏,我们在验证集上对它进行测试,观察模型的精准率precision和召回率recall:

    >> ./fasttext test model_cooking.bin cooking.valid                 
    N  3000
    P@1  0.124
    R@1  0.0541
    Number of examples: 3000
    
    5、精准率Precision和召回率Recall

    精准率Precision指的是预测为正样本中有多少是真正的正样本,召回率Recall指的是样本中的正样本有多少被预测正确了,因此精准率看的是预测为某一类的样本中有多少是真正的属于这一类的,而召回率看的是在分类任务中某一类样本是否完全被预测正确,下面通过一个例子来更清楚的认识这个概念,以下面句子为例:

    Why not put knives in the dishwasher?

    上面句子的正式标签有三个,分别是:equipment, cleaning and knives

    然后我们通过模型对上面句子进行预测,执行如下命令:

    >> ./fasttext predict model_cooking.bin - 5
    

    预测得到的结果分别是:food-safety, baking, equipment, substitutions, bread

    可以看出五个预测的标签中只预测正确了一个标签equipment,我们来看,预测的样本中正确的样本所占的比例即是精准率,因此精准率为1/5=0.2;而真实标签中有多少预测正确了即是召回率,因此召回率为1/3=0.33,这样我们应该能明白精准率和召回率的概念了,想更加详细的了解精准率和召回率,请参考维基百科精准率和召回率

    6、模型优化

    上面通过使用默认参数运行fastText训练得到的模型在分类新问题上效果很差,接下来我们通过更改默认参数来提高性能

    (1) 方案一:数据预处理

    查看数据,我们发现有些单词包含大写字母和标点符号,因此改善模型性能的第一步就是应用一些简单的预处理,预处理可以使用命令行工具例如sed、tr来对文本进行简单的标准化操作,执行命令如下:

    >> cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
    >> head -n 12404 cooking.preprocessed.txt > cooking.train
    >> tail -n 3000 cooking.preprocessed.txt > cooking.valid 
    

    接下来我们在预处理的数据集上进行模型训练并进行测试,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 82041  lr: 0.000000  loss: 5.671649  eta: 0h0m h-14m 
    
    >> ./fasttext test model_cooking.bin cooking.valid 
    N  3000
    P@1  0.164
    R@1  0.0717
    Number of examples: 3000
    

    观察上面的结果,由于对数据预处理,词典变小了,由原来的14K个单词变成了9K,精准率也上升了4%,因此数据预处理起到了一定的效果

    (2) 方案二:更多的训练次数和更大的学习率

    在默认情况下,fastText在训练期间对每个训练用例仅重复使用五次,这太小,因为我们的训练集只有12k训练样例,因此我们可以通过-epoch选项增加每个样例的使用次数,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -epoch 25 
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 77633  lr: 0.000000  loss: 7.147976  eta: 0h0m
    

    然后测试模型查看效果:

    >> ./fasttext test model_cooking.bin cooking.valid                                        
    N  3000
    P@1  0.501
    R@1  0.218
    Number of examples: 3000
    

    从上面测试效果可以看出,精准率和召回率都有了大幅度提升,可见增加每个样例的使用次数对于数据集少的情况下效果提升明显。另一个增强算法能力是改变模型的学习速度即学习速率,这对应于处理每个示例后模型的更改程度,当学习率为0时意味着模型根本不会发生改变,因此不会学到任何东西,良好的学习率值在0.1-1.0的范围内,下面我们通过设置算法学习率为learning rate = 1.0进行模型训练:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0  
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 81469  lr: 0.000000  loss: 6.405640  eta: 0h0m
    
    >> ./fasttext test model_cooking.bin cooking.valid                         
    N  3000
    P@1  0.563
    R@1  0.245
    Number of examples: 3000
    

    可以看到效果比上面增加epoch还要好,下面我们来将二者结合起来:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 76394  lr: 0.000000  loss: 4.350277  eta: 0h0m
    
    >> ./fasttext test model_cooking.bin cooking.valid                                   
    N  3000
    P@1  0.585
    R@1  0.255
    Number of examples: 3000
    

    下面我们来增加一些新的方式来进一步提升模型的性能,看方案三

    (3) 方案三:word n-grams

    此方案中,我们使用单词bigrams而不是仅仅是unigrams来提高模型的性能,这对于词序很重要的分类问题尤其重要,例如情感分析。n-gram是基于语言模型的算法,基本思想是将文本内容按照子节顺序进行大小为N的窗口滑动操作,最终形成窗口为N的字节片段序列。训练模型命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 75366  lr: 0.000000  loss: 3.226064  eta: 0h0m 
    
    >> ./fasttext test model_cooking.bin cooking.valid                                                 
    N  3000
    P@1  0.599
    R@1  0.261
    Number of examples: 3000
    

    通过几个步骤,可以看出我们将模型精准率从12.4%提升到了59.9%,总结一下主要包含以下步骤:
    (1) 数据预处理
    (2) 更改样本训练次数epochs(使用参数 –epoch,标准范围[5, 50])
    (3) 更改学习率learning rate(使用参数 –lr,标准范围[0.1-1])
    (4) 使用word n-grams(使用参数 –wordNgrams,标准范围[1-5])

    7、什么是Bigram

    unigram指的是单个不可分割的单元和标记,通常用做模型的输入,并且在不同的模型中unigram可以是单词或是字母,在fastText中,我们是在单词级别上进行训练模型,因此unigram是单词。类似的,bigram值的是两个连续的单词的串联,n-grams指的便是n个单词的串联。举个例子,现在有这样一句话:Last donut of the night,如果是unigrams则是last,donut,of,the,night,而对于bigrams指的是last donut,donut of,of the,the night

    8、提升训练速度

    目前我们在几千个示例中训练我们的模型,训练只需要几秒钟,但如果数据集增大,标签增多,这时模型训练便会变慢,一个让训练变快的方案便是使用分层softmax,而不是使用常规softmax,使用分层softmax是使用参数 –loss hs实现,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2 -bucket 200000 -dim 50 -loss hs
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 2199406  lr: 0.000000  loss: 1.718807  eta: 0h0m 
    

    此时对于我们当前的数据集,训练速度应该不超过1秒

    9、总结

    本教程中我们简单介绍了如何使用fastText来训练强大的分类器,同时介绍了一些重要的参数选项,通过调参来进行模型优化


    三、fastText教程-单词表示词向量

    现在机器学习中一个十分流行的做法便是用向量表示单词,即词向量化wordEmbedding,这些向量可以捕捉到有关语言的一些隐藏信息,例如语法信息,语义信息等,好的词向量表示可以提升分类器的性能,在本教程中,我们展示如何使用fastText工具来构建词向量,安装fastText过程请参考上一讲

    1、获取数据

    为了计算词向量,我们需要一个大的文本语料库,根据语料库的不同,单词向量也将捕捉到不同的信息,在本教程中,我们关注Wikipedia的文章,当然也可以考虑其他语料库来源,例如新闻活着Webcrawl,下载Wikipedia语料库执行如下命令:

    wget https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
    

    下载Wikipedia语料库需要挺长时间,如果不使用Wikipedia全部语料库信息,我们可以在Wikipedia前10亿字节信息进行词向量学习,此数据可以在Matt Mahoney网站上下载

    $ mkdir data
    $ wget -c http://mattmahoney.net/dc/enwik9.zip -P data
    $ unzip data/enwik9.zip -d data
    

    这样我们便获得了Wikipedia的部分数据,因为Wikipedia语料库中包含大量的HTML/XML数据,因此需要对数据进行预处理,我们可以使用与fastText自带的wikifil.pl脚本对其进行预处理,这个脚本最初由Matt Mahoney创建,因此可以在下面网址上找到:http://mattmahoney.net/,执行如下命令对数据进行预处理:

    $ perl wikifil.pl data/enwik9 > data/fil9
    

    我们可以执行如下命令检查我们的文件数据:

    $ head -c 80 data/fil9
    anarchism originated as a term of abuse first used against early working class
    

    可以观察到我们的文本经过了很好的处理,接下来可以用文本来学习词向量

    2、训练词向量

    数据集已经取到了,现在我们可以使用如下的简单命令在上述数据集上训练我们的词向量

    $ mkdir result
    $ ./fasttext skipgram -input data/fil9 -output result/fil9
    

    分解上述命令:./fasttext使用skipgram模型调用二进制fastText可执行文件,当然也可以使用cbow模型,-input表示输入数据路径,-output表示训练的词向量模型所在路径,当fastText运行时,屏幕会显示进度和估计的完成时间,程序完成后,结果目录应该出现如下两个文件,可通过下面命令查看:

    $ ls -l result
    -rw-r-r-- 1 bojanowski 1876110778 978480850 Dec 20 11:01 fil9.bin
    -rw-r-r-- 1 bojanowski 1876110778 190004182 Dec 20 11:01 fil9.vec
    

    fil9.bin文件是一个二进制文件,它存储了整个fastText模型,随后可以进行加载,fil9.vec文件是一个包含单词向量的文本文件,每一行对应词汇表中的每个单词,可通过如下命令查看fil9.vec中的信息

    $ head -n 4 result/fil9.vec
    218316 100
    the -0.10363 -0.063669 0.032436 -0.040798 0.53749 0.00097867 0.10083 0.24829 ...
    of -0.0083724 0.0059414 -0.046618 -0.072735 0.83007 0.038895 -0.13634 0.60063 ...
    one 0.32731 0.044409 -0.46484 0.14716 0.7431 0.24684 -0.11301 0.51721 0.73262 ...
    

    从上面结果可见,第一行显示的是单词向量和向量维度,接下来几行是词汇表中所有单词的单词向量,顺序是按照频率降低的顺序进行排序

    3、skipgram VS cbow

    fastText为计算单词表示提供了两种模型:skipgram和cbow,这和word2vec一样,cbow全称:Continuous-bag-of-words,skipgram模型运行机理是通过附近的词来预测目标单词,而cbow模型则是根据目标词的上下文来预测目标词,这里的上下文指的便是目标词周围的固定大小窗口中包含的单词包,下面通过例子便能够体会到上下文的含义。例如:给出这样一个句子:

    Poets have been mysteriously silient on the subject of cheese

    其目标词是slient,skipgram模型是通过目标词附近的词去预测slient,例如subjector, mysteriously, 而cbow模型则是通过目标词的上下文词来预测slient,如:{been, mysteriously, on, the},并且使用单词的向量预测目标,下面一个示例图展示了二者的差异,使用的句子是

    I am selling these fine leather jackets

    在这里插入图片描述

    上面已经使用skipgram模型对数据集进行了训练,如果想用cbow模型训练之行如下命令

    ./fasttext cbow -input data/fil9 -output result/fil9
    

    从实际效果中看,我们会发现skipgram模型对于单词信息的处理效果要优于cbow模型

    4、模型参数调优

    上面的训练都是使用的默认的参数运行fastText,但根据数据的不同,这些参数可能不是最优的,让我们介绍一下子向量的一些关键参数。

    模型中最重要的两个参数是:词向量大小维度、subwords范围的大小,词向量维度越大,便能获得更多的信息但同时也需要更多的训练数据,同时如果它们过大,模型也就更难训练速度更慢,默认情况下使用的是100维的向量,但在100-300维都是常用到的调参范围。subwords是一个单词序列中包含最小(minn)到最大(maxn)之间的所有字符串(也即是n-grams),默认情况下我们接受3-6个字符串中间的所有子单词,但不同的语言可能有不同的合适范围

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -minn 2 -maxn 5 -dim 300
    

    下面介绍另外两个参数:epoch、learning rate、epoch根据训练数据量的不同,可以进行更改,epoch参数即是控制训练时在数据集上循环的次数,默认情况下在数据集上循环5次,但当数据集非常大时,我们也可以适当减少训练的次数,另一个参数学习率,学习率越高模型收敛的速度就越快,但存在对数据集过度拟合的风险,默认值时0.05,这是一个很好的折中,当然在训练过程中,也可以对其进行调参,可调范围是[0.01, 1],下面命令便尝试对这两个参数进行调整:

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -epoch 1 -lr 0.5
    

    最后fastText是多线程的,默认情况下使用12个线程,如果你的机器只有更少的CPU核数,也可以通过如下参数对使用的CPU核数进行调整

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -thread 4
    
    5、打印词向量

    直接从fil9.vec文件中搜索和打印词向量是十分麻烦的,但幸运的是fastText提供了打印词向量的功能,我们可以通过fastText中print-word-vectors功能打印词向量,例如,我们可以使用以下命令打印单词asparagus、pidgey和yellow单词的词向量:

    $ echo "asparagus pidgey yellow" | ./fasttext print-word-vectors result/fil9.bin
    asparagus 0.46826 -0.20187 -0.29122 -0.17918 0.31289 -0.31679 0.17828 -0.04418 ...
    pidgey -0.16065 -0.45867 0.10565 0.036952 -0.11482 0.030053 0.12115 0.39725 ...
    ·0.040719 -0.30155 ...
    

    一个很好的功能是我们可以查询到未出现在数据中的单词,实际上,单词是由字符串的总和组成,只要未知的单词是由已知的字串构成,就可以得到单词的词向量,举个例子下面尝试一下查询拼写出错的单词:

    $ echo "enviroment" | ./fasttext print-word-vectors result/fil9.bin
    

    结果仍然可以查询到词向量,但是至于效果怎么样,我们可以在下一节找到答案

    6、临近词向量查询

    检查单词向量质量的一种简单的方法是查看此此单词的临近词,可以通过临近词比较来查看词向量对于语义的表达。最临近词向量查询可以通过fastText提供的nn功能来实现,例如我们可以通过运行一下命令来查询单词10个最近邻居:

    $ ./fasttext nn result/fil9.bin
    Pre-computing word vectors... done.
    

    然后命令行便会提示我们输入需要查询的词,我们尝试一下asparagus

    Query word? asparagus
    beetroot 0.812384
    tomato 0.806688
    horseradish 0.805928
    spinach 0.801483
    licorice 0.791697
    lingonberries 0.781507
    asparagales 0.780756
    lingonberry 0.778534
    celery 0.774529
    beets 0.773984
    

    从上面结果可以看出效果不错,查询词之间由很大的共性,再尝试查询pidgey,结果如下

    Query word? pidgey
    pidgeot 0.891801
    pidgeotto 0.885109
    pidge 0.884739
    pidgeon 0.787351
    pok 0.781068
    pikachu 0.758688
    charizard 0.749403
    squirtle 0.742582
    beedrill 0.741579
    charmeleon 0.733625
    

    上面提到了如果单词拼写出错可能影响词向量的查询,那如果单词拼写错误,如果查询其临近词结果如何,下面展示一下效果:

    Query word? enviroment
    enviromental 0.907951
    environ 0.87146
    enviro 0.855381
    environs 0.803349
    environnement 0.772682
    enviromission 0.761168
    realclimate 0.716746
    environment 0.702706
    acclimatation 0.697196
    ecotourism 0.697081
    

    可以看出虽然单词拼写出错,但是查询结果还是捕获到了单词的主要信息,拼写出错的单词也与合理的单词匹配,虽然还是有一些影响,但整体方向是正确的。

    为了找到词向量临近的单词,我们需要计算的单词之间的相似度得分。模型训练的单词是由连续的单词向量表示,因此我们可以对其进行相似度的比较,一般情况下,我们使用余弦相似度去衡量两个单词之间的相似度,我们可以计算词汇表中任意单词和所有其他单词之间的相似度,并显示10个最相似单词,当然被查询单词本身肯定排在顶部,相似度为1

    7、单词类比

    在相似度问题中,有时会进行单词类比,例如我们训练的模型能够知道法国是什么,并且知道柏林对于德国来说意味着什么。这个在fastText中是可以做到的,利用单词类比这个功能即可实现,例如下面我们输入三个单词,然后输出单词的类比单词:

    $ ./fasttext analogies result/fil9.bin
    Pre-computing word vectors... done.
    Query triplet (A - B + C)? berlin germany france
    paris 0.896462
    bourges 0.768954
    louveciennes 0.765569
    toulouse 0.761916
    valenciennes 0.760251
    montpellier 0.752747
    strasbourg 0.744487
    meudon 0.74143
    bordeaux 0.740635
    pigneaux 0.736122
    

    上面模型类比功能提供的最可能结果是巴黎,显然是十分准确,下面我们再来看一个不太明显的例子:

    Query triplet (A - B + C)? psx sony nintendo
    gamecube 0.803352
    nintendogs 0.792646
    playstation 0.77344
    sega 0.772165
    gameboy 0.767959
    arcade 0.754774
    playstationjapan 0.753473
    gba 0.752909
    dreamcast 0.74907
    famicom 0.745298
    

    从上面结果可以看出模型认为psx是索尼的游戏手柄,因此nintendo任天堂类比的是gamecube,这个类比也比较合理。当然类比的质量也取决于训练模型的数据集,类比的结果也仅仅在数据集的范围内

    8、 字符n-grams重要性

    利用subword-level信息也即是n-grams对于构建未知单词词向量很有趣,例如Wikipedia中不存在gearshift这个单词,但是我们仍然能够查询到它的临近单词:

    Query word? gearshift
    gearing 0.790762
    flywheels 0.779804
    flywheel 0.777859
    gears 0.776133
    driveshafts 0.756345
    driveshaft 0.755679
    daisywheel 0.749998
    wheelsets 0.748578
    epicycles 0.744268
    gearboxes 0.73986
    

    效果还可以,因为大多数被检索到的单词共享大量的子串,当然也有些特殊的单词比较特殊,例如cogwheel,我们可以看到subword-level对于未知单词查询所起到的效果,但是如果我们在训练模型的时候没有使用subwords这个参数,结果会如何,下面我们便进行尝试,运行以下命令训练没有subwords的模型:

    $ ./fasttext skipgram -input data/fil9 -output result/fil9-none -maxn 0
    

    此时训练的模型保存在result/fil9-non.vec和result/fil9-non.bin,为了表明不加subwords模型的不同,我们再举一个wikipedia中不常见的单词如:accomodation,就类似于accommodation住宿这个单词,下面给出其相似词的查询结果:

    $ ./fasttext nn result/fil9-none.bin
    Query word? accomodation
    sunnhordland 0.775057
    accomodations 0.769206
    administrational 0.753011
    laponian 0.752274
    ammenities 0.750805
    dachas 0.75026
    vuosaari 0.74172
    hostelling 0.739995
    greenbelts 0.733975
    asserbo 0.732465
    

    可以看出结果中的词没有任何意义,大多数词都是不想关的,我们再用使用了subwords的模型测试accomodation的相似词,结果便有明显的差别:

    Query word? accomodation
    accomodations 0.96342
    accommodation 0.942124
    accommodations 0.915427
    accommodative 0.847751
    accommodating 0.794353
    accomodated 0.740381
    amenities 0.729746
    catering 0.725975
    accomodate 0.703177
    hospitality 0.701426
    

    上面结果准确捕捉到相似度很高的accommodation这个单词,同时我们还捕获到语义相关的词如:便利设施amenities和寄宿lodging,因此训练模型加上subwords参数对模型效果有很大的提升

    9、 结论

    在小节中,详细展示了如果在wikipedia上获得词向量,对于其他语言也都可以同样运行,下面网址提供了fastText在词向量上的多个预训练模型,可以参考使用预训练模型网址


    四、常用命令备忘录

    词向量的学习-使用fastText学习词向量执行以下命令:

    $ ./fasttext skipgram -input data.txt -output model
    

    取得词向量-将模型学习得词向量打印到文件中执行如下命令:

    $ ./fasttext print-word-vectors model.bin < queries.txt
    

    文本分类-训练一个文本分类模型执行如下命令:

    $ ./fasttext supervised -input train.txt -output model
    

    当一个模型训练结束后,我们可以通过在测试集上计算精准率Precision和召回率Recall进行模型评估,执行如下命令:

    $ ./fasttext test model.bin test.txt 1
    

    为了直接预测一段文本最可能的k个标签,执行如下命令:

    $ ./fasttext predict model.bin test.txt k
    

    为了直接预测一段文本的k个最可能的标签及其相关概率大小,可以执行如下命令:

    $ ./fasttext predict-prob model.bin test.txt k
    

    如果想要计算句子或段落的向量表示,执行如下命令:

    $ ./fasttext print-sentence-vectors model.bin < text.txt
    

    为了创建一个内存更小的模型可以执行如下命令

    $ ./fasttext quantize -output model
    

    所有其他的命令都类似下面test命令

    $ ./fasttext test model.ftz test.txt
    

    五、模型可选参数列表及默认值

    $ ./fasttext supervised
    Empty input or output path.
    
    The following arguments are mandatory:
      -input              training file path
      -output             output file path
    
      The following arguments are optional:
      -verbose            verbosity level [2]
    
      The following arguments for the dictionary are optional:
      -minCount           minimal number of word occurrences [5]
      -minCountLabel      minimal number of label occurrences [0]
      -wordNgrams         max length of word ngram [1]
      -bucket             number of buckets [2000000]
      -minn               min length of char ngram [3]
      -maxn               max length of char ngram [6]
      -t                  sampling threshold [0.0001]
      -label              labels prefix [__label__]
    
      The following arguments for training are optional:
      -lr                 learning rate [0.05]
      -lrUpdateRate       change the rate of updates for the learning rate [100]
      -dim                size of word vectors [100]
      -ws                 size of the context window [5]
      -epoch              number of epochs [5]
      -neg                number of negatives sampled [5]
      -loss               loss function {ns, hs, softmax} [ns]
      -thread             number of threads [12]
      -pretrainedVectors  pretrained word vectors for supervised learning []
      -saveOutput         whether output params should be saved [0]
    
      The following arguments for quantization are optional:
      -cutoff             number of words and ngrams to retain [0]
      -retrain            finetune embeddings if a cutoff is applied [0]
      -qnorm              quantizing the norm separately [0]
      -qout               quantizing the classifier [0]
      -dsub               size of each sub-vector [2]
    

    默认值可能因模型不同,例如单词表示模型skip gram和cbow使用默认的minCount为5


    六、fastText中常见问题汇总

    1、什么是fastText

    fastText是一个用于文本分类和词向量表示的库,它能够把文本转化成连续的向量然后用于后续具体的语言任务,目前教程较少!

    2、为什么训练的模型非常大

    fastText对字和字符串使用hash表,hash表的大小将直接影响模型的大小,可以通过选项-hash来减少词汇hash表的大小,一个可选的好参数时20000。另一个影响模型大小重要的因素是训练向量的维度大小(-dim),如果维度缩小模型将大大减小,但同时也会很大程度影响模型的性能,因为向量维度越大则捕获的信息越多,当然还有一种将模型变小的方法是使用量化选项(-quantize),命令如下所示:

    ./fasttext quantize -output model
    
    3、模型中使用单词短语而不是单个单词最佳方式是什么

    目前使用单词短语或句子最好的方式是使用词向量的bow(bag of words),另一种方式例如New York,我们可以将其处理成New_York也会有帮助

    4、为什么fastText甚至可以为语料库中未出现的单词产生词向量

    fastText一个重要的特性便是有能力为任何单词产生词向量,即使是未出现的,组装的单词。主要是因为fastText是通过包含在单词中的子字符substring of character来构建单词的词向量,正文中也有论述,因此这种训练模型的方式使得fastText可以为拼写错误的单词或者连接组装的单词产生词向量

    5、为什么分层softmax在效果上比完全softmax略差

    分层softmax是完全softmax的一个近似,分层softmax可以让我们在大数据集上高效的建立模型,但通常会以损失精度的几个百分点为代价,

    6、可以在GPU上运行fastText项目吗

    目前fastText仅仅可运行在CPU上,但这也是其优势所在,fastText的目的便是要成为一个高效的CPU上的分类模型,可以允许模型在没有CPU的情况下构建

    7、可以使用python语言或者其他语言使用fastText嘛

    目前在GitHub上有很少的关于fastText的其他语言实现的非官方版本,但可以负责任的说,是可以用tensorflow实现的

    8、可以在连续的数据集上使用fastText吗

    不可以,fastText仅仅是用于离散的数据集,因此无法直接在连续的数据集上使用,但是可以将连续的数据离散化后使用fastText

    9、数据中存在拼写错误,我们需要对文本进行规范化处理吗

    如果出现的频率不高,没有必要,对模型效果不会有什么影响

    10、在模型训练时遇到了NaN,为什么会这样

    这种现象是可能出现的,很大原因是因为你的学习率太高了,可以尝试降低一下学习率直到不再出现NaN

    11、系统无法编译fastText,怎么处理

    尝试更新一下编译器版本,很大可能就是因为编译器太旧了

    12、如何完全重现fastText的运行结果,为什么每次运行的结果都有些差异

    当多次运行fastText时,因为优化算法异步随机梯度下降算法或Hogwild,所以每次得到的结果都会略有不同,如果想要fastText运行结果复现,则必须将参数thread设置为1,这样你就可以在每次运行时获得完成相同的性能

    展开全文
  • LSTM这一篇就够了

    万次阅读 多人点赞 2019-09-16 15:02:25
    ▌短时记忆 NN 会受到短时记忆的影响。如果条序列足够长,那它们将很难将... 因此,如果你正在尝试处理段文本进行预测,RNN 可能从开始就会遗漏重要信息。 在反向传播期间,RNN 会面临梯度消失的问题。 梯...
  • 也说bot–一篇survey https://zhuanlan.zhihu.com/p/21626875 *:粗体部分为附加说明 也说bot–一篇survey 张俊· 引 chatbot是最近一段时间非常火的一个或者一个应用,不仅仅各大新闻媒体在热炒bot的概念,...
  • 学习HTML5这一篇就够了

    万次阅读 多人点赞 2020-09-18 20:50:46
    目录第章 HTML5概述1.1、什么是HTML1.2、什么是HTML51.3、本文重要说明1.4、浏览器的版本1.5、选择开发工具第二章 HTML5语法2.1、基本结构2.2、语法规范2.3、标签规范第三章 HTML5标签3.1、标题标签3.2、段落标签...
  • 如何阅读一篇论文

    千次阅读 2018-07-12 23:56:18
    如何阅读一篇论文摘要:研究人员花大量时间阅读研究论文。然而,这种技能很少被传授,这就导致了大量多余的努力。本文概述了一种实用、高效的研究论文三遍阅读方法。我还描述了如何使用这种方法做文献综述。关键词:...
  • ElasticSearch中文分词,看这一篇就够了

    万次阅读 多人点赞 2020-06-03 16:09:11
    可是由于咱们用的是最新的7.7版本,截止到我写这文章的时候,7.7版本还只提供源码包,没有编译后的包: 如果你看这文章的时候,这里已经提供了编译后的包,请把编译好的包直接下载下来并解压,然后跳过下小节...
  • Hadoop一直是我想学习的技术,正巧...《Hadoop基础教程》是我读的第本Hadoop书籍,当然在线只能试读第章,不过对Hadoop历史、核心技术和应用场景有了初步了解。   Hadoop历史  雏形开始于2002年的Apache
  • AGI:走向通用人工智能的【生命学&哲学&科学】第一篇——生命、意识、五行、易经、量子 经典的物理统一在原子上,量子的物理统一在量子上,化学统一在元素上,而生命统一在DNA上,DNA本身拆干了,其实就是一群元素,...
  • 位几年前带我入坑的前辈的话——坑就在你面前,别总是犹豫徘徊,大胆一点:向前一步,入了这个坑,莽着头就是往前冲,别多想,别回头,终有天——>你也会成为别人的前辈!???? 今日份鸡汤已成功送达,目
  • LDA主题词模型

    万次阅读 2016-06-07 17:55:28
    最终确定去360做安全网关部分的自然语言处理环节,...LDA主题词模型探析 参考博主:http://www.tuicool.com/articles/E7RVFzU 内容再自行整理得来,侵权删。 LDA是什么?  LDA(Latent Dirichlet Allocation 文档
  • 摘要指导性写作00引言1、摘要的结构与内容1.1目的...数学建模的比赛中最终提供的是一篇科技性质的论文,在评委阅卷时,由于工作量太大。一篇务实、规整的摘要绝对可以使你的论文得到加分。可是如何写好摘要呢?在结...
  • 真的,Kafka 入门一篇文章就够了

    千次阅读 多人点赞 2019-11-28 12:53:57
    Kafka 是由 Linkedin 公司开发的,它是个分布式的,支持多分区、多副本,基于 Zookeeper 的分布式消息流平台,它同时也是款开源的基于发布订阅模式的消息引擎系统。 Kafka 的基本术语 消息:Kafka 中的数据...
  • bert系列第一篇: bert进行embedding

    千次阅读 2020-10-04 23:22:33
    bert可以干啥 我们理解bert为个transformer集合,输入是...输入句话(序列),输出抽取后的embedding序列。 输入输出 输入会加入特殊的[CLS]代表整句话的含义,可以用于分类。 input的help,prince,ma
  • 这段时间,想复习一下英语,做一下笔记,于是选中了之前胡敏老师主编的本《考研英语核心词汇笔记》,既学习了英语,又能为考研需要的同学做一些帮助,何乐而不为呢?于是计划周把这本单词书看完,并做好笔记。...
  • 知乎赚钱实战:我是如何一篇文章赚 3000+

    千次阅读 多人点赞 2020-11-18 21:09:04
    【爬实战】教你最有用的爬虫实战每周,痴海会教你一个爬虫实战应用。通过项目思路讲解,让你知道原来爬虫还可以这样逆天操作!今天的这篇就是教大家如何利用爬虫思维赚钱。我通过这样的一套玩法,一篇...
  • 一篇文章让你搞懂NFV

    千次阅读 2020-03-09 23:44:39
    今天,我们要来说说IT“三字经”中的个,也是最近常被攻城狮们聊起的——NFV。 什么是NFV NFV(network function virtulization,网络功能虚拟化)是指种操作框架,目的是为了将部署在COTS硬件上的...
  • 本次 Chat 的第一部分:首先讲解如何从零基础开始阅读一篇机器学习方向的论文,以及对待论文中的数学问题。随后,从一篇经典论文入手,讲解如何快速梳理和理解一个深度学习框架及模型。最近人工智能和机器学习方向的...
  • 深入理解CNN--这一篇就够了

    万次阅读 多人点赞 2019-05-14 12:57:18
     本博客内写过一些机器学习相关的文章,但上一篇技术文章“LDA主题模型”还是写于2014年11月份,毕竟自2015年开始创业做在线教育后,太多的杂事、琐碎事,让我一直想再写点技术性文章但每每恨时间抽不开。...
  • 如何写一篇英文文章的Summary?

    万次阅读 2014-09-28 08:25:18
    摘要是对一篇文章的主题思想的简单陈述。它用最简洁的语言概括了原文的主题。写摘要主要包括三个步骤:(1)阅读;(2)写作;(3)修改成文。  第一步:阅读 A.认真阅读给定的原文材料。如果一遍不能理解,...
  • 程序员如何才能写出一篇好的技术文章

    千次阅读 多人点赞 2016-03-01 00:00:42
    文章来源于 @justjavac在...从我大二的时候,大概六年前开始写技术博客,到现在已经有540+了,大概每年会写左右。这个答案由四部分组成: 博客的流量来源 不同文章类型的写作要点 如何写博客 如何收集写作的灵感
  • 一篇云计算论文读后感

    千次阅读 2011-03-09 20:21:00
    发表于:2011-03-08 21:12 | 分类:转载 阅读:(21) 评论:(1)  刚看了一个关于一篇云计算的论文的评论,也同样是通俗易懂,既适合同行看,也适合非IT人士科普一下。故转之,大家共赏。   ...
  • 一篇难得的关于傅里叶分析的好文

    万次阅读 多人点赞 2018-03-25 09:25:03
    文章的核心思想就是: 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是个数学工具,更是种可以彻底颠覆个人以前世界观的思维模式。但不幸的是,傅里叶分析的公式看起来太复杂了,...
  • 这是“容器”这个给人们的第印象。 而我们这个说的“容器”(英文:Container)也是用来盛装东西的,只是这个东西比较特别,是个软件应用。在英文中Container这个含义更偏向于“集装箱”,这也是很多介绍...
  • 关键词抽取就是从文本里面把跟这文档意义最相关的一些抽取出来。这个可以追溯到文献检索初期,当时还不支持全文搜索的时候,关键词就可以作为搜索这论文的词语。因此,目前依然可以在论文中看到关键词这项。...
  • python 文本聚类分析案例说明摘要1、结巴分词2、去除停用词3、生成tfidf矩阵4、K-means聚类5、获取主题词 / 主题词团 说明 实验要求:对若干条文本进行聚类分析,最终得到几个主题词团。 实验思路:将数据进行预处理...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,729
精华内容 36,691
关键字:

一篇的核心词