手机怎么做网站教程,苏州出名的网站公司,凡科建站官网免费注册,苏州代做淘宝网站一#xff0c;文件准备 该问答系统是基于已知的问题和其一一对应的答案进行实现的。首先需要准备两个文本文件#xff0c;分别命名为“question.txt”和“answer.txt”#xff0c;分别是问题文件和答案文件#xff0c;每一行是一个问题以及对应的答案。 问题文件: 中国的首…一文件准备 该问答系统是基于已知的问题和其一一对应的答案进行实现的。首先需要准备两个文本文件分别命名为“question.txt”和“answer.txt”分别是问题文件和答案文件每一行是一个问题以及对应的答案。 问题文件: 中国的首都是哪个城市 今天气温多少度 天津距离北京有多远 小明正在干什么 答案文件: 北京市 26度 135公里 在上课
二实现原理
1导入模块
import jieba
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
2读取数据集:输入为文件名输出为列表
def read_corpus(file):lt []with open(file, r, encodingutf-8) as f:for line in f:lt.append(line.strip())
return lt
执行结果: q_list read_corpus(questions.txt) q_list [中国的首都是哪个城市, 今天气温多少度, 天津距离北京有多远, 小明正在干什么] a_list read_corpus(answers.txt) a_list [北京市, 26度, 135公里, 在上课] (3)分词
def preprocess_text(q_list):lt []for q in q_list:q word_segment(q)lt.append(q)
return lt
preprocess_text()函数将列表q_list中的句子逐个切词并放入lt列表中。
在preprocess_text()函数调用word_segment()函数。
def word_segment(sentence):
return ,.join(jieba.cut(sentence)) s 今天气温多少度 word_segment(s) 今天,气温,多少度, 将2中的q_list作为参数传递给preprocess_text()执行结果如下 q_list preprocess_text(q_list) q_list [中国,的,首都,是,哪个,城市,, 今天,气温,多少度,, 天津,距离,北京,有多远,, 小明,正在,干什么,] 4将问题列表q_list向量化计算每一个特征的权重
def convert2tfidf(q_list):vectorizer, q_tfidf calc_tfidf(q_list)
return vectorizer, q_tfidfdef calc_tfidf(q_list, ngram_range(1, 1)):# 实例化一个tfidf对象vectorizer TfidfVectorizer(min_df1, norml2, \smooth_idfTrue, \use_idfTrue, \ngram_rangengram_range)# 计算每个词的tfidf值features vectorizer.fit_transform(q_list)
return vectorizer, features
将3中的问题列表q_list作为参数传递给convert2tfidf()函数 vectorizer, q_tfidf convert2tfidf(q_list) # vectorizer是一个向量化器 type(q_tfidf) # q_tfidf是一个稀疏矩阵 class scipy.sparse.csr.csr_matrix q_tfidf.toarray().round(2) # 将稀疏矩阵转化为普通矩阵保留两位小数 array([[0.5, 0., 0., 0.5, 0.5, 0., 0., 0., 0., 0., 0., 0., 0., 0.5], [0., 0.58, 0., 0., 0., 0.58, 0., 0., 0., 0., 0., 0.58, 0., 0.], [0., 0., 0.5, 0., 0., 0., 0.5, 0., 0., 0.5, 0., 0., 0.5, 0.], [0., 0., 0., 0., 0., 0., 0., 0.58, 0.58, 0., 0.58, 0., 0., 0.]]) q_tfidf.toarray()[0] # 查看q_tfidf矩阵的第一行 array([0.5, 0. , 0. , 0.5, 0.5, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.5]) 上述矩阵就是问题“中国的首都是哪个城市”向量化后的结果。 vectorizer.vocabulary_ # 向量化器vectorizer的词典 {中国: 0, 首都: 13, 哪个: 3, 城市: 4, 今天: 1, 气温: 11, 多少度: 5, 天津: 6, 距离: 12, 北京: 2, 有多远: 9, 小明: 7, 正在: 10, 干什么: 8} 由上述可知向量的第一个特征是“中国”第二个特征是“今天”第三个特征是“北京”依次类推其他特征。
5响应用户的“查询”
def answer(query):query word_segment(query) # 对查询语句进行切词query vectorizer.transform([query]) # 将查询语句向量化best_idx idx_of_largest_sim(query, q_tfidf) # 得到与查询语句最相似问题的下标
return a_list[best_idx] # 返回与best_idx下标对应的答案
def idx_of_largest_sim(query, q_tfidf): # 下标idx indexlt []# 将query由稀疏矩阵转为普通矩阵并取其第1行此处目的是将其转为一维矩阵。query query.toarray()[0] # 其实query二维矩阵只有一行for q in q_tfidf:q q.toarray() # 将q由稀疏矩阵转换为普通矩阵num float(np.matmul(q, query)) # 计算矩阵的点积denom np.linalg.norm(q) * np.linalg.norm(query) if denom 0:cos 0.0else:cos num / denom # 规范化denom分母lt.append(cos)best_idx lt.index(max(lt))return best_idx # 返回值是与查询语句最相似的问题下标
np.linalg.norm(q)是问题向量的长度 np.linalg.norm([1, 3, 2]) 3.7416573867739413 上述代码计算了的值
np.linalg.norm(q)是查询向量的长度
三完整代码
import jieba
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizerdef read_corpus(file):lt []with open(file, r, encodingutf-8) as f:for line in f:lt.append(line.strip())return ltdef preprocess_text(q_list):lt []for q in q_list:q word_segment(q)lt.append(q)return lt# 度量查询query与问题库中各个问题的相似程度similarity
def idx_of_largest_sim(query, q_tfidf): # idx indexlt []# 将query由稀疏矩阵转换为普通矩阵并取其第1行query query.toarray()[0] for q in q_tfidf:q q.toarray() # 将q由稀疏矩阵转换为普通矩阵num float(np.matmul(q, query)) # 计算矩阵的点积denom np.linalg.norm(q) * np.linalg.norm(query)if denom 0:cos 0.0else:cos num / denomlt.append(cos)best_idx lt.index(max(lt))return best_idxdef calc_tfidf(q_list, ngram_range(1, 1)):# 实例化一个tfidf对象vectorizer TfidfVectorizer(min_df1, norml2, \smooth_idfTrue, \use_idfTrue, \ngram_rangengram_range)# 计算每个词的tfidf值features vectorizer.fit_transform(q_list)return vectorizer, featuresdef convert2tfidf(q_list):vectorizer, q_tfidf calc_tfidf(q_list)return vectorizer, q_tfidfdef word_segment(sentence):return ,.join(jieba.cut(sentence))def answer(query):query word_segment(query)query vectorizer.transform([query])best_idx idx_of_largest_sim(query, q_tfidf)return a_list[best_idx]if __name__ __main__:q_list read_corpus(questions.txt) # 问题列表a_list read_corpus(answers.txt) # 答案列表# 分词后的问题列表每个问题的分词字符串为一个列表元素q_list preprocess_text(q_list)vectorizer, q_tfidf convert2tfidf(q_list)flag Truewhile flag:print(\n请输入查询输入结束后按回车键)query input()if query.lower() q:breakprint(正在为您查询请稍后)print(查询结果, answer(query), sep)