机器之心整理
参与:蒋思源
机器之心曾采访过语知科技的董强先生,在那一篇文章中,我们详细讨论了基于知网知识库的 NLP 解决方案。虽然我们已经了解了这种方法的潜力,但只有真正实现了调用过程,并明确体会到知网知识库的强大之处,我们才真正对这种方法有一个直观的理解。
基于知网(HowNet)知识库的方法在实践和研究中确实大大提升了 NLP 的性能。在最近的 ACL 2017 会议中,清华大学牛艺霖、谢若冰、刘知远和孙茂松等人发表了一篇名为《Improved Word Representation Learning with Sememes》的论文。该论文首次将义原信息考虑到词向量的学习任务中,在很大程度上提升了词向量的表示能力。该论文是以经典的 skip-gram 模型为基础提出来的改进模型,相对于 skip-gram 模型只考虑了上下文信息,该论文提出的模型同时考虑词的义原信息以及义原信息与词义之间的关系。
除此之外,清华大学袁星驰,谢若冰,刘知远,孙茂松等人还在 IJCAIL 2017 上发表了一篇名为《Lexical Sememe Prediction via Word Embeddings and Matrix Factorization》的论文。该论文介绍了义原信息(sememe)在提高词向量表示能力方面的作用,并且首次提出从已有的人工标注数据集学习词汇与义原的通用的关系,借助协同过滤和矩阵分解的方法,自动构造出新词的义原。
由此可见,知网知识库确实为 NLP 提供了一个强大的平台。下面在详细解释调用 API 之前,我们先简要了解知网知识库的结构与概念。之后我们再详细说明整个 API 的参数与调用过程。
义原的定义
知识是一个系统,是一个包含着各种概念与概念之间的关系,以及概念的属性与属性之间的关系的系统。富有知识的人不仅掌握了更多的概念,同时也掌握了更多的概念之间的关系以及概念的属性与属性之间的关系。所以知网是一种可以被称为知识系统的常识性知识库。它以通用的概念为描述对象,建立并描述这些概念之间的关系。
董强先生表明,义原(Sememe)是最基本的、不易于再分割的意义的最小单位。例如:「人」虽然是一个非常复杂的概念,它可以是多种属性的集合体,但我们也可以把它看作为一个义原。我们设想所有的概念都可以分解成各种各样的义原。同时我们也设想应该有一个有限的义原集合,其中的义原可以组合成一个无限的概念集合。如果我们能够把握这一有限的义原集合,并利用它来描述概念之间的关系以及属性与属性之间的关系,我们就有可能建立我们设想的知识系统。
董强先生说:「义原的是知网基本应用的描述单位,它是基于我们的观察而得出,比如说现代汉语词典,它仅使用 2000 多汉字就能解释所有的词条。所以知网的方法就是对大约六千个汉字进行考察和分析来提取有限的义原集合。以事件类为例,在中文中具有事件义原的汉字(单纯词)中曾提取出 3200 个义原。但我们需要对重复义原进行合并,3200 个事件义原在初步合并后可得到 1700 个,进一步归类后得到大约 800 多个义原。因为这些义原完全不涉及多音节的词语,所以我们需要将其作为标注集去标注多音节的词。最后我们需要对所有 2800 多个义原进行编码,编码采用助记符的形式表达,如词语「打开」,其中一个概念是「打开一个东西(盒子)」的动作,用义原 {open|打开} 表示,另外一个意思例如「打开一盏灯」,义原的表示的方式就是 {turn on|打开}。」
概念的表征
知网还着力要反映概念之间和概念的属性之间的关系。知网知识网络体系明确地提供给了计算机,因此我们可以输入形式化的知识而构建计算机系统来实现自然语言处理任务。我们不仅需要义原,同时还需要它们之间的关系来表示知识。通常一个词其具体的概念会采用树型的结构利用义原和关系描述该概念。例如「医院」这一个词的概念根据具体语境可定义为 DEF={InstitutePlace|场所:domain={medical|医},{doctor|医治:content={disease|疾病},location={~}}},我们可以看到整个词的概念属性可以由多个义原按照关系和层次进行定义。
整个知识网络都是以义原为基础建立起来的概念性系统。义原是通过关系描述概念的最小单位,知网认为它是一种最基本的概念,任何复杂的概念都是由基本概念通过某种关系构建而成,而知网用基本单位描述这种关系的方法我们称之为 KDML(Knowledge Database Markup Language),这种描述方法将复杂中多个义原嵌套和多个关系嵌套的问题解决了。
关于知网更多信息请查看:http://www.keenage.com/zhiwang/c_zhiwang.html
下面,我们将开始介绍知网知识库的 API 参数与调用过程,此外这一部分还提供了调用案例,读者可根据该实例尝试调用知网知识库。
参数名 | 说明 | 备注 |
---|---|---|
api_key | 注册用户的认证唯一标识,用户注册登录后即可看到 | 接口调用必传参数 |
text | 需要分析的文本,适用于中、英文语义分析接口 | UTF-8编码格式,语义解析必传参数 |
word1 | 相似性/相关性接口的传入词语一 | 中、英文词语均可,必传参数 |
word2 | 相似性/相关性接口的传入词语二 | 中、英文词语均可,必传参数 |
unitId | 词语在知网词典中的义项ID号,语义解析接口的衍生接口,从语义解析接口返回的结果中即可提取出“unitId” | 每个字(词)拥有唯一unitId,详情参考【调用示例】 |
pattern | pos:词性标注;st:语义标注;sd:语义判定;all:全文解析 | 用以指定所需提供的分析结果 |
调用示例中为目前网站免费提供的接口,鉴于中、英文分析接口相对复杂,如有疑问请参考【接口调用流程演示】或联系管理员
接口功能 | 示例URL | 返回值 | Method |
---|---|---|---|
中文分析 | http://yuzhinlp.com/api/call_chn.do &apiKey=xxxxxxxx&input="我爱中国,我爱世界。" | Json字符串,详情查看【接口调用流程演示】 | post |
英文分析 | http://yuzhinlp.com/api/call_eng.do&apiKey=xxxxxxxx&input="I love China, I love this world!" | Json字符串,详情查看【接口调用流程演示】 | post |
词语相似度检测 | http://yuzhinlp.com/api/call_similarity.do&apiKey=xxxxxxxx&word1=doctor&word2=护士 | Json字符串,例:{"similarity":"0.018605"},其中"similarity"为key,"0.018605"代表相似度结果 | post |
词语相关性检测 | http://yuzhinlp.com/api/call_relevance.do&apiKey=xxxxxxxx&word1=doctor&word2=护士 | Json字符串,例:{"relevance":"1"},其中"relevance"为key,"1"为值,1代表相关,0代表不相关 | post |
根据UNITID查询详细词性 | http://yuzhinlp.com/api/call_UnitIdApi.do&unitId=202591 | Json字符串,详情查看【接口调用流程演示】 | post |
该流程是建立于【调用方式】的基础上,以中文语义解析接口为例,请务必设定为post提交,并设置参数编码为UTF-8
import java.util.ArrayList; import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
public class ApiTest {
public static void main(String[] args){
//创建post请求
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://yuzhinlp.com/api/call_chn.do");
//post请求传入参数
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("apiKey", "YourApiKey"));
parameters.add(new BasicNameValuePair("input", "它好你也好"));
CloseableHttpResponse response = null;
try {
UrlEncodedFormEntity formEntity;
//设置参数编码
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
httpPost.setEntity(formEntity);
// 执行请求
response = httpclient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
//调用结果
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
JSONObject object = JSONObject.parseObject(content);
String result = object.get("success").toString();
//打印到控制台
System.out.println(result);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行后返回Json格式数据结果,其中包含连个父节点分别为"sentence"(您输入的文本内容)和"nodes"(分析结果),"nodes"节点下包含另一个Json格式的数据,即为您所输入的每一个字/词的详细分析结果,其中子节点中的参数含义请参照【参数节点描述】
[{ "sentence": "你来跑,我来追,追上你我就嘿嘿嘿。", "nodes": [{ "NoID_1": "000", "MaskID": "", "NoID_2": "000", "expression": "ROOT", "FH": "", "Son": "", "ES": "", "YS": "", "DP": "", "DeepSon": "", "log": "", "DeepLog": "", "POS": "", "UnitID": "" }, ..., { "NoID_1": " 18", "MaskID": " ", "NoID_2": " 18", "expression": "嘿嘿", "FH": "000", "Son": " ", "ES": " ", "YS": " ", "DP": " ", "DeepSon": " ", "log": "", "DeepLog": "", "POS": "echo", "UnitID": "074279" },{ "NoID_1": " 21", "MaskID": " ", "NoID_2": " 21", "expression": "。", "FH": "000", "Son": " ", "ES": " ", "YS": " ", "DP": " ", "DeepSon": " ", "log": "", "DeepLog": "", "POS": "pun", "UnitID": "010349" }] }]
名称 | 描述 |
---|---|
NoID_1 | 输入文本经过词法处理后各定形词语在文本中排列的序号 |
MaskID | 加工过程中,为了简化句子复杂度暂时屏蔽的标记 |
NoID_2 | 输入文本经过命名体识别和语义判定后在文本中排列的序号 |
expression | 各个定形后的词语 |
FH | 词语的父节点的序号 |
Son | 词语的子节点的序号 |
ES | 词语的姐姐节点的序号 |
YS | 词语的妹妹节点的序号 |
DP | 词语的深层父节点的序号 |
DeepSon | 词语的深层子节点的序号 |
log | 词语的逻辑语义关系 |
DeepLog | 词语的深层逻辑语义关系 |
POS | 词语的词性 |
UnitID | 词语在知网词典中的义项ID号 |
在中、英文语义解析的基础上,调用“call_UnitIdApi.do”接口,并传入参数apiKey和UnitID。其中apiKey为您的凭证,UnitID参数则从刚才中、英文语义解析接口返回的数据中提取。返回结果如下:
UnitID 详细数据:
NO.=074279
W_C=嘿嘿
G_C=echo [2] [hei1 hei1]
S_C=
E_C=
W_E=hey
G_E=noun [3 heynoun-0static声 ]
S_E=
E_E=
DEF={sound|声:{MakeSound|发声:content={~},time={laugh|笑}}}
RMK=
名称 | 描述 |
---|---|
NO. | 记录编号 |
W_C | 中文词语 |
G_C | 中文信息 |
S_C | 中文情感标识 |
E_C | 中文样例 |
W_E | 英文词语 |
G_E | 英文信息 |
S_E | 英文情感标识 |
E_E | 英文样例 |
DEF | 概念定义 |
RMK | 备注 |
本文为机器之心整理,转载请联系本公众号获得授权。