跳转到内容
计算社会科学

用 Potato 做计算社会科学与文本即数据

为新闻和社交媒体帖子编码立场、框架和不文明用语,按问题报告 Krippendorff's alpha,并对照人工编码者检查 LLM 的标签。

Potato 为新闻文章、社交媒体帖子、演讲和评论串编码立场、框架、毒性和虚假信息,每个条目由多位编码者处理,并按问题报告 Krippendorff's alpha。Potato 以声明的模型 ID 记录 LLM 的标签,并把模型与人的一致性同人与人之间的一致性分开报告。

计算社会科学用计算方法研究社会行为,该领域的大量工作把文本当作数据。Grimmer 和 Stewart(2013)综述了用于政治文本的自动内容分析方法。在这类工作中,人工编码的标签有三种用途。标签用来训练分类器,标签是检验模型输出的参照,当语料库小到可以全部编码时,标签本身就是测量。由于每种用途都要求编码者以同样的方式应用编码手册,编码的可靠性也是结果的一部分。Potato 把条目分配给编码者,分别保存每位编码者的回答,并在编码进行时按问题报告一致性。问卷和调查实验见调查研究页面。

Potato 中的文本即数据任务

每一行是 Potato 2.13.1 自带的一项功能,链接页面列出了它的选项。

任务Potato 的做法文档
用编码手册做内容分析radio 和 multiselect 问题,或从 CSV、JSON 或 YAML 文件加载的 hierarchical_multiselect 编码手册内容分析
对某个目标的立场通过 instance_display 把目标显示在文本旁边,再用一道 radio 问题选择支持、反对或都不是单选与多选
框架对框架类别做 multiselect,例如 Media Frames Corpus 的 15 个框架维度单选与多选
毒性与不文明用语用 likert 评分表示程度,用 span 标签标出使评论带有毒性的词语文本片段标注
虚假信息与论断用 span 标签标出值得核查的论断,用 radio 对每条论断做出判定文本片段标注
把文本标度到一个连续维度上bws 元组,由 python -m potato.bws_scoring 用计数法或 Plackett-Luce 模型为每条文本算出一个值最佳最差标度
众包编码通过 Prolific 招募,配合 attention_checks,以及设有准确率下限的 gold_standards众包
对照人工检查的 LLM 辅助编码machine_annotators 把模型声明为一位编码者,一致性报告把模型与人分开LLM 辅助编码
回复串与对话potato convokit 把 ConvoKit 语料库转成 Potato 条目,并保留回复结构串联对话

在一个任务中编码立场、框架和不文明用语

一个任务可以针对同一条帖子提出多个问题。下面的配置把立场目标显示在每条帖子上方,询问作者的立场、帖子使用的框架,以及帖子有多不文明,每个条目有三位编码者。框架标签是 Media Frames Corpus 维度的一个子集,真正的编码手册会在指南中定义每一个框架。

yaml
annotation_task_name: "Stance and framing in news posts"
task_dir: "."
data_files:
  - data/posts.jsonl
item_properties:
  id_key: id
  text_key: text
instance_display:
  fields:
    - key: target
      type: text
      label: "Target"
    - key: text
      type: text
      label: "Post"
output_annotation_dir: annotation_output/
user_config:
  allow_all_users: true
num_annotators_per_item: 3
agreement_metrics:
  enabled: true
  min_overlap: 2
annotation_schemes:
  - annotation_type: radio
    name: stance
    description: "What position does the author take toward the target?"
    labels: [favor, against, neither]
    label_requirement:
      required: true
  - annotation_type: multiselect
    name: frames
    description: "Which frames does the post use? Select all that apply."
    labels: [economic, morality, fairness and equality, legality, security and defense, public opinion, other]
  - annotation_type: likert
    name: incivility
    description: "How uncivil is the post?"
    size: 5
    min_label: "Civil"
    max_label: "Very uncivil"

data/posts.jsonl 中的每个条目带有 id、target 和 text 字段。每个条目三位编码者比两位成本更高。第三位编码者能打破大多数平局,并让不文明用语这类主观问题上的 alpha 更稳定。需要多少位标注者?分析了其中的取舍。编码结束后,reliability 导出会为每个问题写出 Krippendorff's alpha 及自助法区间,立场按名义水平计算,框架集合有重叠时给予部分得分,不文明用语按有序水平计算。

检查众包编码者和 LLM 编码者

Benoit 等人(2016)报告说,由许多非专家的众包工作者编码的政治文本,得到的结果与专家编码相当。Potato 通过 Prolific 招募编码者,并用 attention_checks 筛选每一位编码者,gold_standards 则在运行期间用已知答案的条目度量每位编码者的准确率。金标准与注意力检查介绍了这两种检查。

Gilardi、Alizadeh 和 Kubli(2023)发现,在 2,382 条推文的五项标注任务中,ChatGPT 的零样本准确率在其中四项上超过了众包工作者,这些任务包括立场和框架检测。模型在你的编码手册和你的语料库上是否也一样好,是每项研究都要用实证回答的问题。Potato 以 machine_annotators 中声明的 ID 记录模型的标签,并附上模型名称和运行日期。/admin/iaa 上的一致性报告随后把主要数字保持为仅限人工,并把模型单独报告,csv、tsv 和 parquet 导出还会添加一个 annotator_origin 列,标明每一行来自人还是来自模型。对于单选和评分类问题,一旦有三位或更多的人各自编码了 30 个或更多模型也编码过的条目,管理 API 就会运行 Calderon、Reichart 和 Dror(2025)的替代标注者检验。

导入数据与导出标签

数据文件是 JSON、JSONL、CSV 或 TSV,每行一个条目。在你自己的流程中抽取的帖子或文章样本可以不经转换直接加载。ConvoKit 格式的语料库用一条命令就能导入。下面这条命令为每段对话写出一个条目,并根据语料库元数据生成一份起始配置:

bash
potato convokit conversations-gone-awry-corpus -o data/awry.jsonl --emit-config config.yaml

标签可以导出为每位编码者每个条目一行的 csv、jsonl 或 parquet,也可以导出为用于训练分类器的 Hugging Face 数据集。按编码者逐行的文件保留了每位编码者的回答,供一致性分析使用。convokit 导出会把标签写回语料库的话语和对话上。

与 Prolific、Label Studio 和电子表格的分工

许多内容分析项目在电子表格里编码,许多众包项目在问卷工具里搭建编码表单,再通过 Prolific 招募。这两种做法都把条目到编码者的分配、重叠样本和一致性统计,留给为每项研究单独编写的脚本。Label Studio 是一个开源的数据标注与 AI 评估平台,在一个界面中涵盖文本、图像、音频和时间序列。Potato 围绕编码研究而构建,每个条目的编码者人数在配置中设定,带有注意力检查和金标准检查,按问题报告可靠性,并有一份能为方法部分复现任务的配置文件。Prolific 招募经过验证的学术研究参与者,参与者到达后,由 Potato 运行编码。

借助编程智能体搭建研究

potato-skill 为 Claude Code、Codex 或 Cursor 提供设计和构建 Potato 研究的说明。用平实的语言描述这项工作,就足以开始。一条请求可以短到这样:

为 3,000 条关于碳税的推文设置立场编码,每条推文三位 Prolific 编码者,用十条金标准推文做筛选,并按问题报告 Krippendorff's alpha。

智能体会列出过程中做出的每一项假设,构建 Potato 任务,并把任务渲染出来以检查结果。在邀请标注者之前,先自己打开任务,标几个条目。

常见问题

如何标注推文对某个目标的立场?

用 instance_display 把目标显示在每条推文旁边,再提出一道 radio 问题,选项为支持、反对和都不是,做法与 SemEval-2016 Task 6 相同。目标存放在每个条目的数据中,一个任务就可以涵盖多个目标。立场不同于情感,因为语气负面的推文仍可能支持该目标。指南应当为每种情况各给一个例子。立场检测设计是一份起始配置。

ChatGPT 能取代众包工作者做文本标注吗?

在一项已发表的推文对比中,ChatGPT 在五项文本标注任务里有四项胜过众包工作者,而用你自己的条目做一次测试,才能显示模型在你的数据上表现如何。让人在看不到模型标签的情况下编码一个样本,在 machine_annotators 中声明模型,并把模型与人的一致性同人与人之间的一致性相比较。管理 API 会运行替代标注者检验,用来检查模型能否代替其中一位人工编码者。

延伸阅读

参考文献

  1. Grimmer and Stewart (2013). Text as Data: The Promise and Pitfalls of Automatic Content Analysis Methods for Political Texts. Political Analysis 21(3). https://doi.org/10.1093/pan/mps028
  2. Card, Boydstun, Gross, Resnik, and Smith (2015). The Media Frames Corpus: Annotations of Frames Across Issues. ACL-IJCNLP 2015. https://doi.org/10.3115/v1/P15-2072
  3. Mohammad, Kiritchenko, Sobhani, Zhu, and Cherry (2016). SemEval-2016 Task 6: Detecting Stance in Tweets. SemEval-2016. https://doi.org/10.18653/v1/S16-1003
  4. Benoit, Conway, Lauderdale, Laver, and Mikhaylov (2016). Crowd-sourced Text Analysis: Reproducible and Agile Production of Political Data. American Political Science Review 110(2). https://doi.org/10.1017/S0003055416000058
  5. Gilardi, Alizadeh, and Kubli (2023). ChatGPT Outperforms Crowd Workers for Text-Annotation Tasks. Proceedings of the National Academy of Sciences 120(30). https://doi.org/10.1073/pnas.2305016120
  6. Calderon, Reichart, and Dror (2025). The Alternative Annotator Test for LLM-as-a-Judge: How to Statistically Justify Replacing Human Annotators with LLMs. ACL 2025. https://doi.org/10.18653/v1/2025.acl-long.782

示例设计

每个设计都是可以下载并直接运行的 Potato 配置。

从这里开始

其他领域

全部应用场景