📖 更新 README: 讲义内容展示在仓库首页
This commit is contained in:
894
README.md
894
README.md
@@ -1,3 +1,893 @@
|
|||||||
# homework-4-4
|
<!--
|
||||||
|
本文件由助教自动生成
|
||||||
|
课程: 人工智能数据服务 (090945)
|
||||||
|
班级: AI_251
|
||||||
|
学号: 2509165033
|
||||||
|
原讲义文件: 4-4_标注质量控制与标注管理_学生讲义.md
|
||||||
|
-->
|
||||||
|
|
||||||
4-4 标注质量控制与标注管理(Label Studio)
|
# 4-4 标注质量控制与标注管理(Label Studio)
|
||||||
|
|
||||||
|
## 学习目标
|
||||||
|
|
||||||
|
1. 理解标注质量对 AI 模型的决定性影响
|
||||||
|
2. 掌握 Cohen's Kappa 等一致性指标的计算
|
||||||
|
3. 学会在 Label Studio 中管理组织、成员、角色
|
||||||
|
4. 掌握审核员工作流:抽检、Approve、Reject
|
||||||
|
5. 学会用 Label Studio 解决标注冲突
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 为什么标注质量如此重要
|
||||||
|
|
||||||
|
### 1.1 "垃圾进,垃圾出"原则
|
||||||
|
|
||||||
|
AI 模型效果有个基本规律:
|
||||||
|
|
||||||
|
```
|
||||||
|
高质量标注 + 普通模型 = 还不错的 AI
|
||||||
|
低质量标注 + 顶级模型 = 垃圾 AI
|
||||||
|
```
|
||||||
|
|
||||||
|
**反例**:
|
||||||
|
|
||||||
|
```
|
||||||
|
文本: "苹果很好吃"
|
||||||
|
错误标注: negative ❌
|
||||||
|
正确标注: positive ✅
|
||||||
|
|
||||||
|
结果: AI 学到 "苹果" → 负面
|
||||||
|
但 "苹果" 也可能是公司/手机
|
||||||
|
→ 模型产生错误关联
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 质量问题的代价
|
||||||
|
|
||||||
|
| 阶段 | 代价 | 后果 |
|
||||||
|
|------|------|------|
|
||||||
|
| **标注时** | 低 | 重新标一份数据 |
|
||||||
|
| **训练时** | 中 | 模型效果差,调参浪费时间 |
|
||||||
|
| **上线后** | 高 | 错误预测影响业务 |
|
||||||
|
| **发现后** | 极高 | 返工、数据回炉、商业损失 |
|
||||||
|
|
||||||
|
**越晚发现问题,代价越大**——质量控制必须贯穿全程。
|
||||||
|
|
||||||
|
### 1.3 常见质量问题
|
||||||
|
|
||||||
|
```
|
||||||
|
❌ 标注不一致 两人对同一数据标不同结果
|
||||||
|
❌ 标注错误 把正面标成了负面
|
||||||
|
❌ 标注遗漏 3个目标只标了2个
|
||||||
|
❌ 标注模糊 边界不清,不知标不标
|
||||||
|
❌ 格式错误 坐标超界、JSON 错
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 标注一致性指标
|
||||||
|
|
||||||
|
### 2.1 什么是一致性
|
||||||
|
|
||||||
|
**标注一致性** = 多人对同一份数据的标注结果一致的程度。
|
||||||
|
|
||||||
|
```
|
||||||
|
一致性好:
|
||||||
|
标注员A: "苹果" → 水果
|
||||||
|
标注员B: "苹果" → 水果
|
||||||
|
✅ 两人一致
|
||||||
|
|
||||||
|
一致性差:
|
||||||
|
标注员A: "苹果" → 水果
|
||||||
|
标注员B: "苹果" → 公司
|
||||||
|
❌ 两人不一致
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 简单一致率
|
||||||
|
|
||||||
|
最基础的指标:
|
||||||
|
|
||||||
|
```
|
||||||
|
一致率 = 一致的数量 / 总数量
|
||||||
|
|
||||||
|
例: 100 条数据, 70 条两人标的一致
|
||||||
|
一致率 = 70/100 = 70%
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:未排除随机一致。
|
||||||
|
|
||||||
|
```
|
||||||
|
两人都随机标,三类问题时:
|
||||||
|
期望一致率 = 1/3 = 33%
|
||||||
|
|
||||||
|
但实际可能是"看似 70% 一致",
|
||||||
|
其中 33% 是随机碰巧一致
|
||||||
|
→ 真实一致性被高估
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Cohen's Kappa 系数
|
||||||
|
|
||||||
|
排除随机一致性的指标:
|
||||||
|
|
||||||
|
```
|
||||||
|
P₀ - Pₑ
|
||||||
|
κ = ─────────────
|
||||||
|
1 - Pₑ
|
||||||
|
|
||||||
|
P₀ = 实际观察一致率
|
||||||
|
Pₑ = 期望一致率(随机情况下)
|
||||||
|
```
|
||||||
|
|
||||||
|
**解读标准**:
|
||||||
|
|
||||||
|
| Kappa 值 | 含义 |
|
||||||
|
|----------|------|
|
||||||
|
| κ > 0.9 | 几乎完美一致 |
|
||||||
|
| 0.8 < κ ≤ 0.9 | 高度一致 |
|
||||||
|
| 0.6 < κ ≤ 0.8 | 中等一致(可接受)|
|
||||||
|
| 0.4 < κ ≤ 0.6 | 一致性一般 |
|
||||||
|
| κ ≤ 0.4 | 一致性差,需改进 |
|
||||||
|
|
||||||
|
### 2.4 Kappa 计算示例
|
||||||
|
|
||||||
|
**场景**:两人都对 100 条评论做"正面/负面"二分类标注。
|
||||||
|
|
||||||
|
```
|
||||||
|
标注员B
|
||||||
|
正面 负面 合计
|
||||||
|
标 正面 50 10 60
|
||||||
|
注 ─────────────────────
|
||||||
|
员 负面 5 35 40
|
||||||
|
A
|
||||||
|
合计 55 45 100
|
||||||
|
```
|
||||||
|
|
||||||
|
**计算**:
|
||||||
|
|
||||||
|
```
|
||||||
|
P₀ = 实际一致率 = (50+35)/100 = 0.85
|
||||||
|
|
||||||
|
Pₑ = 期望一致率(两人独立随机标)
|
||||||
|
= (60/100)×(55/100) + (40/100)×(45/100)
|
||||||
|
= 0.33 + 0.18
|
||||||
|
= 0.51
|
||||||
|
|
||||||
|
κ = (0.85 - 0.51) / (1 - 0.51)
|
||||||
|
= 0.34 / 0.49
|
||||||
|
≈ 0.69
|
||||||
|
```
|
||||||
|
|
||||||
|
**结论**:κ = 0.69,介于 0.6-0.8 之间,**中等一致**(可接受但有提升空间)。
|
||||||
|
|
||||||
|
### 2.5 Python 代码实现
|
||||||
|
|
||||||
|
```python
|
||||||
|
from sklearn.metrics import cohen_kappa_score
|
||||||
|
|
||||||
|
annotations_a = ['positive', 'negative', 'positive', 'positive',
|
||||||
|
'negative'] * 20
|
||||||
|
annotations_b = ['positive', 'negative', 'positive', 'positive',
|
||||||
|
'negative'] * 20
|
||||||
|
|
||||||
|
kappa = cohen_kappa_score(annotations_a, annotations_b)
|
||||||
|
print(f"Kappa = {kappa:.3f}")
|
||||||
|
# 两人完全一致 → Kappa = 1.000
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 不同结果示例
|
||||||
|
annotations_a = ['positive'] * 60 + ['negative'] * 40
|
||||||
|
annotations_b = ['positive'] * 55 + ['negative'] * 45
|
||||||
|
|
||||||
|
kappa = cohen_kappa_score(annotations_a, annotations_b)
|
||||||
|
print(f"Kappa = {kappa:.3f}")
|
||||||
|
# Kappa ≈ 0.69
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.6 F1 一致性(适合 NER)
|
||||||
|
|
||||||
|
对于 NER 等"集合型"任务,用 F1 比较两次标注的实体集合:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def ner_f1(entities_a, entities_b):
|
||||||
|
"""entities 是 [(text, type, start, end), ...] 列表"""
|
||||||
|
set_a = set(entities_a)
|
||||||
|
set_b = set(entities_b)
|
||||||
|
|
||||||
|
tp = len(set_a & set_b) # 都标了
|
||||||
|
fp = len(set_a - set_b) # A 标了 B 没标
|
||||||
|
fn = len(set_b - set_a) # B 标了 A 没标
|
||||||
|
|
||||||
|
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
|
||||||
|
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
|
||||||
|
f1 = 2 * precision * recall / (precision + recall) \
|
||||||
|
if (precision + recall) > 0 else 0
|
||||||
|
|
||||||
|
return precision, recall, f1
|
||||||
|
|
||||||
|
# 例
|
||||||
|
a = [("张伟", "PER", 0, 2), ("清华", "ORG", 5, 7)]
|
||||||
|
b = [("张伟", "PER", 0, 2), ("清华", "ORG", 5, 7), ("北京", "LOC", 10, 12)]
|
||||||
|
|
||||||
|
p, r, f1 = ner_f1(a, b)
|
||||||
|
print(f"P={p:.2f} R={r:.2f} F1={f1:.2f}")
|
||||||
|
# P=1.00 R=0.67 F1=0.80
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.7 Fleiss Kappa(多人版)
|
||||||
|
|
||||||
|
3 人及以上用 **Fleiss Kappa**:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from statsmodels.stats.inter_rater import fleiss_kappa
|
||||||
|
|
||||||
|
# 每个任务每个类别有多少人标
|
||||||
|
# 例: 5个任务, 3个类别, 4人标注
|
||||||
|
counts = [
|
||||||
|
[4, 0, 0], # 任务1: 4人都标类别0
|
||||||
|
[0, 4, 0], # 任务2: 4人都标类别1
|
||||||
|
[2, 2, 0], # 任务3: 2人标0, 2人标1
|
||||||
|
[1, 1, 2], # 任务4: 各有分歧
|
||||||
|
[0, 0, 4], # 任务5: 4人都标类别2
|
||||||
|
]
|
||||||
|
|
||||||
|
kappa = fleiss_kappa(counts)
|
||||||
|
print(f"Fleiss Kappa = {kappa:.3f}")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 标注规范制定
|
||||||
|
|
||||||
|
### 3.1 规范的重要性
|
||||||
|
|
||||||
|
**标注规范 = 标注员的工作手册**。
|
||||||
|
|
||||||
|
```
|
||||||
|
没有规范 → 标注员理解不同 → 标注不一致 → 模型效果差
|
||||||
|
↓
|
||||||
|
一份好的规范能让 10 个标注员标得像 1 个人
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 规范的核心内容
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 任务背景 项目目标、数据来源、用途
|
||||||
|
2. 标签定义 每个标签的精确含义
|
||||||
|
3. 标注示例 正例、反例、边界情况
|
||||||
|
4. 标注流程 步骤、工具、快捷键
|
||||||
|
5. 质量要求 准确率、一致性、格式
|
||||||
|
6. 常见问题 FAQ
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 规范模板:情感分析
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# 情感分析标注规范 v1.0
|
||||||
|
|
||||||
|
## 1. 任务定义
|
||||||
|
对用户评论做情感分类,标签: positive / negative / neutral
|
||||||
|
|
||||||
|
## 2. 标签定义
|
||||||
|
|
||||||
|
| 标签 | 定义 | 关键词 |
|
||||||
|
|------|------|--------|
|
||||||
|
| positive | 满意、喜欢、赞美 | 好、棒、赞、超赞、完美 |
|
||||||
|
| negative | 不满、失望、抱怨 | 差、烂、垃圾、失望、后悔 |
|
||||||
|
| neutral | 客观陈述,无情感 | (无明显情感词) |
|
||||||
|
|
||||||
|
## 3. 标注示例
|
||||||
|
|
||||||
|
### ✅ positive
|
||||||
|
- "这家餐厅的菜特别好吃,下次还来"
|
||||||
|
- "服务态度很好,很满意"
|
||||||
|
|
||||||
|
### ✅ negative
|
||||||
|
- "等了两个小时还没上菜,差评"
|
||||||
|
- "产品质量太差,用了几天就坏了"
|
||||||
|
|
||||||
|
### ✅ neutral
|
||||||
|
- "今天吃了火锅" (单纯陈述)
|
||||||
|
- "这家店在市中心" (客观描述)
|
||||||
|
|
||||||
|
## 4. 歧义处理
|
||||||
|
|
||||||
|
| 情况 | 处理 |
|
||||||
|
|------|------|
|
||||||
|
| 反讽 | "真是太好了,等了2小时" → negative |
|
||||||
|
| "还行" / "一般" | neutral |
|
||||||
|
| 双重否定 | "不差" → positive |
|
||||||
|
| 混合情感 | 选主要的,不明显时 neutral |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Label Studio 项目管理实战
|
||||||
|
|
||||||
|
### 4.1 整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
Label Studio 组织架构:
|
||||||
|
|
||||||
|
Organization 组织
|
||||||
|
├── Administrator 管理员 (1人)
|
||||||
|
│ ├── 项目设置
|
||||||
|
│ ├── 成员管理
|
||||||
|
│ └── 角色分配
|
||||||
|
│
|
||||||
|
├── Project A
|
||||||
|
│ ├── Annotator 标注员1
|
||||||
|
│ ├── Annotator 标注员2
|
||||||
|
│ └── Reviewer 审核员1
|
||||||
|
│
|
||||||
|
└── Project B
|
||||||
|
├── Annotator 标注员3
|
||||||
|
└── Reviewer 审核员2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 邀请成员
|
||||||
|
|
||||||
|
**步骤**:
|
||||||
|
|
||||||
|
1. 管理员登录 Label Studio
|
||||||
|
2. 顶部菜单 → `Organization` → `Members`
|
||||||
|
3. 看到成员列表
|
||||||
|
4. 点 `Add Member`
|
||||||
|
5. 输入新成员邮箱
|
||||||
|
6. 选择角色(管理员默认是 Owner)
|
||||||
|
7. 发送邀请
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────┐
|
||||||
|
│ Organization Members │
|
||||||
|
├────────────────────────────────────────┤
|
||||||
|
│ user1@example.com [Owner] [...] │
|
||||||
|
│ user2@example.com [Admin] [...] │
|
||||||
|
│ user3@example.com [Annotator] │
|
||||||
|
│ user4@example.com [Reviewer] │
|
||||||
|
│ │
|
||||||
|
│ [ + Add Member ] │
|
||||||
|
└────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注:Label Studio 在较新版本中区分 Owner / Admin / Annotator / Reviewer。**核心是 Admin / Annotator / Reviewer** 这三种角色。
|
||||||
|
|
||||||
|
### 4.3 三种核心角色
|
||||||
|
|
||||||
|
| 角色 | 权限 |
|
||||||
|
|------|------|
|
||||||
|
| **Admin 管理员** | 创建/删除项目、邀请成员、配置项目、查看所有数据、导出 |
|
||||||
|
| **Annotator 标注员** | 进入被分配的项目、做标注、看到自己的进度 |
|
||||||
|
| **Reviewer 审核员** | 进入被分配的项目、看到所有标注、做 Approve/Reject |
|
||||||
|
|
||||||
|
```
|
||||||
|
Admin 视角:
|
||||||
|
┌─ 项目管理
|
||||||
|
├─ 成员管理
|
||||||
|
├─ 查看所有标注
|
||||||
|
└─ 导出数据
|
||||||
|
|
||||||
|
Annotator 视角:
|
||||||
|
┌─ 我被分配的任务
|
||||||
|
├─ 标注
|
||||||
|
└─ 看自己的进度
|
||||||
|
|
||||||
|
Reviewer 视角:
|
||||||
|
┌─ 所有标注
|
||||||
|
├─ 抽检
|
||||||
|
└─ Approve / Reject
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 创建项目(管理员操作)
|
||||||
|
|
||||||
|
1. `+ Create Project`
|
||||||
|
2. 填写:
|
||||||
|
- **Project Name**: `product_review_sentiment`
|
||||||
|
- **Description**: 商品评论情感三分类
|
||||||
|
3. 进入 `Settings` → `Labeling Interface`,粘贴 XML 配置
|
||||||
|
4. 进入 `Settings` → `Instructions for annotators`,写标注指南
|
||||||
|
5. 进入 `Settings` → `Data Import`,上传数据
|
||||||
|
6. 进入 `Members`,把标注员、审核员加入项目
|
||||||
|
|
||||||
|
### 4.5 任务分配模式
|
||||||
|
|
||||||
|
在项目 `Settings` → `Task Distribution`:
|
||||||
|
|
||||||
|
| 模式 | 说明 | 适用 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Auto** | 自动分配给所有 Annotator | 公平负载 |
|
||||||
|
| **Manual** | 手动分配给指定 Annotator | 精细控制 |
|
||||||
|
| **Round-robin** | 轮流分配 | 均衡工作量 |
|
||||||
|
|
||||||
|
**Overlap(重叠标注数)**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Overlap = 2 表示:
|
||||||
|
每条数据被 2 个标注员同时标
|
||||||
|
→ 用来计算一致性
|
||||||
|
→ 用来仲裁
|
||||||
|
|
||||||
|
适合: 关键数据、希望提高质量
|
||||||
|
不适合: 数据量太大、预算紧
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.6 任务锁定(Locking)
|
||||||
|
|
||||||
|
防止多人同时标注同一条:
|
||||||
|
|
||||||
|
```
|
||||||
|
场景: 两个标注员同时打开任务 #100,都画了框
|
||||||
|
→ 后保存的覆盖先保存的 → 浪费工作
|
||||||
|
|
||||||
|
解决: Label Studio 自动锁定
|
||||||
|
- 任务被某人打开后,其他人在一段时间内(默认 5 分钟)看不到
|
||||||
|
- 那个人 Submit 后锁释放
|
||||||
|
- 超时未 Submit 锁也会释放
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 这个 5 分钟是默认值,可在项目 `Settings` → `Task Distribution` → `Locking timeout` 中调整。任务紧急时设短一点(1-2 分钟)减少等待;任务复杂时可设长一点(10-15 分钟)避免频繁锁切换。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Label Studio 质检流程
|
||||||
|
|
||||||
|
### 5.1 质检三道关
|
||||||
|
|
||||||
|
```
|
||||||
|
第一关: 标注员自检
|
||||||
|
- 提交前自己检查
|
||||||
|
- 提交即认定"已自检"
|
||||||
|
|
||||||
|
第二关: 审核员抽检
|
||||||
|
- Reviewer 进入项目,看到所有标注
|
||||||
|
- 抽样检查
|
||||||
|
- 给出 Approve / Reject
|
||||||
|
|
||||||
|
第三关: 管理员/专家仲裁
|
||||||
|
- 处理标注员和审核员的分歧
|
||||||
|
- 重要案例定调
|
||||||
|
- 更新标注规范
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 审核员工作流(Reviewer)
|
||||||
|
|
||||||
|
进入项目 → 看到任务列表:
|
||||||
|
|
||||||
|
```
|
||||||
|
任务列表:
|
||||||
|
Task #1 [Completed by Alice] → [查看] [Approve] [Reject]
|
||||||
|
Task #2 [Completed by Bob] → [查看] [Approve] [Reject]
|
||||||
|
Task #3 [Pending] → (标注员还没标)
|
||||||
|
Task #4 [Completed by Alice] → [查看] [Approve] [Reject]
|
||||||
|
```
|
||||||
|
|
||||||
|
**操作流程**:
|
||||||
|
|
||||||
|
1. 点击 `查看` → 进入任务的标注结果
|
||||||
|
2. 复核标注是否正确
|
||||||
|
3. 选择:
|
||||||
|
- `Approve` → 通过
|
||||||
|
- `Reject with feedback` → 驳回 + 写原因
|
||||||
|
|
||||||
|
```
|
||||||
|
Reject 示例:
|
||||||
|
|
||||||
|
驳回原因: 这个边界框太大了,应该紧贴目标
|
||||||
|
请重新标注后再提交。
|
||||||
|
|
||||||
|
[Confirm Reject] [Cancel]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 标注员看到反馈
|
||||||
|
|
||||||
|
被驳回的标注员重新进入项目时,会看到:
|
||||||
|
|
||||||
|
```
|
||||||
|
任务列表:
|
||||||
|
Task #1 [Status: REJECTED]
|
||||||
|
原因: "边界框太大,应该紧贴目标"
|
||||||
|
→ [查看反馈] [重新标注]
|
||||||
|
```
|
||||||
|
|
||||||
|
标注员**可以修改**后重新提交。
|
||||||
|
|
||||||
|
### 5.4 冲突解决
|
||||||
|
|
||||||
|
设置 Overlap=2 时,可能出现两人标得不一样:
|
||||||
|
|
||||||
|
```
|
||||||
|
Task #100:
|
||||||
|
标注员A: 框在 (50, 80, 200, 250), 类别=cat
|
||||||
|
标注员B: 框在 (60, 90, 210, 260), 类别=cat
|
||||||
|
→ 两人标的位置略不同
|
||||||
|
→ 类别一致
|
||||||
|
```
|
||||||
|
|
||||||
|
**处理流程**:
|
||||||
|
|
||||||
|
1. Label Studio 显示所有标注
|
||||||
|
2. 管理员 / Reviewer 决定最终结果
|
||||||
|
3. 或让两位标注员讨论
|
||||||
|
4. 决定后,任务标记为 `Resolved`
|
||||||
|
|
||||||
|
### 5.5 导出审核信息
|
||||||
|
|
||||||
|
项目 `Export` → 选 `JSON`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"data": {"image": "cat_001.jpg"},
|
||||||
|
"annotations": [
|
||||||
|
{
|
||||||
|
"created_by": {"username": "alice"},
|
||||||
|
"result": [{"value": {"rectanglelabels": ["cat"]}}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"created_by": {"username": "bob"},
|
||||||
|
"result": [{"value": {"rectanglelabels": ["cat"]}}]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reviews": [
|
||||||
|
{
|
||||||
|
"created_by": {"username": "reviewer1"},
|
||||||
|
"accepted": true,
|
||||||
|
"comment": "OK"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 多个 `annotations` 是因为 Overlap>1,`reviews` 数组里是审核结果。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 验收标准
|
||||||
|
|
||||||
|
### 6.1 三道指标
|
||||||
|
|
||||||
|
| 指标 | 合格线 | 含义 |
|
||||||
|
|------|--------|------|
|
||||||
|
| 准确率 | ≥ 95% | 抽查中,正确标注的比例 |
|
||||||
|
| 一致性 | Kappa ≥ 0.8 | 多人标注的一致程度 |
|
||||||
|
| 完整性 | 100% | 是否有遗漏任务 |
|
||||||
|
|
||||||
|
### 6.2 抽检 SOP
|
||||||
|
|
||||||
|
```
|
||||||
|
每周抽检流程:
|
||||||
|
1. 管理员随机抽 10-20% 任务
|
||||||
|
2. 由 Reviewer 复核
|
||||||
|
3. 统计:
|
||||||
|
- 准确率
|
||||||
|
- 一致性
|
||||||
|
- 每个标注员的通过率
|
||||||
|
4. 不达标:
|
||||||
|
- < 95%: 该批次整体打回重标
|
||||||
|
- 某标注员 < 90%: 该标注员暂停任务, 培训
|
||||||
|
5. 达标:
|
||||||
|
- 归档,进入训练集
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 自动化验收脚本
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 验收脚本示例
|
||||||
|
from sklearn.metrics import cohen_kappa_score, accuracy_score
|
||||||
|
import json
|
||||||
|
|
||||||
|
def accept_check(json_path, gold_path, threshold=0.95):
|
||||||
|
"""
|
||||||
|
:param json_path: 标注员导出的文件
|
||||||
|
:param gold_path: 标准答案
|
||||||
|
:param threshold: 通过线
|
||||||
|
"""
|
||||||
|
with open(json_path) as f:
|
||||||
|
annot = json.load(f)
|
||||||
|
with open(gold_path) as f:
|
||||||
|
gold = json.load(f)
|
||||||
|
|
||||||
|
# 提取标注
|
||||||
|
y_pred = [a['label'] for a in annot]
|
||||||
|
y_true = [g['label'] for g in gold]
|
||||||
|
|
||||||
|
acc = accuracy_score(y_true, y_pred)
|
||||||
|
kappa = cohen_kappa_score(y_true, y_pred)
|
||||||
|
|
||||||
|
print(f"准确率: {acc:.2%}")
|
||||||
|
print(f"Kappa: {kappa:.3f}")
|
||||||
|
|
||||||
|
passed = acc >= threshold and kappa >= 0.8
|
||||||
|
print(f"验收: {'通过 ✅' if passed else '不通过 ❌'}")
|
||||||
|
|
||||||
|
return passed
|
||||||
|
|
||||||
|
# 用法
|
||||||
|
accept_check('annotator_alice.json', 'gold.json')
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 标注员培训与管理
|
||||||
|
|
||||||
|
### 7.1 培训流程
|
||||||
|
|
||||||
|
```
|
||||||
|
阶段 1: 理论学习 (2h)
|
||||||
|
├── 项目背景介绍
|
||||||
|
├── 标签定义
|
||||||
|
└── 标注规范
|
||||||
|
|
||||||
|
阶段 2: 案例学习 (1h)
|
||||||
|
├── 正面案例
|
||||||
|
├── 反面案例
|
||||||
|
└── 疑难案例
|
||||||
|
|
||||||
|
阶段 3: 实操练习 (3h)
|
||||||
|
├── 在 Label Studio 试标
|
||||||
|
└── 培训员答疑
|
||||||
|
|
||||||
|
阶段 4: 考核 (1h)
|
||||||
|
├── 准确率 ≥ 95% 才能上岗
|
||||||
|
└── 不通过: 重新培训
|
||||||
|
|
||||||
|
阶段 5: 正式上岗
|
||||||
|
└── 接入正式任务
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 优秀标注员的能力模型
|
||||||
|
|
||||||
|
```
|
||||||
|
📚 专业知识
|
||||||
|
- 理解项目背景
|
||||||
|
- 熟悉标注规范
|
||||||
|
|
||||||
|
🔍 细致认真
|
||||||
|
- 不漏标、不错标
|
||||||
|
- 严格按规范
|
||||||
|
|
||||||
|
❓ 勤于提问
|
||||||
|
- 不确定时主动问
|
||||||
|
- 不瞎猜
|
||||||
|
|
||||||
|
📈 持续改进
|
||||||
|
- 从错误中学习
|
||||||
|
- 主动提高质量
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 绩效管理
|
||||||
|
|
||||||
|
**指标 + 权重**:
|
||||||
|
|
||||||
|
| 指标 | 权重 | 来源 |
|
||||||
|
|------|------|------|
|
||||||
|
| 产量 | 20% | Label Studio 统计 |
|
||||||
|
| 准确率 | 50% | Reviewer 抽检 |
|
||||||
|
| 一致性 | 20% | 与他人对比 |
|
||||||
|
| 规范遵守 | 10% | 违规次数 |
|
||||||
|
|
||||||
|
**周报示例**:
|
||||||
|
|
||||||
|
```
|
||||||
|
标注员: 张三
|
||||||
|
周期: 2024-05-13 ~ 05-19
|
||||||
|
|
||||||
|
┌──────────────────────────────────────┐
|
||||||
|
│ 指标 结果 目标 评价 │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ 标注数量 450 400 ✅ 超出│
|
||||||
|
│ 准确率 96.2% 95% ✅ 达标│
|
||||||
|
│ Kappa 0.85 0.80 ✅ 达标│
|
||||||
|
│ 违规次数 1 0 ⚠️ │
|
||||||
|
└──────────────────────────────────────┘
|
||||||
|
|
||||||
|
整体评价: 良好
|
||||||
|
建议: 违规次数需注意,标注前再仔细读规范
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.4 常见问题处理
|
||||||
|
|
||||||
|
| 问题 | 原因 | 解决 |
|
||||||
|
|------|------|------|
|
||||||
|
| 准确率下降 | 疲劳/松懈 | 抽检频率↑, 提醒 |
|
||||||
|
| 一致性差 | 规范不清 | 培训+更新规范 |
|
||||||
|
| 产量低 | 不熟工具 | 培训指导 |
|
||||||
|
| 流失 | 工作枯燥 | 任务轮换 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 综合标注项目管理
|
||||||
|
|
||||||
|
### 8.1 完整流程(用 Label Studio 串起来)
|
||||||
|
|
||||||
|
```
|
||||||
|
[1] 项目启动 (Admin)
|
||||||
|
- 明确标注任务
|
||||||
|
- 估算数据量 / 人力 / 时间
|
||||||
|
|
||||||
|
[2] 规范制定 (Admin)
|
||||||
|
- 编写标注规范
|
||||||
|
- 准备示例
|
||||||
|
- 找 2-3 人试标验证
|
||||||
|
|
||||||
|
[3] 配置项目 (Admin)
|
||||||
|
- 创建 Label Studio 项目
|
||||||
|
- 配置 XML 标注界面
|
||||||
|
- 写 Instructions
|
||||||
|
- 设置 Overlap、分配模式
|
||||||
|
|
||||||
|
[4] 团队培训 (Admin)
|
||||||
|
- 培训标注员
|
||||||
|
- 考核上岗
|
||||||
|
- 培训 Reviewer
|
||||||
|
|
||||||
|
[5] 数据导入 (Admin)
|
||||||
|
- 上传数据
|
||||||
|
- 分配任务
|
||||||
|
|
||||||
|
[6] 标注执行 (Annotator)
|
||||||
|
- 按规范标注
|
||||||
|
- 提交
|
||||||
|
|
||||||
|
[7] 抽检审核 (Reviewer)
|
||||||
|
- Approve / Reject
|
||||||
|
- 反馈给标注员
|
||||||
|
|
||||||
|
[8] 修正重标 (Annotator)
|
||||||
|
- 处理 Reject 的任务
|
||||||
|
|
||||||
|
[9] 验收 (Admin)
|
||||||
|
- 准确率 / Kappa 检查
|
||||||
|
- 通过 → 归档
|
||||||
|
- 不通过 → 整体打回
|
||||||
|
|
||||||
|
[10] 导出 (Admin)
|
||||||
|
- 导出最终数据
|
||||||
|
- 准备给训练用
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 项目进度看板
|
||||||
|
|
||||||
|
```
|
||||||
|
项目: 商品评论情感分类
|
||||||
|
数据: 1000 条
|
||||||
|
进度: 750 / 1000 (75%)
|
||||||
|
|
||||||
|
标注员 已完成 目标 状态
|
||||||
|
─────────────────────────────
|
||||||
|
张三 300 400 ✅
|
||||||
|
李四 250 300 ⚠️ 落后
|
||||||
|
王五 200 300 ✅
|
||||||
|
|
||||||
|
质量统计:
|
||||||
|
已审核: 500
|
||||||
|
通过率: 96.5%
|
||||||
|
打回重标: 17
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.3 交付检查清单
|
||||||
|
|
||||||
|
```
|
||||||
|
□ 数据格式正确 (JSON / CoNLL / YOLO)
|
||||||
|
□ 全部任务已标注
|
||||||
|
□ 准确率 ≥ 95%
|
||||||
|
□ Kappa ≥ 0.8
|
||||||
|
□ 质检记录完整
|
||||||
|
□ 标注规范文档齐全
|
||||||
|
□ 数据量与需求一致
|
||||||
|
□ 已通过验收确认
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 实际生产中的经验
|
||||||
|
|
||||||
|
### 9.1 数据分层策略
|
||||||
|
|
||||||
|
```
|
||||||
|
高质量层(人工精标, 5%): 训练集核心
|
||||||
|
- 100% 抽检
|
||||||
|
- 多人交叉标
|
||||||
|
|
||||||
|
中质量层(AI预标+人工校正, 80%): 主训练集
|
||||||
|
- 抽检 20%
|
||||||
|
- 校正后即用
|
||||||
|
|
||||||
|
低质量层(仅AI标, 15%): 增广数据
|
||||||
|
- 弱监督学习
|
||||||
|
- 抽检 1%
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 AI 辅助标注(Label Studio ML Backend)
|
||||||
|
|
||||||
|
Label Studio 支持接入 ML 模型做预标注:
|
||||||
|
|
||||||
|
```
|
||||||
|
流程:
|
||||||
|
1. 用现有模型对新数据预测
|
||||||
|
2. 预标注结果导入 Label Studio
|
||||||
|
3. 标注员只需**校正**(而不是从零标)
|
||||||
|
4. 效率提升 3-5 倍
|
||||||
|
```
|
||||||
|
|
||||||
|
安装 ML 后端(以 YOLO 为例):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install label-studio-ml
|
||||||
|
label-studio-ml start ./my_model --port 9090
|
||||||
|
```
|
||||||
|
|
||||||
|
在 Label Studio 项目 `Settings` → `Model` → 添加 ML 后端 URL。
|
||||||
|
|
||||||
|
### 9.3 主动学习(Active Learning)
|
||||||
|
|
||||||
|
```
|
||||||
|
模型对数据预测:
|
||||||
|
100 条很确定 (置信度 > 0.95)
|
||||||
|
50 条不太确定 (置信度 0.5-0.95) ← 这些让人标
|
||||||
|
10 条完全不确定 (置信度 < 0.5) ← 这些让人标
|
||||||
|
|
||||||
|
只让人标"模型不确定"的,效率最高
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 本节知识小结
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────────────────┐
|
||||||
|
│ 4-4 标注质量控制与标注管理(Label Studio) │
|
||||||
|
├────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ 📌 一致性指标: │
|
||||||
|
│ 简单一致率 (基础) │
|
||||||
|
│ Cohen Kappa (两人, 排除随机) │
|
||||||
|
│ Fleiss Kappa (多人) │
|
||||||
|
│ F1 (NER 等集合型) │
|
||||||
|
│ κ > 0.8 为高度一致 │
|
||||||
|
│ │
|
||||||
|
│ 📌 Label Studio 角色: │
|
||||||
|
│ Admin 创建项目、管理成员 │
|
||||||
|
│ Annotator 完成标注 │
|
||||||
|
│ Reviewer 审核、Approve/Reject │
|
||||||
|
│ │
|
||||||
|
│ 📌 质检流程: │
|
||||||
|
│ 自检 → 抽检 → 仲裁 │
|
||||||
|
│ 抽检比例: 10-50% │
|
||||||
|
│ │
|
||||||
|
│ 📌 验收标准: │
|
||||||
|
│ 准确率 ≥ 95% │
|
||||||
|
│ Kappa ≥ 0.8 │
|
||||||
|
│ 完整性 100% │
|
||||||
|
│ │
|
||||||
|
│ 📌 高级技巧: │
|
||||||
|
│ Overlap > 1: 多人交叉标 │
|
||||||
|
│ ML Backend: AI 预标 │
|
||||||
|
│ Active Learning: 只标难样本 │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 思考题
|
||||||
|
|
||||||
|
1. 标注规范里有模糊地带,两人标出不同结果,如何处理?
|
||||||
|
2. Kappa 系数为什么排除随机一致? 简单一致率有何问题?
|
||||||
|
3. 如果让你管理一个 10 人标注团队,如何设计绩效考核?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 课后任务
|
||||||
|
|
||||||
|
1. 设计一个情感分类标注规范,含 10 正/10 负/10 中示例
|
||||||
|
2. 用 Python 计算给定两标注员数据的 Kappa 系数
|
||||||
|
3. 在 Label Studio 创建项目,邀请一个同学(可以是组员)做 Reviewer,体验 Approve/Reject 流程
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 下节预告
|
||||||
|
|
||||||
|
下一节我们将进行 **4-5 综合标注实战与总结(Label Studio 一站式)**:
|
||||||
|
- 电商评论多模态标注实战
|
||||||
|
- 完整流程演练
|
||||||
|
- 第四章知识地图与速查
|
||||||
Reference in New Issue
Block a user