使用python+stanfordcorenlp+dependency_parse(依赖句法分析)实现英文长句切分

一、问题引入–英文长句切分

其实英文里面也是有一些短语,比如:I traveled to New York last year
其中 New York 可以作为一个短语来看待,在情感分析以及别的任务里面可能会有更好的性能提升。
英文长句的切分也是一个研究的方向:比如论文:Neural Text Segmentation and Its Application to Sentiment Analysis

二、如何解决问题?

我们使用依赖树(好像类似的还有什么依存句法分析等等)算法提供的各个单词之间的依赖关系,进行句子分组,从而实现长句切分

三、代码以及注释

from stanfordcorenlp import StanfordCoreNLP
nlp = StanfordCoreNLP('./stanford-corenlp-4.2.0')

sentence = "Steers turns in a snappy screenplay that curls at the edges ; it 's so clever you want to hate it ."

result = nlp.dependency_parse(sentence)
data = pd.read_csv('data/train_1.csv')


def seg_text(result):
    
    d = {}
    for i in range(1, len(result)):
        d[result[i][2]] = result[i][1]
        
           
    #先将result内部的根节点统计出来
    roots = []
    for i in range(1, len(result)):
        roots.append(result[i][1])
        
    #消除重复的根节点
    roots = list(set(roots))
    roots.sort()
    #存储分割结果
    segs = []
    
    for root in roots:
        print(root)
        #当前根节点的分割方案
        children_root = []
        
        #判断一下这个根节点是否因为是别的节点的孩子而已经被分割到别的组里了
        flag = False
        for seg in segs:
            if root in seg:
                flag = True
                break
        if flag:
            continue
        children_root.append(root)
        
        #下面开始遍历根节点root的所有叶子节点,然后判断是否符合所定义的三种条件
        for re in result:
            
            # re的父节点不是root,因此直接略过不要
            if re[1] == 0:
                continue
            
            #将已经分割好的排除出去
            f1 = False
            for seg in segs:
                if re[2] in seg:
                    f1 = True
            if f1:
                continue
            
            #到了这里,就说明所代表的节点是当前根节点的孩子节点
            if root > re[2]:
                #下面开始在当前re节点和当前根节点里面寻找那两种模式
                #开始判断第一种模式:就是节点re和root之间的所有节点都是root节点的函数
                pattern = False
                for i in range(re[2], root):
                    try:
                        if d[i] != root:
                            pattern = True
                            break
                    except KeyError:
                        continue
                    
                if pattern: #说明在re[2]和root之间有不是root孩子节点的节点
                    #下面开始判断是否是第二种模式
                    flag = True
                    for i in range(re[2], root):
                        try:
                            if d[i] != i+1:
                                flag = False
                                break
                        except KeyError:
                            continue
                                
                    if flag:#此时说明之间的所有 id 都可以加入到当前root的分割里面
                    
                        for ch in range(re[2], root):
                            children_root.append(ch)
     
                else:#说明在re[2]和root之间都是root的孩子节点,将之间的东西全部加入到当前的分割里面
                    for ch in range(re[2], root):
                        children_root.append(ch)
            else:
                #下面开始root比当前节点小的情况的处理,开始识别两种模式
                #现在开始判断第一种模式
                pattern = False
                for i in range(root + 1, re[2] + 1):
                    try:
                        if d[i] != root:
                            pattern = True
                            break
                    except KeyError:
                        continue
                    
                if pattern:#此时说明两者之间有不是root孩子节点的节点
                    #下面开始第二种模式的判断
                    flag = True
                    for i in range(re[2], root, -1):
                        try:
                            if d[i] != i - 1:
                                flag = False
                                break
                        except KeyError:
                            continue
                        
                    if flag: #此时说明符合那个第二种模式的
                        for ch in range(root, re[2] + 1):
                            children_root.append(ch)
                        
                else: #此时两者之间都是root的孩子节点,将他们加入到当前的分割里面
                    for ch in range(root, re[2] + 1):
                        children_root.append(ch)
                        
        children_root = list(set(children_root))                
        segs.append(children_root)
        
        
    #下面开始将分割方案里面长度为1或者2的 合并一些
    def merge(segs):
        
        done = False
        #还要先判断一下segs内部是不是有长度不大于2的EDU才行
        for i in range(len(segs) - 1):
            if len(segs[i]) <= 2:
                done = True
                break
            
        while done:
            segs[i+1].extend(segs[i])
            #下面将已经被合并的EDU弹出去
            segs.pop(i)
            
            for i in range(len(segs) - 1):
                if len(segs[i]) <= 2:
                    done = True
                    break
                else:
                    done = False
        #最后还要再判断一次segs的最后一个是否是长度不大于2的
        if len(segs[-1]) <= 2:
            segs[-2].extend(segs[-1])
            segs.pop(-1)
            

        return segs
            
    segs = merge(segs)
    
    
    l1 = [re[2] for re in result]
    l2 = []
    for seg in segs:
        l2.extend(seg)
    
    other = list(set(l1) ^ set(l2))
    print(other)
    for oth in other:
        for i in range(len(segs)):
            print(segs[i])
            if (oth-1 in segs[i]) or (oth + 1) in segs[i] :
                segs[i].append(oth)
                break
                
                
    sort_segs = []
    for i in range(len(segs)):
        sort_segs.append(segs[i].sort())
            
    return segs
if __name__ == "__main__":
	seg = seg_text(result)
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 下载Stanford CoreNLP 首先,需要下载Stanford CoreNLP。官网地址为:https://stanfordnlp.github.io/CoreNLP/ 。在下载页面选择适合自己系统的版本,下载后解压。 2. 启动Stanford CoreNLP 进入解压后的Stanford CoreNLP目录,执行以下命令启动Stanford CoreNLP服务: ```bash java -mx4g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -port 9000 -timeout 15000 ``` 这个命令会启动一个Stanford CoreNLP服务,监听9000端口,并且会在控制台输出一些信息。 3. 使用Stanford CoreNLP进行依存句法分析 Python中可以使用stanfordcorenlp库来连接Stanford CoreNLP服务,进行依存句法分析。 安装stanfordcorenlp库: ```bash pip install stanfordcorenlp ``` 使用代码: ```python import stanfordcorenlp # 连接Stanford CoreNLP服务 nlp = stanfordcorenlp.StanfordCoreNLP('http://localhost:9000') # 输入文本 text = 'I love natural language processing.' # 进行依存句法分析 result = nlp.dependency_parse(text) # 输出结果 print(result) # 关闭连接 nlp.close() ``` 输出结果: ```python [(2, 1, 'nsubj'), (2, 4, 'dobj'), (4, 3, 'amod'), (0, 2, 'root')] ``` 可以看到,结果是一个列表,每个元素代表一个依存关系,其中每个元素又是一个元组,包含三个元素:依存关系的头部、尾部和关系类型。 其他语言的使用方式与Python类似,只需要将连接Stanford CoreNLP服务和调用依存句法分析的代码翻译成相应语言的语法即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值