无需编程经验,这份Python自动聊天机器人代码帮你玩转对话交流!

import jieba
import pandas as pd

# 尝试打开停用词文件并读取内容
try:
    with open('stopwords.txt', 'r', encoding='utf-8') as f:
        stop_words = {line.strip() for line in f}
except FileNotFoundError:
    print('停用词文件不存在,将创建文件并写入默认停用词表。')
    # 如果停用词文件不存在,创建新文件并写入默认的停用词表
    stop_words = {'的', '了', '着', '在', '是', '我', '你', '他', '她', '我们', '你们', '他们', '她们', '它', '它们', '这',
                  '那', '这个', '那个', '一些', '些许', '有些', '能够', '可以', '可能', '应该', '必须', '需要', '……'}
    with open('stopwords.txt', 'w', encoding='utf-8') as f:
        for word in stop_words:
            f.write(word + '\n')

# 尝试打开Excel文件并读取问题和答案
try:
    qa_df = pd.read_excel('data.xlsx', header=None)
    qa_pairs = list(zip(qa_df[0], qa_df[1]))
except pd.errors.EmptyDataError:
    print('数据文件为空,请添加数据!')
    qa_pairs = []
except FileNotFoundError:
    print('数据文件不存在,将创建一个新的数据文件。')
    qa_pairs = []
    # 创建一个新的Excel文件并写入默认问题和答案
    qa_df = pd.DataFrame({'问题': ['请问有什么可以帮助您的吗?'], '答案': ['暂时我还不知道怎样回答你']})
    qa_df.to_excel('data.xlsx', index=False, header=True)

# 如果Excel表格中没有数据,添加默认问题和答案
if not qa_pairs:
    qa_pairs.append(('请问有什么可以帮助您的吗?', '暂时我还不知道怎样回答你'))

# 从问题答案列表中获取所有问题,不包括第一行
questions = [pair[0] for i, pair in enumerate(qa_pairs) if i != 0]
# 从问题答案列表中获取所有答案,不包括第一行
answers = [pair[1] for i, pair in enumerate(qa_pairs) if i != 0]

# 初始化首次进入对话循环的标志
first_time = True

# 进入对话循环
while True:
    # 获取用户输入
    user_input = input('你好,请问有什么可以帮助你的吗?\n' if first_time else '')

    # 更新首次进入对话循环的标志
    first_time = False

    # 初始化最大相似度和最相似的问题编号
    max_similarity, max_index = 0, 0

    # 遍历所有问题,计算用户输入与每个问题之间的 Jaccard 相似度
    for i in range(len(questions)):
        # 分词,使用中文精确分词模式,并去除停用词
        question_words = set(jieba.lcut(questions[i].lower())) - stop_words
        # 如果问题中只有停用词,则跳过
        if not question_words:
            continue

        # 分词,使用中文精确分词模式,并去除停用词
        user_words = set(jieba.lcut(user_input.lower())) - stop_words
        # 如果用户输入中只有停用词,则跳过
        if not user_words:
            continue

        # 计算 Jaccard 系数的分子和分母
        numerator = len(user_words & question_words)
        denominator = len(user_words | question_words)
        similarity = numerator / denominator

        # 如果相似度大于最大相似度,则更新最大相似度和最相似的问题编号
        if similarity > max_similarity:
            max_similarity = similarity
            max_index = i

    # 判断最大相似度是否大于指定阈值,如果大于则输出对应的答案;否则输出最接近的5个问题
    similar_questions = []
    for i in range(len(questions)):
        # 分词,使用中文精确分词模式,并去除停用词
        question_words = set(jieba.lcut(questions[i].lower())) - stop_words
        # 如果问题中只有停用词,则跳过
        if not question_words:
            continue

        # 分词,使用中文精确分词模式,并去除停用词
        user_words = set(jieba.lcut(user_input.lower())) - stop_words
        # 如果用户输入中只有停用词,则跳过
        if not user_words:
            continue

        # 计算 Jaccard 系数的分子和分母
        numerator = len(user_words & question_words)
        denominator = len(user_words | question_words)
        similarity = numerator / denominator

        if similarity > 0:
            similar_questions.append((similarity, i))

    similar_questions = sorted(similar_questions, key=lambda x: x[0], reverse=True)

    if max_similarity >= 0.5:
        print(answers[max_index])

    else:
        if len(similar_questions) == 0:
            print(f'抱歉,我不太理解你的问题,请重新表述您的问题。')
        else:
            top_5 = similar_questions[:5]

            full_response = f"抱歉,我不太理解你的问题,以下是最接近的5个问题:\n\n"

            for i, q in enumerate(top_5):
                full_response += f"{i + 1}. {questions[q[1]]}\n"

            full_response += "\n请输入所选问题的序号进行提问:"

            print(full_response)

            # 获取用户输入的序号,如果不是数字或者超出范围,输出错误提示
            while True:
                try:
                    choice = int(input())
                    if choice < 1 or choice > len(top_5):
                        print('请输入有效的序号!请重新输入:')
                        continue
                    break
                except ValueError:
                    print('请输入数字!请重新输入:')

            # 根据用户选择输出相应问题
            print(f"您选择了问题'{questions[top_5[choice - 1][1]]},{answers[top_5[choice - 1][1]]}'   请继续提问:")

一、介绍

本代码实现一个基于 Jaccard 相似度的简易聊天机器人,旨在提供一个基础的思路和框架,为希望学习和实践聊天机器人的新手提供参考和学习资料。

二、使用的库

代码使用了 jieba 和 pandas 两个库:jieba 分词库用于将中文文本转换成有意义的词语,pandas 库用于数据处理和分析。

三、代码实现过程(按部分解释)

  • 读取数据:代码首先尝试打开一个名为 data.xlsx 的 Excel 文件,并将其中的问题和答案读取到内存中。如果文件不存在,代码会创建一个名为 data.xlsx 的新 Excel 文件,并将默认问题和答案写入其中。
  • 处理用户输入:将每个问题进行分词,并计算与用户输入之间的 Jaccard 相似度,然后找到相似度最高的问题。如果相似度达到一定阈值,则输出对应的答案;否则,输出最接近的5个问题,让用户选择一个问题,进而获得答案。
  • 输出最终答案:根据用户选择,输出相应的问题和答案,等待下一轮用户输入。

四、停用词

代码使用停用词表过滤一些无关紧要的词汇,从而提高匹配效率。

五、扩展功能

可以加入语义理解和对话记忆等功能来提升聊天机器人的交互性能和用户体验。

六、总结

本代码提供了一个基础的思路和框架,为希望学习和实践聊天机器人的新手提供了很好的参考和学习资料。同时,也提醒在实际使用过程中,还需要考虑数据安全和隐私保护等问题。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现实时语音对讲,可以使用 Python 的音频处理库 PyAudio 来录制和播放音频,同时使用 Socket 实现网络通信,实现音频的实时传输。 具体的实现步骤如下: 1. 导入 PyAudio 和 Socket 库。 ``` import pyaudio import socket ``` 2. 创建 PyAudio 的输入流和输出流。 ``` # 创建 PyAudio 的输入流和输出流 p = pyaudio.PyAudio() input_stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) output_stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True, frames_per_buffer=CHUNK) ``` 其中,FORMAT、CHANNELS、RATE 和 CHUNK 都是常量,分别表示音频的格式、声道数、采样率和缓冲区大小,可以根据需要自行调整。 3. 创建 Socket 连接。 ``` # 创建 Socket 连接 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('127.0.0.1', 8000)) server_socket.listen(1) print('等待连接...') client_socket, client_address = server_socket.accept() print('连接成功:', client_address) ``` 注意要绑定本地 IP 和端口,等待客户端连接。 4. 不断循环,读取输入流的音频数据并发送给客户端,接收客户端发送的音频数据并写入输出流。 ``` # 不断循环,读取输入流的音频数据并发送给客户端,接收客户端发送的音频数据并写入输出流 while True: # 读取输入流的音频数据并发送给客户端 input_data = input_stream.read(CHUNK) client_socket.sendall(input_data) # 接收客户端发送的音频数据并写入输出流 output_data = client_socket.recv(CHUNK) output_stream.write(output_data) ``` 注意要使用 sendall() 和 recv() 函数来确保数据完整性。 完整代码如下: ``` import pyaudio import socket # 定义常量 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 16000 CHUNK = 1024 # 创建 PyAudio 的输入流和输出流 p = pyaudio.PyAudio() input_stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) output_stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True, frames_per_buffer=CHUNK) # 创建 Socket 连接 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('127.0.0.1', 8000)) server_socket.listen(1) print('等待连接...') client_socket, client_address = server_socket.accept() print('连接成功:', client_address) # 不断循环,读取输入流的音频数据并发送给客户端,接收客户端发送的音频数据并写入输出流 while True: # 读取输入流的音频数据并发送给客户端 input_data = input_stream.read(CHUNK) client_socket.sendall(input_data) # 接收客户端发送的音频数据并写入输出流 output_data = client_socket.recv(CHUNK) output_stream.write(output_data) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值