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

如何用yangheng/deberta-v3-base-absa-v1.1模型实现ABSA任务并修复报错?

问题描述

现有一个包含文本和预定义Aspect的DataFrame,部分行无预定义Aspect,数据示例如下:

data = {
    'text': [
        "The camera quality of this phone is amazing.",
        "The belt is poor quality",
        "The battery life could be improved.",
        "The display is sharp and vibrant.",
        "The customer service was disappointing."
    ],
    'aspects': [
        ["camera", "phone"],
        [],
        ["battery", "life"],
        ["display"],
        ["customer service"]
    ]
}

df = pd.DataFrame(data)

需完成两项任务:

  1. 基于文本的预定义Aspect生成情感得分;
  2. 对无预定义Aspect的行,自动提取Aspect并生成对应情感得分。

使用模型yangheng/deberta-v3-base-absa-v1.1,尝试编写代码后报错,原代码如下:

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import pandas as pd

# Load the ABSA model and tokenizer
model_name = "yangheng/deberta-v3-base-absa-v1.1"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)

# Generate aspects and sentiments
aspects = []
sentiments = []

for index, row in df.iterrows():
    text = row['text']
    row_aspects = row['aspects']
    
    aspect_sentiments = []
    
    for aspect in row_aspects:
        inputs = tokenizer(text, aspect, return_tensors="pt")
        
        with torch.inference_mode():
            outputs = model(**inputs)
        
        predicted_sentiment = torch.argmax(outputs.logits).item()
        sentiment_label = model.config.id2label[predicted_sentiment]
        
        aspect_sentiments.append(f"{aspect}: {sentiment_label}")
    
    aspects.append(row_aspects)
    sentiments.append(aspect_sentiments)

# Add the generated aspects and sentiments to the DataFrame
df['generated_aspects'] = aspects
df['generated_sentiments'] = sentiments

# Print the updated DataFrame
print(df)

模型官方使用示例:

import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModelForSequenceClassification

model_name = "yangheng/deberta-v3-base-absa-v1.1"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)

aspects = ["food", "service"]
text = "The food was great but the service was terrible."
sentiment_aspect = {}
for aspect in aspects:
  inputs = tokenizer(text, aspect, return_tensors="pt")

  with torch.inference_mode():
    outputs = model(**inputs)

  scores = F.softmax(outputs.logits[0], dim=-1)
  label_id = torch.argmax(scores).item()
  sentiment_aspect[aspect] = (model.config.id2label[label_id], scores[label_id].item())

print(sentiment_aspect)

期望输出:DataFrame新增generated_aspects和generated_sentiments列,无预定义Aspect的行自动提取Aspect并生成对应情感得分。


解决方案

问题分析

原代码仅处理了有预定义Aspect的行,未实现无预定义Aspect时的自动提取功能;同时未计算情感得分(仅输出标签),也未处理长文本截断等潜在格式问题。

完整实现代码

要完成自动提取Aspect,需搭配Aspect提取模型(yangheng/deberta-v3-base-aspect-extractor),先提取文本中的Aspect,再用ABSA模型判断情感。以下是完整代码:

import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoModelForTokenClassification
import pandas as pd
from typing import List

# 加载ABSA情感分析模型和Aspect提取模型
absa_model_name = "yangheng/deberta-v3-base-absa-v1.1"
aspect_extractor_model_name = "yangheng/deberta-v3-base-aspect-extractor"

# 初始化ABSA模型和分词器
absa_tokenizer = AutoTokenizer.from_pretrained(absa_model_name)
absa_model = AutoModelForSequenceClassification.from_pretrained(absa_model_name)

# 初始化Aspect提取模型和分词器
aspect_extractor_tokenizer = AutoTokenizer.from_pretrained(aspect_extractor_model_name)
aspect_extractor_model = AutoModelForTokenClassification.from_pretrained(aspect_extractor_model_name)

def extract_aspects(text: str) -> List[str]:
    """从文本中自动提取Aspect"""
    inputs = aspect_extractor_tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
    with torch.inference_mode():
        outputs = aspect_extractor_model(**inputs)
    
    predictions = torch.argmax(outputs.logits, dim=2)[0].tolist()
    tokens = aspect_extractor_tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])
    
    aspects = []
    current_aspect = []
    for token, pred in zip(tokens, predictions):
        if pred == 1:  # B-ASPECT(Aspect起始标记)
            if current_aspect:
                aspects.append(aspect_extractor_tokenizer.convert_tokens_to_string(current_aspect))
                current_aspect = []
            current_aspect.append(token)
        elif pred == 2:  # I-ASPECT(Aspect延续标记)
            current_aspect.append(token)
        else:
            if current_aspect:
                aspects.append(aspect_extractor_tokenizer.convert_tokens_to_string(current_aspect))
                current_aspect = []
    # 处理最后一个未闭合的Aspect
    if current_aspect:
        aspects.append(aspect_extractor_tokenizer.convert_tokens_to_string(current_aspect))
    
    # 去重并清理特殊字符
    aspects = list(set([aspect.strip().replace("▁", " ") for aspect in aspects if aspect.strip()]))
    return aspects

def get_sentiment(text: str, aspect: str):
    """获取指定Aspect的情感标签和得分"""
    inputs = absa_tokenizer(text, aspect, return_tensors="pt", truncation=True, max_length=512)
    with torch.inference_mode():
        outputs = absa_model(**inputs)
    
    scores = F.softmax(outputs.logits[0], dim=-1)
    label_id = torch.argmax(scores).item()
    sentiment_label = absa_model.config.id2label[label_id]
    sentiment_score = scores[label_id].item()
    return sentiment_label, sentiment_score

# 处理DataFrame
generated_aspects_list = []
generated_sentiments_list = []

for _, row in df.iterrows():
    text = row["text"]
    predefined_aspects = row["aspects"]
    
    # 确定要处理的Aspect:有预定义则用预定义,否则自动提取
    target_aspects = predefined_aspects if predefined_aspects else extract_aspects(text)
    
    # 处理每个Aspect的情感
    sentiment_results = []
    for aspect in target_aspects:
        label, score = get_sentiment(text, aspect)
        sentiment_results.append(f"{aspect}: {label} (得分: {round(score, 4)})")
    
    generated_aspects_list.append(target_aspects)
    generated_sentiments_list.append(sentiment_results)

# 添加新列到DataFrame
df["generated_aspects"] = generated_aspects_list
df["generated_sentiments"] = generated_sentiments_list

# 打印结果
print(df)

代码说明

  1. Aspect提取:通过yangheng/deberta-v3-base-aspect-extractor的Token分类功能,识别文本中属于Aspect的连续token,拼接后清理格式并去重。
  2. 情感分析:对每个Aspect(预定义或自动提取),调用ABSA模型计算情感标签和置信度得分,用softmax转换为概率值作为情感得分。
  3. DataFrame处理:遍历每行数据,根据是否有预定义Aspect选择对应逻辑,将结果存入新增列。

注意事项

  • 确保安装依赖库:pip install torch transformers pandas
  • 首次运行会自动下载模型权重,需保证网络通畅
  • 可根据文本长度调整max_length参数,适配更长文本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:54:57