自然语言处理-实际开发:用语义开放平台olami写一个翻译的应用

原创 2017年07月04日 14:51:24

自然语言处理-实际开发

一个可以识别自然语言的翻译应用

-----------------------------------------------------------------------------

必不可少的开发环境

Eclipse4.5+JDK1.7+WindowBuilder插件

其他资源

语义平台:OLAMI


1.界面及使用

这里介绍一下页面。
整体分为三个部分,最上面的是对话框,中间的是回答框,最下面的比较大的显示的是从语义平台取得的语义数据。



使用方式:把需要理解的语句输入到对话框中,点击发送,就可以得到结果。



返回结果:




2.代码简介

这里先整体简单介绍一下。



NLPJSON.java 里面是拿到语义返回JSON数据的关键字;
APIJSON.java 里面是拿到翻译返回JSON数据的关键字。
ApiLanguage.java 里面是翻译API接口需要的各国语言的缩写;
Encrypt.java 功能是加密字符串,里面只有MD5加密的方法;
Format.java 功能是整理JSON内容,用于输出;
GetModifier.java 功能是从OLAMI提供的API接口拿到语义;
HttpRequestUtils.java 功能是发送HTTP请求,获得HTTP返回的数据;
MainWindow.java 是主程序,做的是窗口的建立和主流程的控制;
ModifierProcess.java 功能是处理语义;
TranslateByAPI.java 功能是从翻译API接口拿到翻译的结果;

3.核心代码

3.1 MainWindows.java

		Button btnNewButton = new Button(translateShell, SWT.NONE);
		translateShell.setDefaultButton(btnNewButton);
		btnNewButton.setLocation(319, 91);
		btnNewButton.setSize(80, 27);
		btnNewButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				NLPText.setText("");
				String src = inputText.getText();
				if (src == null || src.length() == 0) {
					answerText.setText("你还没有输入内容!");
					return;
				}
				
				// 把string用接口拿到语义
				JSONObject nlp = GetModifier.GetNLI(src);
				NLPText.setText(Format.formatJson(nlp.toString()));

				// 处理语义
				String answer = ModifierProcess.NLPProcess(nlp);
				answerText.setText(answer);
				
				if (errorFlag == 1) {
					answerText.setText(errorMessage);
				} else if (errorFlag == 2) {
					answerText.setText("遇到了错误,但这不是我的锅!");
				}
				
				resetError();

			}
		});
		btnNewButton.setText("发送");

这里是主程序的处理流程,发送按钮做了监听。
先处理输入内容,然后把内容发送到语义平台拿到语义,然后去处理语义,输出结果。

3.2 GetModifier.java

	protected static JSONObject GetNLI(String src) {
		JSONObject data = new JSONObject();
		data.put("input_type", 1);
		data.put("text", src);
		
		JSONObject send = new JSONObject();
		send.put("data_type", "stt");
		send.put("data", data);
		// 时间戳
		long timestamp = new Timestamp(System.currentTimeMillis()).getTime();
		
		// 签名
		String sign = appSecret + "api=" + api + "appkey=" + appKey + "timestamp=" + timestamp + appSecret;
		sign = Encrypt.MD5(sign);
		
		// 参数
		Map<String, String> post_data = new HashMap<String, String>();
		post_data.put("appkey", appKey);
		post_data.put("api", api);
		post_data.put("timestamp", String.valueOf(timestamp));
		post_data.put("sign", sign);
		post_data.put("rq", send.toString());
		post_data.put("cusid", cusid);

		return HttpRequestUtils.httpPost(apiUrl, post_data);
	}

3.3 ModifierProcess.java

	protected static String NLPProcess(JSONObject nlpJson) {
		String status = nlpJson.getString(NLPJSON.JSON_STATUS);
		if (status == null || !NLPJSON.STATUS_OK.equalsIgnoreCase(status)) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		// Get info from JSON
		String result = "";
		String modifier = null;
		String src_language = null;
		String dst_language = null;
		String src_code = null;
		String dst_code = null;
		String content = null;
		String resultLanguage = null;
		
		try {
			JSONObject nli = nlpJson.getJSONObject(NLPJSON.JSON_DATA).getJSONArray(NLPJSON.DATA_NLI).getJSONObject(0);
			JSONObject descobj = nli.getJSONObject(NLPJSON.NLI_DESCOBJ);
			if (!"0".equals(descobj.getString(NLPJSON.DESCOBJ_STATUS))) {
				MainWindow.setErrorFlag(1);
				MainWindow.setErrorMessage(descobj.getString(NLPJSON.DESCOBJ_RESULT));
				return "";
			}
			JSONObject semantic = nli.getJSONArray(NLPJSON.NLI_SEMANTIC).getJSONObject(0);
			modifier = semantic.getJSONArray(NLPJSON.SEMANTIC_MODIFIER).getString(0);
			
			JSONArray slotsArray = semantic.getJSONArray(NLPJSON.SEMANTIC_SLOTS);
			if (slotsArray != null && slotsArray.size() > 0) {
				Map<String, String> slotsMap = new HashMap<String, String>();
				for (int i = 0; i < slotsArray.size(); i++) {
					JSONObject slots = slotsArray.getJSONObject(i);
					String name = slots.getString(NLPJSON.SLOTS_NAME);
					String value = slots.getString(NLPJSON.SLOTS_VALUE);
					slotsMap.put(name, value);
				}
				
				src_language = slotsMap.get(NLPJSON.S_SRCLANGUAGE);
				dst_language = slotsMap.get(NLPJSON.S_DSTLANGUAGE);
				content = slotsMap.get(NLPJSON.S_CONTENT);
			}
			
		} catch (Exception e) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		// Process the info
		if (modifier == null || modifier.length() < 1) {
			MainWindow.setErrorFlag(2);
			return "";
		}// 问能力
		if (modifier.equalsIgnoreCase(NLPJSON.M_CAN)) {
			if (dst_language != null && dst_language.length() > 0) {
				String language = ApiLanguage.language.get(dst_language);
				if (language != null && language.length() > 0) {
					MainWindow.resetLastLanguage();
					MainWindow.setLastDstLanguage(dst_language);
					result = "没问题!";
					return result;
				}
				result = "我还不懂" + dst_language + ",但我会慢慢学习的!";
				return result;
			}
			result = "我可以翻译,问我吧,但最好不要太难哟!";
			return result;
		} else if (modifier.equalsIgnoreCase(NLPJSON.M_CANDOWHICH)) { // 问能翻译多少种语言
			// map.keyset get 5 languages
			Set<String> set = ApiLanguage.language.keySet();
			set.remove(ApiLanguage.AUTO);
			String[] language = set.toArray(new String[set.size()]);
			int start = 0;
			for (int i = 0; i < outputLanguageNumber; i++) {
				Random random = new Random();
				start += random.nextInt(language.length - outputLanguageNumber + i - start) + 1;
				result += language[start] + "、";
			}
			MainWindow.resetLastLanguage();
			result = "我会翻译" + result.substring(0, result.length() - 1) + "...还有好多种语言!";
			return result;
		} else if (modifier.equalsIgnoreCase(NLPJSON.M_TRANSLATE)) { // 翻译内容
			// If content exist, get languages, translate it by translateApi
			if (content != null && content.length() > 0) {
				if (src_language == null || src_language.length() == 0) {
					String lastSrcLanguage = MainWindow.getLastSrcLanguage();
					if (lastSrcLanguage == null || lastSrcLanguage.length() == 0) {
						src_code = ApiLanguage.language.get(ApiLanguage.AUTO);
					} else {
						src_code = ApiLanguage.language.get(lastSrcLanguage);
					}
				} else {
					src_code = ApiLanguage.language.get(src_language);
					if (src_code == null || src_code.length() == 0) {
						result = "我还没有学会" + src_language + ",等我学会之后你再问我吧!";
						return result;
					}
				}
				if (dst_language == null || dst_language.length() == 0) {
					String lastDstLanguage = MainWindow.getLastDstLanguage();
					if (lastDstLanguage == null || lastDstLanguage.length() == 0) {
						dst_code = ApiLanguage.language.get(ApiLanguage.ENGLISH);
						resultLanguage = ApiLanguage.ENGLISH;
					} else {
						dst_code = ApiLanguage.language.get(lastDstLanguage);
						resultLanguage = lastDstLanguage;
					}
				} else {
					dst_code = ApiLanguage.language.get(dst_language);
					resultLanguage = dst_language;
					if (dst_code == null || dst_code.length() == 0) {
						result = "我还没有学会" + dst_language + ",等我学会之后你再问我吧!";
						return result;
					}
				}

				MainWindow.setLastSrcLanguage(src_language);
				MainWindow.setLastDstLanguage(dst_language);
				
				String transResult = TranslateByAPI.translateProcess(content, src_code, dst_code);
				if (transResult.equals(content)) {
					dst_code = ApiLanguage.language.get(ApiLanguage.CHINESE);
					resultLanguage = ApiLanguage.CHINESE;
					transResult = TranslateByAPI.translateProcess(content, src_code, dst_code);
				}
				if ("".equals(transResult)) {
					return "";
				}
				
				result = "【" + content + "】翻译成" + resultLanguage + "的结果是【" + transResult + "】";
				return result;
			} else {
				if (src_language != null && src_language.length() > 0 && dst_language != null && dst_language.length() > 0) {
					MainWindow.setLastSrcLanguage(src_language);
					MainWindow.setLastDstLanguage(dst_language);
				}
				result = "你说,我来翻译!";
				return result;
			}

		}
		// 前面没有处理,设置错误标志
		MainWindow.setErrorFlag(2);
		return result;
	}

从语义数据拿到语义信息,然后判断返回的modifier和slot内容作出处理。

3.4 TranslateByAPI.java

	protected static String translateProcess(String src, String from, String to) {
		
		if (src == null || src.length() == 0) {
			MainWindow.setErrorFlag(2);
			return "";
		} else if (src.length() > 1500) {
			MainWindow.setErrorFlag(1);
			MainWindow.setErrorMessage("翻译的文字太多了!");
			return "";
		}
		if (from == null) {
			MainWindow.setErrorFlag(1);
			MainWindow.setErrorMessage("输入的文字看不懂啊!");
			return "";
		}
		if (to == null) {
			MainWindow.setErrorFlag(1);
			MainWindow.setErrorMessage("我还不会你想要的语言!");
			return "";
		}
		
		int salt = new Random().nextInt(10000);
		// 签名
		String sign = Encrypt.MD5(APPID + src + salt + key);
		if (sign == "") {
			return "";
		}
		
		Map<String, String> params = new HashMap<String, String>();
		
		params.put("appid", APPID);
		params.put("salt", String.valueOf(salt));
		params.put("sign", sign);
		params.put("from", from);
		params.put("to", to);
		params.put("q", src);

		JSONObject translate = HttpRequestUtils.httpPost(apiUrl, params);
		
		String errorCode = translate.getString(APIJSON.ERROR);
		if (errorCode != null && errorCode.length() > 0) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		JSONObject transResult = null;
		try {
			transResult = translate.getJSONArray(APIJSON.TRANS_RESULT).getJSONObject(0);
		} catch (Exception e) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		if (transResult == null) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		String result = transResult.getString(APIJSON.RESULT_DST);
		
		if (result == null) {
			MainWindow.setErrorFlag(2);
			return "";
		}
		
		return result;
		
	}
通过翻译API来翻译内容。API的调用方法大同小异。

到此为止,翻译工作就完成了。

4.总结

总体来说,功能简单,代码简单,但是能做到的事情就很强大,总体还是归功于语义开放平台的语义解析。

其他说明

GetModifier.java 里面所使用到的调用语义API接口的关键信息,开发者需自行在OLAMI官网注册生成并更换,这样开发者可以自己定义所需的语法。
TranslateByAPI.java 里所使用到的调用翻译API接口的关键信息,开发者也需自行更换。目前某度的翻译API处于量小免费量大收费的模式,开发者使用的话还是不用担心超出免费额度的情况。但是如果发现有被乱用的现象,作者将关闭翻译API的接口。

语义开放平台

1.注册登陆OLAMI官网
2.点击账号出现下拉菜单,点击“NLI系统”进入语法编辑系统(可以选择导入已有的模块,也可以创建模块自定义语法);
3.导入translate语义模块;
4.进入语义模块,点击“发布”进入发布页面,点击“发布”按钮,启用刚才导入的语法;
5.回到官网,点击账号出现菜单,点击“应用管理”,进入应用管理页面,点击“创建新应用”,新建一个应用;
6.配置应用,点击“配置模块”,勾选模块,选择这个应用需要支持的模块,第一个选项卡是自定义的模块,第二个选项卡是系统自带模块;
7.“查看Key”可以查询使用API调用应用所需要的key,“测试”可以测试应用的语法。
更多的文档可以参照OLAMI文档中心

最后

这里只是做了一个可以运行的demo。如果说能把这些功能整合到个人网站,或者公众号、微信小程序之中,就能极大的提高逼格。
有其他的问题可以联系作者。



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011211290/article/details/74330469

自然语言处理-实际开发:用语义开放平台olami写一个翻译的应用

自然语言处理-实际开发 一个可以识别自然语言的翻译应用
  • u011211290
  • u011211290
  • 2017-07-04 14:51:24
  • 1315

开发者实验室体验之文智自然语言处理SDK by python

1. 前言2. 实验2.1 实验准备新手可以去文智管理平台领取5万次新手礼包,并创建一个新的API的公钥和私钥。(果然是腾讯,连这个都成为新手礼包……游戏玩多了吧。)2.2 创建工作目录在根目录下创建...
  • qq_35082030
  • qq_35082030
  • 2017-08-02 22:50:33
  • 818

olami开放平台语法(grammar)编写简介

olami开发平台网址:https://cn.olami.ai/open/website/home/home_show 下面简单介绍下怎么在olami开放平台编写语法。1.登录主页注册账户后,需要创...
  • ls0609
  • ls0609
  • 2017-05-11 13:47:55
  • 1078

用Kotlin开发android平台语音识别,语义理解应用(olamisdk)

本文使用Kotlin开发android平台的一个语音识别方面的应用,用的是欧拉密开放平台olamisdk。1.Kotlin简介Kotlin是由JetBrains创建的基于JVM的编程语言,Intell...
  • ls0609
  • ls0609
  • 2017-07-13 17:04:12
  • 2755

五个非常实用的自然语言处理资源

摘要: 正在学习NLP,手中没有资源?快来看看这些免费的NLP学习资源吧!如果你对自然语言处理方面的资源感兴趣,请仔细阅读本篇文章。运行数据科学POC的7个步骤网上有很多依靠深度学习方法的NLP资源,...
  • yunqiinsight
  • yunqiinsight
  • 2018-03-27 14:35:22
  • 46

机器翻译需要的软件 自然语言处理专业所涉及的软件

、第一个开源的统计机器翻译工具包——Egypt 如前所述,Egypt是在1999年约翰霍普金斯大学统计机器翻译夏季讨论班上,由一些研究人员共同合作开发的统计机器翻译工具包。它包括4个模块: ...
  • u013736042
  • u013736042
  • 2014-08-03 20:36:27
  • 1593

基于OLAMI平台的语义理解微信小程序开发

基于OLAMI平台开发识别自然语言的微信小程序“寂无free” 微信小程序功能如下: 查询手机系统信息 查询手机网络状态 查询天气等各种实用功能 查询快递物流信息 因为课程设计的需要,做了一...
  • Albert_Bolt
  • Albert_Bolt
  • 2018-01-05 13:53:32
  • 198

Olami智能语义解析—学习娱乐小能手

一款用JTabbedPane选项卡实现的实例,其功能有:笑话、新闻、星座运势、成语、解梦。询问不同领域的问题,自动切换至对应的选项卡来输出答案。用到的技术主要有:javax.swing.JFrame,...
  • u011827504
  • u011827504
  • 2017-07-18 12:12:10
  • 503

Java开发、网络爬虫、自然语言处理、数据挖掘简介

一、java开发 (1) 应用开发,即Java SE开发,不属于java的优势所在,所以市场占有率很低,前途也不被看好。 (2) web开发,即Java Web开发,主要是基于自有或第三方成熟框...
  • kl28978113
  • kl28978113
  • 2016-09-09 18:35:53
  • 1028

自然语言处理怎么最快入门?

作者:微软亚洲研究院链接:https://www.zhihu.com/question/19895141/answer/149475410来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业...
  • imissucc
  • imissucc
  • 2018-03-16 17:22:41
  • 42
收藏助手
不良信息举报
您举报文章:自然语言处理-实际开发:用语义开放平台olami写一个翻译的应用
举报原因:
原因补充:

(最多只允许输入30个字)