在线客服回答推荐实现
2017-03-20 本文已影响108人
HelloArmin
在特定业务的客服领域,用户的常见问题是可以收敛在一定范围内的。 根据用户的输入,智能推荐出常见问题的回答,能提高在线客服服务用户的效率,提高客服的受理用户量。
实现逻辑
实现逻辑其实很简单:
首先我们会维护一个常见问题的知识库, 一问一答形式。根据用户的输入,在知识库里查找最相似的问题,把回答推荐给用户或者客服。
其中的难点是,如何做文本的相似度比较。在python领域,已经有很多文本相似度的算法已经实现和开源,只要拿来用即可。
实现步骤
大学时期学的高等数学都已经还给老师了,这里就不再列出公司。只简单描述下主要的步骤和思想。
分词和去停用词
对问题文本进行中文分词,然后过滤掉停用词。
停用词是语料当中对文本内容意义不大但出现频率很高的词。像“我”,“的”等。
选择特征值计算权重
过滤掉停用词后,剩下的词就是关键词,即为文本的特征值。每个特征值将作为文本向量的一个维度,而每个维度的特征值都将按照一定的规则被富于一个权重表示他们在文档中的重要程度。这里我们通过TF-IDF来计算权值。
TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
向量空间模型和余弦计算
向量空间模型(VSM:Vector Space Model)的思想是,将文本表示为以特征值(关键词)的权重为分量的N维向量。每个特征值对应一个维度,权重对应在坐标轴上的值。一个文本就是坐标系中的一个向量。
最后通过这个坐标系,来计算 用户输入的问题文本的向量与常见问题列表中的问题文本向量的夹角余弦。余弦夹角最小的,即使相似度最高。
源码
import jieba
import csv
from gensim import corpora, models, similarities
def load_fqa_file():
fqas = []
with open('fqastore.csv', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
if row:
fqas.append(row)
print('fqa file is loaded...')
return fqas
def load_stop_words():
stop_words = []
with open('stopwords.txt', encoding='utf-8') as file:
for row in file:
if row.strip():
stop_words.append(row.strip())
print('stop words is loaded.')
return stop_words
def cut_questions(fqas, stop_words):
all_question_word_bag = []
for fqa in fqas:
words = cut_words(fqa[0], stop_words)
all_question_word_bag.append(words)
return all_question_word_bag
def cut_words(str, stop_words):
seg_list = jieba.cut(str, cut_all=False)
words = ''
for word in seg_list:
if word not in stop_words:
words += word + ' '
return words
def main():
stop_words = load_stop_words()
fqas = load_fqa_file()
cuted_questions = cut_questions(fqas, stop_words) # 中文分词,去停用词
texts = [[word for word in question.split()] for question in cuted_questions]
dictionary = corpora.Dictionary(texts) # 生成词典 每个词都会生成对应的ID
corpus = [dictionary.doc2bow(text) for text in texts] # 将每个问题文本转化为词袋 [(单词1_id,词频),(单词n_id,词频) ]
tfidf = models.TfidfModel(corpus) # tf idf 模型
featureNum = len(dictionary.token2id.keys()) # 多少个词即多少个特征值
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=featureNum) # 稀疏矩阵
user_question = input("Please input your question:\n")
user_question_word = cut_words(user_question, stop_words).split()
user_question_vec = dictionary.doc2bow(user_question_word)
sim = index[tfidf[user_question_vec]] # 计算最终相似度结果
max_sim = 0
max_sim_index = -1
for index in range(len(sim)):
if sim[index] > max_sim:
max_sim = sim[index]
max_sim_index = index
if max_sim_index > -1:
print(fqas[max_sim_index][1])
if __name__ == '__main__':
main()