golang知识图谱NLP实战第一节——整体思路
golang知识图谱NLP实战第二节——解析依存句法分析结果
golang知识图谱NLP实战第三节——关系抽取
基于依存句法分析的开放式中文实体关系抽取https://blog.csdn.net/heuguangxu/article/details/80088489
基于神经网络的高性能依存句法分析器http://www.hankcs.com/nlp/parsing/neural-network-based-dependency-parser.html
基于依存关系的空间关系抽取算法https://blog.csdn.net/sinat_28901239/article/details/52184531
语言云API使用文档https://www.ltp-cloud.com/document/
https://api.ltp-cloud.com/analysis/?api_key=U1H0S1Z1CkcUtrLouJvyHVNSOWkY9ycmAVahcduW&text=%E6%88%BF%E9%A1%B6%E4%B8%8A%E8%90%BD%E7%9D%80%E4%B8%80%E5%8F%AA%E5%B0%8F%E9%B8%9F&pattern=all&format=xml
可以用hanlp做句子的依存句法分析,得到字段如下:问题,怎样得到json数据?怎样让hanlp提供服务?
1 房顶 房顶 n n _ 2 定中关系 _ _
2 上 上 nd f _ 3 状中结构 _ _
3 站 站 v v _ 0 核心关系 _ _
4 着 着 u u _ 3 右附加关系 _ _
5 一 一 m m _ 6 定中关系 _ _
6 只 只 q q _ 7 定中关系 _ _
7 小鸟 小鸟 n n _ 3 动宾关系 _ _
也可以用语言云API,得到json数据如下
[
[
[
{
"id": 0,
"cont": "房顶",
"pos": "n",
"ne": "O",
"parent": 1,
"relate": "ATT",
"semparent": 2,
"semrelate": "Loc",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "Loc"
}
]
},
{
"id": 1,
"cont": "上",
"pos": "nd",
"ne": "O",
"parent": 2,
"relate": "ADV",
"semparent": 0,
"semrelate": "mRang",
"arg": [],
"sem": [
{
"id": 0,
"parent": 0,
"relate": "mRang"
}
]
},
{
"id": 2,
"cont": "落",
"pos": "v",
"ne": "O",
"parent": -1,
"relate": "HED",
"semparent": -1,
"semrelate": "Root",
"arg": [
{
"id": 0,
"type": "LOC",
"beg": 0,
"end": 1
},
{
"id": 1,
"type": "A1",
"beg": 4,
"end": 6
}
],
"sem": [
{
"id": 0,
"parent": -1,
"relate": "Root"
}
]
},
{
"id": 3,
"cont": "着",
"pos": "u",
"ne": "O",
"parent": 2,
"relate": "RAD",
"semparent": 2,
"semrelate": "mTime",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "mTime"
}
]
},
{
"id": 4,
"cont": "一",
"pos": "m",
"ne": "O",
"parent": 5,
"relate": "ATT",
"semparent": 5,
"semrelate": "Quan",
"arg": [],
"sem": [
{
"id": 0,
"parent": 5,
"relate": "Quan"
}
]
},
{
"id": 5,
"cont": "只",
"pos": "q",
"ne": "O",
"parent": 6,
"relate": "ATT",
"semparent": 6,
"semrelate": "Qp",
"arg": [],
"sem": [
{
"id": 0,
"parent": 6,
"relate": "Qp"
}
]
},
{
"id": 6,
"cont": "小鸟",
"pos": "n",
"ne": "O",
"parent": 2,
"relate": "VOB",
"semparent": 2,
"semrelate": "Exp",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "Exp"
}
]
}
]
]
]
那么有了以上数据,从go语言角度,如何实现关系抽取呢?按照上述的参考文章,先将数据转为struct,然后进行判断逻辑关系,无论是主谓关系,定中关系……还是空间方位……通过代码找出三元体吧。下一节贴出。以下是先实现了2种数据转为struct。
package main
import (
// "bytes"
// "crypto/aes"
// "crypto/cipher"
// "crypto/rand"
"encoding/json"
"fmt"
// "io"
// "io/ioutil"
"log"
// "os"
// "github.com/bitly/go-simplejson" // for json get
"strings"
)
type Hanlp struct {
ID string `json:"id"`
FORM string `json:"form"`
LEMMA string `json:"lemma"`
CPOSTAG string `json:"cpostag"`
POSTAG string `json:"postag"`
FEATS string `json:"feats"`
HEAD string `json:"head"`
DEPREL string `json:"deprel"`
}
type Ltp2 struct {
Ltptwo []Ltp1
}
type Ltp1 struct { //这个办法不行,保留!
Ltpone []Ltp
}
type Ltp struct {
Id int64 `json:"id"`
Cont string `json:"cont"`
Pos string `json:"pos"`
Ne string `json:"ne"`
Parent int64 `json:"parent"`
Relate string `json:"relate"`
Semparent int64 `json:"semparent"`
Semrelate string `json:"semrelate"`
Arg []Arg1 `json:"arg"`
Sem []Sem1 `json:"sem"`
}
type Sem1 struct {
Id int64 `json:"id"`
Parent int64 `json:"parent"`
Relate string `json:"relate"`
}
type Arg1 struct {
Id int64 `json:"id"`
Type string `json:"type"`
Beg int64 `json:"beg"`
End int64 `json:"end"`
}
func main() {
jsonHanlpStr := `1 房顶 房顶 n n _ 2 定中关系 _ _
2 上 上 nd f _ 3 状中结构 _ _
3 站 站 v v _ 0 核心关系 _ _
4 着 着 u u _ 3 右附加关系 _ _
5 一 一 m m _ 6 定中关系 _ _
6 只 只 q q _ 7 定中关系 _ _
7 小鸟 小鸟 n n _ 3 动宾关系 _ _`
// var hanlp []Hanlp
hanlp := make([]Hanlp, 0) //这里不能加*号
aa := make([]Hanlp, 1)
array := strings.Split(jsonHanlpStr, "\n")
for _, v := range array {
array1 := strings.Split(v, " ")
// for _, w := range array1 {
aa[0].ID = array1[0]
aa[0].FORM = array1[1]
aa[0].LEMMA = array1[3]
aa[0].CPOSTAG = array1[5]
aa[0].POSTAG = array1[6]
aa[0].FEATS = array1[7]
aa[0].HEAD = array1[8]
aa[0].DEPREL = array1[9]
// }
hanlp = append(hanlp, aa...)
}
fmt.Println(hanlp)
// jsonLtpStr := `[[[{"id": 0,"cont": "房顶","pos": "n","ne": "O","parent": 1,
//"relate": "ATT","semparent": 2,"semrelate": "Loc","arg": [],"sem": [{"id": 0,
//"parent": 2,"relate": "Loc"}]}]]]`
jsonLtpStr := `[
[
[
{
"id": 0,
"cont": "房顶",
"pos": "n",
"ne": "O",
"parent": 1,
"relate": "ATT",
"semparent": 2,
"semrelate": "Loc",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "Loc"
}
]
},
{
"id": 1,
"cont": "上",
"pos": "nd",
"ne": "O",
"parent": 2,
"relate": "ADV",
"semparent": 0,
"semrelate": "mRang",
"arg": [],
"sem": [
{
"id": 0,
"parent": 0,
"relate": "mRang"
}
]
},
{
"id": 2,
"cont": "落",
"pos": "v",
"ne": "O",
"parent": -1,
"relate": "HED",
"semparent": -1,
"semrelate": "Root",
"arg": [
{
"id": 0,
"type": "LOC",
"beg": 0,
"end": 1
},
{
"id": 1,
"type": "A1",
"beg": 4,
"end": 6
}
],
"sem": [
{
"id": 0,
"parent": -1,
"relate": "Root"
}
]
},
{
"id": 3,
"cont": "着",
"pos": "u",
"ne": "O",
"parent": 2,
"relate": "RAD",
"semparent": 2,
"semrelate": "mTime",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "mTime"
}
]
},
{
"id": 4,
"cont": "一",
"pos": "m",
"ne": "O",
"parent": 5,
"relate": "ATT",
"semparent": 5,
"semrelate": "Quan",
"arg": [],
"sem": [
{
"id": 0,
"parent": 5,
"relate": "Quan"
}
]
},
{
"id": 5,
"cont": "只",
"pos": "q",
"ne": "O",
"parent": 6,
"relate": "ATT",
"semparent": 6,
"semrelate": "Qp",
"arg": [],
"sem": [
{
"id": 0,
"parent": 6,
"relate": "Qp"
}
]
},
{
"id": 6,
"cont": "小鸟",
"pos": "n",
"ne": "O",
"parent": 2,
"relate": "VOB",
"semparent": 2,
"semrelate": "Exp",
"arg": [],
"sem": [
{
"id": 0,
"parent": 2,
"relate": "Exp"
}
]
}
]
]
]`
//json字符串解析到结构体,以便进行追加
var ltp [][][]Ltp
err := json.Unmarshal([]byte(jsonLtpStr), <p)
if err != nil {
// beego.Error(err)
log.Fatal(err)
}
fmt.Println(ltp)
fmt.Println(ltp[0][0][0].Parent)
//json str 转struct
// var config ConfigStruct
// if err := json.Unmarshal([]byte(jsonStr), &config); err == nil {
// fmt.Println("================json str 转struct==")
// fmt.Println(config)
// fmt.Println(config.Host)
// }
}
打印结果
D:/Go/bin/go.exe build -i [D:/gowork/src/test_go]
成功: 进程退出代码 0.
D:/gowork/src/test_go/test_go.exe [D:/gowork/src/test_go]
table `user` already exists, skip
[{1 房顶 房顶 n n _ 2 定中关系} {2 上 nd f _ 3 状中结构 } {3 站 v _ 0 核心关系 _} {4 着 u _ 3 右附加关系 _ _} {5 一 m _ 6 定中关系 _} {6 只 q _ 7 定中关系 _} {7 小鸟 小鸟 n n _ 3 动宾关系}]
[[[{0 房顶 n O 1 ATT 2 Loc [] [{0 2 Loc}]} {1 上 nd O 2 ADV 0 mRang [] [{0 0 mRang}]} {2 落 v O -1 HED -1 Root [{0 LOC 0 1} {1 A1 4 6}] [{0 -1 Root}]} {3 着 u O 2 RAD 2 mTime [] [{0 2 mTime}]} {4 一 m O 5 ATT 5 Quan [] [{0 5 Quan}]} {5 只 q O 6 ATT 6 Qp [] [{0 6 Qp}]} {6 小鸟 n O 2 VOB 2 Exp [] [{0 2 Exp}]}]]]
1
成功: 进程退出代码 0.