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

如何识别句子中影响特定情感类别的词汇?附Transformer模型代码

找出Transformer情感分析中驱动情感类别的词汇实现思路

你当前使用nlptown/bert-base-multilingual-uncased-sentiment完成情感分类,要定位导致最终情感类别的关键词汇,以下是三种实用的实现思路,可直接结合你的现有代码调整:

1. 基于注意力权重的分析

Transformer的注意力机制天然能反映每个token对最终输出的贡献度,通过提取对应情感类别的注意力权重,就能定位关键词汇:

  • 实现步骤:
    1. 修改模型前向传播,让模型返回注意力权重;
    2. 对最后一层(或多层)的注意力权重取平均,映射到每个输入token;
    3. 按权重排序,筛选出权重最高的若干token。
  • 代码示例:
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

MODEL = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
txt = "你的测试文本"

# 编码文本并获取注意力权重
tokens = tokenizer.encode_plus(txt, add_special_tokens=True, return_tensors='pt')
outputs = model(**tokens, output_attentions=True)

# 提取最后一层注意力权重,取多头注意力的平均值
last_layer_attn = outputs.attentions[-1]  # shape: (1, num_heads, seq_len, seq_len)
avg_attn = last_layer_attn.mean(dim=1).squeeze(0)  # shape: (seq_len, seq_len)
# 取<CLS> token对其他token的注意力(因为<CLS>对应最终分类输出)
cls_attn = avg_attn[0][1:-1]  # 去掉<CLS>和<SEP>对应的权重

# 映射token和权重
input_tokens = tokenizer.convert_ids_to_tokens(tokens['input_ids'][0])[1:-1]
token_attn_pairs = list(zip(input_tokens, cls_attn.tolist()))
# 按权重降序排序
token_attn_pairs.sort(key=lambda x: x[1], reverse=True)

print("按注意力权重排序的关键词汇:")
for token, attn in token_attn_pairs[:5]:  # 取top5
    print(f"{token}: {attn:.4f}")

2. 基于梯度的特征重要性(Integrated Gradients)

通过计算每个token嵌入对目标情感类别概率的梯度,梯度绝对值越大,说明该token对结果的影响越强:

  • 实现步骤:
    1. 将token输入设置为可求导;
    2. 计算目标类别概率对token嵌入的梯度;
    3. 对梯度取绝对值并平均,映射到token后排序。
  • 代码示例:
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

MODEL = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
txt = "你的测试文本"
sen_dict= {1:'Highly-negative',2:'Negative',3:'Neutral',4:'Positive',5:'Highly-positive'}

# 编码文本,保留token嵌入并设置可求导
tokens = tokenizer.encode_plus(txt, add_special_tokens=True, return_tensors='pt')
input_ids = tokens['input_ids']
embeddings = model.get_input_embeddings()(input_ids)
embeddings.requires_grad = True

# 前向传播获取输出
outputs = model(inputs_embeds=embeddings, attention_mask=tokens['attention_mask'])
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
sen_idx = probs.argmax(dim=1).item() + 1  # 对应1-5的情感类别
target_prob = probs[0, sen_idx-1]  # 目标类别概率

# 计算梯度
target_prob.backward()
gradients = embeddings.grad.squeeze(0)
# 对梯度取绝对值,按token维度平均(因为每个token嵌入是多维的)
token_importance = gradients.abs().mean(dim=1).tolist()[1:-1]  # 去掉<CLS>和<SEP>

# 映射token和重要性
input_tokens = tokenizer.convert_ids_to_tokens(input_ids[0])[1:-1]
token_importance_pairs = list(zip(input_tokens, token_importance))
token_importance_pairs.sort(key=lambda x: x[1], reverse=True)

print(f"驱动{sen_dict[sen_idx]}的关键词汇:")
for token, importance in token_importance_pairs[:5]:
    print(f"{token}: {importance:.4f}")

3. 基于遮挡的分析(Occlusion Testing)

逐个遮挡输入中的每个token(替换为[MASK]或删除),观察目标情感类别概率的变化,下降越多说明该token越关键:

  • 实现步骤:
    1. 计算原文本的目标类别概率;
    2. 遍历每个token,生成遮挡后的文本并计算对应概率;
    3. 计算概率差值,差值大的token即为关键词汇。
  • 代码示例:
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

MODEL = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL)
txt = "你的测试文本"
sen_dict= {1:'Highly-negative',2:'Negative',3:'Neutral',4:'Positive',5:'Highly-positive'}

# 计算原文本的情感概率和类别
tokens = tokenizer.encode_plus(txt, add_special_tokens=True, return_tensors='pt')
outputs = model(**tokens)
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
sen_idx = probs.argmax(dim=1).item() + 1
original_prob = probs[0, sen_idx-1].item()

# 遍历每个token(排除<CLS>和<SEP>)
input_ids = tokens['input_ids'][0].tolist()
input_tokens = tokenizer.convert_ids_to_tokens(input_ids)
token_importance = []

for i in range(1, len(input_ids)-1):
    # 替换当前token为[MASK]
    occluded_ids = input_ids.copy()
    occluded_ids[i] = tokenizer.mask_token_id
    occluded_tokens = {'input_ids': torch.tensor([occluded_ids]), 'attention_mask': tokens['attention_mask']}
    
    # 计算遮挡后的概率
    with torch.no_grad():
        occluded_outputs = model(**occluded_tokens)
        occluded_probs = torch.nn.functional.softmax(occluded_outputs.logits, dim=-1)
        occluded_prob = occluded_probs[0, sen_idx-1].item()
    
    # 概率下降值越大,token越关键
    importance = original_prob - occluded_prob
    token_importance.append((input_tokens[i], importance))

# 按重要性降序排序
token_importance.sort(key=lambda x: x[1], reverse=True)

print(f"驱动{sen_dict[sen_idx]}的关键词汇:")
for token, importance in token_importance[:5]:
    print(f"{token}: {importance:.4f}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:02:03