pyltp句法分析

###分句-------
import re
'''文章分句处理, 切分长句,冒号,分号,感叹号等做切分标识'''
def split_sents(content):
    return [sentence for sentence in re.split(r'[??!!。;;::\n\r]', content) if sentence]

content = '我购买了一件玩具,孩子非常喜欢这个玩具,但是质量不太好。希望商家能够保障商品质量,不要再出现类似问题。'
sentences = split_sents(content)
print(sentences)
['我购买了一件玩具,孩子非常喜欢这个玩具,但是质量不太好', '希望商家能够保障商品质量,不要再出现类似问题']
#参考LTP附录:https://ltp.readthedocs.io/zh_CN/latest/appendix.html#id3
#pyltp文档:https://pyltp.readthedocs.io/zh_CN/latest/api.html
#pyltp的下载方法:先将python降级成3.6的,再下载pyltp的.whl文件,pip install 下载好的.whl文件 (非常容易出错,自求多福吧 555)
#下载pyltp的.whl文件在https://blog.csdn.net/liqueding/article/details/100085114

print("*************************** 1.分词、识别词语类型 ***************************")
import os
from pyltp import Segmentor, Postagger,NamedEntityRecognizer,Parser,SementicRoleLabeller

LTP_DIR = "D:\BaiduNetdiskDownload\ltp_data"# ltp模型目录的路径

segmentor = Segmentor()
segmentor.load(os.path.join(LTP_DIR, "cws.model"))

postagger = Postagger()
postagger.load(os.path.join(LTP_DIR, "pos.model"))

sentence = '奥巴马昨晚在白宫发表了演说'

words = list(segmentor.segment(sentence))#分词
segmentor.release()
print(words, len(words))

postags = list(postagger.postag(words))#识别词语类型
postagger.release()
print(postags, len(postags))


print("*************************** 2.命名实体识别(暂时没用到)***************************")
recognizer = NamedEntityRecognizer() # 初始化实例
recognizer.load(os.path.join(LTP_DIR, "ner.model")) # 加载模型

netags = recognizer.recognize(words, postags)# 命名实体识别

print ('\t'.join(netags))
recognizer.release()# 释放模型   


print("*************************** 3.依存句法关系:词和词之间的关系 ***************************")
parser = Parser()
parser.load(os.path.join(LTP_DIR, "parser.model"))

# if __name__ == '__main__':
#依存句法分析
arcs = parser.parse(words, postags)
#z找任意两个词语之间的关系
#主谓关系、状中结构、状中结构、介宾关系、核心关系、右附加关系、动宾关系
#SBV、      ADV、       ADV、     POB、     HED、    RAD、       VOB
#参考:https://ltp.readthedocs.io/zh_CN/latest/appendix.html#id3
print([(arc.head,arc.relation) for arc in arcs])
parser.release()
###与当前关系的位置相同的单词  与  数字(从0开始)中词语的关系


print("*************************** 4.语义角色类型(返回值为空,可能是pyltp的问题,本部分暂未用到)***************************")
labeller = SementicRoleLabeller()
labeller.load(os.path.join(LTP_DIR, 'pisrl_win.model'))

roles = labeller.label(words, postags, arcs)
roles_dict={}


for role in roles:
    roles_dict[role.index] = {arg.name:[arg.name,arg.range.start, arg.range.end] for arg in role.arguments}

for role in roles:
    print(role.index, "".join(["%s:(%d,%d)" % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments]))

print("*************************** 5.句法分析 ***************************")

print("5.1child_dict_list---为句子中的每个词语维护一个保存句法依存儿子节点的字典,即每个词和其他词的关系------")
def build_parse_child_dict(words, postags, arcs):
    child_dict_list = []
    format_parse_list = []
    
    for index in range(len(words)):
        print("当前处理的是第",index,"个单词----")
        #为每个词构建的词典,存储它与其他词的关系
        child_dict = dict()
        #循环全部的关系
        for arc_index in range(len(arcs)):
            print("当前处理的是第",arc_index,"个arcs","arcs[arc_index].head=",arcs[arc_index].head,"index+1=",index+1)


            #ROOT 节点的索引是 0,不代表某个单词 ,arc. relation 表示依存弧的关系。

            #arc_index是当前arc在arcs中的位置,从0开始;[arc_index].head指主词的位置,从1开始
            #关系指的是words[arcs[arc_index].head]与word[arc_index+1]的关系
            if arcs[arc_index].head == index+1:#当前关系的索引头如果是当前单词
                if arcs[arc_index].relation in child_dict:
                    child_dict[arcs[arc_index].relation].append(arc_index)#就将当前关系加入当前单词的关系词典当中
                else:
                    child_dict[arcs[arc_index].relation] = []#新建
                    child_dict[arcs[arc_index].relation].append(arc_index)
        print("child_dict是:")
        print(child_dict)
        child_dict_list.append(child_dict)
        
    print("5.2.format_parse_list----------------------------------------------------------------------------")
    rely_id = [arc.head for arc in arcs]# 提取所有依存父节点词语的id
    print(rely_id)
    relation = [arc.relation for arc in arcs]# 提取所有依存关系
    print(relation)
    heads = ['Root' if id == 0 else words[id - 1] for id in rely_id]# 提取所有父节点词语
    print(heads)
    
    for i in range(len(words)):
        a = [relation[i], words[i], i, postags[i], heads[i], rely_id[i]-1, postags[rely_id[i]-1]]
        format_parse_list.append(a)
        print("第",i,"个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性)",a)
    
    return child_dict_list, format_parse_list

# if __name__ == '__main__':
child_dict_list, format_parse_list = build_parse_child_dict(words, postags, arcs)


*************************** 1.分词、识别词语类型 ***************************
['奥巴马', '昨晚', '在', '白宫', '发表', '了', '演说'] 7
['nh', 'nt', 'p', 'n', 'v', 'u', 'v'] 7
*************************** 2.命名实体识别(暂时没用到)***************************
S-Nh	O	O	O	O	O	O
*************************** 3.依存句法关系:词和词之间的关系 ***************************
[(5, 'SBV'), (5, 'ADV'), (5, 'ADV'), (3, 'POB'), (0, 'HED'), (5, 'RAD'), (5, 'VOB')]
*************************** 4.语义角色类型(返回值为空,可能是pyltp的问题,本部分暂未用到)***************************
*************************** 5.句法分析 ***************************
5.1child_dict_list---为句子中的每个词语维护一个保存句法依存儿子节点的字典,即每个词和其他词的关系------
当前处理的是第 0 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 1
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 1
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 1
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 1
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 1
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 1
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 1
child_dict是:
{}
当前处理的是第 1 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 2
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 2
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 2
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 2
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 2
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 2
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 2
child_dict是:
{}
当前处理的是第 2 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 3
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 3
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 3
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 3
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 3
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 3
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 3
child_dict是:
{'POB': [3]}
当前处理的是第 3 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 4
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 4
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 4
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 4
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 4
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 4
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 4
child_dict是:
{}
当前处理的是第 4 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 5
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 5
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 5
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 5
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 5
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 5
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 5
child_dict是:
{'SBV': [0], 'ADV': [1, 2], 'RAD': [5], 'VOB': [6]}
当前处理的是第 5 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 6
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 6
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 6
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 6
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 6
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 6
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 6
child_dict是:
{}
当前处理的是第 6 个单词----
当前处理的是第 0 个arcs arcs[arc_index].head= 5 index+1= 7
当前处理的是第 1 个arcs arcs[arc_index].head= 5 index+1= 7
当前处理的是第 2 个arcs arcs[arc_index].head= 5 index+1= 7
当前处理的是第 3 个arcs arcs[arc_index].head= 3 index+1= 7
当前处理的是第 4 个arcs arcs[arc_index].head= 0 index+1= 7
当前处理的是第 5 个arcs arcs[arc_index].head= 5 index+1= 7
当前处理的是第 6 个arcs arcs[arc_index].head= 5 index+1= 7
child_dict是:
{}
5.2.format_parse_list----------------------------------------------------------------------------
[5, 5, 5, 3, 0, 5, 5]
['SBV', 'ADV', 'ADV', 'POB', 'HED', 'RAD', 'VOB']
['发表', '发表', '发表', '在', 'Root', '发表', '发表']
第 0 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['SBV', '奥巴马', 0, 'nh', '发表', 4, 'v']
第 1 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['ADV', '昨晚', 1, 'nt', '发表', 4, 'v']
第 2 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['ADV', '在', 2, 'p', '发表', 4, 'v']
第 3 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['POB', '白宫', 3, 'n', '在', 2, 'p']
第 4 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['HED', '发表', 4, 'v', 'Root', -1, 'v']
第 5 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['RAD', '了', 5, 'u', '发表', 4, 'v']
第 6 个关系:(关系,当前词语,i,当前词语的词性,父节点词语,父节点id,父节点的词性) ['VOB', '演说', 6, 'v', '发表', 4, 'v']

关于arcs:
pyltp句法分析_第1张图片

你可能感兴趣的:(知识图谱+自然语言处理,句法分析,知识图谱)