一、基本流程
我们可以参照以下流程进行智能机器人的程序设计工作,
(1)利用已有的数据对 TfidfVectorizer 模型进行训练
(2)利用训练好的TF-IDF模型进行训练数据data0和真实数据data1的TFIDF值求解
(3)通过余弦相似度进行两者的比较找到data1和data0中的所有值的相似值
(4)取出相似值结果中最相似值的索引,并将该索引对应的答复输出即可
参考代码:
import numpy as np
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
# 车机的命令与回复数组
from sklearn.metrics.pairwise import cosine_similarity
command=[['请打开车窗','好的,车窗已打开'],
['我要听陈奕迅的歌','为你播放富士山下'],
['我好热','已为你把温度调到25度'],
['帮我打电话给小猪猪','已帮你拨小猪猪的电话'],
['现在几点钟','现在是早上10点'],
['我要导航到中华广场','高德地图已打开'],
['明天天气怎么样','明天天晴']
]
# 利用 jieba 转换命令格式
def getWords():
comm=np.array(command)
list=[jieba.lcut(sentence) for sentence in comm[:,0]]
words=[' '.join(word) for word in list]
return words
#获取输入命令的分词
def getInputWords():
# 把输入命令转化为数组格式
sentence = jieba.lcut(inputCommand)
words = ' '.join(sentence)
list = []
list.insert(0, words)
return list
# 训练 TfidfVectorizer 模型
def getModel():
words=getWords()
vectorizer=TfidfVectorizer()
model=vectorizer.fit(words)
return model
# 计算 consine 余弦相似度
def consine(): # 获取训练好的 TfidfVectorizer 模型
model=getModel()
# 获取车机命令的 TF-IDF 向量
data0=model.transform(getWords()).toarray().reshape(len(command),-1)
# 获取输入命令的 TF-IDF 向量
data1=model.transform(getInputWords()).toarray().reshape(1,-1)
# 余弦相似度对比
result=cosine_similarity(data0,data1)
print('相似度对比:\n{0}'.format(result))
return result
if __name__=='__main__':
inputCommand=input('您请说:')
# 获取余弦相似度
result=np.array(consine())
# 获取相似度最高的命令 index
argmax=result.argmax()
# 读取命令回复
data=command[argmax][1]
print('命令:{0}\n回复:{1}'.format(inputCommand,data))
问答机器人代码:
train.py
import jieba
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from joblib import dump
import xlrd
# 车机的命令与回复数组
# command=[['请打开车窗','好的,车窗已打开'],
# ['我要听陈奕迅的歌','为你播放富士山下'],
# ['我好热','已为你把温度调到25度'],
# ['帮我打电话给小猪猪','已帮你拨小猪猪的电话'],
# ['现在几点钟','现在是早上10点'],
# ['我要导航到中华广场','高德地图已打开'],
# ['明天天气怎么样','明天天晴']
# ]
filepath = r'222.xls'
wb = xlrd.open_workbook(filepath)
sheet = wb.sheet_by_index(0)
command = []
for i in range(1,sheet.nrows):
command.append(sheet.row_values(i))
# 利用 jieba 转换命令格式
def getWords():
comm=np.array(command)
list=[jieba.lcut(sentence) for sentence in comm[:,0]]
words=[' '.join(word) for word in list]
return words
# 训练 TfidfVectorizer 模型
def getModel():
words=getWords()
vectorizer=TfidfVectorizer()
model=vectorizer.fit(words)
return model
def maintrain():
model = getModel()
dump(model, 'model.pkl')
# 获取车机命令的 TF-IDF 向量
data0 = model.transform(getWords()).toarray().reshape(len(command), -1)
return data0,command
if __name__ == '__main__':
maintrain()
textsame.py
import numpy as np
import jieba
import streamlit as st
from joblib import load
from train import maintrain
from sklearn.metrics.pairwise import cosine_similarity
# 车机的命令与回复数组
# command=[['请打开车窗','好的,车窗已打开'],
# ['我要听陈奕迅的歌','为你播放富士山下'],
# ['我好热','已为你把温度调到25度'],
# ['帮我打电话给小猪猪','已帮你拨小猪猪的电话'],
# ['现在几点钟','现在是早上10点'],
# ['我要导航到中华广场','高德地图已打开'],
# ['明天天气怎么样','明天天晴']
# ]
# # 利用 jieba 转换命令格式
# def getWords():
# comm=np.array(command)
# list=[jieba.lcut(sentence) for sentence in comm[:,0]]
# words=[' '.join(word) for word in list]
# return words
# 计算 consine 余弦相似度
def consine(inputCommand):
# 把输入命令转化为数组格式
sentence=jieba.lcut(inputCommand)
words=str.join(' ',sentence)
list=[]
list.insert(0,words)
# 获取训练好的 TfidfVectorizer 模型
model=load('model.pkl')
# 获取输入命令的 TF-IDF 向量
data1=model.transform(list).toarray().reshape(1,-1)
# 余弦相似度对比
result=cosine_similarity(data0,data1)
#print('相似度对比:\n{0}'.format(result))
return result
if __name__=='__main__':
#相似度
treshold = 0.8
#拒识话术
jstext = '抱歉,这个问题我不会!!!'
data0,command = maintrain()
comm = st.text_input(label='您请说:', value='')
#comm='我要听陈奕迅的歌'
if comm:
# 获取余弦相似度
result=np.array(consine(comm))
# 获取相似度最高的命令 index
argmax=result.argmax()
# 读取命令回复
data=command[argmax][1]
#print('命令:{0}\n回复:{1}'.format(comm,data))
if result[argmax][0] >= treshold :
data = data
else:
data = jstext
else:
data = ''
st.text_area(label='回复:', value=data)
sbert:
from sentence_transformers import SentenceTransformer, util
import xlrd
import torch
import streamlit as st
#获取知识库中的问题和答案
filepath = r'222.xls'
wb = xlrd.open_workbook(filepath)
sheet = wb.sheet_by_index(0)
normal_questions = sheet.col_values(0)[1:]
normal_answer = sheet.col_values(1)[1:]
#加载模型
model = SentenceTransformer('paraphrase-distilroberta-base-v1')
#获得所有问题的向量
embeddings = torch.load('myTensor.pth')
# 相似度
treshold = 0.7
# 拒识话术
jstext = '抱歉,这个问题我不会!!!'
def sim(query):
#查询条件向量化
q_emd = model.encode(query)
#语料库中的标准问题向量化
#计算相似度
cosine_scores = util.cos_sim(q_emd,embeddings)[0]
top_res = torch.topk(cosine_scores,k=1)
return float(top_res[0]),normal_answer[int(top_res[1])]
if __name__ == '__main__':
st.header("知识问答平台")
comm = st.text_input(label='您请说:', value='')
if comm:
scorebest,answer = sim(query=comm)
if scorebest >= treshold:
data = answer
else:
data = jstext
else:
data = ''
st.text_area(label='回复:', value=data, height=200)