基于百度理解与交互技术实现机器问答

本文博客所在地址:基于百度理解与交互技术实现机器问答

AI系列网址:AI 系列 总目录

如果图片看不到,就直接去博客上看看,相对完整。

http://www.cnblogs.com/linbin524/p/8136799.html

一、前言

我们都知道现在聊天对话机器是一个很有意思的东西,比如说苹果siri,比如说微软的小冰。

聊天对话机器的应用场景也很广泛,比如说:银行的自助办卡机器人、展会讲解解说等等。


我们对机器人说句话,机器人从听取,到语义识别,认知转换,到最后调出我们所想要的东西,这个过程看似简单,其实内藏许多黑科技,让我们来一一解析一下。


1、我们对机器人说句话:我想看一下今天的天气?

技术实现:不论是语音、文字,机器首先要采集到我们的问题,语音还需要语音转换的一个过程,且内容转换结果必须准确,否则就有点像不同语言体系的人在对话,有种鸡同鸭讲的感觉,结果肯定也是一个大坑了。


2、语义识别

技术实现:通常这个阶段,已经将内容转换为一段文字,程序会对文字进行分词,结合关键字截取拼接语义(这里需要AI的训练)

3、认知转换

技术实现:上述的那就话中,今天是个关键词,天气是个关键词,  在训练库中需要提炼词槽,将可能语句尽可能提供给机器人


4、调用结果

当认知转换完成后,需要对关键词进行规则判断,比如说, 想看 + 今天+ 天气,组成时候,自动调用查询天气接口


上述的结果,更多需要我们对机器人进行训练,让它学习,要不然结果肯定不是那么友好的。



二、技术需求


通过文字输入问题,动态理解转化,识别内容,进行机器解答和语音提示。

PS:上述的需求基本可以理解为你叫机器人做一件事,机器人领悟,按照你的要求执行。

进阶:可以采用语音输入,转换为文字,之后的序列一样。(需要阵列麦克风)

三、技术选型

1、采用C# winform 作为程序主题

2、采用win7 TTS 作为语音朗读功能

3、采用百度理解交互技术 UNIT 作为识别基础


四、实现

1、新建winform 窗体




2、添加TTS,引用System.Speech




3、进行 语音朗读测试


SpeechSynthesizer voice = new SpeechSynthesizer(); //创建语音实例

voice.Rate = 2; //设置语速,[-10,10]

voice.Volume = 100; //设置音量,[0,100]

voice.SpeakAsync(“您好!”); //播放指定的字符串,这是异步朗读


PS:有些win7 系统TTS 有问题,需要自己百度查找,下载TTS 进行安装。目前上述支持中文,输入英文,只会念字母,因为需要朗读类别做转换,详细请百度speech 操作。



 4、结合百度理解与交互技术


百度提供的sdk 目前只支持android 和IOS,但有提供http API,所以笔者采用C#实现了。

先去官网注册成为百度开发者。


(1) 创建应用



 (2) 创建场景,场景编号是后面需要用到的




(3)新建单元,官方提供对话单元和问答单元,我们选择创建对话单元





(4)、对对话单元进行配置,新建词藻





新建词藻


 词藻词典有自定义的,也有系统的,本文中选择系统通用的。也可以下载自定义模板,写入自己的自定义词典




这个对话单元中,有文本回复和执行函数,我们这里选文本回复

触发的规则:会话规则中,上述的词藻已填充,那么文本内容才会出现



保存完成,后再次新建对话单元,主要说明介绍我们的公司






 跳转到数据中心,进行新建对话样本






 添加



 依法将公司介绍关键词添加


来的训练与验证板块

输入打开菜单,一开始输入,可能得到错误答案,你要 @UNIT 纠正意图与词槽,手动将关键词和意图、取词、词藻匹配上




 完成后的结果:



(1)、

配置基本参数


///

/// 理解与交互技术UNIT

///

public class ConfigUnit

{

///

/// Api key

///

public static String clientId = "";

// 百度云中开通对应服务应用的 Secret Key

public static String clientSecret = "";

//场景Id

public static string clientSceneId = "";

}

部分解析实体model

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace BaiduAIAPI.Model.UnitModel

{

public class UnitModel

{

public long log_id { get; set; }

public string error_code { get; set; }

public string error_msg { get; set; }

public UnitResult result { get; set; }

public bool IsSuccess { get; set; }

public string returnSay { get; set; }

}

public class UnitResult

{

public string session_id { get; set; }

public List action_list { get; set; }

public object schema { get; set; }

public object qu_res { get; set; }

}

public class UnitAction_list

{

public string action_id { get; set; }

public object action_type { get; set; }

public object arg_list { get; set; }

public object code_actions { get; set; }

public float confidence { get; set; }

public object exe_status { get; set; }

public string main_exe { get; set; }

public string say { get; set; }

public object hint_list { get; set; }

}

///

/// 其余的model 还没补充完整

///

public class UnitSchema {

}

}

错误信息定义


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace BaiduAIAPI.Type

{

public class BaiduUnitType

{

public static string GetErrorCodeToDescription(string errorCode)

{

string errorDecrition = "";

switch (errorCode)

{

case "1": errorDecrition = "服务器内部错误,请再次请求, 如果持续出现此类错误,请通过QQ群(224994340)联系技术支持团队。"; break;

case "2": errorDecrition = "服务暂不可用,请再次请求, 如果持续出现此类错误,请通过QQ群(224994340)或工单联系技术支持团队。"; break;

case "3": errorDecrition = "调用的API不存在,请检查后重新尝试。"; break;

case "4": errorDecrition = "集群超限额。"; break;

case "6": errorDecrition = "无权限访问该用户数据。"; break;

case "14": errorDecrition = "IAM鉴权失败,建议用户参照文档自查生成sign的方式是否正确,或换用控制台中ak sk的方式调用。"; break;

case "17": errorDecrition = "每天请求量超限额。"; break;

case "18": errorDecrition = "QPS超限额。"; break;

case "19": errorDecrition = "请求总量超限额。"; break;

case "100": errorDecrition = "无效的access_token参数,请检查后重新尝试。"; break;

case "110": errorDecrition = "access token无效。"; break;

case "111": errorDecrition = "access token过期。"; break;

case "282004": errorDecrition = "请求参数格式不正确。"; break;

case "282900": errorDecrition = "必传字段为空。"; break;

case "282901":

errorDecrition = "场景ID校验失败,请确认console中app和场景是否关联了:https://console.bce.baidu.com/ai/#/ai/unit/app/list。"; break;

case "282902":

errorDecrition = "UNIT环境启动中,请稍后再试;如果持续出现此类错误,请通过QQ群(224994340)联系技术支持团队。"; break;

case "282903":

errorDecrition = "UNIT系统异常;如果持续出现此类错误,请通过QQ群(224994340)联系技术支持团队。"; break;

case "282000": errorDecrition = "服务器内部错误,如果您使用的是高精度接口,报这个错误码的原因可能是您上传的图片中文字过多,识别超时导致的,建议您对图片进行切割后再识别,其他情况请再次请求, 如果持续出现此类错误,请通过QQ群(631977213)或工单联系技术支持团队。"; break;

default: errorDecrition = "未知的错误!"; break;

}

return errorDecrition;

}

}

}

封装的接口方法


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Web.UI.WebControls;

using AOP.Common;

using BaiduAIAPI.Model.UnitModel;

using BaiduAIAPI.Type;

namespace BaiduAIAPI.UNIT

{

public class UnderstandingAndInteractiveTechnology

{

// unit对话接口

public static UnitModel Unit_Utterance(string token, string sceneId, string query)

{

UnitModel result = new UnitModel();

#region 基础校验

string error = "";

if (string.IsNullOrWhiteSpace(token))

{

error += "token不能为空!";

}

if (string.IsNullOrWhiteSpace(sceneId))

{

error += "场景编号不能为空!";

}

if (string.IsNullOrWhiteSpace(query))

{

error += "询问问题不能为空!";

}

if (!string.IsNullOrWhiteSpace(error))

{

result.error_msg = error;

return result;

}

#endregion

string host = "https://aip.baidubce.com/rpc/2.0/solution/v1/unit_utterance?access_token=" + token;

string str = "{\"scene_id\":" + sceneId + ",\"query\":\"" + query + "\", \"session_id\":\"\"}"; // json格式

var tempResult = HttpRequestHelper.Post(host, str);

result=Json.ToObject(tempResult);

if (!string.IsNullOrWhiteSpace(result.error_code))

{

result.error_msg = BaiduUnitType.GetErrorCodeToDescription(result.error_code);

result.IsSuccess = false;

}

else

{

result.IsSuccess = true;

result.returnSay = result.result.action_list[0].say;

}

return result;

}

}

}

首先用单元测试结果:


using System;

using BaiduAIAPI;

using BaiduAIAPI.UNIT;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AIAPIUnitTestProject.BaiduAIAPI

{

[TestClass]

public class BaiduUnitTest

{

[TestMethod]

public void TestChat()

{

var accessTokenModel = Access_Token.GetAccessToken(ConfigUnit.clientId, ConfigUnit.clientSecret);

if (accessTokenModel.IsSuccess)

{

string queryString = "今天天气怎么样?";

var tempUnitResult = UnderstandingAndInteractiveTechnology.Unit_Utterance(accessTokenModel.SuccessModel.access_token, ConfigUnit.clientSceneId, queryString);


}

}

}

}

确定接口没有问题,结合到我们的Demo程序中,界面代码如下:


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Speech.Synthesis;

using BaiduAIAPI;

using BaiduAIAPI.UNIT;

using BaiduAIAPI.Model.UnitModel;

namespace SpeechDemo

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e)

{

if (tb_YourSay.Text.Trim() == "")

{

MessageBox.Show("请你输入你要说的话!");

return;

}

UnitModel result = new UnitModel();

var accessTokenModel = Access_Token.GetAccessToken(ConfigUnit.clientId, ConfigUnit.clientSecret);

if (accessTokenModel.IsSuccess)

{

string queryString = tb_YourSay.Text.Trim();

result = UnderstandingAndInteractiveTechnology.Unit_Utterance(accessTokenModel.SuccessModel.access_token, ConfigUnit.clientSceneId, queryString);

}

else

{

result.returnSay = result.error_msg;

}

tb_RobotSay.Text = result.returnSay;

SpeechSynthesizer voice = new SpeechSynthesizer(); //创建语音实例

voice.Rate = 2; //设置语速,[-10,10]

voice.Volume = 100; //设置音量,[0,100]

voice.SpeakAsync(result.returnSay); //播放指定的字符串,这是异步朗读

}

}

}

结果展示




评价

理解和交互需要做大量的对话样本和语言交互纠错,才可以实现相对比较精准的回答。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,628评论 18 139
  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa阅读 8,855评论 0 6
  • 傻子很少去网吧也从来没有玩过网络游戏,在网吧里看见很多人玩地下城与勇士,于是他也加入其中。傻子选了个神枪手的职业,...
    Inveteratepoiso阅读 394评论 2 2
  • 一个人死后来到天堂,上帝问他,你在人间生活得怎么样啊?这个人回答,非常好我很成功,有很好的事业、大房子、很多钱、车...
    何偀阅读 198评论 1 2
  • 2014年5月28日国家食品药品监督管理总局发布《互联网食品药品经营监督管理办法﹙征求意见稿﹚》,最近又有消息称近...
    6f36c3afafe7阅读 422评论 0 4