问答场景 实战案例

莫慌:本文不需要你有TensorFlow基础,仅只调用了google训练好的模型。其中标题一至三都是数据清洗工作,标题四至七是数据投喂至模型预测

本文所使用的数据文件为:comment.csv,提取码:2323。文件不大,无需百度网盘会员也可短时间下载完毕。代码建议在jupyter中运行

一、模块引入,如下

import os
import random
import numpy as np
import pandas as pd
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_text
# 注意:若果先前安装过tensorflow、numpy库等,这次在安装tensorflow_text模块时,极大可能会卸载掉不匹配当前下载的tensorflow_text版本的tensorflow和numpy等一些依赖模块,
# 并会重新下载适应tensorflow_text版本的tensorflow和numpy等一些模块,中途若出现安装失败莫慌,大可放心费点时间,烦请百度都是有解决方法的。这也是TensorFlow在windows下开发不友好的一点

二、抽取带楼主回复的评论, 如下

代码展示前,需要对comment.csv文件内容有所了解。如下图,并不是每条粉丝评论都有其对应的楼主回复,即楼主回复 列带有NaN表示楼主没有对粉丝评论做出回复。此外,数据有25674行和5列在这里插入图片描述
对数据有所了解后,需要只抽取带楼主回复的评论, pandas实现代码如下

df_merge = pd.read_csv('./平安银行f/comment.csv', header=None, keep_default_na=False) # comment.csv路径替换成自己的
qa_df = df_merge[df_merge[2].map(lambda x: len(x)>0)]
questions = list(qa_df[1]) # 摘取粉丝评论列数据
replies = list(qa_df[2]) # 摘取楼主回复列数据
replies_context = replies
print(len(questions), len(replies))
list(zip(questions, replies))

25674行数据只有3631行数据带有楼主回复,看下运行结果图:
在这里插入图片描述

三、随机打乱“抽取带楼主回复的评论”, 如下

打乱问答顺序且保持问与答不错乱。标题三这一步代码可有可无,本案例中完全是画蛇添足,当然考虑到一些机器模型训练数据要随机打乱,故添加一下功能

questions_and_replies = list(zip(questions, replies))
np.random.shuffle(questions_and_replies)
# questions_and_replies
questions = list(list(zip(*questions_and_replies))[0])
replies = list(list(zip(*questions_and_replies))[1])
replies_context = replies
list(zip(questions, replies))

看下运行结果图:
在这里插入图片描述

四、加载google已经训练好的模型, 如下

首次运行会下载以下代码中两个链接文件到系统缓存文件中,故首次运行是需要花费几分钟,因网速和电脑配置而异。

# 加载问答(Q&A)模型
module = hub.load('https://hub.tensorflow.google.cn/google/universal-sentence-encoder-multilingual-qa/3')
# 加载语义相似性比对模型
embed = hub.load("https://hub.tensorflow.google.cn/google/universal-sentence-encoder-multilingual-large/3")

以上两个模型都是在谷歌TensorFlow Hub中开源的,感兴趣的可以复制上述代码中两个链接到浏览器地址栏查看模型使用说明,这里不多介绍,仅下载下来使用

五、“抽取带楼主回复的评论”数据投喂至“问答模型”,如下

# 问答情景函数QA定义
question_embeddings_outputs_list = []
response_embeddings_outputs_list = []
def QA(questions_sub, replies_sub, replies_context_sub):
    question_embeddings = module.signatures['question_encoder'](tf.constant(questions_sub))
    response_embeddings = module.signatures['response_encoder'](input=tf.constant(replies_sub),context=tf.constant(replies_context_sub))
    question_embeddings_outputs_list.append(question_embeddings['outputs'])
    response_embeddings_outputs_list.append(response_embeddings['outputs'])

上述代码块是模型运行核心代码,有时间会逐一注释讲解,现快速上线,需要了解的可以访问标题四中的链接。调用上述代码块QA函数如下:

# 调用问答情景函数。分批次调用QA函数,每个批次256行数据。
# 之后通过tf.concat函数将每个批次的256行数据再合并成3631行数据。(因256无法被3631整除,故最后一个批次不足256行数据,不过这个函数依然可以合并)
# 若不分批次将3631行数据全部置入模型显卡内存不足程序就会报错
result = []
for i in range(0, len(questions), 256):
    questions_sub = questions[i:i + 256]
    replies_sub = replies[i:i + 256]
    replies_context_sub = replies_context[i:i + 256]
    result.append(QA(questions_sub, replies_sub, replies_context_sub))
result = np.inner(tf.concat(question_embeddings_outputs_list, 0), tf.concat(response_embeddings_outputs_list, 0))
result

看下运行结果图:
在这里插入图片描述

六、“抽取带楼主回复的评论”数据投喂至“语义相似性模型”,如下

# 语义相似性比对函数semanticSimilarity定义
questions_embed_list = []
def semanticSimilarity(questions_sub):
    questions_embed = embed(questions_sub)
    questions_embed_list.append(questions_embed)
for i in range(0, len(questions), 256):
    questions_sub = questions[i:i + 256]
    semanticSimilarity(questions_sub)

上述代码块是模型运行核心代码,有时间会逐一注释讲解,现快速上线,需要了解的可以访问标题四中的链接。调用上述代码块语义相似性比对函数如下:

# 调用语义相似性比对函数。分批次调用semanticSimilarity函数,每个批次256行数据,若不分批次将3631行数据全部置入模型显卡内存不足程序就会报错
user_input = ['我想买下整座银行'] # 这里是用户提出的问题,你可以把“我想买下整座银行”替换成你想问的问题,具体问哪些问题可以参考comment.csv文件中“粉丝评论”一列,替换的问题含义与粉丝评论相似即可,不必文字完全一致
# 当你把第2行的问题替换成你自己定义的后,直接从此代码块开始往后运行
user_input_embed = embed(user_input)
# for i in range(0, len(questions), 256):
#     questions_sub = questions[i:i + 256]
#     semanticSimilarity(questions_sub)
semantic_similarity = np.inner(user_input_embed, tf.concat(questions_embed_list, 0))
for semantic in semantic_similarity:
	# 下一行的argsort()方法默认表示对semantic numpy数组增序排序,[::-1]表示降序排序,[0:5]表示取前5最大可能性
    semantic_topN = semantic.argsort()[::-1][0:5]
    for order, semantic_one in enumerate(semantic_topN, start=1):
        print('模型预测提出问题{}:{}'.format(order, questions[semantic_one]))

# 随机选择问题
choice_one_question = questions[random.choice(semantic_topN)]
print("\n随机选择的问题是:{}".format(choice_one_question))

看下运行结果图:
在这里插入图片描述

七、根据五和六俩步骤,对提出的问题给出多个可能性回复,如下

question_index = questions.index(choice_one_question)
print('真实回答:', replies_context[question_index])
replies_index = result[question_index]
replies_index_top3 = replies_index.argsort()[::-1][0:10]
for order, replies_index in enumerate(replies_index_top3, start=1):
    print('模型预测给出答复{}:{}'.format(order, replies_context[replies_index]))

标题六中提出的问题是:我想买下整座银行。然后语义相似模型就预测了我们可能想提出的问题,我展示出了可能性最大的5个问题,并从这5个问题中随机选择一个问题对其进行回答预测。看下运行结果图:
在这里插入图片描述

八、其他说明,如下

本文的案例远远不够强大,有很多需要完善的地方,比如加大comment.csv数据量,提高案例模型的准确率,这只是其中一点,再站在数据特征层面来讲,如何通过分词去除无关词汇提高数据的代表性等等,后续时间空了会不断升级完善这个案例。后续见。。。

结尾:comment.csv数据文件来自今日头条某条主与粉丝的互动。数据真实有效,是结合爬虫摘取下来后清洗保存的一份数据文件,若侵犯隐私联系删除

猜你喜欢

转载自blog.csdn.net/weixin_47834823/article/details/123835604