基于词向量word2vec匹配的英文问答系统
基于词向量word2vec匹配的英文问答系统
基于词向量word2vec匹配的英文问答系统环境准备
python3.6
pandas --读取并处理csv文件
nltk --http://www.nltk.org/ 自然语言处理工具包,用于分词,词干提取,语料库
gensim -- 训练word2vec词向量的工具包
实现过程
导入工具包
import pandas as pd from nltk.tokenize import word_tokenize import matplotlib.pyplot as plt #可视化数据集时使用 from gensim.models import Word2Vec import string import numpy as np from queue import PriorityQueue from nltk.corpus import stopwords from nltk.stem import WordNetLemmatizer lemmatizer = WordNetLemmatizer()#词形还原,去掉单词词缀,提取单词主干
构建问题词集
对数据库中的所有问题的单词进行提取汇总,构造成含有单词和单词出现次数信息的字典。对各个单词出现的次数进行可视化。
数据集的csv文件如下图所示:
data = pd.read_csv('./qanda.csv') q=data['question'] question_list=q.values.tolist()#以每个问题文本为元素的列表 a=data['answer'] answer_list=a.values.tolist()#以每个答案文本为元素的列表 #构建问题词集 key:单词 value:频数 word_in_q = {} for x in question_list: for x1 in word_tokenize(x.rstrip('?')):#删除? if x1 in word_in_q: word_in_q[x1] += 1 else: word_in_q[x1] = 1 word_num = sum(word_in_q.values()) word_different = len(word_in_q.keys()) #可视化 dictionary = dict(sorted(word_in_q.items(),key=lambda x:x[1],reverse=True))#按照value的值从大到小排序 x_axis = list(dictionary.keys()) y_axis = list(dictionary.values()) plt.plot(x_axis[:20],y_axis[:20]) plt.show()
文本预处理
文本预处理主要做以下几个部分:
1.去掉问题集的无用词(nltk的停止词语料库)
包括:{‘ourselves’, ‘hers’, ‘between’, ‘yourself’, ‘but’, ‘again’, ‘there’, ‘about’, ‘once’, ‘during’, ‘out’, ‘very’, ‘having’, ‘with’, ‘they’, ‘own’, ‘an’, ‘be’, ‘some’, ‘for’, ‘do’, ‘its’, ‘yours’, ‘such’, ‘into’, ‘of’, ‘most’, ‘itself’, ‘other’, ‘off’, ‘is’, ‘s’, ‘am’, ‘or’, ‘who’, ‘as’, ‘from’, ‘him’, ‘each’, ‘the’, ‘themselves’, ‘until’, ‘below’, ‘are’, ‘we’, ‘these’, ‘your’, ‘his’, ‘through’, ‘don’, ‘nor’, ‘me’, ‘were’, ‘her’, ‘more’, ‘himself’, ‘this’, ‘down’, ‘should’, ‘our’, ‘their’, ‘while’, ‘above’, ‘both’, ‘up’, ‘to’, ‘ours’, ‘had’, ‘she’, ‘all’, ‘no’, ‘when’, ‘at’, ‘any’, ‘before’, ‘them’, ‘same’, ‘and’, ‘been’, ‘have’, ‘in’, ‘will’, ‘on’, ‘does’, ‘yourselves’, ‘then’, ‘that’, ‘because’, ‘what’, ‘over’, ‘why’, ‘so’, ‘can’, ‘did’, ‘not’, ‘now’, ‘under’, ‘he’, ‘you’, ‘herself’, ‘has’, ‘just’, ‘where’, ‘too’, ‘only’, ‘myself’, ‘which’, ‘those’, ‘i’, ‘after’, ‘few’, ‘whom’, ‘t’, ‘being’, ‘if’, ‘theirs’, ‘my’, ‘against’, ‘a’, ‘by’, ‘doing’, ‘it’, ‘how’, ‘further’, ‘was’, ‘here’, ‘than’}
2.全部转为小写
3.去掉低频词(本次未使用)
由于本次实验的问题集很少,因此去掉低频词反而会让结果更加不准确
4.对出现纯数字的情况进行转换
对于纯数字符转成 ‘#number’
5.词干提取(nltk.stem)
忽略每个单词的时态、后缀等变体,我们提取词干的原因是为了缩短查找的时间,使句子正常化。
stopwords = stopwords.words('english') stopword = ['when','how','what','where','who'] stopwords = [word for word in stopwords if word not in stopword] #低频词,语料库小的时候不去除 #low_frequency_words = [word for word in word_in_q.keys() if word_in_q[word]<2] #delete_word = stopwords + low_frequency_words delete_word = stopwords def text_processing(question): every_question_word = list() question = question.lower()#小写 question = question.strip('?.,!') for word in word_tokenize(question): word = ''.join(letters for letters in word if letters not in string.punctuation) if word not in string.punctuation else word#去标点 word = '#number'if word.isdigit() else word#只有数字用 if word not in delete_word: every_question_word.append(lemmatizer.lemmatize(word))#提取每个问句中的单词词干 return every_question_word all_question_word = list()#把经过文本预处理的语料库中的问题放入all_quetion_word的list中
训练词向量
model = Word2Vec(all_question_word,min_count=1)
构建单词与单词出现的索引列表构成的字典
统计好每个单词出现在了哪些问题里,有助于接下来根据实际提问筛选出疑似的问题
index_inverted = dict()#构建index_inverted的倒排表,key:单词 value:索引列表 for question in question_list: preprocessed_word = text_processing(question) all_question_word.append(preprocessed_word) for word in preprocessed_word: if word not in index_inverted: index_inverted.update({word: [question_list.index(question)]}) else: index_inverted[word].append(question_list.index(question))
输入实际提问问题并做预处理
输入实际问题文本之后,通过之前定义的text_processing函数对文本进行预处理,并且将处理后得到的单词列表与index_inverted中的键值单词相对应。得到这些单词对应的疑似数据库问题的索引filter_index。
real_question = "What else is Montreal called?"#可通过语音识别输入 real_question_word = text_processing(real_question) filter_index = set() real_question_word_exist = real_question_word[:] #复制列表 # 这里筛去了问题集中没有但是实际提问中出现的单词,便于后续计算余弦相似度 for word in real_question_word: if word not in index_inverted.keys(): real_question_word_exist.remove(word) else: filter_index.update(index_inverted[word])
求词向量余弦距离得到匹配的问题及对应答案
#过滤出疑似问题 part_question_word = list() for index in filter_index:#过滤出疑似问题 one_question_word = all_question_word[index] part_question_word.append(one_question_word) siml_list = list() for question_word in part_question_word: siml=model.n_similarity(real_question_word_exist,question_word)#计算集合之间的余弦相似度 siml_list.append(siml) if max(siml_list)>0.9:#存在相似度大于0.9的问题才给出对应回答 top_question = PriorityQueue()#优先队列 for i in range(len(siml_list)): top_question.put((siml_list[i],part_question_word[i]))# if len(top_question.queue) > 5:#每次top_question.queue超过5个时就踢走最大的元素 和 值 top_question.get()#得到最大的5个元素和值(未排序) top_question = top_question.queue print(top_question) sorted_top_question = sorted(top_question, key=lambda t: t[0], reverse=True) print('sorted_top_question\n',sorted_top_question)#打印出相似度前5的问题 answers = [answer_list[all_question_word.index(question[1])] for question in sorted_top_question] print('answers\n',answers) #打印出问题对应的答案 else:#提问不在问题集的范围内,另做处理 print("This question not exist in my lib!")
最终输出结果
sorted_top_question
[(1.0, ['what', 'else', 'montreal', 'called']), (0.43783137, ['what', 'mechanical', 'knight']), (0.3780565, ['what', 'origin', 'comic', 'sans', 'font']), (0.32334372, ['what', 'moravec', 'paradox', 'state']), (0.32260603, ['what', 'nanobot'])]
answers
['Montreal is often called the City of Saints or the City of a Hundred Bell Towers.', 'A robot sketch made by Leonardo DaVinci.', "Comic Sans is based on Dave Gibbons' lettering in the Watchmen comic books.", "Moravec's paradox states that a computer can crunch numbers like Bernoulli, but lacks a toddler's motor skills.", 'The smallest robot possible is called a nanobot. ']
总结
这是一个很简单的根据词向量相似度匹配的问答系统,对于给定问答集的情况可以使用。效果好于使用预训练的glove.6B词向量。
需要改进的地方:
对实际问题的文本处理需要剔除问题集中没有的词汇,这对于替换近义词提问难以得到正确答案。
……
参考链接
NLTK最详细功能介绍
简易英文问答系统(glove.6B词向量)
基于词向量word2vec匹配的英文问答系统相关教程
-
SpringMVC之基于注解的数据校验
SpringMVC之基于注解的数据校验 文章目录 前言 一、为什么使用后端数据校验? 二、使用步骤 1.引包 2.打上对应的注解 3.在controller层对应方法的参数上打上注解 4.判断是否成功校验 5.表单回显 前言 越学越能体会spring框架的精妙 , 基于注解的设计真是太优雅
-
基于 Keras 和 Tensorflow 的标签平滑实现
基于 Keras 和 Tensorflow 的标签平滑实现 首先谢谢原文作者写出这么好的文章,帮助像我这样的初学者能快速的了解并应用相关技术,谢谢!!! 首先附上原文地址 :基于 Keras 和 Tensorflow 的标签平滑实现. 目录 1.标签平滑出现的意义和背景 2.标签平滑以及其
-
西门子PLC-1200的基于232串口的Modbus RTU通讯实例
西门子PLC-1200的基于232串口的Modbus RTU通讯实例 西门子PLC-1200的基于232串口的Modbus RTU通讯实例 这里先讲一下Modbus和232,232和485串口是一种串口接法,这种接法实际能实现十几种的协议通讯,有基于串口的Modbus RTU,Modbus+,有基于以太网接口的Modbus
-
(转)基于TLS证书手动部署kubernetes集群(上)
(转)基于TLS证书手动部署kubernetes集群(上) 转:https://www.cnblogs.com/wdliu/archive/2018/06/06/9147346.html 一、简介 Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。 K8S是Google内部一个叫Borg的
-
基于Javaweb的学生宿舍管理系统(源码+数据库+报告)
基于Javaweb的学生宿舍管理系统(源码+数据库+报告) 1、 系统开发目标及设计思想 1.1 系统开发基本目标 学生宿舍管理系统的开发主要是为了解决学生住宿及其相关问题,同时满足管理者方便管理的需求。随着各个高校不断扩招,与住宿的同学数量的增多,各种住宿
-
基于H.ui.Admin UI模板的网站管理后台
基于H.ui.Admin UI模板的网站管理后台 最近接手一个跨境电商平台开发,客户侧重电商网站UI设计,对管理后台要求不高,由我们决定选哪一款后台模板。找来找去,感觉还是H.ui靠谱一些,主要是这个模板清爽,不需要过多选择。其他的流行后台模板也看了,但功能
-
javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式
javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP+JavaBean模式程序各个模
-
基于深度学习的推荐(四):阿里DIN,使用Attention获得用户的动态
基于深度学习的推荐(四):阿里DIN,使用Attention获得用户的动态representation 文章目录 公众号 前言 1.模型分析 1.1 Baseline 1.2 DIN 2. 训练技巧 2.1 Dice激活函数 2.2 Mini-batch 正则化 3.实战 3.1 数据集 3.2 代码分析 参考 关注公众号: 推荐算法工程