讲解基本自然语言处理NLP

来源:互联网 发布:python sum axis 1 编辑:程序博客网 时间:2024/06/07 19:42

简介

前几天用自然语言处理技术学习了一下习主席的十九大报告,发布到朋友圈以后反响比较大,很多同事和朋友都好奇我是怎么做到的;由于学习的算法比较简单,所以我基本上两三句话都给他们解释清楚了。我觉得很多人也会对类似的话题感兴趣,所以这里要写这么篇博文,来document一下我的这个非常简单的自然语言处理程序,给大家揭开一点迷雾。

原理分析

这个算法来自斯坦福的抽象编程课,若干年前叫cs106b, 不知道现在还上不上这门课。主要的方法就是对文章中出现的每一个字都建立一个索引,这个索引里包含了所有紧跟在它后面出现的字及其出现的次数,自动生成文章的时候会使用一个seed,不断生成随机数,按照紧跟字出现的概率和随机数来决定下一个字。

先说索引,索引里包含了所有紧跟在它后面出现的字及其出现的次数。比如说字“同“,我们发现文章里有同学这个词,于是“同“的索引里就有“学“这个字,又发现文章里有同胞这个词,于是“同“的索引里就又有了“胞“这个字。索引不光是紧跟字的集合,也记录了每个紧跟字的出现次数。就拿习主席的报告为例,学习完成后,发现“培“字后面分别紧跟“育“、“养“和“训“三个字,他们的出现次数是11、10和2。

当我们有了一个种子(seed)的时候,我们可以查看它的紧跟列表,按照概率来选出下一个字。就拿“培“打个比方,后一个字有1123 的几率会是“育“字,1023 的几率是“养“字,223 的几率是训字。选出下一个字以后,这个字又做为新的种子重复上述的过程。

有趣的是逗号、句号这种标点符号也被当成一个字,所以新生成的文章也会有明显的断句。

程序实现

先说我封装的一个重要的类:Token. 我们先来看一下类的UML图:
自然语言处理类UML图

最底层的类叫做CharacterNOccurrence,这是一个字符(Character)和它的出现次数(int)组成的类,它有一个公有方法叫做addOneOccurrence(), 就是增加一次出现次数。

Token类aggregate了这个CharacterNOccurrence类,这是对于现实中每个字都有对应的索引的抽象,我把一个字(一个Character对象)和它的索引(List<CharacterNOccurrence>) 封装在同一个对象里,方便使用。

主程序的学习部分就是读取一个文本文件,为每个字生成一个Token实例,并用一个Map把文字本身和它对应的Token实例存储起来,以便自动写文章的时候使用。Map是一个Map<String, Token> 的形式。

主程序的书写部分就是hardcode一个种子,到Map当中去找对应Token,按照概率选出下一个字,再重复之前的操作。

代码在Github . 有问题欢迎提问。

原创粉丝点击