golang知识图谱NLP实战第四节——关系抽取完善逻辑

 陈同学将hanlp做成了服务:https://gitee.com/Erichan/EngineerCMS-HanLPService

用golang应用提交文字给这个hanlp服务,返回json数据格式的依存句法分析结果。

//这个是专门解析json的
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/url"

	"github.com/astaxie/beego/httplib"
)

type Dict struct {
	SBV []HanlpJson
	VOB []HanlpJson
	IOB []HanlpJson
	FOB []HanlpJson
	DBL []HanlpJson
	ATT []HanlpJson
	ADV []HanlpJson
	CMP []HanlpJson
	COO []HanlpJson
	POB []HanlpJson
	LAD []HanlpJson
	RAD []HanlpJson
	IS  []HanlpJson
	HED []HanlpJson
}

type HanlpResult struct {
	Result HanlpWord `json:"result"`
}

type HanlpWord struct {
	Word []HanlpJson `json:"word"`
}

//用于json数据解析
type HanlpJson struct {
	ID      int64
	LEMMA   string
	CPOSTAG string
	POSTAG  string
	HEAD    Json
	DEPREL  string
	NAME    string
}

type Json struct {
	ID      int64
	LEMMA   string
	CPOSTAG string
	POSTAG  string
	DEPREL  string
	NAME    string
}

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() {
	link := url.QueryEscape("输水干线从佛山市顺德区杏坛镇西江干流中央的鲤鱼洲岛端部取水")
	req := httplib.Post("http://localhost:8888/max?sentence=" + link)
	str, err := req.String()
	if err != nil {
		log.Fatal(err)
	}
	//	fmt.Println(str)
	//json字符串解析到结构体
	var hanlpresult HanlpResult
	err = json.Unmarshal([]byte(str), &hanlpresult)
	if err != nil {
		log.Fatal(err)
	}
	//	fmt.Println(hanlpresult.Result.Word)
	hanlp := hanlpresult.Result.Word
	dict := make([]Dict, 0)
	for _, w := range hanlp {
		dict1 := make([]Dict, 1)
		for _, x := range hanlp {
			if w.ID == x.HEAD.ID {
				list1 := make([]HanlpJson, 1)
				list1[0] = x
				switch x.DEPREL {
				case "主谓关系":
					dict1[0].SBV = list1
				case "动宾关系":
					dict1[0].VOB = list1
				case "间宾关系":
					dict1[0].IOB = list1
				case "前置宾语":
					dict1[0].FOB = list1
				case "兼语":
					dict1[0].DBL = list1
				case "定中关系":
					dict1[0].ATT = list1
				case "状中结构":
					dict1[0].ADV = list1
				case "动补结构":
					dict1[0].CMP = list1
				case "并列关系":
					dict1[0].COO = list1
				case "介宾关系":
					dict1[0].POB = list1
				case "左附加关系":
					dict1[0].LAD = list1
				case "右附加关系":
					dict1[0].RAD = list1
				case "独立结构":
					dict1[0].IS = list1
				case "核心关系":
					dict1[0].HED = list1
				}
				//				bb = make([]Hanlp, 0)
			}
		}
		dict = append(dict, dict1...)
	}
	//	fmt.Println(dict)
	for i := 0; i < len(dict); i++ {
		extract(hanlp, dict, i)
	}
}

func extract(hanlp []HanlpJson, dict []Dict, i int) {
	w := hanlp[i]
	ww := dict[i]
	//主谓宾关系:刘小绪生于四川
	if len(ww.SBV) > 0 && len(ww.VOB) > 0 {
		entity1 := ww.SBV[0].LEMMA
		// 排除:刘小绪和李华是朋友
		prep := ww.SBV[0]
		prepIndex := prep.ID - 1
		prepDict := dict[prepIndex] //这个写法注意,当做dict数组的索引和它ID是一致的
		if len(prepDict.COO) > 0 {
			relation := ww.VOB[0].LEMMA
			entity2 := prepDict.COO[0].LEMMA
			fmt.Println(entity1 + "," + relation + "," + entity2)
		} else {
			entity2 := ww.VOB[0].LEMMA
			relation := w.LEMMA
			fmt.Println(entity1 + "," + relation + "," + entity2)
		}
	}

	// 动补结构:刘小绪洗干净了衣服
	//"主谓关系"]
	//"动宾关系"]
	//"动补结构"]
	if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.CMP) > 0 {
		entity1 := ww.SBV[0].LEMMA
		complement := ww.CMP[0].LEMMA
		entity2 := ww.VOB[0].LEMMA
		if len(ww.RAD) > 0 { //右附加关系
			subjoin := ww.RAD[0].LEMMA
			relation := w.LEMMA + complement + subjoin
			fmt.Println(entity1 + "," + relation + "," + entity2)
		} else {
			relation := w.LEMMA + complement
			fmt.Println(entity1 + "," + relation + "," + entity2)
		}
	}

	//定中关系
	if len(ww.ATT) > 0 {
		entity1 := ww.ATT[0].LEMMA
		relation := w.LEMMA
		for _, ii := range dict { //这里要用dict maps数组
			//"主谓关系"]
			//"动宾关系"]
			if len(ii.SBV) > 0 && len(ii.VOB) > 0 {
				if ii.SBV[0].LEMMA == relation {
					entity2 := ii.VOB[0].LEMMA
					fmt.Println(entity1 + "," + relation + "," + entity2)
				}
			}
		}
	}

	// 状动结构:父亲非常喜欢跑步
	// 非常 是 跑步的状语,关系应该为非常喜欢
	//"主谓关系"]
	//动宾关系"]
	//"状中结构"]
	if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.ADV) > 0 {
		entity1 := ww.SBV[0].LEMMA
		adverbial := ww.ADV[0].LEMMA
		entity2 := ww.VOB[0].LEMMA
		relation := adverbial + w.LEMMA
		fmt.Println(entity1 + "," + relation + "," + entity2)
	}

	// 状动补结构
	//"主谓关系"]
	//"动宾关系"]
	//"状中结构"]
	//"动补结构"]
	if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.ADV) > 0 && len(ww.CMP) > 0 {
		entity1 := ww.SBV[0].LEMMA
		adverbial := ww.ADV[0].LEMMA
		complement := ww.CMP[0].LEMMA
		entity2 := ww.VOB[0].LEMMA
		relation := adverbial + w.LEMMA + complement
		fmt.Println(entity1 + "," + relation + "," + entity2)
	}

	// 定语后置:父亲是来自肯尼亚的留学生
	if w.DEPREL == "定中关系" {
		if len(ww.VOB) > 0 {
			entity1 := hanlp[w.HEAD.ID-1].LEMMA
			relation := w.LEMMA
			entity2 := ww.VOB[0].LEMMA
			fmt.Println(entity1 + "," + relation + "," + entity2)
		}
	}

	// 介宾关系:刘小绪就职于学校
	// 于 和 学校 是介宾关系
	//"主谓关系"]
	//"动补结构"]
	if len(ww.SBV) > 0 && len(ww.CMP) > 0 {
		entity1 := ww.SBV[0].LEMMA
		prep := ww.CMP[0] //maps["动补结构"][0]
		prepIndex := prep.ID - 1
		prepDict := dict[prepIndex] //这个写法注意,当做dict数组的索引和它ID是一致的
		if len(prepDict.POB) > 0 {
			entity2 := prepDict.POB[0].LEMMA //"介宾关系"][0]
			relation := w.LEMMA + prep.LEMMA
			fmt.Println(entity1 + "," + relation + "," + entity2)
		}
	}

	// 宾语前置结构:海洋由水组成
	if len(ww.FOB) > 0 {
		entity2 := ww.FOB[0].LEMMA //maps["前置宾语"][0]
		if len(ww.ADV) > 0 {
			adverbial := ww.ADV[0] //maps["状中结构"][0]
			prepIndex := adverbial.ID - 1
			prepDict := dict[prepIndex]
			if len(prepDict.POB) > 0 {
				entity1 := prepDict.POB[0].LEMMA
				relation := w.LEMMA
				fmt.Println(entity1 + "," + relation + "," + entity2)
			}
		}
	}
}

 

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/81322890
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭