自然语言处理--基于示例检索的聊天机器人

一种“倾听”用户的数据驱动方法是在历史对话日志中搜索之前的语句。这类似于人类倾听者尝试回想之前他们在哪里听到过该问题、句子或词。机器人不仅可以搜索自己的对话日志,还可以搜索任何人与人之间的对话记录、机器人和人之间的对话记录,甚至是机器人和机器人之间的对话记录,当然机器人和机器人之间的对话记录慎用。这是基于搜索的聊天机器人,它可以使用历史对话日志来查找和机器人的交谈对象刚刚说的话类似的语句示例。

import pandas as pd
import re
from tqdm import tqdm
from sklearn.feature_extraction.text import TfidfVectorizer

df = pd.read_csv("xxx\\ubuntu_dialog.csv").iloc[:100000, :]
print(df)

# 创建一个函数来按照“__eot__”符号拆分并清理“__eou__”标记
def split_turns(s, splitter=re.compile('__eot__')):
    for utterance in splitter.split(s):
        utterance = utterance.replace('__eou__', '\n')
        utterance = utterance.replace('__eot__', '').strip()
        if len(utterance):
            yield utterance

# 示例:在 DataFrame 中的几行数据上运行 split_turns 函数
for i, record in df.head(3).iterrows():
    statement = list(split_turns(record.Context))[-1]
    reply = list(split_turns(record.Utterance))[-1]
    print('Statement: {}'.format(statement))
    print()
    print('Reply: {}'.format(reply))

def preprocess_ubuntu_corpus(df):
    """
    Split all strings in df.Context and df.Utterance on
    __eot__ (turn) markers
    """
    statements = []
    replies = []
    for i, record in tqdm(df.iterrows()):
        turns = list(split_turns(record.Context))
        # 这里需要一个 if,因为有些提问和回复只包含空白符
        statement = turns[-1] if len(turns) else '\n'
        statements.append(statement)
        turns = list(split_turns(record.Utterance))
        reply = turns[-1] if len(turns) else '\n'
        replies.append(reply)
    df['statement'] = statements
    df['reply'] = replies
    return df

# 在语句(statement)列中检索与用户语句最接近的匹配,并使用回复(reply)
# 列中相应的回复进行回答:使用词频向量和 TF-IDF 向量查找相似
# 的自然语言文档
df = preprocess_ubuntu_corpus(df)
'''
min_df:当构建词汇表时,严格忽略低于给出阈值的文档频率的词条,语料指定的停用词。
    如果是浮点值,该参数代表文档的比例,整型绝对计数值,如果词汇表不为None,此参数被忽略。
max_df:当构建词汇表时,严格忽略高于给出阈值的文档频率的词条,语料指定的停用词。
    如果是浮点值,该参数代表文档的比例,整型绝对计数值,如果词汇表不为None,此参数被忽略。
max_features:如果不为None,构建一个词汇表,仅考虑max_features--按语料词频排序,如果词汇表不为None,这个参数被忽略
'''
tfidf = TfidfVectorizer(min_df=8, max_df=.3, max_features=50000)
# 只需要计算提问(不包括回复)的 TF-IDF,因为提问是我们需要搜索的对象
tfidf.fit(df.statement)

# 创建一个名为 X 的 DataFrame,保存 15 万条语句的所有 TF-IDF 向量
X = tfidf.transform(df.statement)
# todense():将矩阵显示出来
X = pd.DataFrame(X.todense(), columns=tfidf.get_feature_names())
print(X)

# 查找最接近语句的一种方法是计算从查询语句到 X 矩阵中所有语句的余弦距离
x = tfidf.transform(['This is an example statement that we want to retrieve the best reply for.'])
cosine_similarities = x.dot(X.T)
reply = df.loc[cosine_similarities.argmax()]
print(reply.reply)

猜你喜欢

转载自blog.csdn.net/fgg1234567890/article/details/114234170
今日推荐