资讯专栏INFORMATION COLUMN

微信公号DIY:训练微信聊天机器人&公号变身图片上传工具

anonymoussf / 984人阅读

摘要:使用图灵机器人训练之前在对比聊天机器人实现方案的时候,我试用过图灵机器人,他们号称中文语境下智能渡最高的机器人大脑。

上一篇 一小时搭建微信聊天机器人 介绍了如何搭建一个可用的聊天机器人,但是和机器人聊完你会发现,聊天机器人实在是太傻了,来回就那么几句。这是因为我们给聊天机器人的数据太少,他只能在我们给的训练集中找它认为最合适的。那么,如何导入更多的训练数据呢?
我能想到最简单的方法是找对话的数据,然后把这些数据作为训练数据训练机器人。

感谢 candlewill 已经收集好了大量的训练数据,dialog_corpus https://github.com/candlewill/Dialog_Corpus 。

这个库中包含电影台词、中英文短信息、自然语言处理相关的数据集、小黄鸡语料等。这里我选择电影台词语料。

语料地址为:dgk_lost_conv:https://github.com/rustch3n/dgk_lost_conv

chatterbot 训练逻辑处理模块

这个模块提供训练机器人的方法,chatterbot自带了通过输入list来训练(["你好", "你好啊"] 后者是前者的回答)以及通过导入Corpus格式文件来训练的方式。

这里我们选择使用第一种,通过输入list来训练机器人。

处理训练数据

首先下载数据集:

wget https://codeload.github.com/rustch3n/dgk_lost_conv/zip/master
# 解压
$ unzip dgk_lost_conv-master.zip

我们先打开一个文件看下数据结构:

E
M 你得想想办法 我弟弟是无辜的
M 他可是美国公民啊
M 对此我也无能为力
M 你当然能
M 再去犯罪现场看看 定能证实清白
M 你看 我不过是个夜间办事员而已
M 你若真想解决问题
M 最好等领事来
M 他早上才上班
M 我很抱歉
E
M 那我自己来搞定
M 你兄弟
M 关在哪个监狱?
M 索纳监狱
E
M 怎么了?
M 那里关的都是最穷凶极恶的罪犯
M 别的监狱都不收

.conv 语料文件中:E 是分隔符 M 表示会话。因为我是使用输入list 的方式训练数据,这时我可以以分隔符E为分隔,将一段对话放入一个list中,那么上述例子中的训练数据应该被格式化为:

convs = [
    [
       "你得想想办法 我弟弟是无辜的",
       "他可是美国公民啊",
       "对此我也无能为力",
       "你当然能",
       "再去犯罪现场看看 定能证实清白",
       "你看 我不过是个夜间办事员而已",
       "你若真想解决问题",
       "最好等领事来",
       "他早上才上班",
       "我很抱歉"
    ],
    [
       "那我自己来搞定",
       "你兄弟",
       "关在哪个监狱?",
       "索纳监狱",
    ],
    [
       "怎么了?",
       "那里关的都是最穷凶极恶的罪犯",
       "别的监狱都不收",
    ]
]

导入训练数据的脚本如下:

from chatterbot import ChatBot
from chatterbot.trainers import ListTrainer

# 初始化聊天机器人
momo = ChatBot(
    "Momo",
    storage_adapter="chatterbot.storage.MongoDatabaseAdapter", # 使用mongo存储数据
    logic_adapters=[ # 指定逻辑处理模块
            "chatterbot.logic.BestMatch",
            "chatterbot.logic.MathematicalEvaluation",
            "chatterbot.logic.TimeLogicAdapter",
        ],
    input_adapter="chatterbot.input.VariableInputTypeAdapter",
    output_adapter="chatterbot.output.OutputAdapter",
    database="chatterbot", # 指定数据库
    read_only=True
)

# 读取.conv 数据文件,因为我服务器配置较低,所以选择了一个内容较少的文件
# 这个函数是一个生成器
def read_conv(filename="prisonb.conv"):
    with open(filename, "rt") as f:
        conv = []
        # 逐行读取
        for line in f:
            _line = line.replace("
", "").strip()  # 预处理字符串 去掉首位空格
            if _line == "E":  # 如果是分隔符 表示对话结束 返回对话列表
                yield conv
                conv = []  # 重置对话列表
            else:  # 不是分隔符则将内容加入对话列表
                c = _line.split()[-1]  # 其实这里如果对话中包含空格 对话数据会不完整,应该只去掉M和开头的空格
                conv.append(c)


def traine_momo():
    for conv in read_conv():
        print(conv)
        momo.set_trainer(ListTrainer) # 指定训练方式
        momo.train(conv) # 训练数据


def main():
    traine_momo()


if __name__ == "__main__":
    main()

这个脚本比较简单,只是简单的将数据从对话文件中读取出来,然后拼接为对话列表输入聊天机器人。

由于这里对话大部分都是多行数据,聊天机器人匹配结果时运算量会大幅提升,我单核cpu的服务器在导入一个700k 的语料文件后每次聊天都会让cpu飚到100%!?‍ 无奈之下只能删掉大半数据。

对话示例如图:

导入电影台词后,虽然训练数据大幅提升,但是你会发现聊天机器人开始答非所问了,这是因为聊天数据噪音太大,对白也有点问题。

使用图灵机器人训练

之前在对比聊天机器人实现方案的时候,我试用过 图灵机器人,他们号称中文语境下智能渡最高的机器人大脑。他们的对话比我自己的搭建的靠谱很多,那么我们是不是可以利用一下他的数据呢?

我的方案是这样的,在图灵机器人新建两个机器人教练A 和 教练B,让两个机器人互相对话,然后把训练数据导入chatterbot。

打开 http://www.tuling123.com,注册账号

新建两个机器人(免费用户最多可以创建5个,每个机器人每天最多请求5000次)

调用对话API,让两个机器人互相聊天

建好机器人后的界面:

训练示例代码如下:

# tuling_trainer.py
import sys
from time import sleep

from chatterbot import ChatBot
from chatterbot.trainers import ListTrainer

import requests

API_URL = "http://www.tuling123.com/openapi/api"
API_KEY0 = ""  # 机器人1 的key
API_KEY1 = ""  # 机器人2 的key

# 初始化chatterbot
momo = ChatBot(
    "Momo",
    storage_adapter="chatterbot.storage.MongoDatabaseAdapter",
    logic_adapters=[
            "chatterbot.logic.BestMatch",
            "chatterbot.logic.MathematicalEvaluation",
            "chatterbot.logic.TimeLogicAdapter",
        ],
    input_adapter="chatterbot.input.VariableInputTypeAdapter",
    output_adapter="chatterbot.output.OutputAdapter",
    database="chatterbot",
    read_only=True
)

# 请求图灵机器人接口
def ask(question, key, name):
    params = {
        "key": key,
        "userid": name,
        "info": question,
    }
    res = requests.post(API_URL, json=params)
    result = res.json()
    answer = result.get("text")
    return answer


def A(bsay):
    # 打印 A 和 B 的对话内容
    print("B:", bsay)
    answer = ask(bsay, API_KEY0, "momo123")
    print("A:", answer)
    return answer


def B(asay):
    print("A:", asay)
    answer = ask(asay, API_KEY1, "momo456")
    print("B", answer)
    return answer


def tariner(asay):
    momo.set_trainer(ListTrainer)  # 设置处理方式
    while True:  # 两个机器人训练的主循环
        conv = []
        conv.append(asay) # 先把 A 说的第一句加入到对话列表
        bsay = B(asay)  # A 先问 B
        conv.append(bsay) # 将B 的回答加入到对话列表
        momo.train(conv) # 将对话用于训练
        print(conv)
        conv = []
        conv.append(bsay) # 用B的对话 去问 A 步骤和上述方式一致
        asay = A(bsay)
        conv.append(asay)
        momo.train(conv)
        print(conv)
        sleep(5)  # 控制频率


def main(asay):
    tariner(asay)


if __name__ == "__main__":
    main(*sys.argv[1:])  # 接收参数作为开始的第一句话
    
# 执行脚本
# python tuling_trainer.py 你好?

使用图灵聊天机器人训练的时候是需要监测的,因为如果两个机器人说的内容一样的时候,机器人可能会一直重复同一句话,直到调用次数耗尽,你需要看一下两个机器人的对话是否陷入了僵局。

当然也可以在程序中加入判断,先多设定几个开始打招呼的句子,如果一句话连续出现多次的时候,换下一个句子纠正他们。

以下是我训练了两天之后的结果:

虽然还是答非所问,但是已经比之前像样了。

图灵聊天机器人免费版每天可调用5000 次,如果觉得次数太少可以多新建几个轮流使用

聊天机器人的配置及训练方式就到这里了,接下来介绍个更实用的功能,如何让微信公号变成图床。

如何让微信公号化身图片上传助手

在使用 markdown 格式来写文章的过程中,发现图片地址是一个比较麻烦的事情,每次贴图获取图片URL都是一个比较麻烦的过程。
以我使用的七牛为例,获取图片地址的步骤如下:

登录七牛网站,打开存储空间>内容管理

上传文件

返回内容管理找到刚才上传的文件,获取外链

按照这个步骤上传一张图片至少耗时半分钟。

那能不能简化这个步骤呢?

答案是可以!

微信公号是可以发送图片消息的,我的做法是

将图片发送到公号

服务器获取触发图片消息的处理逻辑> 将图片使用七牛提供的第三方资源抓取API另存到,七牛存储空间

将设定好的图片地址返回给微信,发送到公号消息对话中

示例如下图所示:

实现步骤

注册个七牛账号

新建存储空间

在个人中心秘钥管理获取 AccessKey 和 SecreKey

pip install qiniu

代码实现如下:

# media.py
# 图片抓取逻辑处理
from qiniu import Auth, BucketManager

from momo.settings import Config

def qiniu_auth():
    access_key = str(Config.QINIU_ACCESS_TOKEN)
    secret_key = str(Config.QINIU_SECRET_TOKEN)
    auth = Auth(access_key, secret_key)
    return auth
    
def media_fetch(media_url, media_id):
    """抓取url的资源存储在库"""
    auth = qiniu_auth()
    bucket = BucketManager(auth)
    bucket_name = Config.QINIU_BUCKET  # 存储空间名称
    ret, info = bucket.fetch(media_url, bucket_name, media_id) # 参数依次是第三方图片地址,空间名称,目标文件名
    if info.status_code == 200:
        return True, media_id # 如果上传成功,返回文件名
    return False, None

抓取第三方图片文档地址为:第三方资源抓取 https://developer.qiniu.com/kodo/api/1263/fetch。

微信图片消息处理逻辑代码:

class WXResponse(_WXResponse):

    def _image_msg_handler(self):
        media_id = self.data["MediaId"]
        picurl = None
        if not picurl:
            picurl = self.data["PicUrl"]  # 从消息中获取图片地址
        is_succeed, media_key = media_fetch(picurl, media_id) # 使用图片抓取接口将图片存储到七牛并获取图片文件名
        if is_succeed:
            qiniu_url = "{host}/{key}".format(host=Config.QINIU_HOST, key=media_key) # 拼接图片地址
        else:
            qiniu_url = "图片上传失败,请重新上传"
        self.reply_params["content"] = qiniu_url # 返回图片地址
        self.reply = TextReply(**self.reply_params).render()

代码已开源道github,详细代码逻辑参考 gusibi/momo: https://github.com/gusibi/momo/tree/chatterbot

欢迎试用体验:

请不要上传高清图片,微信会压缩损坏图片质量

也不要上传太个人的图片,毕竟内容我能看到

总结

这一篇主要提供了两个训练 chatterbot 的思路,以及使用公号作为图片上传客户端提高上传图片的效率的解决方法。
接下来公号还是继续开发,准备给公号加一个记账功能,促使自己养成记账的习惯。

预告

下一篇的公号DIY 将介绍 记账的功能设计以及实现思路


最后,感谢女朋友支持。

欢迎关注(April_Louisa) 请我喝芬达

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38702.html

相关文章

  • 微信公号DIY:MongoDB 简易ORM & 公号记账数据库设计

    摘要:然后又介绍了基于的公号账本应用的数据库设计。欢迎关注公号四月试用。 前两篇 微信公号DIY 系列: 微信公号DIY:一小时搭建微信聊天机器人 微信公号DIY:训练聊天机器人&公号变身图片上传工具 介绍了如何使用搭建&训练聊天机器人以及让公号支持图片上传到七牛,把公号变成一个七牛图片上传客户端。这一篇将继续开发公号,让公号变成一个更加实用的工具账本(理财从记账开始)。 代码: 项目代...

    fobnn 评论0 收藏0
  • 微信公号DIY:MongoDB 简易ORM & 公号记账数据库设计

    摘要:然后又介绍了基于的公号账本应用的数据库设计。欢迎关注公号四月试用。 前两篇 微信公号DIY 系列: 微信公号DIY:一小时搭建微信聊天机器人 微信公号DIY:训练聊天机器人&公号变身图片上传工具 介绍了如何使用搭建&训练聊天机器人以及让公号支持图片上传到七牛,把公号变成一个七牛图片上传客户端。这一篇将继续开发公号,让公号变成一个更加实用的工具账本(理财从记账开始)。 代码: 项目代...

    Backache 评论0 收藏0
  • 微信公号DIY:MongoDB 简易ORM & 公号记账数据库设计

    摘要:然后又介绍了基于的公号账本应用的数据库设计。欢迎关注公号四月试用。 前两篇 微信公号DIY 系列: 微信公号DIY:一小时搭建微信聊天机器人 微信公号DIY:训练聊天机器人&公号变身图片上传工具 介绍了如何使用搭建&训练聊天机器人以及让公号支持图片上传到七牛,把公号变成一个七牛图片上传客户端。这一篇将继续开发公号,让公号变成一个更加实用的工具账本(理财从记账开始)。 代码: 项目代...

    DoINsiSt 评论0 收藏0
  • 微信公号DIY:一小时搭建微信聊天器人

    摘要:最近借用了女朋友的公号,感觉如果只是用来发文章,太浪费微信给提供的这些功能了。想了想,先从最简单的开始,做一个聊天机器人吧。是一款接口的,基于一系列规则和机器学习算法完成的聊天机器人。 最近借用了女朋友的公号,感觉如果只是用来发文章,太浪费微信给提供的这些功能了。想了想,先从最简单的开始,做一个聊天机器人吧。 使用Python实现聊天机器人的方案有多种:AIML、chatterBot以...

    source 评论0 收藏0
  • 微信公号生成便签

    摘要:具体差异可以使用源码测试一下还是有问题优化完图片生成速度后,发现在长文本状态下,公号还是会超时报错。经过检查发现是图片上传到公众平台太慢了服务器只有带宽,没有办法。 最近有文字转图片的需求,但是不太想下载 APP,就使用 Python Pillow 实现了一个,效果如下: showImg(https://segmentfault.com/img/remote/1460000015565...

    Near_Li 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<