两周!从入门到第15到第3!小白和你一起入门NLP


本文致力于通过还原我在TAIL CAMP学习NLP两周的学习经历,用最通俗易懂的方式给大家讲述训练营两个任务:文本相似度、作文自动评分中应用到的NLP技术。对于和NLP相关性不大的技术一笔带过,希望能通过一篇文章让你了解NLP的基础知识,也希望能在下次的训练营中不再云里雾里,Let’s go!

好未来AI训练营?我也能去么?

我叫王大锤(误),是好未来集团学而思培优事业部的一个普通的高中数学老师。17年大数据的浪潮让我也不能免俗地投入了Python的学习中去,半年的学习中没有同伴、没有导师,在各个坑中不停地翻来滚去,从学数据分析开始,到转去写爬虫,写网站,让我都快忘了自己为什么要学Python了,直到有一天……

上班用钉钉打卡的时候,发现上方的Banner有一个好未来AI训练营,我终于回想起我学Python原本是为了不要在AI浪潮中掉队啊!粗略浏览了一下时间安排和学员要求,感觉自己和要求差得蛮远的,毕竟是实战训练营,需要有一定基础才能够得上两周的艰巨任务,我也是“抱着试试看的心态”准备投个简历,心想虽然我不是在校学生也不是科班出身,但是训练营万一看我骨骼惊奇就把我选进去了呢?

三大训练营的选择与艰难的笔试题

训练营分三个分营:数据挖掘、图像识别、自然语言处理。选择哪一个呢?数据挖掘我以前学过一些,但是无论如何以后的工作可能都接触不到大数据;图像识别我一窍不通,也没有相应的硬件能搞的定……最后思来想去(当然还有一些不足为外人道的原因),选择了自然语言处理(NLP)。看了一下笔试题,题目是关于隐马尔科夫链的一些思考,还好以前在吴军老师的《数学之美》这本书里面见过一些,翻开看了看,再加上李航老师的《统计学习方法》上简洁明了的指引,算是能回答了这个问题。之后就是听天由命了,等着万一AI LAB和平台给我打上一个“骨骼惊奇”的标签,我就可以进入训练营啦!

第一周的任务?NLP到底要做什么?

无书则短,总之大概是因为我的简历字写得比较好看(明明是电子版)进入了训练营,选择了两周合作的队友,开始了第一周的任务:句子相似度判别。

望着第一周的任务书我就开始迷茫起来了,明明雅思7.5,可是满任务书的专有词汇,我却一个都看不懂。第一天和第二天的任务书上写着很多文本预处理的方法和技巧,但是对于我这种NLP一窍不通的选手来说,了解NLP是做什么的才最重要。跟着指定的书目和文档我终于了解了NLP问题和其他数据挖掘问题的根本区别:计算机是读不懂语言的,而如何把语言转化成计算机能理解的数据呢?怎么理解文本这种类型的数据呢?
以下都是我个人基于在训练营两周的学习的看法。我尽量写得通俗易懂,也算是给自己的复习材料,当然不具有权威性,也请各位多指正哈!

第一天的任务-预处理与词袋模型

预处理:POS-Tagging/Lower/Stopword removal/Tokenizing/Stemming/Lemmatizing

POS-Tagging

词性标注,标记每个词在句子中的词性。比如某个词后面标记着NNS表示它是一个名词的复数。

Lower

通常来说大写和小写对于一个词的区别不是很大,但是如果单单从字符串的角度来说,”I love you”和”i love you”是完全不同的两个字符串,所以我们通常会先将字符串全部改成小写再继续文本预处理的工作。

Stopword removal

我们也会去掉一些不必要的标点符号和所谓的停止词,例如”the”这样的词汇在很多文档都会出现,但是却没有什么实际的意义,不如在预处理时根本不看它。

Tokenizing

可以认为是标识化(?),把文本的词分割出来,对于英语来说,词和词之间的空格就是天然的标识分隔:”I love you.”
”i love you”
{“i”, “love”, “you”}。但是中文就会麻烦一些,因为牵扯到分词的问题。但是有一些现成的工具比如jieba这样的开源库就可以搞定这些问题。

Stemming

词干化,英语中的词汇变形非常多,而类似driving和drive这样的变形本身对于词义来说区别不大,我们可以把他们看做是同一个东西,仅仅提取词汇的词干。但是Stemming对于drove这样的词汇就无能为力了,因为Stemming的实现做减法的多一些。所以就需要Lemmatizing了。

Lemmatizing

变体还原,直接把drove这样的词变回drive。但是很多情况下因为词性的不同,它的原型可能也不一样,比如went到底是人的名字还是动词go的过去式呢?这时候需要POS-Tagging来帮忙了。

词袋与N-Grams模型

词袋模型

词袋模型是一种这样看待文本的方法:一个文档的内容仅仅和出现在文档中的词汇(还有它出现的次数)有关,而和词汇与词汇间的前后关系无关。当我们统计了文档中和文档间的词频之后,就可以通过各种各样的方式如One-hot编码、TF-IDF(后面会简单提到)来对文档数字化了。
举例来说:如果通过One-hot编码的话,我们可以给每一个词汇表里的单词一个索引,通过索引出现的个数来表示一篇文档。比如我们的词汇表对应它们的编号有{‘Jack’:0, ‘loves’:1, ‘Mary’:2, ‘him’:3, ‘hates’:4},那么接下来三篇文档:

"Jack loves Mary."
"Mary loves Jack"
"Jack loves Mary, but Mary hates him."

就分别表示成了[1, 1, 1, 0, 0]、[1, 1, 1, 0, 0]、[1, 1, 2, 1, 1]。

  • 可以看到”but”这个词没有出现在词汇表中,这也是不可避免的事情。One-hot编码的词袋模型会形成非常稀疏的向量,因为向量的维度就是词汇表的大小,每个文档的词汇量又有限,所以0的个数非常多。而有些不常见的词汇如果全部编入词汇表,会让词汇表的大小迅速膨胀,这时候可以通过计算每个词出现的频率,定一个词汇表的大小,这样也能极大地提高效率。
  • 同时也可以看到很多问题,比如第一个文档和第二个文档明显意思不同,但是词袋模型完全把它们看做是同一回事了。所以词袋模型虽然效率高,能解决非常多的问题,但是还有一些缺陷。后面的N-grams就可以在一定程度上解决这个问题。
N-Grams模型

词袋模型可以认为是建立在”文档仅仅由词组成”这个假设的基础上,而进一步N-grams就可以认为是建立在”文档是由连续的N个词所组成的词组组成”的基础上了。这时如果我们看刚才的两个例子:”Jack loves Mary”,”Mary loves Jack”,利用二元的模型就可以把他们分别拆成这么两个词的集合:{“Jack loves”,”loves Mary”}, {“Mary loves”, “loves Jack”},无论用哪种方式重新编码(哪怕是One-Hot),都会得到“两个句子完全不同”这样一个结论。当然也就能解决像”not good”这种到底是褒义还是贬义的问题。但是肉眼可见的,因为N-grams模型所产生的词汇表要比仅仅单个单词词袋的词汇表大太多,无论是存储空间还是进行相应的数学计算(比如常见的TF-IDF计算)都是巨大的开销。所以据说谷歌的罗塞塔系统也仅仅用了四元模型,即便如此也打败了几乎所有的竞争对手(吴军《数学之美》3.2.1)。

第二天的任务-Gensim:TF-IDF与Word2Vec

根据任务书上的任务,第二天是学会使用Gensim库,了解TF-IDFWord2Vec这种词向量生成方法。

TF-IDF

词频-逆文档频率,简单说来就是每个词在某文档中的重要性,和它在这个文档中出现的频率正相关,和这个词在其他文档中出现的比例负相关(这里是取对数)。某个词W1
在其他文档中出现的比例越高(比如100篇文档99篇有出现),那么这个词在这篇文档D
中就越不重要;相应的100篇文档只有4篇出现的词W2W3
,就更能代表这篇文章的意思,同时如果W2
W3
在文档D
出现的频率更高,说明W2
更重要。这就是TF-IDF的思想。
相对于one-hot仅仅用词出现的次数编码来说,用TF-IDF构成向量更科学一些。这样通过每个文档的TF-IDF向量,也可以计算出两个文档的相似程度。

Word2Vec

前一天我们学会了从词形本身去了解文本的的信息,但是这种表示文档的方法有一些缺陷,就是仅仅词本身能表示的信息量实在太少了,我们很难能找到”big”和”large”这两个词的内在语义联系。怎么能让词有更大的信息量呢?这里需要用到Word Embedding这个技术。通过大量的语料(比如我第一周使用的是我自己用下载的维基百科训练的语料,第二周使用了网上斯坦福大学开源的预训练的语料)把每一个词训练成一个N维的向量(N的大小可以自己定),使得语义相近的词语所对应的词向量V
在向量空间中也很接近,甚至达到VkingVman+Vwoman=Vqueen
这种理想中的程度。
举个例子来说,在我用非常小的语料训练的5维Word2Vec模型中,”eat”和”bite”所对应的词向量长这样

eat:[-3.121694,  -0.8472571,  3.7435691,  4.955612 ,  3.632117 ]
bite:[-2.1504984 ,-0.56168956, 2.6603925 ,  2.8402011 ,  2.3802428 ]

可以看到这两个词在向量空间中是非常相近的。
有了每个词的语义表示词向量了之后,我们就有了更好的表示词的方法,至此就算仅仅考虑构成文档的单词(也是基于和词袋模型类似的思想),也能较好地表现”He loves kitties.”和”He likes cats.”之间的相似程度了。比如计算两个文档词向量的平均值构成的新向量的相似度。

第三天的任务 – Scikit-learn:什么是回归?

第三天的任务终于接触到了机器学习的一些算法和sklearn的API。任务书上给出了需要了解岭回归和SVR支持向量回归,简单来说回归问题是通过已有数据集的特征向量和给定的输出值(标签)训练回归模型,再通过测试数据集的特征向量来预测某个新的文档的输出值。换句话说和找规律很类似,都是通过对一些已有的题目和答案的学习,来填答案未知的题目的过程。在这周的任务里,我们通过词袋和词向量等等方式已经构建了每一个文档的很多特征,通过这些特征和最终的相似度评分就可以回归出一个不错的模型。这部分和NLP本身关系不大,我在参加训练营前也了解过一些,在这就不记录了。

第四~六天的任务 – 阅读论文、提取特征、写代码

终于到了写代码的时候了,第一周我对NLP的理解非常浅薄,仅仅知道了一些概念,在提取特征的过程中也异常艰难,根本无心阅读论文。在最后一天终于想起来阅读论文了,可是时间已经不允许我把那些特征转换成代码了。最后主要用了句子各部分的词向量的余弦相似度等等作为特征,零零散散最后算是有了十几个特征,拿到了第15/43。

第二周的任务:传统特征工程VS深度学习

第二周的内容非常有意思,是学生作文的自动评分。这个任务无论是用传统的特征工程方法还是用深度学习方法都是很有效果的。这一周我吸取了前一周的教训,从周一开始每天花一点时间阅读论文,了解论文中提取的特征也了解其他人搭建深度学习模型的方法。当然每天花更多的时间完成任务书上的任务也是非常重要的。在我看来,在这一周我主要了解了特征工程和深度学习各自的特点和互补的关系。在这里把我学到的一些关于NLP的知识记录一下吧!

(你敢信,通过研究我发现,其实仅仅注意三个点就可以保证自己的英语作文得分不太低了!

第一天和第二天的任务 – 句子解析与可读性分析

对于英语作文而言,句子的语法当然是评分的其中一项。无论是确认句子是否有语法错误,还是统计所有句子语法书的深度,都需要对文本进行语法解析。语法解析是一个相对而言更有技术含量的工作,涉及到了NLP的方方面面。好在目前的任务对句子解析的要求不是很高,只需要比较浅地解析句子,同时也有很多现成的库和api可以使用,所以在这两周就没有太多关注Parsing这一块,接下来的一段时间我准备把它捡起来好好学习一下。
可读性也是评价作文的一类指标,通过对单词音节数、句子单词数等等特征的分析,通过一系列复杂公式的计算就能得到很多种可读性指标。当然有些指标能通过内置的词汇表输出某个单词到底是几年级水平的词汇,在分级阅读中有相关的应用。
不过经过后期的分析,发现这两类指标其实对作文评分的相关性并不是很强,或者说被更强的特征掩盖了。

第三天的任务 – 深度学习:Keras的安装与使用

终于走到深度学习这一关了,而NLP怎么和深度学习结合在一起呢?
上面我们学到了各种各样的词袋的表示方式,无论是用频率还是TF-IDF无论是一元的词袋还是N-gram,都没有考虑袋子中装的东西的先后顺序,而是仅仅用词(或词组)的出现与否、频率高低来表示一个文档。而在深度学习的领域,我们完全可以把句子作为一个序列输入给网络,而怎样才能把句子编码为一个序列呢?

将文档编码成向量

还是回到上面的例子。

{'Jack':0, 'loves':1, 'Mary':2, 'him':3, 'hates':4}
"Jack loves Mary."
"Mary loves Jack"
"Jack loves Mary, but Mary hates him."

通过词袋我们可以把三个句子表示成[1, 1, 1, 0, 0]、[1, 1, 1, 0, 0]、[1, 1, 2, 1, 1],但是已经提到过,这里完全没有考虑用词的顺序。让我们先对词汇表稍作更改:

{'Jack':1, 'loves':2, 'Mary':3, 'him':4, 'hates':5}

那么0代表什么呢?0我们可以代表这个位置没有出现词汇,或者说这个位置的词汇词汇表中并不存在。那么每一个句子的序列就可以表示成下面的样子:

[1, 2, 3] #"Jack loves Mary."
[3, 2, 1] #"Mary loves Jack"
[1, 2, 3, 0, 3, 5, 4] #"Jack loves Mary, but Mary hates him." 这里but词汇表中不存在,所以用0补位

但是通常来说我们需要让网络的输入的向量维度一样,所以我们确定一个文档的最大词汇数,比如在这个例子中我们设定成6,那么不足的我们需要用0补全,超过的我们可以选择简单的截断:

[0, 0, 0, 1, 2, 3]
[0, 0, 0, 3, 2, 1]
[1, 2, 3, 0, 3, 5]

这样就保证了每一个文档的向量都是6维的了。

Word Embedding

因为我们刚才的编码方式是给每个词一个单独的索引,依然仅仅考虑到了词形,没有考虑到词义。根据我们以前的学习我们可以把每一个词编码成N维的词向量,然后用这个词向量来表示这个词。当然把词 用词向量替换的过程,我们可以使用预训练的词向量(常见),也可以在先初始化一个向量然后再训练模型的过程中训练这些词向量。无论如何,每个文档都被编码为一个d×d
的矩阵,而这个矩阵就可以用作整个网络的输入了。

可以用什么网络

在这方面,我作为一个菜鸟可没有什么发言权,通过阅读论文和与伙伴们的探讨,在这个任务中使用CNN和RNN比较有效(也有大佬尝试使用胶囊网络,但是我实在是不太懂这个。)

CNN卷积神经网络

简单说来,文档作为一个一维的序列(文字只有出现在前后的分别,没有上下左右这种情况),一维的卷积神经网络通过卷积核提取了相邻的几个单词的特征,和上文我们说到的N-grams模型很类似。多层的卷积神经网络可以提取前后跨越相当大的词汇间的特征,对于学生作文这种前后文联系紧密的任务较为有效。

RNN循环神经网络

简单说来,相对于传统的神经网络每一层节点之间没有连接,循环神经网络每一层之间的神经元也会进行连接,每一时刻的输出都包含着以前的信息。所以特别适用于序列问题:当前神经元的输出与前面的输出有关,正如这个词的意思和使用的正确与否,与前面的几个词都有关系一样。但是Simple RNN也有自己的一些比如“梯度消失”这样的问题,所以改进的LSTM(长短时记忆网络)就更加适合文本处理了。

第四~六天的任务 – 阅读论文、提取特征、搭建模型

第四天的任务开始根据论文的内容提取各种特征。根据论文中的内容提取了47个特征,虽然很多特征有重复的情况,但是的确特征工程的过程中非常有意思。在经过了长时间多方面的特征选择之后,最后发现有三个指标对于预测作文的分数有非常大的重要性(仅仅三个特征加上最简单的线性回归就达到了线上0.85的皮尔逊相关系数),分别是:文章长度的四次方根不重复的单词个数字符长度大于4的单词个数。我认为这三个特征分别从三个不同的方面体现了一个学生驾驭essay的能力:

  • 文章长度的四次方根 学生行文的流畅性(限时的情况下能写出很长的篇幅)
  • 不重复的单词个数 反映了学生词汇的多样性、词汇资源的广度
  • 字符长度大于4的单词个数 反应了学生词汇的难度、词汇资源的深度

深度网络的尝试

最终选择的神经网络是在助教大佬的提点下想到的,模型有两个输入端:一个是Word Embedding的输入端,由卷积层和LSTM构成,合并前将所有的输出对时间进行了平均;一个是Feature Vector的输入端,从特征工程那里拿到的特征放到模型中,合并上一个输入端的结果,最终通过全连接层进行拟合。

第二周的结果

第二周在最后得到了3/31的成绩,算是给自己两周的拼命一个交代。

训练营感悟

感谢集团和平台提供的机会,感谢导师的鼓励和指导,感谢辅导员和志愿者的付出,更感谢所有的小伙伴的讨论氛围,让我有更大的进步。
这次训练营期间因为一开始什么都不会,非常着急,不是很沉稳。对学习算是囫囵吞枣,能调包先用着的态度,等到今天总结的时候感觉自己对做的事情了解实在太少。接下来的时间必须按部就班,一步一个脚印地从头开始NLP基础的学习,争取以后能从更深的层次分享自己学到的东西。

两周!从入门到第15到第3!小白和你一起入门NLP相关推荐

  1. python编程从入门到实践看完了看什么-小白Python编程从入门到实践——列表是什么...

    01 列表是什么 在日常生活中,我们经常会遇到排队,此时由人们排成的队伍,就是一种列表,队伍中的人,就相当于是列表中一个个的元素.在计算机世界中,有一种列表你们也很熟悉,那就是各位在某宝某东里面的购物 ...

  2. 以太坊重出江湖:两周大涨78%,暴涨背后危机四伏

    文 | 棘轮 林格 沉寂两年后,以太坊"重出江湖". 近两周来,以太坊币价大涨78%,成为了当之无愧的"牛市发动机". 除了币价,以太坊的交易量.活跃地址数涨势 ...

  3. Django - 两周从入门到熟练工

    初识 Django 之前 Python 后端开发框架中,对 Tornado 和 Flask 接触比较多,前者适合作为服务框架,后者由于轻量常用来构建简单的后台或服务. Django 之于上面两个 We ...

  4. 分享Silverlight/WPF/Windows Phone一周学习导读(8月15日-8月19日)

    分享Silverlight/WPF/Windows Phone一周学习导读(8月15日-8月19日) 本周Silverlight学习资源更新: Silverlight Tools 4安装时的错误提示 ...

  5. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(10月15日-10月21日)

    Silverlight/Windows8/WPF/WP7/HTML5周学习导读(10月15日-10月21日) 本周Silverlight学习资源更新 Silverlight + DomainServi ...

  6. 我的2015年读书计划,每两周读完一本书!

    近日看到一篇文章,说Facebook CEO 马克·扎克伯格给自己的2015年定下了一个新的挑战,每两周就要读完一本书(传送门:戳这里).想了一下,我自己也很久没看书了,所以今年要改变一下,给自己定一 ...

  7. 近找到了一个免费的python教程,两周学会了python开发【内附学习视频】

    原文作者:佛山小程序员 原文链接:https://blog.csdn.net/weixin_44192923/article/details/86515984 最近找到了一个免费的python教程,两 ...

  8. 最近找到了一个免费的python教程,两周学会了python开发

    最近找到了一个免费的python教程,两周学会了python开发 最近找到了一个免费的python教程,两周学会了python开发.推荐给大家,希望召集更多的朋友一起学习python. 最近开始整理p ...

  9. 如何两周学会Python 第00天

    程序源码下载 http://pan.baidu.com/s/1bpKnVK7 笔者从今年4月开始写博客, 一眨眼就过去2个月了. 时间过得真快啊! 想想也挺感慨的, 从15年秋开始学习java, 至今 ...

最新文章

  1. 安装黑屏_含能公司黑屏管理助力智能化改造
  2. python---pandas.merge使用
  3. react数据从本地读取_如何将从Google表格读取的React应用程序部署到Netlify
  4. leetcode刷题——415. 字符串相加
  5. 跨境电商独立站门槛高,为什么还有无数人挤破头想入坑!
  6. 什么样的水平才算是java高级工程师?
  7. 文本对比工具哪些好用?竟然有在线的。真香。
  8. 全国计算机等级考试二级Web程序设计考试大纲(2018年版)
  9. 一步一步教你写股票走势图——分时图三(对齐图表、自定义高亮)
  10. k8s集群外部域名dns解析问题
  11. 微分方程的Matlab解法
  12. 苹果开发证书导出P12的问题
  13. 修改linux xorg端口,Xorg服务开启tcp/ip监听,允许其它机器客户端连接
  14. 转 Android屏幕适配全攻略(最权威的官方适配指导)
  15. LeetCode题解(1628):设计带解析函数的表达式树(Python)
  16. 美丽田园ipo上市,它的底气从何而来?
  17. 机器学习——模型评估,选择与验证
  18. 推荐个WIN7下小巧的可转录声音的软件-Audio Record Wizard V6.99
  19. 关联规则挖掘Apriori算法的实现
  20. 浪潮商用机器携手长亮科技和南大通用 打造基于GBase国产高端数据仓库方案

热门文章

  1. 蚂蚁金服有哪些金融特色的机器学习技术?
  2. thrift的使用介绍
  3. 计算机网络——以太网的信道利用率
  4. 学习ROS常用的官方网站,学习资源整理
  5. Docker镜像瘦身
  6. 关于选择,关于职业发展
  7. 解读照明设备出口沙特具体法规要求!
  8. 关于ssh登录时卡顿30s左右的问题调试处理
  9. Spark教程(三)—— 安装与使用
  10. Spark学习笔记[1]-scala环境安装与基本语法