zoukankan      html  css  js  c++  java
  • NLP(二)

    本节内容:

    • 分词

    • 拼写纠错

    • 停用词过滤

    • 词的标准化

    智能客服

    根据问题相似度去回答

    • 正则 适合没数据的时候使用
    • 计算字符串的相似度

    基于搜索的问答系统

    知识库中存储着问题和答案,根据相似度搜索最相似的问题,返回其答案

    输入句子

    分词

    预处理

    • 拼写纠错
    • Lemmatisation(词性还原)/ Stemming(词干提取)
    • 停用词过滤
    • 同义词

    文本表示

    文本转为向量形式

    • boolean vector
    • count vector
    • tf-idf
    • word2vec
    • seq2seq

    计算相似度

    根据相似度排序

    NLP项目一般流程:

     一、分词

    常用分词工具:

    • Jieba分词https://github.com/fxsjy/jieba
    • SnowNLP https://github.com/isnowfy/snownlp
    • LTP http://www.ltp-cloud.com/
    • HanNLP https://github.com/hankcs/HanLP/
    • ...

    1.1 最大匹配

    前向最大匹配(forward-max matching)

    例子:我们经常有意见分歧
    词典:[“我们”, “经常”, “有”, “有意见”,“意见”,“分歧”]

    假设max-len设为5

    第一轮,选定前五个字

    [我们经常有],词典中没有单词匹配,去掉最后一个字

    [我们经常],词典中没有单词匹配,去掉最后一个字

    [我们经],词典中没有单词匹配,去掉最后一个字

    [我们],词典中有单词匹配

    第二轮,选定我们后面的五个字

    [经常有意见],词典中没有单词匹配,去掉最后一个字

    [经常有意],词典中没有单词匹配,去掉最后一个字

    [经常有],词典中没有单词匹配,去掉最后一个字

    [经常],词典中有单词匹配

    第三轮,选定经常后面的五个字

    [有意见分歧],词典中没有单词匹配,去掉最后一个字

    [有意见分],词典中没有单词匹配,去掉最后一个字

    [有意见],词典中有单词匹配

    第四轮,选定有意见后面的五个字

    [分歧],词典有单词匹配

    分词结果:我们 经常 有意见 分歧

    后向最大匹配

    例子:我们经常有意见分歧
    词典:[“我们”, “经常”, “有”, “有意见”,“意见”,“分歧”]

    假设max-len设为5

    第一轮,选定最后5个子

    [常有意见分歧],词典中没有单词匹配,去掉最前一个字

    [有意见分歧],词典中没有单词匹配,去掉最前一个字

    [意见分歧],词典中没有单词匹配,去掉最前一个字

    [见分歧],词典中没有单词匹配,去掉最前一个字

    [分歧],词典中有单词匹配

    第二轮,选定分歧前5个字

    [经常有意见],词典中没有单词匹配,去掉最前一个字

    [常有意见],词典中没有单词匹配,去掉最前一个字

    [有意见],词典中有单词匹配

    第三轮,选定有意见前5个字

    [我们经常],词典中没有单词匹配,去掉最前一个字

    [们经常],词典中没有单词匹配,去掉最前一个字

    [经常],词典中有单词匹配

    第四轮,选定经常前5个字

    [我们],词典中有单词匹配

    分词结果:我们 经常 有意见 分歧

    后向前向最大匹配都是贪心算法,缺点:细分,可能有更好的,局部最优,效率低,没考虑语义

    1.2 考虑语义

    选择其中最好的要根据工具选择

    最经典的工具是语言模型(Language Model)

    s1 = 经常 有 意见 分歧

    s2 = 经常 有意见 分歧

    语言模型可以计算概率 P(s1)、P(s2)

    P(经常,有,意见,分歧) = P(经常)P(有)P(意见)P(分歧)

    P(经常,有意见,分歧) = P(经常)P(有意见)P(分歧)

    概率是如何得到呢?

    比如,有一本大部头的书,统计每个单词出现的次数,单词出现次数/所有词的数量 就是这个单词的概率了。

    某个单词的概率P往往非常小,多个单词的概率相乘容易引发溢出错误(underflow)

    于是,我们往往加log,比如计算logP(经常,有,意见,分歧)=logP(经常) + logP(有) + logP(意见) + logP(分歧),转为了加法

    log可以保证P(s1)>P(s2)时,logP(s1)>logP(s2)

    缺点:复杂度非常高,因为要生成所有可能的分割组合。

    1.3 维特比算法

    上面的方法分两步:step1,生成所有可能分割;step2,选择最好的。

    两步合并能不能降低复杂度呢?

    蓝直线,代表一个字,上面的数字是其概率,假设词典没有出现的单词其概率为20

    蓝曲线箭头,将词典中出现的词的字连起来,将词的概率标注在线的上面,比如经常的概率为2.3 

    于是所有蓝线可以进行组合从1到8,每个组合都是一个分词结果,找到概率和最小的路径即可

    假设

    f(8):从节点1到8的最短路径的值

    f(7):从节点1到7的最短路径的值

    f(6):从节点1到6的最短路径的值

    ...

    先看f(8),只用一步有几条路到第8个节点呢

    5->8,6->8,7->8

    因此,f(8)就是下面的最小值

    那么f(7):f(6) + 2.3

    f(6):

    f(5):f(4) + 3

    ...

    因此,我们可以计算f(1)、f(2)、f(3)...f(8)

     上面是最短路径,下面是最短路径对应的节点,比如f(8)最短路径值是6.2,对应的上一个节点是6,节点6最短路径值是4.6,对应节点是3,节点3最短路径值是2.3,对应节点是1

    因此,1368是最佳组合,分词是: 经常 有意见 分歧

    维护数组

    二、错误拼写纠正(Spell Correction)

     最经典方法计算编辑距离

    一般有三个操作:insert、delete、replace,成本都是1

    therr变为there,需要把r替换为1,成本为1

    therr变为their,需要把r替换为i,成本为1

    therr变为thesis,需要r替换为s,增加一个i,r替换为s,成本为3

    therr变为theirs,需要r替换为i,增加一个s,成本为2

    therr变为the,需要删除两个r,成本为2

    因此,there和their是最佳选择,此时需要根据上下文、词频判断,返回最佳的一个单词。

    循环词典,找出最佳编辑距离的词,复杂度非常高是O(V),其中V是词典中所有的单词。

    dp算法的核心是问题拆分

    dp算法练习题:https://people.cs.clemson.edu/~bcdean/dp_practice/

    有什么方法降低时间复杂度呢?

    主动生成想要的字符串,选择编辑距离1和2,是因为这两种情况可以覆盖绝大多数场景

    通过独立使用add、replace、delete三种操作生成编辑为1的字符串组合

    生成编辑为1的字符串后,再重复上面操作,生成编辑距离为2的字符串

    生成大量字符串后,如何选择最合适的字符串呢?

     比如,正确apple

    用户1:app

    用户2:appl

    用户3:appl

    用户4:app

    用户5:appla

    用户6:appl

    P(appl|apple)=3/6=50%

    P(app|apple)=2/6=33.3%

    P(s|c):c是正确的单词,对于一个正确的字符串,有百分之多少的人写成了s的形式?

    P(c):c在整个文档中出现的概率,倾向于选最可能出现的单词

    三、词过虑

    通常把停用词、出现频率很低的词汇过滤掉。这其实类似于特征筛选的过程。

    过滤停用词

    英文里的the,an,their等,但是,也需要考虑自己的应用场景。

    过滤低频词

    出现频率特别低的词汇对分析作用不大,所以一般也会去掉。把停用词、出现频率低的词过滤之后,既可以得到一个词典库。

    四、词的标准化

    常用的技术

    • Stemming
    • Lemmatization

    词形还原(lemmatization),是把一个任何形式的语言词汇还原为一般形式(能表达完整语义),而词干提取(stemming)是抽取词的词干或词根形式(不一定能够表达完整语义)。

    Stemming

    不保证还原为有效的单词,比如

    deny,denied,denying 可以还原为 deni

    fly,flies 可以还原为 fli 

    著名算法 PorterStemmer

    https://tartarus.org/martin/PorterStemmer/java.txt

    下面介绍了规则,这些规则是基于语言学家的经验

     

  • 相关阅读:
    推荐一款快得令地发指本地搜索软件:Everything,绝对改变对NTFS的看法
    “/”应用程序中的服务器错误 WebParts开发时出现的错误
    《让人无法说 NO的攻心说话术》摘要
    UXWEEK
    2012中国交互设计体验日演讲实录
    彩色铅笔入门
    ClickOnce证书签名
    DevExpress控件使用小结
    解决ClickOnce签名过期问题
    属于自己的小小空间
  • 原文地址:https://www.cnblogs.com/aidata/p/12337844.html
Copyright © 2011-2022 走看看