如何在Pandas中应用零样本Transformer生成标签与概率列?
问题需求
- 已基于Hugging Face Transformer构建零样本分类pipeline,需将其应用于调查数据集的开放式回答列,逐行处理后实现两类数据输出:
- 单标签模式:拆分当前合并在
theme列中的标签与概率,生成独立的theme(最高概率标签)和prob(对应概率)列 - 多标签模式(开启
multi_label = True):筛选概率>0.6的结果,生成多组theme_n和prob_n列(n为序号,如theme_1、prob_1,theme_2、prob_2等)
- 单标签模式:拆分当前合并在
- 背景:刚从R转Python,需解决上述数据处理问题
数据集示例
import pandas as pd # 模拟调查数据集 survey_data = pd.DataFrame({ "open_response": [ "产品界面操作太复杂,找功能花了很久", "客服响应速度快,解决了我的登录问题,但支付流程有点卡顿", "对新推出的会员权益很满意,希望能增加更多专属内容" ] })
原自定义函数及运行代码
from transformers import pipeline # 初始化零样本分类pipeline classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") # 自定义分类函数(原版本,返回标签+概率的合并字符串) def classify_text(text, candidate_labels, multi_label=False): result = classifier(text, candidate_labels, multi_label=multi_label) return f"{result['labels'][0]} ({result['scores'][0]:.4f})" # 候选主题标签 candidate_labels = ["产品体验", "客服服务", "支付问题", "会员权益"] # 原运行方式:生成合并的theme列 survey_data["theme"] = survey_data["open_response"].apply( lambda x: classify_text(x, candidate_labels, multi_label=False) )
多标签模式原结果示例(合并状态)
开启multi_label=True时,原函数返回的合并结果示例:
"产品体验 (0.8923), 支付问题 (0.6541)"
解决方案
1. 单标签模式:拆分标签与概率列
修改自定义函数返回标签与概率的元组,再通过apply拆分到独立列:
# 修改后的单标签分类函数 def classify_single_label(text, candidate_labels): result = classifier(text, candidate_labels, multi_label=False) # 返回(最高概率标签, 对应概率)元组 return result['labels'][0], result['scores'][0] # 应用函数并拆分列 survey_data[["theme", "prob"]] = survey_data["open_response"].apply( lambda x: pd.Series(classify_single_label(x, candidate_labels)) )
处理后数据集示例:
| open_response | theme | prob |
|---|---|---|
| 产品界面操作太复杂,找功能花了很久 | 产品体验 | 0.9215 |
| 客服响应速度快,解决了我的登录问题,但支付流程有点卡顿 | 客服服务 | 0.7832 |
2. 多标签模式:生成多组theme_n和prob_n列
编写函数筛选概率>0.6的结果,整理为可扩展的列结构:
# 多标签分类处理函数 def classify_multi_label(text, candidate_labels, threshold=0.6): result = classifier(text, candidate_labels, multi_label=True) # 筛选符合阈值的结果,按概率降序排列 filtered = sorted( zip(result['labels'], result['scores']), key=lambda x: x[1], reverse=True ) filtered = [item for item in filtered if item[1] >= threshold] # 整理为theme_n/prob_n格式的字典 output = {} for i, (label, score) in enumerate(filtered, 1): output[f"theme_{i}"] = label output[f"prob_{i}"] = round(score, 4) return pd.Series(output) # 应用多标签函数并合并到原数据集 multi_label_results = survey_data["open_response"].apply( lambda x: classify_multi_label(x, candidate_labels) ) survey_data = pd.concat([survey_data, multi_label_results], axis=1)
处理后多标签数据集示例:
| open_response | theme_1 | prob_1 | theme_2 | prob_2 |
|---|---|---|---|---|
| 客服响应速度快,解决了我的登录问题,但支付流程有点卡顿 | 客服服务 | 0.9123 | 支付问题 | 0.6789 |
| 对新推出的会员权益很满意,希望能增加更多专属内容 | 会员权益 | 0.9567 | NaN | NaN |
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

