首页 AI Studio教育版 帖子详情
作业帖 | NLP+推荐-深度学习集训营
收藏
快速回复
AI Studio教育版 其他课程答疑 17878 149
作业帖 | NLP+推荐-深度学习集训营
收藏
快速回复
AI Studio教育版 其他课程答疑 17878 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)
时间顺序
j
jianghaoyu123
#122 回复于2020-03

AI Studio用户名:jianghaoyu123

作业2-1附加题:

利用T-SNE工具对训练好的CBOW模型的embedding进行可视化:

from sklearn.manifold import TSNE
%matplotlib inline
import matplotlib 
import matplotlib.pyplot as plt
Weight=skip_gram_model.embedding._w
TEM=Weight.numpy()
#词频最高的2000词中抽取50词利用T-SNE进行可视化
data = [id2word_dict[random.randint(1, 2000)] for i in range(50)]
data=list(tuple(data))
vector = np.array([TEM[word2id_dict[i],:] for i in data])
tsne=TSNE()
tsne.fit_transform(vector)
coordinate = tsne.embedding_
#画图
plt.figure(figsize=(20,10))
for i in range(len(data)):
    plt.text(*coordinate[i], data[i], fontsize='xx-large')
    plt.scatter(*coordinate[i])
plt.show()

0
回复
d
ddocan56
#123 回复于2020-03

AI Studio用户名:ddocan56

作业2-1附加题:

以下为使用CBOW来做的,效果不够理想。

0
回复
晟灬熙
#124 回复于2020-03

作业2-1:

修改skip-gram,数据读取部分,对数据进行预处理(停用词,去词干),并根据出现频次进行过滤,同时,将dataset也变为迭代器,以解决内存溢出问题。

最后skip-gram得到的词向量如下:

之后,写了CBOW模型:

作业2-2:

观察CBOW模型输出的词向量,并查看 king-man+woman 与queen的余弦相似度是否接近1 

 

0
回复
泪如秋思化成雪
#125 回复于2020-03

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

作业2-1飞桨实现一个CBOW模型

作业2-2 用t-sne进行可视化

0
回复
Wuhiu
#126 回复于2020-03

AI Studio用户名:Jesus丶cia

作业2-1附加题:

在训练好的Embedding中查询指定的一些词的词向量,并进行K-means聚类和T-SNE可视化:

import matplotlib.pyplot as plt
from sklearn import manifold
from sklearn.cluster import KMeans

def t_sne(query_words, embedding):
    embed_words = list()
    look_up = embedding.numpy()
    for word in query_words:
        embed_words.append(look_up[word2id_dict[word]])
    embed_words = np.array(embed_words)
    
    n_clusters = 3
    kmeans = KMeans(n_clusters=n_clusters)
    kmeans.fit(embed_words)
    classes = kmeans.predict(embed_words)
    
    tsne = manifold.TSNE(n_components=3, init='pca', random_state=501)
    X_tsne = tsne.fit_transform(embed_words)
    
    #嵌入空间可视化
    x_min, x_max = X_tsne.min(0), X_tsne.max(0)
    X_norm = (X_tsne - x_min) / (x_max - x_min)  # 归一化
    plt.figure(figsize=(8, 8))
    for i in range(X_norm.shape[0]):
        plt.scatter(X_norm[i, 0], X_norm[i, 1],color=plt.cm.Set1(classes[i]))
        plt.text(X_norm[i, 0], X_norm[i, 1], str(query_words[i]), color=plt.cm.Set1(classes[i]),
                 fontdict={'weight': 'bold', 'size': 12})
    plt.title('Embedding T-SNE Visualization')
    plt.show()

结果如下:

0
回复
JacksonL1
#127 回复于2020-03

AI Studio 用户名: JacksonL1

作业1-1:

    (1). jieba模型(https://github.com/fxsjy/jieba) 

  

                         

    (2): LAC模型,调用paddlehub

        hub run lac --input_text "今天天气真不错"
        hub run lac --input_file test.txt

    (3): 人民日报语料,计算信息熵

0
回复
JacksonL1
#128 回复于2020-03

AI Studio 用户名: JacksonL1

作业1-2:

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

  答: 最理想情况:N/M次。 最差的情况:N*M*M

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

  答:

import jieba
seg = jieba.cut("今天天气真不错", cut_all=True)
seg_list = list(seg)
print('分词个数: ', len(seg_list ), '\n候选分词: ', seg_list )

     输出:

         分词个数: 7
         候选分词: ['今天', '今天天气', '天天', '天气', '真不', '真不错', '不错']

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

答:

    隐马尔可夫模型的3个关键矩阵:初始概率矩阵、状态转移概率矩阵、发射概率矩阵。根据训练样本获取每个词的状态(S:单字词, B:词的开头,M:词的中间,E:词的末尾)如果是单字词,则记录第一个字的状态,用于计算初始状态概率。如果不是单字词,则统计状态转移次数,并计算对应的概率。通过上面步骤得到3个概率矩阵,并且由训练样本可得可观测序列,通过维特比算法(Viterbi)来求得在马尔可夫模型中最优的隐含状态。维特比算法其实就是一个求最短路径的动态规划问题。

0
回复
l
lu66a
#129 回复于2020-03

AI Studio 用户名:lu66a
(1) 下载飞桨本地并安装成功

(2)学习使用PaddleNLP下面的LAC模型或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)


# 使用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的句子,那么最大前向匹配的计算复杂度是
假设词表中词的最大长度为1(最坏的情况),此时得到第一个分词需要计算M*N次,得到第二个需要(M-1)*N,依次类推得到最后一个为 1*N次,合计M*N+ (M-1)*N
+ ... 1*N = N* M*(M+1)/2 算法的复杂为O(NM^2)
(2)给定一个句子,如何计算里面有多少种分词候选,代码实现

0
回复
Love萌
#130 回复于2020-03

AI Studio用户名:Love萌
作业1-1:
(1)已发班主任
(2)
strs = ["一行行行行行","一行不行行行不行","今天中午不吃食堂","我一把把把把住了"]
#jieba 分词
import jieba
jieba.enable_paddle()
for text in strs:
jieba_word_list1 = jieba.cut(text, use_paddle = True)
print("\nPaddle model:",'/'.join(list(jieba_word_list1)))
jieba_word_list2 = jieba.cut(text)
print("\nDefault model:",'/'.join(list(jieba_word_list2)))
结果:
Paddle model: 一行/行行/行行
Default model: 一行行/行行行
Paddle model: 一行/不行/行行/不行
Default model: 一行/不行/行/行不行
Paddle model: 今天中午/不/吃/食堂
Default model: 今天/中午/不吃/食堂
Paddle model: 我/一把把把把/住/了
Default model: 我/一把/把/把/把住/了
#LAC分词
import paddlehub as hub
module = hub.Module(name="lac")
results = module.lexical_analysis(data = {"text": strs})
print('\n')
for result in results:
print("LAC Module", '/'.join(result["word"]))
结果:
LAC Module 一行/行行/行行
LAC Module 一行/不行/行行/不行
LAC Module 今天中午/不/吃/食堂
LAC Module 我/一把把/把把/住/了
(3)
import jieba
import os
import re
import numpy as np
import paddlehub as hub
module = hub.Module(name='lac')

ex_dir = 'example'
text = []
symbol = '!"#$%&()*+,-./:;<=>?@[\\]^_’‘{|}~《》【】……!~·。、“”`·!@#¥%-——'
for file_name in os.listdir(ex_dir):
file_path = os.path.join(ex_dir, file_name)
#print(file_path)

with open(file_path,'r',encoding='utf-8') as f:
file_raw = f.read()
file_context = file_raw.split('专栏:')[1][4:]
#print(file_context)
for ch in symbol:
file_context = file_context.replace(ch," ")
file_context = ''.join([line.strip() for line in file_context.split('\n')])
text.append(file_context)

#jieba分词
jieba_word = []
for text_w in text:
jieba_word += jieba.lcut_for_search(text_w)
print("jieba total word:",len(jieba_word))
#lac分词
lac_segs = module.lexical_analysis(data={'text':text})
lac_word=[]
for seg in lac_segs:
lac_word.extend(seg['word'])
print("LAC total word:",len(lac_word))

lac_word_dict = {}
for word in lac_word:
if word in lac_word_dict:
lac_word_dict[word] += 1
else:
lac_word_dict[word] = 1
lac_fre = np.array(list(lac_word_dict.values()))
p_lac = lac_fre / lac_fre.sum()
lac_entropy = np.sum(-p_lac*np.log2(p_lac))

jieba_word_dict = {}
for word1 in jieba_word:
if word1 in jieba_word_dict:
jieba_word_dict[word1] += 1
else:
jieba_word_dict[word1] = 1
jieba_fre = np.array(list(jieba_word_dict.values()))
p_jieba = jieba_fre / jieba_fre.sum()
jieba_entropy = np.sum(-p_jieba*np.log2(p_jieba))
print(("jieba'entropy",jieba_entropy))
print(("LAC'entropy",lac_entropy))
输出结果:
jieba total word: 181111
LAC total word: 152841
"jieba'entropy", 11.00230543412186
"LAC'entropy", 10.687446660282601
作业1-2:
(1)
时间复杂度o(maxlen(word)*n)
(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
输出结果:
句子中的单词包括: ['今', '天', '中', '午', '不', '吃', '食', '堂', '今天', '中午', '不吃', '吃食', '食堂']
分词候选个数 20
[['今', '天', '中', '午', '不', '吃', '食', '堂'],
['今', '天', '中', '午', '不', '吃', '食堂'],
['今', '天', '中', '午', '不', '吃食', '堂'],
['今', '天', '中', '午', '不吃', '食', '堂'],
['今', '天', '中', '午', '不吃', '食堂'],
['今', '天', '中午', '不', '吃', '食', '堂'],
['今', '天', '中午', '不', '吃', '食堂'],
['今', '天', '中午', '不', '吃食', '堂'],
['今', '天', '中午', '不吃', '食', '堂'],
['今', '天', '中午', '不吃', '食堂'],
['今天', '中', '午', '不', '吃', '食', '堂'],
['今天', '中', '午', '不', '吃', '食堂'],
['今天', '中', '午', '不', '吃食', '堂'],
['今天', '中', '午', '不吃', '食', '堂'],
['今天', '中', '午', '不吃', '食堂'],
['今天', '中午', '不', '吃', '食', '堂'],
['今天', '中午', '不', '吃', '食堂'],
['今天', '中午', '不', '吃食', '堂'],
['今天', '中午', '不吃', '食', '堂'],
['今天', '中午', '不吃', '食堂']]
(3)有序列标记算法,目前对于自然语言处理中的序列标记问题其主要的研究方法主要包括概率图模型(隐马尔科夫模型(HMM)、条件随机场(CRF))和神经网络

0
回复
AIStudio810258
#131 回复于2020-03

AI Studio用户名:FutureSI
作业1-1 (1)下载飞桨本地并安装成功,将截图发给班主任

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

作业1-1 (3)对人民日报语料完成切词,并通过统计每个词出现的概率

#!unzip -d /home/aistudio/work /home/aistudio/data/data22678/1946年05月.zip
import os
import re
import paddlehub as hub
import numpy as np
from collections import Counter

def getData():
    fileList = os.listdir('/home/aistudio/work/194605')
    data = []
    for fileName in fileList:
        content = open('/home/aistudio/work/194605/'+fileName, "r",encoding = 'utf-8').read()
        #除去中文、数字外的所有字符
        content = re.sub(r'[^\u4e00-\u9fa50-9]', " ",content)
        content = content.strip()
        content = re.sub(r' +', " ", content)
        sentence = content.split(' ')
        data = data + sentence
    return data

def cut(sentences):
    module = hub.Module(name="lac")
    wordListTotal = []
    for sentence in sentences:
        wordList = []
        words = module.lexical_analysis(data={"text": [sentence]})
        for w in words:
            wordList.extend(w['word'])
        wordListTotal = wordListTotal + wordList
    return wordListTotal

def getEntropy(word):
    wordRate = Counter(word) #统计词频
    p = np.array(list(wordRate.values()))
    p = p / len(word)
    return -(p*np.log2(p)).sum()

def getStopWord():
    content = open('/home/aistudio/baidu_stopwords.txt', "r",encoding = 'utf-8').read()
    return content.split('\n')

sentences = getData()
words = cut(sentences)
entropy = getEntropy(words)
print("信息熵:"+str(entropy))
entropy = getEntropy([w for w in words if w not in getStopWord()])
print("去掉停止词信息熵:"+str(entropy))
0
回复
w
wsdsoft
#132 回复于2020-03

感谢各位老师,各位同学,各位大神。我神往AI已久,现在终于有时间,系统学习。来得晚了点,还在学习前面的课;已略有心得,甚是欢喜。

1
回复
AIStudio810258
#133 回复于2020-03

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

  • 匹配过程如下: 1.首先得到词表中最长词的长度MaxLen(word) 2.匹配句子中前MaxLen(word)个字的组合是否在词表中,如果在,匹配一词,如果不在,字的组合末尾去掉一位递归重复第2步。如果递归将所有字都从末尾一一去掉,则本次匹配得到本句子中第一个字单独成词。计算所需时间复杂度为O(MaxLen(word))。 3在最极端复杂的情况下,句子的每一个字都被单独切成一个词,则第2步骤需被重复M此,所以整个句子匹配需要MaxLen(word) * M(M为句子长度)次计算,则整个句子最大前向匹配的计算复杂度是O(MaxLen(word) * M) 如果字典不采用链表而是采用树状结构存储,则在每一轮切词时,前述第2步骤匹配从长度为MaxLen(word),MaxLen(word) - 1, MaxLen(word) - 2, MaxLen(word) - 3,...3, 2, 1的词典中的词语时,只需一次遍历。 所以匹配所需时间复杂度为0(M)。

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

text = '今天中午不吃食堂'
dictionary = ['今', '天', '中', '午', '不', '吃', '食', '堂', '今天', '中午', '不吃', '吃食', '食堂']
availableList = list() #存储text中出现的dictionary中的词语,以待全部完成一遍切词后打印
def count_seg(avaList, rest, dic):
    #print(avaList) #打印已切分完成的词语列表
    #print(rest) #打印还未切词的句子的剩余部分
    if len(rest) == 0: #如果本次切词完成,打印切分方式
        print('/'.join(avaList))
        return 1 #每次成功切分返回一个1用以计数切分方式
    
    count = 0 #本分支初始化切分方式计数
    for i in range(1, len(rest)+1): #将rest中的所有字按从左到右的顺序逐一尝试切分
        #print(i)
        if rest[:i] not in dic: #如果rest中的前i个字符的组合不在dic中则跳过本次尝试。
            continue
        #如果rest中的前i个字符的组合在dic中,则递归调用本函数,尝试进行从rest中划入avaList一个字进行切分
        #本层以下分支切分数目全部加和
        count += count_seg(avaList + [rest[:i]], rest[i:], dic)
    return count #返回本分支递归共进行了多少种切分

print('候选分词数为', count_seg(availableList, text, dictionary))

输出结果:

  • 今/天/中/午/不/吃/食/堂
    今/天/中/午/不/吃/食堂
    今/天/中/午/不/吃食/堂
    今/天/中/午/不吃/食/堂
    今/天/中/午/不吃/食堂
    今/天/中午/不/吃/食/堂
    今/天/中午/不/吃/食堂
    今/天/中午/不/吃食/堂
    今/天/中午/不吃/食/堂
    今/天/中午/不吃/食堂
    今天/中/午/不/吃/食/堂
    今天/中/午/不/吃/食堂
    今天/中/午/不/吃食/堂
    今天/中/午/不吃/食/堂
    今天/中/午/不吃/食堂
    今天/中午/不/吃/食/堂
    今天/中午/不/吃/食堂
    今天/中午/不/吃食/堂
    今天/中午/不吃/食/堂
    今天/中午/不吃/食堂
    候选分词数为 20

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

  • 还有序列标注算法、HMM隐形马尔科夫模型、CRF随机条件场、Structured SVM等。可以参考资料 https://www.hankcs.com/ml/comparison-of-sequence-labeling-models.html
0
回复
AIStudio810258
#134 回复于2020-03
作业1-2 (1)思考一下,假设输入一个词表里面含有N个词,输入一个长度为M的句子,那么最大前向匹配的计算复杂度是多少? 匹配过程如下: 1.首先得到词表中最长词的长度MaxLen(word) 2.匹配句子中前MaxLen(word)个字的组合是否在词表中,如果在,匹配一词,如果不在,字的组合末尾去掉一位递归重复第2步。如果递归将所有字都从末尾一一去掉,则本次匹配得到本句子中第一个字单独成词。计算所需时间复杂度为O(MaxLen(word))。 3在最极端复杂的情况下,句子的每一个字都被单独切成一个词,则第2步骤需被重复M此,所以整个句子匹配需要MaxLen(word) * M(M为句子长度)次计算,则整个句子最大前向匹配的计算复杂度是O(MaxLen(word) * M) 如果字典不采用链表而是采用树状结构存储,则在每一轮切词时,前述第2步骤匹配从长度为MaxLen(word),MaxLen(word) - 1, MaxLen(word) - 2, MaxLen(word) - 3,...3, 2, 1的词典中的词语时,只需一次遍历。 所以匹配所需时间复杂度为0(M)。 作业1-2 (2)给定一个句子,如何计算里面有多少种分词候选,你能给出代码实现吗? [代码] 输出结果: 今/天/中/午/不/吃/食/堂 今/天/中/午/不/吃/食堂 今/天/中/午/不/吃食/堂 今/天/中/午/不吃/食/堂 今/天/中/午/不吃/食堂 今/天/中午/不/吃/食/堂 今/天/中午/不/吃/食堂 今/天/中午/不/吃食/堂 今/天/中午/不吃/食/堂 今/天/中午/不吃/食堂 今天/中/午/不/吃/食/堂 今天/中/午/不/吃/食堂 今天/中/午/不/吃食/堂 今天/中/午/不吃/食/堂 今天/中/午/不吃/食堂 今天/中午/不/吃/食/堂 今天/中午/不/吃/食堂 今天/中午/不/吃食/堂 今天/中午/不吃/食/堂 今天/中午/不吃/食堂 候选分词数为 20 作业1-2 (3)除了最大前向匹配和N-gram算法,你还知道其他分词算法吗,请给出一段小描述。 还有序列标注算法、HMM隐形马尔科夫模型、CRF随机条件场、Structured SVM等。可以参考资料 https://www.hankcs.com/ml/comparison-of-sequence-labeling-models.html
展开

AI Studio用户名:FutureSI

0
回复
余音竖图
#135 回复于2020-03

 

AI Studio用户名:余音竖图

作业1-1

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

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

# LAC 分词

import paddlehub as hub
module = hub.Module(name="lac")
test_text = ["今天是个好日子", "天气预报说今天要下雨", "下一班地铁马上就要到了"]
results = module.lexical_analysis(data={"text":test_text})
print(results)

{'word': ['今天', '是', '个', '好日子'], 'tag': ['TIME', 'v', 'q', 'n']},

{'word': ['天气预报', '说', '今天', '要', '下雨'], 'tag': ['n', 'v', 'TIME', 'v', 'v']},

{'word': ['下', '一班', '地铁', '马上', '就要', '到', '了'], 'tag': ['f', 'm', 'n', 'd', 'v', 'v', 'xc']}]

# 信息熵 

# 读取测试 语料
symbol = r'[a-zA-Z0-9’!"#$%&\'()*+,-./:;<=>?@:,。()?@★、…【】《》?“”‘’!^_`{|}~\s]+'
with open("./test100.txt", "r", encoding="utf-8") as D:
data = D.read()
data_unsymbol = re.sub(symbol, "", data)

data_jieba =jieba.lcut(data_unsymbol)
print(len(data_jieba))
data_list = collections.Counter(data_jieba)

data_num = np.array(list(data_list.values()))
p1 = data_num / data_num.sum()

jieba_entropy = np.sum(-p1*np.log2(p1))
print("分词的信息熵:", jieba_entropy)

112919
分词的信息熵: 10.341794453554972

0
回复
蓝路白
#136 回复于2020-03

AI Studio用户名:蓝路白

作业1-1:

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

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

# encoding=utf-8
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))

Paddle Mode: 我/来到/北京清华大学

Paddle Mode: 乒乓球/拍卖/完/了

Paddle Mode: 中国科学技术大学

Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学

Default Mode: 我/ 来到/ 北京/ 清华大学

他, 来到, 了, 网易, 杭研, 大厦

小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

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

# encoding=utf-8
import jieba
import numpy as np


def load_data(file_name):
    with open(file_name, encoding='gbk') as f:
        content = f.read().strip('\n')
    f.close()
    return content


def calc_shannon_ent(data):
    numData = len(data)
    unique_data, counts = np.unique(np.array(data), return_counts=True)
    prob = counts / numData
    shannon_ent = -(np.sum(prob * np.log2(prob)))
    return shannon_ent


if __name__ == '__main__':
    content = load_data('rmrb19640515.txt')
    seg_list = jieba.cut(content, use_paddle=True)
    shannon_ent = calc_shannon_ent(list(seg_list))
    print(len(content))
    print("信息熵:", shannon_ent)


3305
信息熵: 8.094496950793541

作业1-2:

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

最大前向匹配的计算复杂度是O(N*M*M)。假设单词的最大长度为M,首先将M整个取出与词表中的N个词匹配,匹配失败,每次去掉匹配字段最后面的一个字,继续匹配;匹配成功后,去掉匹配成功的字段,一轮计算复杂度为N*M;直到匹配字段长度为0,结束。在最坏情况下,需要匹配M轮,因此计算复杂度为O(N*M*M)。


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

import jieba
seg = jieba.cut("乒乓球拍卖完了", cut_all=True)
seg_list = list(seg)
print('分词个数: ', len(seg_list), '\n候选分词: ', seg_list)


分词个数:  7

候选分词:  ['乒乓', '乒乓球', '乒乓球拍', '球拍', '拍卖', '卖完', '了']

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

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

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

LSTM长短期记忆网络:在NLP中,最常用的神经网络为循环神经网络(RNN,Recurrent Neural Network),它在处理变长输入和序列输入问题中有着巨大的优势。LSTM为RNN变种的一种,在一定程度上解决了RNN在训练过程中梯度消失和梯度爆炸的问题。使用LSTM模型可以更好的捕捉到较长距离的依赖关系。

BiLSTM双向长短期记忆网络:双向循环神经网络分别从句子的开头和结尾开始对输入进行处理,将上下文信息进行编码,提升预测效果。前向的LSTM与后向的LSTM结合成BiLSTM。BiLSTM可以更好的捕捉双向的语义依赖。

BiLSTM+CRF:双向长短期记忆网络和条件随机场的结合。

参考资料:

【1】https://www.jianshu.com/p/715fa597c6bc

【2】https://www.jiqizhixin.com/articles/2018-10-24-13

1
回复
小村童
#137 回复于2020-03

AIstudio 用户名:Hi_Boy022

作业1-1:

切词模型我选用LAC模型,选取的人民日报的第一个语料,

jieba切词的前20个结果:

'为', '七百万', '人民', '请命', '李庄', '一', '毁灭', '与', '新生', '四月', '九日', '五辆', '吉普车', '载', '着', '黄河', '勘察', '团', '从', '荷泽'

作业1-2:

(1):按照句子中每一个词匹配的最坏情况,计算复杂度为O(N*M)

(3):最短路径分词算法——最短路径分词算法首先将一句话中的所有词匹配出来,构成词图(有向无环图DAG),之后寻找从起始点到终点的最短路径作为最佳组合方式

参考来源:https://zhuanlan.zhihu.com/p/50444885

0
回复
小村童
#138 回复于2020-03
小村童 #137
AIstudio 用户名:Hi_Boy022 作业1-1: 切词模型我选用LAC模型,选取的人民日报的第一个语料, jieba切词的前20个结果: '为', '七百万', '人民', '请命', '李庄', '一', '毁灭', '与', '新生', '四月', '九日', '五辆', '吉普车', '载', '着', '黄河', '勘察', '团', '从', '荷泽' 作业1-2: (1):按照句子中每一个词匹配的最坏情况,计算复杂度为O(N*M) (3):最短路径分词算法——最短路径分词算法首先将一句话中的所有词匹配出来,构成词图(有向无环图DAG),之后寻找从起始点到终点的最短路径作为最佳组合方式 参考来源:https://zhuanlan.zhihu.com/p/50444885
展开

补充作业内容,语料计算的信息熵为:8.3472

0
回复
AIStudio810258
#139 回复于2020-03
  • AI Studio用户名:FutureSI
    作业2
    请尝试用飞桨实现一个CBOW模型,并使用text8语料进行训练(或尝试提高skip-gram的训练速度)
  • CBOW的代码在原来skip-gram代码基础上主要做了两处修改:
    1.build_data()函数返回的dataset从(中心词,上下文词正/负的样本,label)的三元组改为(上下文词,中心词正/负样本,label)的三元组。
#构造数据,准备模型训练
#max_window_size代表了最大的window_size的大小,程序会根据max_window_size从左到右扫描整个语料
#negative_sample_num代表了对于每个正样本,我们需要随机采样多少负样本用于训练,
#一般来说,negative_sample_num的值越大,训练效果越稳定,但是训练速度越慢。 
def build_data(corpus, word2id_dict, max_window_size = 3, 
               negative_sample_num = 3):
    
    #使用一个list存储处理好的数据
    dataset = []
    
    #corpus = corpus[:1000000]
    #corpus = corpus[:1000]
    #从左到右,开始枚举每个中心点的位置
    for center_word_idx in range(len(corpus)):
        #以max_window_size为上限,随机采样一个window_size,这样会使得训练更加稳定
        #window_size = random.randint(1, max_window_size)
        window_size = max_window_size
        #当前的中心词就是center_word_idx所指向的词
        center_word = corpus[center_word_idx]

        #以当前中心词为中心,左右两侧在window_size内的词都可以看成是正样本
        positive_word_range = (max(0, center_word_idx - window_size), min(len(corpus) - 1, center_word_idx + window_size))
        positive_word_candidates = [corpus[idx] for idx in range(positive_word_range[0], positive_word_range[1]+1) if idx != center_word_idx]
        if center_word_idx % 100000 == 0:
            print(center_word_idx, window_size, center_word, positive_word_range, positive_word_candidates)
        #对于每个正样本来说,随机采样negative_sample_num个负样本,用于训练
        for positive_word in positive_word_candidates:
            #首先把(中心词,正样本,label=1)的三元组数据放入dataset中,
            #这里label=1表示这个样本是个正样本
            #dataset.append((center_word, positive_word, 1))
            dataset.append((positive_word, center_word, 1))

            #开始负采样
            i = 0
            while i < negative_sample_num:
                negative_word_candidate = random.randint(0, vocab_size-1)

                if negative_word_candidate not in positive_word_candidates:
                    #把(中心词,正样本,label=0)的三元组数据放入dataset中,
                    #这里label=0表示这个样本是个负样本
                    #dataset.append((center_word, negative_word_candidate, 0))
                    dataset.append((positive_word, negative_word_candidate, 0))
                    i += 1
    
    return dataset

dataset = build_data(corpus, word2id_dict)
for _, (center_word, target_word, label) in zip(range(100), dataset):
    #print("center_word %s, target %s, label %d" % (id2word_dict[center_word],id2word_dict[target_word], label))
    print("context_word %s, target %s, label %d" % (center_word,target_word, label))
  • 2.修改forward()正向计算函数.其实因为输入数据的格式和skip-gram是一样的,所以模型的网络结构是无需改动的.在此处将两个词的点乘改为计算余弦相似度是为了增进模型的效率.

 

        word_sim = fluid.layers.elementwise_mul(center_words_emb, target_words_emb)
        word_sim = fluid.layers.reduce_sum(word_sim, dim = -1)
        a = fluid.layers.elementwise_mul(center_words_emb, center_words_emb)
        a = fluid.layers.reduce_sum(a, dim = -1)
        a = fluid.layers.sqrt(a)
        b = fluid.layers.elementwise_mul(target_words_emb, target_words_emb)
        b = fluid.layers.reduce_sum(b, dim = -1)
        b = fluid.layers.sqrt(b)
        word_sim = word_sim / a / b

 

 

 

0
回复
AIStudio810258
#140 回复于2020-03

AI Studio用户名:FutureSI
作业2 附加题 打开脑洞,尝试各种embedding花样玩法

  • 记得上学时玩过一个叫colorgenics的网页应用,其通过让用户点击屏幕上8个不同颜色的立方体,根据用户点击的顺序判断用户当时的心理状态.准不准的反正当时觉得挺好玩,毕竟做这个网站的是个在米国职业的心理医师.我就想词向量模型可不可以做类似的好玩儿的应用.比如通过输入一个人的微信或博客的文本资料,统计个人的口头禅,并进一步通过公开的数据集或模型进行迁移学习,分析个人的性格倾向,如乐观程度、积极程度、文明用语水平等。当然应用背后有心理学模型支撑才称得上“科学”,这个应用主要是好玩。
0
回复
AIStudio810258
#141 回复于2020-03

AI Studio用户名:FutureSI
作业2 附加题 打开脑洞,尝试各种embedding花样玩法

  • 家里有小度智能音箱.孩子平时挺喜欢玩.我也写技能给孩子用.dueros能将语音信息转换为文本资料.我想能不能用word2vector的模型做评价幼儿词汇丰富程度的技能,甚至可以进而评价幼儿的语言能力.
0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户