×

聊天机器人开源分享

消耗积分:2 | 格式:zip | 大小:0.00 MB | 2023-06-20

分享资料个

描述

是时候谈谈了。

我想我应该给这个它自己的特定帖子——这是我在我的RaspbinatorNvidinator项目中使用的聊天机器人。下面链接的 GitHub 将随着我对其进行改进而不断更新。

我已经决定了 Chatbot 8 这个名字——在我使用 GitHub 之前,我把它放在了我的 Google Drive 上,每次迭代我都会增加它的数量;我很高兴在 Raspbinator 中使用的第一个是第 8 次迭代,现在,这个名字有点卡住了。

主要目标:

  • 制作一个可以响应人类输入的机器人,随着时间的推移学习并返回更多有机响应。
  • 能够从大型文本文件(例如电影脚本和对话记录)中进行训练。
  • 使其能够轻松集成到其他项目中。

工作原理。

所以这是我的GitHub 上的代码

我已经让这些聊天机器人与Raspberry Pi项目一起工作——因此一切都将基于 Pi 和 Raspbian 操作系统。

有几个依赖项:

其他一切都应该包含在Raspbian上的 Python 包中

在较高层次上,系统的逻辑如下:

Bot 说最初的“你好”。
人类回应。
Bot 存储对“Hello”的响应,并在其数据库中搜索其之前所说的与人类输入的内容非常匹配的任何内容,然后显示先前交互的结果。

通过存储人类对机器人 Mongo 数据库的反应并将它们分配给机器人之前说过的事情,然后将人的输入与这些项目进行比较以找到合适的反应,您可以从机器人那里得到一些相当不错的反应。

举个例子; 如果机器人说“天气怎么样”并且我输入“外面正在下雨”,它会存储该响应并将其与该输入相关联。现在,如果其他人出现并输入“天气如何”,它将在其数据库中搜索相近的匹配项并找到之前的回复“天气怎么样”,此时它将搜索对此的回复并找到我的回复“它的外面在下雨”。因此,虽然它并没有真正“思考”它的反应,但它确实最终会给出一些合理的回复。

它将首先以相当高的准确度搜索已知输入,然后如果失败,它将降低到中等准确度,最后降低到低准确度。我目前正在使用 这个 库来比较字符串:

准确度级别为:

  • fuzz.ratio(Str1.lower(),Str2.lower())
  • fuzz.partial_ratio(Str1.lower(),Str2.lower())
  • fuzz.token_set_ratio(Str1,Str2)

您可以在我上面链接的网站上看到这些函数是如何工作的——但通常所需的准确性会随着函数的运行而降低。每个的阈值也可以调整。

因此,如果输入字符串/存储字符串的最高返回比率低于阈值,它将下降到第二个部分匹配并执行相同的操作,最后如果失败;它将移动到设定的比率匹配。最后一个适用于具有匹配单词的不同大小的字符串。

现在如果上面没有匹配项会发生什么?在机器人响应之前,它会将收到的输入存储到数据库中,它还会拆分每个输入并存储所有单个单词。因此,当它找不到之前对您的输入的回复时,它有 40% 的机会从这些词中生成一个随机句子,并有 60% 的机会选择一个它知道的完全随机的完整句子。

现在你可能会认为这会导致机器人说很多废话——你是对的,但一开始它只会在你和它说话时重复你说的话。但是你输入和回复的越多,它学到的越多,它生成的随机句子有时实际上有一定的意义;当你回复它时,它就会有一个参考点,用于确定它何时收到类似于它刚才所说的输入。

这是另一个例子:

如果我对机器人说:“我喜欢奶酪”,它的数据库中没有任何输入信息,也没有足够的词来生成一个随机句子,基本上是一个猜测,它可能会返回:“Hello television like usually”。这当然没有意义,但如果我随后回复“是的,我也喜欢电视”,它会存储该回复。现在,比方说,其他人出现并输入“我通常看电视”,它会在数据库中运行它并找到它与之前所说的相似(“你好电视就像通常一样”)并找到我的回答(“是的,我喜欢电视也是”),给人一种真实反应的错觉。

它本质上是从头开始学习,它什么都不知道,所以它会尽力使用以前的经验,作为最后的手段,猜测——直到它学到更多,这样它就不必再猜测了。

它还能够与多人保持对话——为与之交谈的每个人创建一个新班级,并记录他们与机器人的最后回应。因此,当您使用“change_name”命令或通过从外部程序向对话功能输入不同的名称来切换人员时,它可以与在该会话中已经与之交谈过的人进行对话。

模块化的。

最近,我添加了将聊天机器人导入其他程序的功能,并且能够从机器人获取文本输入和接收输出——具有一个简单的界面,只需要一个带名称的输入字符串。然后机器人本身会处理之前的回复和机器人响应;随着对话切换并返回响应。

它还可以独立运行以进行测试,即使作为另一个项目的组件也可以轻松进行训练和测试——例如与Nvidianator的 STT/TTS 和 ML 部分集成

要使用它,只需将 bot .py 文件放在与它将使用的程序相同的文件夹中并使用:

将 bot_8 导入为聊天机器人

一旦导入到 Python 程序中,它就可以与命令交互:

回复 = chatbot.conversation(inputWords,humanid)

输入的单词当然就是输入的内容,因此这可以从语音到文本功能(例如wit.ai 或其他一些文本输入)中获取。

humanid 是当前与之交互的人的名字。

将这两个输入都放入函数后,它将以字符串形式返回回复——然后可用于在导入聊天机器人的程序中进行进一步处理。

训练。

我还添加了一个训练模块——这可以很方便地加载大型文本文件,例如电影剧本或对话记录,这样机器人就可以在现有数据上进行训练——我已经用合金装备的脚本试过了它工作得很好。

它通过扫描每一行并将数据放入机器人来工作——当每一行新行进入机器人代码时,都会将其分配为对前一行的响应。

它被编程为过滤掉以非字母字符开头的空行和句子,以及以“:”分割行;因此,如果一个脚本的名字表示谁在说话,并且有各种注释,应该跳过这些行并删除名字。虽然目前这有点混乱并且可以做一些工作,但这基本上意味着你可以插入一个脚本并且它(应该)整齐地通过它,只选择相关的语音文本。

通过在脚本上训练机器人,您可以输入来自游戏/电影/对话的输入,它会非常可靠地返回正确的响应——就上面的《合金装备》脚本而言,您可以通过输入角色所说的话。

例如,使用上述 MGS 训练数据:

  • 如果我输入“你是菜鸟吗?”
  • 机器人用 Meryl 的一句话回应:“小心,我不是菜鸟!!”

等等。

可以使用开关“-fresh”调用训练模块,这将清除数据库并从头开始训练,如果没有此开关,它将进一步训练现有数据库。

训练数据需要与机器人位于同一文件夹中,并称为“learning.txt”。

还有一个 deleteDB 模块,当它运行时,它按照它说的去做并清除数据库。

从理论上讲,如果它接受大量正常人类对话的训练,它会返回大量有机反应;此外,根据他们接受的培训输入,每个机器人都可以有自己独特的个性。

正在进行中。

随着时间的推移,我将继续改进它以使其变得更好。因此,请继续检查我的 GitHub 以获取更新。

我也在努力让聊天机器人与Docker打包在一起 ——这样它就可以很容易地与所有依赖项一起部署,并且在同一台机器上也有单独的持久机器人,甚至不需要在操作系统本身上安装 MongoDB。

您有任何改进机器人的想法吗?让我知道。

也可以随意下载并自己尝试——请注意,从空白开始,在它开始变得有意义之前需要大量的训练数据/与之交谈。

下个项目见。

 
poYBAGOo5Q-AErUdAABVisbHvsM916.png
 

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'聊天机器人开源分享',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);