wiki语料库训练检索式聊天机器人

环境:

python3.7~9,chatterbot库

语料库:

中文语料库​github.com/brightmart/nlp_chinese_corpus

可以从我的网盘下:

trained_txt: (我训练时踩坑然后去掉每一步遇到的非法json处理后的txt)

https://www.aliyundrive.com/s/GwtwpfH56fj

原始语料库:

https://pan.baidu.com/s/1cOF_uYC1eymOafeG690H4Q?pwd=y79x​pan.baidu.com/s/1cOF_uYC1eymOafeG690H4Q?pwd=y79x

用的是wiki

chatterbot

pip install ChatterBot==1.0.8

chatterbot可以从这里下(如果pip安装失败的话)

ChatterBot-1.0.8 https://www.aliyundrive.com/s/9TnnaGEAiFB

https://pan.baidu.com/s/1aZatb1Lj8bL42Lex62YEzw?pwd=l00d​pan.baidu.com/s/1aZatb1Lj8bL42Lex62YEzw?pwd=l00d

下载完解压,然后在chatterbot-1.0.8根目录执行

# 1 构建
python setup.py build
# 2 安装
python setup.py install

数据预处理

该语料库的单行是这种结构

{"id": "53", "url": "https://zh.wikipedia.org/wiki?curid=53", "title": "经济学", "text": "经济学\n\n经济学是一门对产品和服务的生产、分配以及消费进行研究的社会科学。西方语言中的“经济学”一词源于古希腊的。\n\n经济学注重的是研究经济行为者在一个经济体系下的行为,以及他们彼此之间的互动。在现代,经济学的教材通常将这门领域的研究分为总体经济学和个体经济学。微观经济学检视一个社会里基本层次的行为,包括个体的行为者(例如个人、公司、买家或卖家)以及与市场的互动。而宏观经济学则分析整个经济体和其议题,包括失业、通货膨胀、经济成长、财政和货币政策等。..."}

而chatterbot需要的数据是一问一答的,为了方便,一问一答放在不同行,所以我们需要提取这个json里的title(问)和text(答)

我一开始是想遍历文件夹(AA~AM)然后发现运行到一半报错(而且好像文件太大没办法一次性搞完),因为它的json里面有一些字符没办法解析(也不知道为啥)然后就一个一个文件夹去遍历,遇到错的就去掉那一行继续遍历……

处理逻辑(可以跳过,直接用我上面分享的trained_txt里的文件训练)

# 文件
import os
# 处理json
import json# wiki_zh下所有子目录名称,用于遍历
# AM目录只有74个文件(wiki_73)
# todo 每次训练完一个文件夹,就把该文件夹名从这里去掉
wiki_c_file_name = ['AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM']
path = './wiki_zh/'  # 目录路径
for c_dir_name in wiki_c_file_name:
    # 拼接 -> ./wiki_zh/AA
    dir_name = os.path.join(path, c_dir_name)
    # ./wiki_zh/AA/*
    files = os.listdir(dir_name)
    # print(files)
    for filename in files:
        if os.path.isfile(os.path.join(dir_name, filename)):
            # 控制当前训练的文件到精确位置
            # 1,训练
            # 2,到了异常的地方就复制 id
            # 3,ctrl shift f -> id
            # 4,ctrl x 该id对应的那行,黏贴到桌面的txt
            # 5,修改文件名 train_before_${id}
            # 6,修改判断条件 int(data['id']) < ${id}
            # 7,修改判断条件 int(filename[(wiki + 1):]) < id所在文件的编号
            wiki = filename.find("_")
            if (c_dir_name != 'AA'):
                print(filename)
                break
            # 跳过 上一次报错的位置 之前的数据 todo 每次报错重新训练要更改
            if (int(filename[(wiki + 1):]) < 0):
                print(filename[(wiki + 1):])
                continue
            with open(os.path.join(dir_name, filename), 'r', encoding='utf-8') as f:
                # 读取所有内容
                content = f.read()
                content = content.replace("\n", '')
                content = content.replace("\\n", '')
                while content.find('{"id":') != -1:
                    # 从 {"id": 开始,到 "} 结束 
                    start = content.find('{"id":')
                    end = content.find('"}')
                    print(content[start:(end + 2)])
                    # start到end这段(json) -> 转为json对象 -> 字典
                    json_str = content[start:(end + 2)]
                    json_str = json_str.replace('\\n', '')
                    json_str = json_str.replace('\n', '')
                    # 加载、解析json数据
                    data = json.loads(json_str)
                    # 从原来的文本里去掉start到end的这段
                    content = content[(end + 2):]
                    print(data['text'])
                    # 跳过 上次报错的json的id 之前的数据 todo 每次报错重新训练要更改
                    if (int(data['id']) <= 0):
                        continue
                    # 打开文件,如果不存在则创建, 把训练完的数据保存到txt文件
                    # todo 每次报错把创建的文件改名 train_before_AA_错误的json的id
                    # todo 每次训练完一个文件夹下的所有文件,需要把AA改成下一个要训练的文件夹(AB、AC...)
                    with open('train_before_AA_.txt', 'a', encoding='utf-8') as file:
                        file.write(data['title'] + '\n')
                        file.write(data['text'] + '\n')
                        file.close()
        f.close()

训练(批量)

from chatterbot import ChatBot
from chatterbot.trainers import ListTrainer
import os

path = './train_txt/'  # 目录路径
files = os.listdir(path) # 该目录下的子目录s
print(files) # xxx.txt
corpus = []  # 加载的语料,一行问,一行答
for filename in files:
    if os.path.isfile(os.path.join(path, filename)):
        print(filename)
        open_file = os.path.join(path, filename)
        print(open_file)
        # 导入语料库
        file = open(open_file, 'r', encoding='utf-8')
        print('开始加载语料!')
        while 1:
            try:
                line = file.readline()
                print(line)
                if not line:
                    break
                corpus.append(line.strip('\n'))
            except:
                pass
        file.close()
print('语料加载完毕')
my_bot = ChatBot("wiki",database_uri='sqlite:///db.sqlite3')
print('Type something to begin...')
trainer = ListTrainer(my_bot)
print('开始训练!')
# trainer.train(corpus[:10000])
trainer.train(corpus)
print('训练完毕!')

如果批量不行,就单个

trained_txt

from chatterbot import ChatBot
from chatterbot.trainers import ListTrainer

corpus = []  # 加载的语料,一行问,一行答
# 导入语料库
# todo 训练完改为下一个文件
file = open('train_txt/train_before_53890.txt', 'r', encoding='utf-8')
print('开始加载语料!')
while 1:
    try:
        line = file.readline()
        print(line.strip('\n'))
        if not line:
            break
        corpus.append(line.strip('\n'))
    except:
        pass
file.close()
print(corpus)
print('语料加载完毕')
# 使用不同语料+同个数据库训练不会覆盖数据库原有数据
my_bot = ChatBot("wiki", database_uri='sqlite:///db.sqlite3')
print('Type something to begin...')
trainer = ListTrainer(my_bot)
print('开始训练!')
# trainer.train(corpus[:10000])
trainer.train(corpus)
print('训练完毕!')

# 测试
# text = input("You: ")
# res = my_bot.get_response(text)
# print(res)

使用flask作为服务器提供服务:

from chatterbot import ChatBot
# flask创建http接口
from flask import Flask, request, jsonify
from flask_cors import CORS

# 使用训练好保存了的数据
# 初始模型
my_bot = ChatBot("wiki", database_uri='sqlite:///db.sqlite3')
# flask
app = Flask(__name__)
CORS(app, resources=r'/*')  # 注册CORS, "/*" 允许访问所有api


# /api/wiki/q
@app.route("/api/wiki/<q>", methods=['get'])
def wiki_answer_path(q):
    res = str(my_bot.get_response(q))
    return jsonify({"res": res}), 200


# /api/wiki?q=xxx
@app.route("/api/wiki", methods=['get'])
def wiki_answer_query():
    # 获取路径参数 ?q=xxx
    q = request.args.get("q")
    res = str(my_bot.get_response(q))
    return jsonify({"res": res}), 200


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8181)

如果报错需要en,可以从这里下载

链接:https://pan.baidu.com/s/1urcaSqBz3nv2K73naGZV9A?pwd=5ino

补:打包...

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞鸟malred

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值