首页 AI Studio教育版 帖子详情
作业帖 | NLP+推荐-深度学习集训营
收藏
快速回复
AI Studio教育版 其他课程答疑 17678 149
作业帖 | NLP+推荐-深度学习集训营
收藏
快速回复
AI Studio教育版 其他课程答疑 17678 149

百度深度学习集训营第二阶段的NLP+推荐系统内容开讲啦,每个阶段的作业都将有各自的奖励,欢迎大家学习~

PS:如遇帖子过期、审核不通过的情况,请先复制内容保存在word文档,然后根据提示,完成个人实名验证,刷新后重新粘贴复制的内容,即可提交~

欢迎大家报名参加~

请大家按照作业格式将作业回帖在下面,并备注自己的AI Studio用户名~

 

2月27日第二次作业

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

实践作业:(必做)

路径:AI Studio课程-作业-NLP作业2

•请尝试用飞桨实现一个CBOW模型,并使用text8语料进行训练(或尝试提高skip-gram的训练速度)

附加题:(选做,答案回复在作业帖下)

•打开你的脑洞,尝试embedding的各种花样玩法,比如计算同义词,进行推理,将embedding进行聚类,或者用t-sne进行可视化。

附加题回复格式:

AI Studio用户名:XXXX

作业2-1附加题:XXX

 

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算法,你还知道其他分词算法吗,请给出一段小描述。

回复作业格式:

AI Studio用户名:XXXX

作业1-1:XXX

作业1-2:

(1)XXX

(2)XXX

 

报名流程:

1.加入QQ群:677320960,班主任会在QQ群里进行学习资料、答疑、奖品等活动

2.点此链接,加入课程报名并实践:https://aistudio.baidu.com/aistudio/course/introduce/888

温馨提示:课程的录播会在3个工作日内上传到AI studio《百度架构师手把手教深度学习》课程上

8
收藏
回复
全部评论(149)
时间顺序
山竹小果
#102 回复于2020-03

AI Studio用户名:Shona1021

作业2-1附加题:

加载已经保存好的CBOW模型找相近词 & 可视化embedding:

利用tensorflow开源工具进行可视化:

0
回复
诸葛AI云
#103 回复于2020-03

AI Studio用户名:诸葛AI云

作业1-1:

(1)安装paddlepaddle截图

(2)学习LAC和jieba分词

(3)计算信息熵:

def Keyword_part_LAC(arr):
    model = paddlehub.Module(name="lac")
    result=model.lexical_analysis(data={'text':arr})
    return result


def Keyword_part_jieba(arr):
    seg_list = jieba.cut_for_search(str(arr))  # 搜索引擎模式
    a = ", ".join(seg_list)
    a = a.split(',')
    print(a)
    return a


def informationentropy(strs):  # Calculating information entropy

    strs_number = {}
    for i in range(int(len(strs))):
        if i in strs_number:
            strs_number[i] += 1
        else:
            strs_number[i] = 1

    strs_count = len(strs)
    info = 0
    for Key, value in strs_number.items():
        p = value / strs_count
        info = info - p * math.log(p, 2)
    return info


if __name__ == "__main__":
    strs1 = read_md('data/1946-05-15_艾森豪威尔_过京沪即将赴日.md')
    a = input('请选择分词方法:' + '\n' + '1.jieba分词' + '\n' + '2.paddle_LAC分词' + '\n' + '请输入【1/2】')
    a=int(a)
    print('\n')
    if a == 1:
        arr = Keyword_part_jieba(strs1)
    elif a == 2:
        arr = Keyword_part_LAC(strs1)
    else:
        print('please input agin')
    entr = informationentropy(arr)
    print('\n'+"information entropy:{}".format(entr))

用1和2选择分词方法

下图为jieba分词的效果以及信息熵

信息熵为7.179909090014958

作业1-2:

(1)计算复杂度 O(N*(M^2))

(2)

jieba分词:Paddle模式  全模式  精确模式 搜索模式

paddlepaddle:LAC模型

(3)分词算法:

1.基于CRF的分词方法

CRF是无向图模型 

Z(O)将其归一化

P (I|O)表示在给定观测序列O=(O1,O2,...Oi)的情况下,我们用CRF求出的隐序列I = (I1,I2,...Ii)的概率,注意这里I是一个序列,有多个元素

优点:

克服了HMM的观测独立假设以及MEMM标注偏差问题
缺点:

全局化特征模型会更复杂,导致训练周期长,计算量较大

 

2.基于深度学习的端对端的分词方法

BiLSTM-CRF的网络结构如上图所示,输入层是一个embedding层,经过双向LSTM网络编码,输出层是一个CRF层,经过双向LSTM网络输出的实际上是当前位置对于各词性的得分,CRF层的意义是对词性得分加上前一位置的词性概率转移的约束,其好处是引入一些语法规则的先验信息 。

3.隐马尔可夫模型(Hidden Markov Model,HMM)

是用来描述一个含有隐含未知参数的马尔可夫过程,隐马尔科夫模型在中文分词中的应用是将分词作为字在字符串中的序列标注任务来实现的:每个字在构成一个特定的词语时都会占据着一个确定的构词位置(词位),这里每个字只有四个位置:即B(词首)、M(词中)、E(词尾)、S(单独成词)。

0
回复
不用谢逍遥游
#104 回复于2020-03

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

已发。

(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更大。Paddle的分词效果较强悍。

(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)

(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可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词有很好的识别能力,但开销较大。

 

 

0
回复
YBStefan
#105 回复于2020-03

AI Studio用户名:YBStefan

作业1-1:

(1)已经发QQ:

(2)

AI Studio用户名:YBStefan

作业1-1:

(1)已经发QQ:

(2)

Paddle enabled successfully......
2020-02-26 10:46:23,867-DEBUG: Paddle enabled successfully......
Building prefix dict from the default dictionary ...
2020-02-26 10:46:23,925-DEBUG: Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\ASUS\AppData\Local\Temp\jieba.cache
2020-02-26 10:46:23,927-DEBUG: Loading model from cache C:\Users\ASUS\AppData\Local\Temp\jieba.cachePaddle Mode: 我/来到/北京清华大学
Paddle Mode: 乒乓球/拍卖/完/了
Paddle Mode: 中国科学技术大学

Loading model cost 0.876 seconds.
2020-02-26 10:46:24,802-DEBUG: Loading model cost 0.876 seconds.
Prefix dict has been built successfully.
2020-02-26 10:46:24,803-DEBUG: Prefix dict has been built successfully.


Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
Default Mode: 我/ 来到/ 北京/ 清华大学
他, 来到, 了, 网易, 杭研, 大厦
小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

3)对人民日报进行分词,计算信息熵:

作业1-2:

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

         最大的前向匹配的计算复杂度是0(NM^2)

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

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

基于词表的分词方法:
   正向最大匹配法(forward maximum matching method, FMM)
   逆向最大匹配法(backward maximum matching method, BMM)
    N-最短路径方法:

基于统计模型的分词方法:
  基于N-gram语言模型的分词方法

基于序列标注的分词方法:
  基于HMM的分词方法
  基于CRF的分词方法
  基于词感知机的分词方法
  基于深度学习的端到端的分词方法

0
回复
zhou573223360
#106 回复于2020-03

用户名:zhou573223360

作业1-1-1:

已发给班主任

作业1-1-2:

通过jieba分词

作业1-1-3:计算1946年5月人民日报数据的信息熵

作业1-2-1

一共需要计算N*M*(M-1)次,时间复杂度为O(NM^2)。

作业1-2-2

作业1-2-3

小白,不了解了

0
回复
bnpzsx
#107 回复于2020-03

AI Studio用户名:bnpzsx

作业2-1附加题:

1. 使用t-sne给text8语料中频率最高的前2000个词的词向量降维, 并可视化

from sklearn.manifold import TSNE
import matplotlib.pyplot as plt

#获取频率最高2000词词向量
data = [id2word_dict[i] for i in range(2000)]
vector = np.array([model[i] for i in data])

#降维
tsne=TSNE()
tsne.fit_transform(vector)
coordinate = tsne.embedding_

#画图
plt.figure(figsize=(100,100))
for i in range(len(data)):
plt.text(*coordinate[i], data[i], fontsize='xx-large')
plt.scatter(*coordinate[i])
plt.savefig('词图.jpg')


在图中语义越相似的词距离越小, 以下为一些局部图片

/

/

2. 基于语言的逻辑推理

#关键推理函数
def inference(text, k=5, embed=embedding_matrix, embed_out=embedding_out_matrix):
    t = text.replace(' ', '')
    vectors = []
    cache = ''
    sign = 1
    num = 0
    for i in (t + '+'):
        if i in ('+', '-'):
            if sign == 1:
                vectors.append(get_vector(cache, embed))
                num += 1
            else:
                vectors.append(-get_vector(cache, embed))
                num -= 1
            cache = ''
            sign = 1 if i == '+' else -1
        else:
            cache += i
    r = np.sum(vectors, axis=0) / max(1, num)
    print(f'for `{text}`')
    if num <= 1:
        get_similar_tokens1(r, 5, embed)
    else:
        get_similar_tokens1(r, 5, embed_out)

测试

inference('physics')
inference('earth - human + life')
inference('woman + pregnancy')
inference('crops + autumn')
inference('teacher + student + house')

输出

for `physics`
the similar word is physics(1.000)
the similar word is mechanics(0.585)
the similar word is quantum(0.576)
the similar word is newtonian(0.559)
the similar word is mathematical(0.521)
for `earth - human + life`
the similar word is earth(0.713)
the similar word is life(0.625)
the similar word is planets(0.391)
the similar word is mars(0.379)
the similar word is crater(0.376)
for `woman + pregnancy`
the similar word is woman(0.522)
the similar word is child(0.420)
the similar word is children(0.418)
the similar word is adult(0.408)
the similar word is disease(0.386)
for `crops + autumn`
the similar word is crops(0.404)
the similar word is harvest(0.384)
the similar word is winter(0.383)
the similar word is tea(0.362)
the similar word is farm(0.359)
for `teacher + student + house`
the similar word is college(0.459)
the similar word is student(0.459)
the similar word is teacher(0.452)
the similar word is education(0.439)
the similar word is school(0.429)
0
回复
土豆芽
#108 回复于2020-03

AI Studio用户名:石晶

2月25日第一次作业

**作业1-1**

(1)下载飞桨本地并安装成功

(2)学习使用PaddleNLP下面的LAC模型或Jieba分词

已下载

(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵

**作业1-2**


(1) 思考一下,假设输入一个词表里面含有N个词,输入一个长度为M的句子,那么最大前向匹配的计算复杂度是多少?
O(M*M)和O(M)之间
(2) 给定一个句子,如何计算里面有多少种分词候选,你能给出代码实现吗?
import jieba
import re
cut_words=[]
for line in open('./text1.txt',encoding='utf-8'):
line.strip('\n')
line = re.sub("[A-Za-z0-9\:\·\—\,\。\“ \”]", "", line)
seg_list=jieba.cut(line,cut_all=True)
(3)除了最大前向匹配和N-gram算法,你还知道其他分词算法吗,请给出一段小描述。
逆向最大匹配算法RMM
是正向最大匹配的逆向思维,匹配不成功,将匹配字段的最前一个字去掉,实验表明,逆向最大匹配算法要优于正向最大匹配算法。

双向最大匹配法
双向最大匹配法是将正向最大匹配法得到的分词结果和逆向最大匹配法的到的结果进行比较,从而决定正确的分词方法。

设立切分标志法
收集切分标志,在自动分词前处理切分标志,再用MM、RMM进行细加工。

最佳匹配法(正向,逆向)
对分词词典按词频大小顺序排列,并注明长度,降低时间复杂度。

隐马尔可夫模型分词方法
隐马尔可夫的三大问题分别对应了分词中的几个步骤。参数估计问题就是分词的学习阶段,通过海量的预料数据来学习归纳出分词模型的各个参数。状态序列问题是分词的执行阶段,通过观测变量(待分词句子的序列)来预测出最优的状态序列(分词结构)。

 

 

0
回复
AIStudio810260
#109 回复于2020-03

AI Studio用户名:深渊上的坑

作业1-1

(1)已发班主任

(2)使用PaddleNLP下面的LAC模型,以及使用Jieba分词模型

import paddlehub as hub
module = hub.Module(name="lac")

import jieba
jieba.enable_paddle()

test_text = ["Lexical Analysis of Chinese,简称 LAC,是一个联合的词法分析模型,在单个模型中完成中文分词、词性标注、专名识别任务",
            "我们在自建的数据集上对分词、词性标注、专名识别进行整体的评估效果,具体数值见下表",
            "此外,我们在百度开放的 ERNIE模型上 finetune,并对比基线模型、BERT finetuned和ERNIE finetuned的效果,可以看出会有显著的提升",
            "可通过AI开放平台-词法分析线上体验百度的词法分析服务"
            ]

for str in test_text:

    result = module.lexical_analysis(data={"text": [str]})
    print('/'.join(list(result[0]['word'])))

    seg_list = jieba.cut(str,use_paddle=True)
    print('/'.join(list(seg_list)))
    
    seg_list = jieba.cut(str)
    print('/'.join(list(seg_list)))


Paddle enabled successfully......
2020-03-02 10:22:03,514-DEBUG: Paddle enabled successfully......
[2020-03-02 10:22:03,522] [    INFO] - 20 pretrained paramaters loaded by PaddleHub
Building prefix dict from the default dictionary ...
2020-03-02 10:22:03,553-DEBUG: Building prefix dict from the default dictionary ...
Lexical/ /Analysis/ /of/ /Chinese/,/简称/ /LAC/,/是/一个/联合/的/词法/分析/模型/,/在/单个/模型/中/完成/中文/分词/、/词性/标注/、/专名/识别/任务
L/exical Analysis of Chinese,简称 LAC,/是/一个/联合/的/词法/分析/模型/,/在/单个/模型/中/完成/中文/分词/、/词性/标注/、/专名/识别/任务
Lexical/ /Analysis/ /of/ /Chinese/,/简称/ /LAC/,/是/一个/联合/的/词法/分析模型/,/在/单个/模型/中/完成/中文/分词/、/词性/标注/、/专名/识别/任务
我们/在/自建/的/数据集/上/对/分词/、/词性/标注/、/专名/识别/进行/整体/的/评估/效果/,/具体/数值/见/下/表
我们/在/自建/的/数据集/上/对/分词/、/词性/标注/、/专名/识别/进行/整体/的/评估/效果/,/具体/数值/见/下/表
我们/在/自建/的/数据/集上/对/分词/、/词性/标注/、/专名/识别/进行/整体/的/评估/效果/,/具体/数值/见/下表
此外/,/我们/在/百度/开放/的/ /ERNIE/模型/上/ /finetune/,/并/对比/基线/模型/、/BERT finetuned/和/ERNIE finetuned/的/效果/,/可以/看出/会/有/显著/的/提升
此外/,/我们/在/百度/开放/的/ ERNIE/模型/上/ finetune,并对比基线模型、BERT finetuned/和/ERNIE finetuned/的/效果/,/可以/看出/会/有/显著/的/提升
此外/,/我们/在/百度/开放/的/ /ERNIE/模型/上/ /finetune/,/并/对比/基线/模型/、/BERT/ /finetuned/和/ERNIE/ /finetuned/的/效果/,/可以/看出/会/有/显著/的/提升
可/通过/AI/开放/平台/-/词法/分析/线上/体验/百度/的/词法/分析/服务
可/通过/AI/开放/平台/-/词法/分析/线上/体验/百度/的/词法/分析/服务
可/通过/AI/开放平台/-/词法/分析线/上/体验/百度/的/词法/分析/服务
Dumping model to file cache /tmp/jieba.cache
2020-03-02 10:22:04,306-DEBUG: Dumping model to file cache /tmp/jieba.cache
Loading model cost 0.806 seconds.
2020-03-02 10:22:04,360-DEBUG: Loading model cost 0.806 seconds.
Prefix dict has been built successfully.
2020-03-02 10:22:04,361-DEBUG: Prefix dict has been built successfully.

(3)切词,并通过统计每个词出现的概率,计算信息熵

import os
import sys
import re
import tqdm
from collections import Counter
import paddlehub as hub
import jieba
import numpy as np
from wordcloud import WordCloud

def search_file(path):
    if not os.path.exists(path):
        print("path not exist!")
        sys.exit(1)

    # 遍历文件夹 单层
    file_list = os.listdir(path)
    file_list=[os.path.join(path,i) for i in file_list]

    return file_list

def get_sentence(file_list):
    text=[]
    for filename in file_list:
        # print(filename)
        data=open(filename, "r",encoding = 'utf-8').read()

        # 除去中文 数字外的所有字符
        data = re.sub(r'[^\u4e00-\u9fa50-9]', " ",data) 
        data = data.strip() #去掉开头结尾的空格
        data = re.sub(r' +', " ",data) #去掉中间多余的空格
        data = data.split(' ')
        # print(data)
        text=text+data
        # break

    return  text

def Entropy(word):
    word_rate = Counter(word)
    p=np.array(list(word_rate.values()))
    p=p/len(word)
    return -(p*np.log2(p)).sum()

def get_stopword(filename):
    data=open(filename, "r",encoding = 'utf-8').read()
    return data.split('\n')



# 位置
path = "rmrb/example/1946年05月"

# 获取句子
file_list=search_file(path)
print("文章数量:",len(file_list))
data=get_sentence(file_list)
print("句子数量:",len(data))

#获取停用词
stopword=get_stopword('stopwords/百度停用词表.txt')

# 词云
w = WordCloud(font_path="NOTOSANSCJKSC-BLACK.OTF",
      width=1000, height=700, background_color="white",
      collocations=False
      )

# lac 分词
module = hub.Module(name="lac")
result_list = module.lexical_analysis(data={"text": data})
word=[]
for result in result_list:
    word=word+result['word']
print('LAC分词之后总共单词数量:',len(Counter(word)))
print("LAC分词之后信息熵: ", Entropy(word))
word = [w for w in word if w not in stopword and len(w)>2 and not re.match('^[a-z|A-Z|0-9|.]*$',w)]
print('LAC分词+stopword之后总共单词数量:',len(Counter(word)))
print("LAC分词+stopword之后信息熵: ", Entropy(word))
print(Counter(word).most_common(10))
w.generate(" ".join(word))
w.to_file("LAC_stopword.png")

# jieba 分词,使用paddle模式
jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持
word=[]
for s in tqdm.tqdm(data):
    result = jieba.lcut(s,use_paddle=True) # 使用paddle模式
    word=word+result
print('jieba分词+paddle模式之后总共单词数量:',len(Counter(word)))
print("jieba分词+paddle模式之后信息熵: ", Entropy(word))
word = [w for w in word if w not in stopword and len(w)>2 and not re.match('^[a-z|A-Z|0-9|.]*$',w)]
print('jieba分词+paddle模式+stopword之后总共单词数量:',len(Counter(word)))
print("jieba分词+paddle模式+stopword之后信息熵: ", Entropy(word))
print(Counter(word).most_common(10))
w.generate(" ".join(word))
w.to_file("jieba_paddle_stopword.png")

# jieba 分词,使用默认模式
word=[]
for s in tqdm.tqdm(data):
    result = jieba.lcut(s) # 使用默认模式
    word=word+result
print('jieba分词+默认模式之后总共单词数量:',len(Counter(word)))
print("jieba分词+默认模式之后信息熵: ", Entropy(word))
word = [w for w in word if w not in stopword and len(w)>2 and not re.match('^[a-z|A-Z|0-9|.]*$',w)]
print('jieba分词+默认模式+stopword之后总共单词数量:',len(Counter(word)))
print("jieba分词+默认模式+stopword之后信息熵: ", Entropy(word))
print(Counter(word).most_common(10))
w.generate(" ".join(word))
w.to_file("jieba_stopword.png")

作业1-2:

(1)最大前向匹配的计算复杂度

N个词,输入一个长度为M的句子,最大前向匹配的计算复杂度为 O(N∗M(M+1)/2)=O(N∗M^2)

(2)给定一个句子,如何计算里面有多少种分词候选

import jieba

data = '给定一个句子'
word_dict= list(jieba.cut(data,cut_all=True))

dic=list(data)+word_dict
print("句子中的单词包括:",dic)

def pref_cut(pre,data,dic,ans=[]):
    if len(data)==0:
        # print(pre)
        ans.append(pre)
        return 0
    for i in range(len(data)):
        if data[:i+1] in dic:
            pref_cut(pre+[data[:i+1]],data[i+1:],dic,ans)
    return ans

word=pref_cut([],data,dic)
print("分词候选个数",len(word))
word
句子中的单词包括: ['给', '定', '一', '个', '句', '子', '给定', '一个', '句子']
分词候选个数 8
[['给', '定', '一', '个', '句', '子'],
 ['给', '定', '一', '个', '句子'],
 ['给', '定', '一个', '句', '子'],
 ['给', '定', '一个', '句子'],
 ['给定', '一', '个', '句', '子'],
 ['给定', '一', '个', '句子'],
 ['给定', '一个', '句', '子'],
 ['给定', '一个', '句子']]

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

基于词表的分词方法

最大后向匹配法(backward maximum matching method, BMM)

基本原理与最大前向匹配法类似,只是分词顺序变为从右至左。
双向最大匹配

将最大前向匹配和最大后向匹配的结果结合起来
基于序列标注的分词方法

基于HMM的分词方法

对应隐马尔科夫模型的解码问题,模型参数(转移矩阵,发射矩阵)可以使用统计方法计算得到,原始文本为输出序列,词位是隐状态序列,使用Viterbi算法求解
基于CRF的分词方法

一种判别式模型,CRF通过定义条件概率P(Y∣X)P(Y∣X)P(Y∣X)来描述模型。基于CRF的分词方法与传统的分类模型求解很相似,即给定feature(字级别的各种信息)输出label(词位)
基于词感知机的分词方法
基于深度学习的端到端的分词方法

如BiLSTM-CRF(参考资料#4)的网络结构如上图所示,输入层是一个embedding层,经过双向LSTM网络编码,输出层是一个CRF层。经过双向LSTM网络输出的实际上是当前位置对于各词性的得分,CRF层的意义是对词性得分加上前一位置的词性概率转移的约束,其好处是引入一些语法规则的先验信息。

0
回复
XiaMen1004212
#110 回复于2020-03

AI Studio用户名:dfenglei

作业1-1:

(1)提交班主任

(2)学习分词模型


(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵

# encoding=utf-8
import os
import math
import jieba
from collections import Counter


def word_count(filepath):
word_list = []
file_list = os.listdir(filepath)
for file in file_list:
path = os.path.join(filepath, file)
text = open(path, encoding='utf-8').read()
text = text.strip().replace(' ', '').replace('\n', '').replace('“', '') \
.replace('”', '').replace('、', '') \
.replace(',', '').replace('。', '').replace('。', '') \
.replace('(', '').replace(')', '').replace('-', '')
seg_list = jieba.cut(text)
word_list += seg_list
word_count = Counter(word_list)
# 计算信息熵
entropy = 0
for word in word_count:
word_count[word] /= len(word_list)
percent = word_count[word]
entropy += percent * math.log(percent, 2)
entropy = -entropy
print("信息熵:", entropy)


if __name__ == '__main__':
file_dir = '194605'
word_count(file_dir)

 

信息熵: 11.762779320674419

作业1-2:

(1)计算复杂度 O(NM^2)

(2)
# encoding=utf-8
import jieba
import paddle
import jieba.posseg as pseg
sentence ='我爱百度飞浆'
words = pseg.cut(sentence) #jieba默认模式
for word, flag in words:
print('%s %s' % (word, flag))

sentence ='我爱北京清华大学'
worddict = list(jieba.cut(sentence,cut_all=True))

def list_segment(result, sentence, worddict):

cnt = 0
if len(sentence) == 0:
print("/".join(result))
return 1
for i in range(1, len(sentence)+1):
if sentence[:i] in worddict:
cnt += list_segment(result+[sentence[:i]], sentence[i:], worddict)
return cnt
cnt =list_segment([],sentence,worddict)
print('候选分词可能数目:%d' % cnt)
我 r
爱 v
百度 n
飞浆 n
我/爱/北京/清华/大学
我/爱/北京/清华大学
候选分词可能数目:2
(3)

分词算法可分为三大类:

 

 

1.基于词典:基于字典、词库匹配的分词方法;(字符串匹配、机械分词法)除了最大前向匹配还有逆向最大匹配法(ReverseMaximum Matching Method)(3)最少切分法

使每一句中切出的词数最小。(4)双向最大匹配法( Bi-directction Matching method )

2.基于统计:基于词频度统计的分词方法;除了N-gram算法,主要统计模型有:隐马尔科夫模型(Hidden Markov Model, HMM)。

3.基于规则:基于知识理解的分词方法。基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段.

0
回复
不用谢逍遥游
#111 回复于2020-03
作业1-1 (1) 下载飞桨本地并安装成功,将截图发给班主任 已发。 [图片] (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的分词粒度大于Jieba,可以推测Paddle的预设词汇表比Jieba更大。Paddle的分词效果较强悍。 (3) 对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵 [代码] 结果: entropy= 11.778569558439427 作业1-2 (1)思考一下,假设输入一个词表里面含有N个词,输入一个长度为M的句子,那么最大前向匹配的计算复杂度是多少? 答: O(M * N) 理由: 最大前向匹配最坏的情况是:句子分词结果为单个字,并且每个字都需要遍历词表全部。所以最后的匹配结果次数为N * (M + M-1 + … + 2 + 1),所以时间复杂度为O(N * M^2) (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可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词有很好的识别能力,但开销较大。    
展开

忘记写用户名了,补上:

AI Studio用户名:不用谢逍遥游

0
回复
R
RheftButler
#112 回复于2020-03

2月25日第一次作业

AI Studio用户名:RheftButler

作业1-1

(1)下载飞桨本地并安装成功

(2)学习使用PaddleNLP下面的LAC模型或Jieba分词

jieba分词

(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵

# encoding: utf-8
'''
@author: jinjin
@contact: cantaloupejinjin@gmail.com
@file: test.py
@time: 2020/3/2 10:19
'''

import jieba
import os
import re
from collections import Counter
from math import log


path = "194605"
writeDir = 'test_text.txt'
result = os.listdir(path)
total_words = []
for fileDir in result:
    with open(path+'/'+fileDir, 'r',encoding='utf-8') as f:
        content = f.read()
        content = content.strip().replace('\n','').replace(' ','').replace(', ','').replace('  ','')
        p = ',,、:。?“”;#()'
        content = re.sub(r'[%s]+' %p, "", content)
        total_words += jieba.cut(content, use_paddle=True)
c = Counter(total_words)

def calcShannonEnt(dict):
    shannonEnt = 0.0
    wordlen = len(total_words)
    for key in dict:
        prob = float(dict[key])/wordlen
        shannonEnt -= prob * log(prob, 2)
    return shannonEnt
print("信息熵:",calcShannonEnt(c))
信息熵: 11.09682047298585

作业1-2

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

O(M*M)

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

import jieba
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
print(", ".join(seg_list))

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

基于字符串匹配的分词方法(最大前向匹配、最大后向匹配、双向最大匹配)
基于统计的分词方法(N-gram、HMM、ME、CRF)
基于理解的分词方法
0
回复
诸葛AI云
#113 回复于2020-03

AI Studio用户名:诸葛AI云

实践题:已提交版本

作业2-1附加题:

用TSNE进行数据降维并展示聚类结果

from sklearn.manifold import TSNE

tsne = TSNE()
tsne.fit_transform(data_zs) #进行数据降维       
tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #转换数据格式
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

#不同类别用不同颜色和样式绘图
d = tsne[r[u'聚类类别'] == 0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚类类别'] == 1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚类类别'] == 2]
plt.plot(d[0], d[1], 'b*')
plt.show()
0
回复
aaaLKgo
#114 回复于2020-03

AI Studio用户名:aaaLKgo

作业1-1:

(1)第(3)题中有使用

(2)第(3)题中,两个库都有使用

(3)统计词的概率与信息熵

import jieba
import paddlehub as hub
import os
import re
from tqdm import tqdm
import numpy as np
from collections import Counter

def get_passages(example=False):
    root_dir = "rmrb/example/1946年05月"
    news = os.listdir(root_dir)
    if example:
        example_path = os.path.join(root_dir, news[3])
        with open(example_path, "r") as f:
            return f.read()
    else:
        passages = []
        for fname in news:
            path = os.path.join(root_dir, fname)
            with open(path, "r") as f:
                passages.append(f.read())
        return passages

def cut_passages(passages):
    pattern = r',|\.|/|;|\'|`|\[|\]|<|>|\?|:|"|\{|\}|\~|!|@|#|\$|%|\^|&|\(|\)|-|=|\_|\+|,|。|、|:|”|“|;|‘|’|【|】|·|!| |…|(|)|\n|\u3000'
    sentences = []
    for passage in passages:
        words_sentence = re.split(pattern, passage)
        words_sentence = [item for item in words_sentence if item]
        sentences += words_sentence
    return sentences
    
    
def cut_sentence(words_sentence, cut_mode="lac"):
    if cut_mode == "lac":
        lac = hub.Module(name="lac")
        result = lac.lexical_analysis(data={"text": words_sentence})
        words = [word for item in result for word in item["word"]]
    else:
        jieba.enable_paddle()
        kwargs = {"use_paddle": True} if cut_mode == "paddle" else {}
        words = [word for sentence in words_sentence
                 for word in jieba.cut(sentence, **kwargs)]
    return words

def calculate_prob(words, use_stop_words=True):
    count_words = dict(Counter(words))
    if use_stop_words:
        with open("中文停用词表.txt", "r") as f:
            stop_words = f.read().split("\n")
        count_words = {word: word_num for word, word_num in count_words.items()
                       if word not in stop_words}
    count_words = list(sorted(count_words.items(), key=lambda x:-x[1]))
    total_len = np.sum([num for word, num in count_words])
    total_unique_len = len(count_words)
    print("total words: {}".format(total_len))
    print("total unique words: {}".format(total_unique_len))
    words_prob = [word_num / total_len for word, word_num in count_words]
    print("top 5 words: {}".format([(word, "{:.4f}".format(word_num / total_len))
                                    for word, word_num in count_words[:5]]))
    return words_prob

def entropy(prob):
    return -prob * np.log2(prob)

def calculate_entropy(words_probs):
    h = np.sum([entropy(prob) for prob in words_probs])
    return h

if __name__ == "__main__":
    passages = get_passages()
    cut_modes = {"default": "jieba的精确模式", "paddle": "jieba的Paddle模式", "lac": "Paddle的lac模型"}
    stop_words_mode = {True: "停用词模式", False: "非停用词模式"}
    for cut_mode, cut_mode_desc in cut_modes.items():
        print("=" * 50)
        print(cut_mode_desc)
        sentences = cut_passages(passages)
        words = cut_sentence(sentences, cut_mode=cut_mode)
        for i, (use_stop_words, stop_words_desc) in enumerate(stop_words_mode.items()):
            if i != 0:
                print("+" * 25)
            print(stop_words_desc)
            words_probs = calculate_prob(words, use_stop_words=use_stop_words)
            final_entropy = calculate_entropy(words_probs)
            print("{} + {} 的最终信息熵为: {}".format(cut_mode_desc, stop_words_desc, final_entropy))

输出结果:

Paddle enabled successfully......
2020-03-02 11:21:02,464-DEBUG: Paddle enabled successfully......
Building prefix dict from the default dictionary ...
2020-03-02 11:21:02,465-DEBUG: Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
2020-03-02 11:21:02,467-DEBUG: Loading model from cache /tmp/jieba.cache
==================================================
jieba的精确模式
Loading model cost 0.720 seconds.
2020-03-02 11:21:03,186-DEBUG: Loading model cost 0.720 seconds.
Prefix dict has been built successfully.
2020-03-02 11:21:03,188-DEBUG: Prefix dict has been built successfully.
停用词模式
Paddle enabled successfully......
2020-03-02 11:21:04,730-DEBUG: Paddle enabled successfully......
total words: 103174
total unique words: 21271
top 5 words: [('国民党', '0.0086'), ('人民', '0.0067'), ('版', '0.0043'), ('1946', '0.0043'), ('05', '0.0043')]
jieba的精确模式 + 停用词模式 的最终信息熵为: 12.510029192369057
+++++++++++++++++++++++++
非停用词模式
total words: 138548
total unique words: 21732
top 5 words: [('的', '0.0405'), ('在', '0.0113'), ('了', '0.0093'), ('国民党', '0.0064'), ('是', '0.0057')]
jieba的精确模式 + 非停用词模式 的最终信息熵为: 11.821520711584395
==================================================
jieba的Paddle模式
停用词模式
[2020-03-02 11:21:33,812] [    INFO] - Installing lac module
total words: 99354
total unique words: 21466
top 5 words: [('国民党', '0.0069'), ('人民', '0.0069'), ('群众', '0.0049'), ('中', '0.0047'), ('1946', '0.0045')]
jieba的Paddle模式 + 停用词模式 的最终信息熵为: 12.492192767721901
+++++++++++++++++++++++++
非停用词模式
total words: 135834
total unique words: 21900
top 5 words: [('的', '0.0418'), ('在', '0.0116'), ('了', '0.0095'), ('之', '0.0069'), ('是', '0.0057')]
jieba的Paddle模式 + 非停用词模式 的最终信息熵为: 11.739260319485465
==================================================
Paddle的lac模型
Downloading lac
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpvsxxc2n0/lac
[==================================================] 100.00%
[2020-03-02 11:21:37,187] [    INFO] - Successfully installed lac-2.0.0
[2020-03-02 11:21:37,252] [    INFO] - 20 pretrained paramaters loaded by PaddleHub
停用词模式
total words: 98089
total unique words: 21853
top 5 words: [('人民', '0.0066'), ('国民党', '0.0065'), ('群众', '0.0049'), ('1946', '0.0046'), ('05', '0.0046')]
Paddle的lac模型 + 停用词模式 的最终信息熵为: 12.542586308603399
+++++++++++++++++++++++++
非停用词模式
total words: 134265
total unique words: 22288
top 5 words: [('的', '0.0422'), ('在', '0.0118'), ('了', '0.0095'), ('之', '0.0065'), ('是', '0.0057')]
Paddle的lac模型 + 非停用词模式 的最终信息熵为: 11.772977082383104

在运行速度上,jieba的精确模式十分快速,LAC最慢;其次,三者信息熵基本一致,可以发现使用停用词之后,信息的质量有一定上升。

作业1-2:

(1)N个词,输入一个长度为M的句子,最大前向匹配的计算复杂度为O(N*M(M+1)/2)=O(N*M^2)

(2)计算句子中的候选词

from itertools import combinations, chain

def powerset(s):
    return chain.from_iterable([combinations(s, i) for i in range(len(s) + 1)])

def get_candidate_seg(sentence):
    words_count = len(sentence)
    for i in powerset(range(1, words_count)):
        yield [sentence[m:n] for m, n in zip((0, ) + i, i + (words_count, ))]

if __name__ == "__main__":
    sentence = "南京市长江大桥"
    all_segs = list(get_candidate_seg(sentence))
    print("总候选分词数: {}".format(len(all_segs)))
    for seg in all_segs:
        print(seg)

输出结果:

总候选分词数: 64
['南京市长江大桥']
['南', '京市长江大桥']
['南京', '市长江大桥']
['南京市', '长江大桥']
['南京市长', '江大桥']
['南京市长江', '大桥']
['南京市长江大', '桥']
['南', '京', '市长江大桥']
['南', '京市', '长江大桥']
['南', '京市长', '江大桥']
['南', '京市长江', '大桥']
['南', '京市长江大', '桥']
['南京', '市', '长江大桥']
['南京', '市长', '江大桥']
['南京', '市长江', '大桥']
['南京', '市长江大', '桥']
['南京市', '长', '江大桥']
['南京市', '长江', '大桥']
['南京市', '长江大', '桥']
['南京市长', '江', '大桥']
['南京市长', '江大', '桥']
['南京市长江', '大', '桥']
['南', '京', '市', '长江大桥']
['南', '京', '市长', '江大桥']
['南', '京', '市长江', '大桥']
['南', '京', '市长江大', '桥']
['南', '京市', '长', '江大桥']
['南', '京市', '长江', '大桥']
['南', '京市', '长江大', '桥']
['南', '京市长', '江', '大桥']
['南', '京市长', '江大', '桥']
['南', '京市长江', '大', '桥']
['南京', '市', '长', '江大桥']
['南京', '市', '长江', '大桥']
['南京', '市', '长江大', '桥']
['南京', '市长', '江', '大桥']
['南京', '市长', '江大', '桥']
['南京', '市长江', '大', '桥']
['南京市', '长', '江', '大桥']
['南京市', '长', '江大', '桥']
['南京市', '长江', '大', '桥']
['南京市长', '江', '大', '桥']
['南', '京', '市', '长', '江大桥']
['南', '京', '市', '长江', '大桥']
['南', '京', '市', '长江大', '桥']
['南', '京', '市长', '江', '大桥']
['南', '京', '市长', '江大', '桥']
['南', '京', '市长江', '大', '桥']
['南', '京市', '长', '江', '大桥']
['南', '京市', '长', '江大', '桥']
['南', '京市', '长江', '大', '桥']
['南', '京市长', '江', '大', '桥']
['南京', '市', '长', '江', '大桥']
['南京', '市', '长', '江大', '桥']
['南京', '市', '长江', '大', '桥']
['南京', '市长', '江', '大', '桥']
['南京市', '长', '江', '大', '桥']
['南', '京', '市', '长', '江', '大桥']
['南', '京', '市', '长', '江大', '桥']
['南', '京', '市', '长江', '大', '桥']
['南', '京', '市长', '江', '大', '桥']
['南', '京市', '长', '江', '大', '桥']
['南京', '市', '长', '江', '大', '桥']
['南', '京', '市', '长', '江', '大', '桥']

(3)其他分词算法:

最大负向匹配算法:与正向最大匹配法类似,只是分词顺序变为从右至左;

HMM分词:HMM是一个生成模型,分词对应HMM的解码问题,模型参数(转移矩阵,发射矩阵)可以使用统计方法计算得到,原始文本为输出序列,词位是隐状态序列,使用Viterbi算法求解即可。

CRF分词:CRF是一种判别式模型,CRF通过定义条件概率P(Y∣X)来描述模型。基于CRF的分词方法与传统的分类模型求解很相似,即给定feature(字级别的各种信息)输出label(词位)。

BiLSTM-CRF:BiLSTM-CRF的输入层是一个embedding层,经过双向LSTM网络编码,输出层是一个CRF层。经过双向LSTM网络输出的实际上是当前位置对于各词性的得分,CRF层的意义是对词性得分加上前一位置的词性概率转移的约束,其好处是引入一些语法规则的先验信息。

0
回复
吖小吞
#115 回复于2020-03

AI Studio用户名:吖小吞

作业2-1附加题:打开你的脑洞,尝试embedding的各种花样玩法,比如计算同义词,进行推理,将embedding进行聚类,或者用t-sne进行可视化。

参照76楼大佬,但效果不太理想,没时间调了,先交一稿[捂脸]:

0
回复
星光ld1
#116 回复于2020-03

AI Studio用户名:星光ld1

作业2-1附加题:

下面测试一下词的加减运算

def get_similar_tokens(query_token, k, embed):
    W = embed.numpy()
    print(W.shape)
    x = W[word2id_dict[query_token]]
    print(x.shape)
    cos = np.dot(W, x) / np.sqrt(np.sum(W * W, axis=1) * np.sum(x * x) + 1e-9)
    flat = cos.flatten()
    indices = np.argpartition(flat, -k)[-k:]
    indices = indices[np.argsort(-flat[indices])]
    for i in indices:
        print('for word %s, the similar word is %s' % (query_token, str(id2word_dict[i])))

def get_word(query_token1, query_token2, query_token3, k, embed):
    W = embed.numpy()
    x = W[word2id_dict[query_token1]]
    y = W[word2id_dict[query_token2]]
    z = W[word2id_dict[query_token3]]
    result = x-y+z
    cos = np.dot(W, result) / np.sqrt(np.sum(W * W, axis=1) * np.sum(result * result) + 1e-9)
    flat = cos.flatten()
    indices = np.argpartition(flat, -k)[-k:]
    indices = indices[np.argsort(-flat[indices])]
    for i in indices:
        print('%s - %s + %s = %s' % (query_token1, query_token2, query_token3, str(id2word_dict[i])))

with fluid.dygraph.guard(fluid.CUDAPlace(0)):
    get_similar_tokens('beijing', 5, cbow_model.embedding._w)
    get_word('beijing', 'china', 'america', 5, cbow_model.embedding._w)

结果如下:

效果不是特别好

0
回复
物理介入
#117 回复于2020-03

作业1-1

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

 

(2)学习使用PaddleNLP下面的LAC模型或Jieba分词

import jieba

jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持
strs=["我来到北京清华大学","乒乓球拍卖完了","中国科学技术大学"]
for str in strs:
    seg_list = jieba.cut(str,use_paddle=True) # 使用paddle模式
    print("Paddle Mode: " + '/'.join(list(seg_list)))

seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精确模式

seg_list = jieba.cut("他来到了网易杭研大厦")  # 默认是精确模式
print(", ".join(seg_list))

seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
print(", ".join(seg_list))

output:

Paddle enabled successfully......
2020-02-27 03:08:04,141-DEBUG: Paddle enabled successfully......
Building prefix dict from the default dictionary ...
2020-02-27 03:08:04,157-DEBUG: Building prefix dict from the default dictionary ...
Paddle Mode: 我/来到/北京清华大学
Paddle Mode: 乒乓球/拍卖/完/了
Paddle Mode: 中国科学技术大学
Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
Default Mode: 我/ 来到/ 北京/ 清华大学
他, 来到, 了, 网易, 杭研, 大厦
小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
Dumping model to file cache /tmp/jieba.cache
2020-02-27 03:08:04,929-DEBUG: Dumping model to file cache /tmp/jieba.cache
Loading model cost 0.826 seconds.
2020-02-27 03:08:04,984-DEBUG: Loading model cost 0.826 seconds.
Prefix dict has been built successfully.
2020-02-27 03:08:04,986-DEBUG: Prefix dict has been built successfully.

 

(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵

import jieba
import os
from collections import Counter
import math
jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持

# 去掉符号
def remove_token(data):
    dic = ('!', '"', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '_', 
              '{', '|', '}', '~', '°', '±', '×', '—', '‘', '’', '“', '”', '′', '″', '≤', '≥', '①', '②', '③', '④', '⑤', '⑥',
              '⑦', '⑧', '⑨', '⑩', '、', '。', '《', '》', '【', '】', '〔', '〕', '!', '"', '(', ')', ',', ':', ';', '?', '~',
              '¥','。','.','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2',
               '3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U',
               'V','W','X','Y','Z','\n','\t','\u3000', ' ')
    for iter in dic:
        data = data.replace(iter, '')
    return data

# 去掉助词
def remove_zhuci(data):
    dic = ('的','了', '和', '与','阿','啊','啦','唉','呢','吧','哇','呀','不仅','虽然','但是','而且','因为','所以',
                  '不但','但','不只','一些','甚至','接着','然后','之','已','于','在','我','你','他','她','是','着','也',
                '说','要','对','不','都','这','那','又','并','就','去','它')
    for iter in dic:
        data = data.replace(iter, '')
    return data

with open('text.txt', 'r') as f:
    data = f.readline() # 因为文章只有一行,所以用readline()
    data = data.strip()
    print(len(data))
    data = remove_token(data)
    data = remove_zhuci(data)
    # print(data)
    seg_list = jieba.cut(data, use_paddle=True) # 使用paddle模式
    seg_list = list(seg_list)
    print("Paddle Mode: " + '/'.join(seg_list))
    total_num = len(seg_list)
    dic = Counter(seg_list)
    entropy = 0.0
    for value in dic.values():
        p = float(value) / float(total_num)
        entropy -= p * math.log(p)
    print('\nThe entropy of text is', entropy)
f.close()

信息熵为:

The entropy of text is 6.355102868728095
0
回复
物理介入
#118 回复于2020-03

作业1-2

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

'''
计算前项匹配的计算复杂度,考虑最坏的情况:
1. 词表中N个单词的长度全为1
2. 句子中所有的词都由词表中最后一个单词组成。
此时完成全部匹配过程计算量如下
N * M + N * (M-1) + N * (M-2) + ... + N * 1 = N * (M + 1)*M / 2
所以计算复杂度为O(NM^2)
'''

 

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

text = '南京市长江大桥'
d = ['南京', '市', '长江', '大桥', '市长', '江大桥']
li = list()
def count_seg(can, rem, dic):
    # print(can)
    # print(rem)
    if len(rem) == 0:
        print('/'.join(can))
        return 1
    
    count = 0
    for i in range(1, len(rem)+1):
        # print(i)
        if rem[:i] not in dic:
            continue
        count += count_seg(can + [rem[:i]], rem[i:], dic)
    return count

print('候选分词数为', count_seg(li, text, d))

output:

南京/市/长江/大桥
南京/市长/江大桥
候选分词数为 2

 

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

'''
与最大前项匹配相关的最大后项匹配,最大双向匹配。

HMM的分词方法
对应隐马尔科夫模型的解码问题,模型参数(转移矩阵,发射矩阵)可以使用统计方法计算得到,原始文本为输出序列,词位是隐状态序列,使用Viterbi算法求解
基于CRF的分词方法
'''
0
回复
Action
#119 回复于2020-03

AI Studio 用户名: Action

作业2-1:附加题

embedding 可视化

embedding learning result:

 

0
回复
thunder95
#120 回复于2020-03

AI Studio 用户名: thunder95

作业2-1:附加题

1.       计算相似的词和相似距离,代码和结果输出:

2. 对12个单词进行kmeans聚类并t-sne可视化:

1
回复
泪如秋思化成雪
#121 回复于2020-03

AI Studio用户名:泪如秋思化成雪

作业1-1          

(1)(2)


(3)对人民日报语料完成切词,并通过统计每个词出现的概率,计算信息熵

作业1-2

(1)最大前向匹配的计算复杂度是为:O(N∗M^2)
(2)
(3)联想—回溯法(Association-Backtracking Method,简称 AB 法)。这种方法要求建立三个知识库——特征词词库、实词词库和规则库。首先将待切分的汉字字符串序列按特征词词库分割为若干子串,子串可以是词,也可以是 由几个词组合而成的词群;然后,再利用实词词库和规则库将词群再细分为词。切词时,要利用一定的语法知识,建立联想机制和回溯机制。联想机制由联想网络和 联想推理构成,联想网络描述每个虚词的构词能力,联想推理利用相应的联想网络来判定所描述的虚词究竟是单独成词还是作为其他词中的构词成分。回溯机制主要 用于处理歧义句子的切分。联想—回溯法虽然增加了算法的时间复杂度和空间复杂度,但这种方法的切词正确率较高,是一种行之有效的方法。

 

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户