基于发电厂知识问答库的检索式问答系统(python有代码)
生活随笔
收集整理的這篇文章主要介紹了
基于发电厂知识问答库的检索式问答系统(python有代码)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前寫過基于倒排表的問答系統。
基于倒排表的電力調度知識問答系統構建
問答系統所需要的數據已經提供,對于每一個問題都可以找得到相應的答案,所以可以理解為每一個樣本數據是 <問題、答案>。 那系統的核心是當用戶輸入一個問題的時候,首先要找到跟這個問題最相近的已經存儲在庫里的問題,然后直接返回相應的答案即可。
由于作者是學電氣的,這里以發電廠知識文本來構建問答系統
該篇是低配版的問答系統,思路不如倒排表。
思路
1,將發電廠知識問答數據集(問題.txt & 答案.txt)通過預處理,整合為格式規范的數據。
2,基于詞袋模型和TFIDF模型,采用余弦相似度作為度量標準,對測試問題語料庫中的問題進行文本相似度計算,找出相似度較高的問題作為相似問題集合。
3,將相似問題集合中的問題進行排序,同時返回其對應的答案給用戶。
文本數據集準備
答案.txt
問題.txt
第一步:讀取數據
#第一步:讀取數據def read_corpus(file):with open(file,'r',encoding='utf8',errors='ignore') as f:list = []lines = f.readlines()for i in lines:list.append(i)return listquestions = read_corpus('./問題.txt') answers = read_corpus('./答案.txt')print('Example:') print('Question',questions[0]) print('Answer',answers[0])第二步:預處理
#第二步:預處理 import re import jiebadef filter_out_category(input):new_input = re.sub('[\u4e00-\u9fa5]{2,5}\\/','',input) #過濾掉非漢字,即標點符號return new_inputdef filter_out_punctuation(input):new_input = re.sub('([a-zA-Z0-9])','',input)#過濾掉字母和數字new_input = ''.join(e for e in new_input if e.isalnum())return new_inputdef word_segmentation(input):new_input = ','.join(jieba.cut(input))#分詞return new_inputdef preprocess_text(data):new_data = []for q in data:q = filter_out_category(q)#過濾掉符號q = filter_out_punctuation(q)#過濾掉字母和數字q = word_segmentation(q)#分詞new_data.append(q)return new_dataqlist = preprocess_text(questions) # 更新后的 print('questions after preprocess',qlist[0:3])第三步:詞袋模型和TFIDF模型
#第三步:詞袋模型和tf_idf模型 from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfVectorizer#詞袋模型 def bow_extractor(corpus, ngram_range=(1, 1)):vectorizer = CountVectorizer(min_df=1, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, features# # 詞袋模型特征 def conver2BOW(data):new_data = []for q in data:new_data.append(q)bow_vectorizer, bow_X = bow_extractor(new_data)return bow_vectorizer, bow_X bow_vectorizer, bow_X = conver2BOW(qlist)# print('BOW model') print('vectorizer',bow_vectorizer.get_feature_names()) print('vector of text',bow_X[0:3].toarray()) #tf_idf def tfidf_extractor(corpus, ngram_range=(1, 1)):vectorizer = TfidfVectorizer(min_df=1, norm='l2', smooth_idf=True, use_idf=True, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, features# # tfidf 特征 def conver2tfidf(data):new_data = []for q in data:new_data.append(q)tfidf_vectorizer, tfidf_X = tfidf_extractor(new_data)return tfidf_vectorizer, tfidf_X tfidf_vectorizer, tfidf_X = conver2tfidf(qlist)print('TFIDF model') print('vectorizer',tfidf_vectorizer.get_feature_names()) print('vector of text',tfidf_X[0:3].toarray())第四步:余弦相似度。
#第四步:余弦相似度 import numpy as np def idx_for_largest_cosine_sim(input, questions):list = []input = (input.toarray())[0]for question in questions:question = question.toarray()num = float(np.matmul(question, input))denom = np.linalg.norm(question) * np.linalg.norm(input)if denom ==0:cos = 0.0else:cos = num / denomlist.append(cos)best_idx = list.index(max(list))return best_idx第五步:對測試問題語料庫中的問題進行文本相似度計算,找出相似度較高的問題作為相似問題集合
#第五步:問題求解 #詞袋模型求解 def answer_bow(input):input = filter_out_punctuation(input)#對輸入進行過濾字母和數字input = word_segmentation(input)#對輸入進行分詞bow = bow_vectorizer.transform([input])#對輸入進行詞袋模型best_idx = idx_for_largest_cosine_sim(bow, bow_X)#將輸入和問答庫的問題進行相似度計算,取出最好的哪一個return answers[best_idx]#tf-idf求解 def answer_tfidf(input):input = filter_out_punctuation(input)#對輸入進行過濾字母和數字input = word_segmentation(input)#對輸入進行分詞bow = tfidf_vectorizer.transform([input])#對輸入進行tf-idf模型best_idx = idx_for_largest_cosine_sim(bow, tfidf_X)#將輸入和問答庫的問題進行相似度計算,取出最好的哪一個return answers[best_idx]第六步:測試
#第六步:測試 print('詞袋 model',answer_bow("火電廠是什么")) print('tfidf model',answer_tfidf("火電廠"))全部代碼
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author: yudengwu(余登武) # @Date : 2020/12/26 #@email:1344732766@qq.com #第一步:讀取數據def read_corpus(file):with open(file,'r',encoding='utf8',errors='ignore') as f:list = []lines = f.readlines()for i in lines:list.append(i)return listquestions = read_corpus('./問題.txt') answers = read_corpus('./答案.txt')#第二步:預處理 import re import jiebadef filter_out_category(input):new_input = re.sub('[\u4e00-\u9fa5]{2,5}\\/','',input) #過濾掉非漢字,即標點符號return new_inputdef filter_out_punctuation(input):new_input = re.sub('([a-zA-Z0-9])','',input)#過濾掉字母和數字new_input = ''.join(e for e in new_input if e.isalnum())return new_inputdef word_segmentation(input):new_input = ','.join(jieba.cut(input))#分詞return new_inputdef preprocess_text(data):new_data = []for q in data:q = filter_out_category(q)#過濾掉符號q = filter_out_punctuation(q)#過濾掉字母和數字q = word_segmentation(q)#分詞new_data.append(q)return new_dataqlist = preprocess_text(questions) # 更新后的問題#第三步:詞袋模型和tf_idf模型 from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfVectorizerdef bow_extractor(corpus, ngram_range=(1, 1)):vectorizer = CountVectorizer(min_df=1, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, features# # 詞袋模型特征 def conver2BOW(data):new_data = []for q in data:new_data.append(q)bow_vectorizer, bow_X = bow_extractor(new_data)return bow_vectorizer, bow_X bow_vectorizer, bow_X = conver2BOW(qlist)#tf_idf def tfidf_extractor(corpus, ngram_range=(1, 1)):vectorizer = TfidfVectorizer(min_df=1, norm='l2', smooth_idf=True, use_idf=True, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, features# # tfidf 特征 def conver2tfidf(data):new_data = []for q in data:new_data.append(q)tfidf_vectorizer, tfidf_X = tfidf_extractor(new_data)return tfidf_vectorizer, tfidf_X tfidf_vectorizer, tfidf_X = conver2tfidf(qlist)#第四步:余弦相似度 import numpy as np def idx_for_largest_cosine_sim(input, questions):list = []input = (input.toarray())[0]for question in questions:question = question.toarray()num = float(np.matmul(question, input))denom = np.linalg.norm(question) * np.linalg.norm(input)if denom ==0:cos = 0.0else:cos = num / denomlist.append(cos)best_idx = list.index(max(list))return best_idx#第五步:問題求解 #詞袋模型求解 def answer_bow(input):input = filter_out_punctuation(input)#對輸入進行過濾字母和數字input = word_segmentation(input)#對輸入進行分詞bow = bow_vectorizer.transform([input])#對輸入進行詞袋模型best_idx = idx_for_largest_cosine_sim(bow, bow_X)#將輸入和問答庫的問題進行相似度計算,取出最好的哪一個return answers[best_idx]#tf-idf求解 def answer_tfidf(input):input = filter_out_punctuation(input)#對輸入進行過濾字母和數字input = word_segmentation(input)#對輸入進行分詞bow = tfidf_vectorizer.transform([input])#對輸入進行tf-idf模型best_idx = idx_for_largest_cosine_sim(bow, tfidf_X)#將輸入和問答庫的問題進行相似度計算,取出最好的哪一個return answers[best_idx]#第六步:測試 print('詞袋 model',answer_bow("火電廠是什么")) print('tfidf model',answer_tfidf("火電廠"))總結
該思路不如倒排表。有空參照下另一篇吧
倒排表速度快。
鏈接如下:
基于倒排表的電力調度知識問答系統構建
作者:電力-余登武
總結
以上是生活随笔為你收集整理的基于发电厂知识问答库的检索式问答系统(python有代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇带你搞透回溯算法
- 下一篇: 结构性存款是理财吗