百度NLP集训营-作业1

2月25日第一次作业

作业奖励: 3月2日中午12点之前完成,会从中挑选10位回答优秀的同学获得飞桨定制数据线+本

作业1-1

(1)下载飞桨本地并安装成功,将截图发给班主任

(2)学习使用PaddleNLP下面的LAC模型或Jieba分词
LAC模型地址:https://github.com/PaddlePaddle/models/tree/release/1.6/PaddleNLP/lexical_analysis
Jieba模型:https://github.com/fxsjy/jieba

(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵
语料地址:https://github.com/fangj/rmrb/tree/master/example/1946%E5%B9%B405%E6%9C%88

作业1-2

(1)思考一下,假设输入一个词表里面含有N个词,输入一个长度为M的句子,那么最大前向匹配的计算复杂度是多少?

(2)给定一个句子,如何计算里面有多少种分词候选,你能给出代码实现吗?

(3)除了最大前向匹配和N-gram算法,你还知道其他分词算法吗,请给出一段小描述。

作业1-1

(1) 下载飞桨本地并安装成功,将截图发给班主任

Paddlepaddle安装成功截图

(2) 学习使用PaddleNLP下面的LAC模型或Jieba分词
  • LAC是一个联合的词法分析模型,整体性地完成中文分词、词性标注、专名识别任务。LAC既可以认为是Lexical Analysis of Chinese的首字母缩写,也可以认为是LAC Analyzes Chinese的递归缩写。
  • LAC基于一个堆叠的双向GRU结构,在长文本上准确复刻了百度AI开放平台上的词法分析算法。效果方面,分词、词性、专名识别的整体准确率95.5%;单独评估专名识别任务,F值87.1%(准确90.3,召回85.4%),总体略优于开放平台版本。在效果优化的基础上,LAC的模型简洁高效,内存开销不到100M,而速度则比百度AI开放平台提高了57%。
Paddlepaddle分词:
import paddlehub as hub
lac = hub.Module(name='lac')
text = ["南京市长江大桥",
        "我在参加百度自然语言处理集训营,",
        "Paddlepaddle很好用,也很强大!",
        "“百度”二字,来自于八百年前南宋词人辛弃疾的一句词:众里寻他千百度。这句话描述了词人对理想的执着追求。"]
inputs = {"text": text}
results = lac.lexical_analysis(data=inputs)
print("Paddle分词结果:")
for result in results:
    print(result['word'])
    # print(result['tag'])    # 词性标注
Jieba分词:
import jieba
print("Jieba分词结果:")
for txt in text:
    jieba_result = jieba.lcut(txt)
    print(jieba_result)
输出:
Paddle分词结果:
['南京市', '长江大桥']
['我', '在', '参加', '百度', '自然语言处理集训营', ',']
['Paddlepaddle', '很好', '用', ',', '也', '很', '强大', '!']
['“', '百度', '”', '二', '字', ',', '来自', '于', '八百年前', '南宋', '词人', '辛弃疾', '的', '一句', '词', ':', '众里寻他千百度', '。', '这句话', '描述', '了', '词人', '对', '理想', '的', '执着', '追求', '。']

Jieba分词结果:
['南京市', '长江大桥']
['我', '在', '参加', '百度', '自然语言', '处理', '集训营', ',']
['Paddlepaddle', '很', '好', '用', ',', '也', '很', '强大', '!']
['“', '百度', '”', '二字', ',', '来自', '于', '八百年', '前', '南宋', '词人', '辛弃疾', '的', '一句', '词', ':', '众里', '寻', '他', '千百度', '。', '这句', '话', '描述', '了', '词人', '对', '理想', '的', '执着', '追求', '。']
结果分析:

Paddlepaddle的分词粒度大于Jieba,可以推测Paddle的预设词汇表比Jieba更大。

(3) 对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵
import paddlehub
import os
import re
import numpy as np
import collections


# 加载paddle的lac模型
lac = paddlehub.Module('lac')
path = '1946年05月'
# 遍历文件夹
files_path = []
for root, dirs, files in os.walk(path):
    for file in files:
        files_path.append(os.path.join(root,file))

# 读取文件内容
passages = []
for path in files_path:
    with open(path, encoding='utf-8') as f:
        one_passage = f.read()
        passages.append(one_passage)

inputs = {"text": passages}
passages = lac.lexical_analysis(data=inputs)
passages_cut = [p['word'] for p in passages]

# 处理特殊字符,替换为空格
text_cleaned = []
for p in passages_cut:
    for string in p:
        strings = re.split(r'[a-zA-Z0-9’!"#$%&\'()*+,-./:;<=>?@,。:()?@★、…【】《》?“”‘’!^_`{|}~\s]+', string)
        text_cleaned.extend(strings)
# 删除所有空字符
text_cleaned = [t for t in text_cleaned if t != '']
print(text_cleaned)

# 三种方法统计词频
# ①直接使用dict【不导包】
# ②使用collections.defaultdict(int)
# ③使用collections.Counter【最简洁】

# # ①直接使用dict
# frequency = {}
# for word in text_cleaned:
#     if word not in frequency:
#         frequency[word] = 1
#     else:
#         frequency[word] += 1

# # ②使用defaultdict
# frequency = collections.defaultdict(int)
# for word in text_cleaned:
#     frequency[word] += 1

# ③使用Counter
frequency = collections.Counter(text_cleaned)

# 按词频排序
frequency = sorted(frequency.items(), key=lambda x: x[1], reverse=True)

# 总词数
word_count = 0
for item in frequency:
    word_count += item[1]

# 求信息熵
entropy = 0
for item in frequency:
    p = int(item[1]) / word_count
    entropy += -p*np.log2(p)

print("信息熵=", entropy)
结果
entropy= 11.778569558439427

截图如下
计算信息熵结果

作业1-2

(1)思考一下,假设输入一个词表里面含有N个词,输入一个长度为M的句子,那么最大前向匹配的计算复杂度是多少?

答: O(M * N)
理由: 最大前向匹配最坏的情况是:句子分词结果为单个字,并且每个字都需要遍历词表全部。所以最后的匹配结果次数为N * (M + M-1 + … + 2 + 1),所以时间复杂度为O(N * M^2)

正向最大匹配算法:首先需要给定一个最大的词条长度,假设定义最大词条长度(滑动窗口的长度)为max_num=3,我们首先取出句子的前3个字符,看前3个字符是否存在于词库中,如果存在,则返回第一个分词,滑动窗口向后滑动3个位置;如果不存在,我们把滑动窗口从右向左缩小1,判断前两个字符是否存在于词库,如果存在,则返回这个分词,滑动窗口向后滑动2,不存在则继续缩小滑动窗口…直至将整个句子遍历完,就得到了最后的分词结果。
摘自:https://zhuanlan.zhihu.com/p/65190736

(2)给定一个句子,如何计算里面有多少种分词候选,你能给出代码实现吗?
(3)除了最大前向匹配和N-gram算法,你还知道其他分词算法吗,请给出一段小描述。
  • 1.基于词表

    • a) 逆向最大匹配法(BMM):类比前向匹配法,顺序相反

    • b) 双向最大匹配法:正向与逆向结合

  • 2.基于统计模型

    • a)隐马尔可夫模型:HMM模型认为在解决序列标注问题时存在两种序列,一种是观测序列,即人们显性观察到的句子,而序列标签是隐状态序列,即观测序列为X,隐状态序列是Y,因果关系为Y->X。因此要得到标注结果Y,必须对X的概率、Y的概率、P(X|Y)进行计算,即建立P(X,Y)的概率分布模型。

    • b)CRF分词算法:CRF可以看作一个无向图模型,对于给定的标注序列Y和观测序列X,对条件概率P(Y|X)进行定义,而不是对联合概率建模。CRF可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词有很好的识别能力,但开销较大

引用:

  1. https://blog.csdn.net/ld326/article/details/81364405
  2. Jiao, Zhenyu and Sun, Shuqi and Sun, Ke. Chinese Lexical Analysis with Deep Bi-GRU-CRF Network. arXiv: https://arxiv.org/abs/1807.01882
  3. https://github.com/PaddlePaddle/models/tree/release/1.6/PaddleNLP/lexical_analysis
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值