Loading

自然语言处理初步作业二

1.什么是词?谈谈你对“词”这个概念的认识。
答:在语言学上,词的定义是具备意义的最小单位。在基于词典的中文分词中,词的定义要现实的多:词典中的字符串就是词。词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。
事实上,语言中的词汇数量是无穷的, 无法用任何词典完整收录。 语言也是时时刻刻在发展变化的,任何词典都只是某个时间节点拍摄的一张快照。齐夫定律告诉我们:一个单词的词频与它的词频排名成反比。

2.写出汉语词语重叠形式的分析规则。
答:有如下分析规则:
(1)最大匹配法 (Maximum Matching, MM)
属于有词典切分,机械切分

  • 正向最长匹配算法 (Forward MM, FMM)
  • 逆向最长匹配算法 (Backward MM, BMM)
  • 双向最长匹配算法 (Bi-directional MM)

在以某个下标为起点递增查词的过程中优先输出更长的单词,这种规则被称为最长匹配算法。该下标的扫描顺序如果从前往后,则称正向最长匹配,反之则称逆向最长匹配。而双向最长匹配算法是同时执行正向和逆向的最长匹配,若两者的词数不同,则返回词数更少的那个,否则返回两者中单字最少的那个。当单字数也相同的时候,优先返回逆向最长匹配的结果。
¨优点:
¤程序简单易行,开发周期短;
¤仅需要很少的语言资源(词表),不需要任何词法、句法、语义资源;
¨弱点:
¤歧义消解的能力差:链接为奇数的交集型歧义,无法发现组合型歧义。
¤切分正确率不高,一般在95%左右。
(2)最少分词法(最短路径法)
根据词典,找出字串中所有可能的词,构造词语切分有向无环图。每个词对应图中的一条有向边,并赋给相应的边长(权值)。然后针对该切分图,在起点到终点的所有路径中,求出长度值按严格升序排列(任何两个不同位置上
的值一定不等,下同)依次为第1、第2、…、第i、…、第N(N≥1)的路径集合作为相应的粗分结果集。如果两条或两条以上路径长度相等,那么,它们的长度并列第i,都要列入粗分结果集,而且不影响其他路径的排列序号,最后的粗分结果集合大小大于或等于N。
假设待分字串S=c1c2…cn,其中,ci(i=1,2,…,n)为单个的汉字,n为字串的长度,n≥1。建立一个结点数为n+1的切分有向无环图G,各结点编号依次为V0,V1,V2,…,Vn。
通过以下两步建立G所有可能的词边:

  1. 相邻结点Vk-1,Vk(1≤k≤n)之间建立有向边Vk-1,Vk,边的长度值为Lk,边对应的词默认为ck(k=1,2,…,n)。
  2. 如果w=cici+1…cj(0<i<j≤n)是词表中的词,则结点Vi-1,Vj之间建立有向边Vi-1,Vj,边的长度值为Lw,边对应的词为w。

这样,待分字串S中包含的所有词与切分有向无环图G中的边一一对应,如下图所示。
image.png
图1 切分有向无环图
求最短路径可以使用贪心法、简单扩展法等方法。
¨优点:
¤切分原则符合汉语自身规律;
¤需要的语言资源(词表)也不多。
¨弱点:
¤对许多歧义字段难以区分,最短路径有多条时,选择最终的输出结果缺乏应有的标 准;
¤字串长度较大和选取的最短路径数增大时,长度相同的路径数急剧增加,选择最终正 确的结果困难越来越越大。
(3)基于语言模型的分词方法
比如基于词的n元语法模型的分词方法,n-gram是一种统计语言模型(Statistical Language Modeling,SLM)。
基于词的n元文法模型是一个典型的生成式模型,早期很多统计分词方法均以它为基本模型,然后配合其他未登录词识别模块进行扩展。其基本思想是:首先根据词典(可以是从训练语料中抽取出来的词典,也可以是外部词典)对句子进行简单匹配,找出所有可能的词典词,然后,将它们和所有单个字作为结点,构造的n元的切分词图,图中的结点表示可能的词候选,边表示路径,边上的n元概率表示代价,最后利用相关搜索算法(如Viterbi算法)从图中找到代价最小的路径作为最后的分词结果。
¨优点:
¤减少了很多手工标注的工作;
¤在训练语料规模足够大和覆盖领域足够多时,可以获得较高的切分正确率。
¨弱点:
¤训练语料的规模和覆盖领域不好把握;
¤计算量较大。
(4)由字构词的汉语分词方法
其实由字构词的汉语分词方法的思想并不复杂,它是将分词过程看作字的分类问题。在以往的分词方法中,无论是基于规则的方法还是基于统计的方法,一般都依赖于一个事先编制的词表,自动分词过程就是通过查词表作出词语切分的决策。与此相反,由字构词的分词方法认为每个字在构造一个特定的词语时都占据着一个确定的构词位置(即词位)。
(5)基于词感知机算法的汉语分词方法
(6)基于字的生成式模型和区分式模型相结合的汉语分词方法
根据前面的介绍,在汉语分词中基于词的n元语法模型(生成式模型)和基于字的序列标注模型(区分式模型)是两大主流方法。其中,基于词的生成式模型对于集内词(词典词)的处理可以获得较好的性能表现,而对集外词(未登录词)的分词效果欠佳;基于字的区分式模型则恰好相反,它一般对集外词的处理有较好的鲁棒性,对集内词的处理却难以获得很好的性能,比基于词的生成式模型差很多
该模型同时融合了基于字的生成模型和基于字的判别式模型的优点,因此,分词性能比两个基本模型有了大幅度的提升。
(7)其他方法
比如基于词的判别式模型[Zhang and Clark, 2007]等模型。

3.试从互联网上找一篇字数在2000字左右的中文文章,进行人工分词,并列举、归纳碰到的问题。
答:我分的文章是余光中先生写的《假如我有九条命》,这是一篇散文。作家写出来的文章用词比较讲究,然而虽然没有像作业一里冗长且意义不明确的句子,但是也是有很多地方值得研究。在分词的时候遇到最主要的问题是生造的词语诗词,其他的则是一些短语的分词比较模糊等问题。
(1)生造的词语。作家大多写文章在语言上比较易懂的,这篇散文也是语言比较平实。而作家也常常在文章中生造一些词,或增加文章的趣味性,或更简单地传情达意。比如这篇散文里的“半昧不明”、“近悦远来”、“隔海越洲”、“即之也温”、“人往人来”。这些词语都带有文言文色彩难以分词,我大多将其作为一个词。
(2)诗词。文中引用了陆游的一首诗,“看渠胸次隘宇宙,惜哉千万不一施。空回英概入笔墨,生民清庙非唐诗。向令天开太宗业,马周遇合非公谁?后世但作诗人看,使我抚几空嗟咨。”由于诗词极其讲究锻字炼句,而且有时还用典,比如此诗的“马周遇合非公谁”,意在说明与马周相比,杜甫虽有才华,却没有遇到如唐太宗一样的明主,使得杜甫一生不得重用,壮志难酬。但是在我初次看来就会不明所以。所以我认为诗词的分词也是一项比较艰难的任务。
(3)有些词语分词比较模糊。比如“现代人”是分为“现代/人”还是直接“现代人”?“就得有钱、有闲”是分为“就/得/有/钱/、/有/闲/”还是“就/得/有钱/、/有闲/”?“细加体会”是“细/加/体会”还是“细加/体会”还是直接“细加体会”?以上我想了想,分为“现代人”、“就/得/有钱/、/有闲/”、“细加/体会”。
(4)还有些生僻的词语。比如“冥隔”、“神恩”、“须弥”会卡住我一下。
我将人工分词的结果与HanLP.segment()分隔的词语对比了一下。HanLP.segment()分词仍然比人工略逊一筹,对上面的问题它有时不能合理地分词。

4.编写程序实现一个有限状态自动机用于识别缩写 {he, she}’s 是 he/she has 还是 he/she is。
答:对以下句子进行判断
image.png
程序运行结果判断均正确:
image.png
思路:
使用nltk库做英文分词和词性判断。通过观察用例发现词性"VBN"是过去分词。而接"RP"后可能是固定搭配。最后再用名词"NN"来判断是否是has。再任何一个状态遇到"IN", "WRB"或"."均认为此句已结束。
状态转换图如下。
IMG_20221125_161258.jpg
代码如下或 见 英文自动机.py

import nltk

def panduan(state):
    if state == 0 or state == 1 or state == 2:
        return "is"
    else:
        return "has"

line = "He's pushed down.\
        He's pushed down a car.\
        She's running a C program.\
        He's killed in a car. \
        He's a good president because he's Trump. \
        He's a boy when he was young. \
        He's a too young, too simple, sometimes naive frog. \
        He's a excited boy. \
        He's given up the game. \
        He's pushed down suddenly.\
        He's pushed down suddenly in a car.\
        "

tokens = nltk.word_tokenize(line)
# print(tokens)

pos_tags = nltk.pos_tag(tokens)
# print(pos_tags)
flag = 0
heshe = ["He", "She", "he", "she"]
jieshu = ["IN", "WRB", "."]


state = 0
for tag in pos_tags:
    if tag[0] in heshe:
        # 遇到he或者she时
        # print(tag[0], tag[1])
        flag = 1
    elif tag[0] == "'s" and flag == 1:
        # 遇到he或者she后的's时
        flag = 2
        # 进入初始状态
        state = 0
    elif flag == 2:
        # print(tag[0], tag[1])

        if state == 0:
            # 状态0
            if tag[1] in jieshu:
                # 结束
                print(panduan(state))
                state = -1
                flag = 0
            elif tag[1] == "VBN":
                # 跳到下一状态
                state = 1
        elif state == 1:
            # 状态1
            if tag[1] == "RP":
                # 跳到下一状态
                state = 2
            elif tag[1] == "NN":
                # 跳到下一状态
                state = 3
            elif tag[1] in jieshu:
                # 结束
                print(panduan(state))
                state = -1
                flag = 0
        elif state == 2:
            # 状态2
            if tag[1] == "NN":
                # 跳到下一状态
                state = 3
            elif tag[1] in jieshu:
                # 结束
                print(panduan(state))
                state = -1
                flag = 0
        elif state == 3:
            # 状态3
            if tag[1] in jieshu:
                # 结束
                print(panduan(state))
                state = -1
                flag = 0
    else:
        flag = 0
posted @ 2023-08-09 06:17  LateSpring  阅读(89)  评论(0编辑  收藏  举报