【ChatBot开发笔记】对语料库进行数据清洗、中文分词,建立训练词向量模型 您所在的位置:网站首页 bore模型库整理 【ChatBot开发笔记】对语料库进行数据清洗、中文分词,建立训练词向量模型

【ChatBot开发笔记】对语料库进行数据清洗、中文分词,建立训练词向量模型

2023-10-04 05:47| 来源: 网络整理| 查看: 265

目录 简述数据清洗去除关键字去除重复语句 中文分词使用gensim训练词向量模型word2vec的训练思路使用gensim训练词向量模型 结语

简述

接前述使用scrapy爬取文件建立聊天语料库一文,在对文件初步清洗之后。由于文本来源的特殊性,需要对其中的特殊关键词进行过滤,以及其他数据清洗操作。这篇文章将在前文基础上,进行数据清洗,中文分词,及word2vec操作。作为中期检测前的最后一篇记录,希望能给大家一点小小的帮助。

数据清洗

由于是对字幕文件的数据清洗,所以除去html标签,去转义,去除特殊符号等操作外,最主要的是去除关键字和去重。以下将着重讲这两个方面。这两个方面应该是放在同一个while中,但我为了方便阅读,分别写了俩while,实际操作时,将俩写入同一个即可。

去除关键字

这一部分比较简单,但是很重要。因为字幕文件的原因,部分关键字频率极高,会影响到后续的词向量模型的训练,所以在此需要去除。直接上代码: 首先,写入需要去除的关键字的列表。

filters = ["字幕", "时间轴:", "校对:", "翻译:", "后期:", "监制:"] filters.append("时间轴:") filters.append("校对:") filters.append("翻译:") filters.append("后期:") filters.append("监制:") filters.append("禁止用作任何商业盈利行为") filters.append("http")

其次,给出清洗文件(from_path)和输出文件(to_path)的地址,打开文件后,判断每一行是否存在关键字,若存在则跳过,同理,判断改行是否存在剧集信息。当所有条件过滤之后,若该句未被过滤,则写入输出文件中。

f = open(from_path, "r+") g = open(to_path, "a+") while True: line = f.readline() if line: line = line.strip() # 关键词过滤 need_continue = False for filter in filters: try: line.index(filter) # 若该行中存在关键字,赋值为True need_continue = True break except: pass # 若为true,跳过该行 if need_continue: continue # 去掉剧集信息 if re.match('.*第.*季.*', line): continue if re.match('.*第.*集.*', line): continue if re.match('.*第.*帧.*', line): continue g.write(line+"\n") else: break f.close() g.close() pass 去除重复语句

去除重复语句不是去除整个文件中出现过的重复语句,而是去除无意义的重复语句,在这里,我判定,两百行中出现重复的语句即为无意义的,于是,如下:

lines_seen = set() while True: line = f.readline() if line: line = line.strip() # 每两百行将不重复的行放入lines_seen中,用于判断行是否重复,超过两百行的重复不作清除处理 if line not in lines_seen: lines_seen.add(line) if len(lines_seen) > 200: lines_seen.clear() else: print(line) continue g.write(line+"\n") else: break f.close() g.close() pass

做完这些以后,语料库的数据清理也就完成了。下面需要进行分词操作。

中文分词

使用jieba库进行中文分词

import jieba from jieba import analyse import os # input:需要分词的文件地址;output:文件分词后的输出地址 def segment(input, output): input_file = open(input, "r+") output_file = open(output, "a+", encoding='utf-8') # 以utf-8输出,方便后续的词向量训练 while True: line = input_file.readline() if line: line = line.strip() seg_list = jieba.cut(line) segments = "" for str in seg_list: segments = segments + " " + str output_file.write(segments) else: break input_file.close() output_file.close() if __name__ == '__main__': from_path = "my_from_path" to_path = "my_to_path" if not os.path.isdir(to_path): # 判断文件夹是否存在,不存在则创建 os.makedirs(to_path) datanames = os.listdir(from_path) # 打开来源文件夹,将其下所有文件写入datanames中 for i in datanames: input = from_path+"/"+i output = to_path+"/all.txt" # 将结果写入输出文件夹中的all.txt文件中 segment(input, output) 使用gensim训练词向量模型 word2vec的训练思路

为了更好的理解word2vec的运行,之前自己捣鼓了一个word2vec的文件,但是经过测试,发现只能对较小数据量的文件进行词向量训练,超过2000词的文件就很吃力了,于是我选择使用gensim库,具体的操作在下一步中,所以在这里只简单讲讲思路,: 首先,确定窗口大小,词嵌入的维度,遍历样本次数。 其次,将语料库转为onehot编码,以方便训练。在这里简单讲讲onehot编码。 one-hot在特征提取上属于词袋模型(bag of words),假设语料库中有三句话: 我爱中国 爸爸妈妈爱我 爸爸妈妈爱中国 首先,将语料库中的每句话分成单词,并编号:

1:我 2:爱 3:爸爸 4:妈妈 5:中国

语句我爱爸爸妈妈中国111001211110301111

所以最终得到的每句话的特征向量就是:

我爱中国 -> 1,1,0,0,1 爸爸妈妈爱我 -> 1,1,1,1,0 爸爸妈妈爱中国 -> 0,1,1,1,1 接着,为每一个词建立索引。 其后,使用skip-gram的网络结构,创建两个随机初始化权重矩阵,后向前传递,得出结果后将其映射到[0,1]之间来得到用来预测的概率。 想法很美好,做的也还过得去,就是现实太过残酷,写的文件在对付小一点的文件还凑合,在面对大的训练集当场罢工。所以还是老老实实使用了库比较好,前人栽树,后人乘凉岂不妙哉。

使用gensim训练词向量模型

Gensim 4.0 更新之后,虽然大部分与旧版本相容,但是也有部分差异,详细请看https://github.com/RaRe-Technologies/gensim/wiki/Migrating-from-Gensim-3.x-to-4,以下为训练词向量的代码。

from gensim.models import word2vec import os import gensim import logging def model_train(train_file_name, save_model_file): # model_file_name为训练语料的路径,save_model为保存模型名 # 模型训练,生成词向量 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) sentences = word2vec.Text8Corpus(train_file_name) # 加载语料 try: model = gensim.models.Word2Vec(sentences, window=5, vector_size=200) # 训练CBOW算法模型; 默认window=5 model.save(save_model_file) model.wv.save_word2vec_format(save_model_file + ".bin", binary=True) # 以二进制类型保存模型以便重用 except: pass def main(): from_path = "my_to_path/all.txt" # 接上文中的myt_to_path/all.txt save_model_name = 'mymodel.model' if not os.path.exists(save_model_name): # 判断文件是否存在 model_train(from_path, save_model_name) else: print('此训练模型已经存在,不用再次训练') # 加载已训练好的模型 model_1 = word2vec.Word2Vec.load(save_model_name) # 将获得的词汇及其对应的向量按字典的格式存放到word_vector_dict中 word_vector_dict = {} # print(model_1.wv.index_to_word) # 获得所有的词汇 for word in model_1.wv.index_to_key: # model_1.wv.get_vector(word) # 获得词汇及其对应的向量 word_vector_dict[word] = model_1.wv.get_vector(word) output_vector_file = 'word_vector.txt' with open(output_vector_file, 'w', encoding='utf-8') as f: f.write(str(word_vector_dict)) # 计算两个词的相似度/相关程度 word1 = "学习" word2 = "快乐" y1 = model_1.wv.similarity(word1, word2) print("两个词的相关程度为:", y1) print("-------------------------------\n") # 计算某个词的相关词列表 y2 = model_1.wv.most_similar(word2, topn=10) # 10个最相关的 print("和", word2, "最相关的词有:\n") for item in y2: print(item[0], item[1]) print("-------------------------------\n") if __name__ == "__main__": main()

运行结果如下: ps:学习是快乐的!这个语料库有问题,学习怎么能和快乐相关程度这么低呢?(认真脸) 在这里插入图片描述 这个结果嘛,差强人意,主要是我的训练集有点小,只有10MB,没有搞很多,方便测试。但是这不是也有相对正确的嘛。以后我填充了我的训练集后,再回来补充,我相信,学习是快乐的!

结语

以上便是这两周的学习内容啦,因为各科的实验都开了,作为强迫症晚期角色,实验是不可能活到ddl的,因此这事就耽搁了。而今天打开年级群时,发现原定第9周的中期答辩,改到了下一周周四,这才想起博客没写,今个补上。祝我自己好运。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有