两周!从入门到第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-IDF
和Word2Vec
这种词向量生成方法。
TF-IDF
词频-逆文档频率,简单说来就是每个词在某文档中的重要性,和它在这个文档中出现的频率正相关,和这个词在其他文档中出现的比例负相关(这里是取对数)。某个词 W