You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用NLTK与spaCy处理单句内双主题的情感分析

解决对比句中多主体的情感区分问题

你的核心问题在于SIA是对整句做情感分析,但对比句里的情感是相对的,没法直接用整句结果对应单个主体。当前代码只是重复跑整句分析,自然区分不开Dogs和Alligators的情感。

下面给你两种可行的改造思路,结合spaCy的语法分析来精准绑定主体和情感:


思路1:针对性拆分对比句

对于含than的对比句,直接根据结构把情感分配给前后主体:

  • 前面的主体(Dogs)对应正面情感(因为用了better这类褒义对比词)
  • 后面的主体(Alligators)对应负面/相对负面情感

修改后的代码如下:

import nltk
import spacy
from nltk.sentiment import SentimentIntensityAnalyzer
from spacy.matcher import PhraseMatcher

sia = SentimentIntensityAnalyzer()
nlp = spacy.load("en_core_web_sm")

text = """Dogs and cats make great pets.
Alligators make poor pets.
Dogs make better pets than Alligators."""

phrase_matcher = PhraseMatcher(nlp.vocab)
phrases = ['Dogs', 'Alligators']
patterns = [nlp(phrase) for phrase in phrases]
phrase_matcher.add('Pets', None, *patterns)

doc = nlp(text)
for sent in doc.sents:
    sent_text = sent.text
    # 先找出句子里的所有目标主体
    matches = phrase_matcher(sent)
    subjects = [sent[start:end].text for match_id, start, end in matches]
    
    # 处理对比句(含than)
    if 'than' in sent_text:
        # 拆分出前后主体
        parts = sent_text.split('than')
        if len(parts) == 2:
            # 前半部分的主体对应正面,后半部分对应负面
            for subj in subjects:
                if subj in parts[0]:
                    res = sia.polarity_scores(parts[0])
                    print(f"{subj} 的情感: {res} (来自对比前半段)")
                elif subj in parts[1]:
                    # 手动调整:对比句中后者是被否定的,取反向情感
                    res = sia.polarity_scores(sent_text)
                    adjusted_res = {
                        'neg': res['neg'] + res['pos'], 
                        'neu': res['neu'], 
                        'pos': 0.0, 
                        'compound': -res['compound']
                    }
                    print(f"{subj} 的情感: {adjusted_res} (来自对比后半段)")
    # 处理普通非对比句
    else:
        res = sia.polarity_scores(sent_text)
        for subj in subjects:
            print(f"{subj} 的情感: {res}")

思路2:用spaCy依赖分析绑定主体与修饰语

更通用的方法是通过spaCy的依赖关系,找到每个主体对应的谓语、形容词等修饰成分,单独分析这些成分的情感,精准匹配主体的情感倾向:

import nltk
import spacy
from nltk.sentiment import SentimentIntensityAnalyzer
from spacy.matcher import PhraseMatcher

sia = SentimentIntensityAnalyzer()
nlp = spacy.load("en_core_web_sm")

text = """Dogs and cats make great pets.
Alligators make poor pets.
Dogs make better pets than Alligators."""

phrase_matcher = PhraseMatcher(nlp.vocab)
phrases = ['Dogs', 'Alligators']
patterns = [nlp(phrase) for phrase in phrases]
phrase_matcher.add('Pets', None, *patterns)

doc = nlp(text)
for sent in doc.sents:
    matches = phrase_matcher(sent)
    for match_id, start, end in matches:
        subj = sent[start:end]
        # 找到主体对应的核心动词
        head_verb = subj.head
        # 收集和主体相关的描述性词汇(形容词、副词等)
        desc_tokens = []
        for child in head_verb.children:
            # 匹配表语、形容词补语、直接宾语等描述性成分
            if child.dep_ in ['acomp', 'attr', 'dobj']:
                desc_tokens.append(child.text)
                # 追加修饰该成分的副词
                desc_tokens.extend([gc.text for gc in child.children if gc.dep_ == 'advmod'])
        # 用描述词汇做情感分析
        if desc_tokens:
            desc_text = ' '.join(desc_tokens)
            res = sia.polarity_scores(desc_text)
            print(f"{subj.text} 的情感: {res} (来自描述: {desc_text})")
        else:
            # 无明确描述时 fallback到整句分析
            res = sia.polarity_scores(sent.text)
            print(f"{subj.text} 的情感: {res} (来自整句)")

思路1针对你的特定对比场景快速生效,思路2更通用,能处理更复杂的句子结构。你可以根据需求调整,比如给对比句的情感权重做手动修正,或者扩展依赖分析的规则覆盖更多情况。

内容的提问来源于stack exchange,提问作者McArtler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:14:57