name: data-labeling description: 使用人工標註工具、半自動化流水線、主動學習和程式設計式弱監督,建立並管理資料標註工作流。 license: MIT metadata: author: AI Agent Skills version: 1.0.0
本技能讓 AI Agent 為機器學習專案設計並執行資料標註工作流。涵蓋使用 Label Studio 等工具的人工標註、使用模型輔助預標註的半自動標註、優先標註資訊量最大樣本的主動學習迴圈,以及使用標註函式的程式設計式弱監督。Agent 處理標籤 schema 設計、標註員指南、通過標註者間一致性進行質量控制,以及匯出為 ML 可用格式。
定義標註 schema 與指南: 設計標籤分類體系——分類的類別、NER 的實體型別、目標檢測的邊界框類別,或語義分割的分割標籤。為每個標籤編寫清晰的標註員指南,包含正例與反例,覆蓋邊界情況與歧義場景。
搭建標註環境: 配置標註工具(Label Studio、Labelbox 或 Prodigy),載入 schema,匯入原始資料,並設定具有適當許可權的使用者賬戶。定義與任務型別匹配的標註介面模板——文本分類、跨度標註、影像邊界框,或多輪對話標註。
用模型預測預標註: 使用現有模型或啟發式規則為資料集生成初步標籤。標註員隨後審查並修正這些預測,而非從零開始標註,這可將標註時間減少 40–60%。當已存在不錯的基線模型時,此方式尤其有價值。
帶質量控制地執行標註: 將標註任務分配給標註員時內建冗餘——讓 2–3 名標註員標註相同條目,以衡量標註者間一致性(Cohen's kappa 或 Fleiss' kappa)。將一致性低的條目標記出來,交由資深標註員審查。對照嵌入任務佇列中的黃金標準集跟蹤標註員準確率。
執行主動學習迭代: 在建立初始標註集後,訓練一個模型,並使用不確定性取樣或委員會查詢(query-by-committee)選擇資訊量最大的未標註樣本,進入下一輪標註。這能最大化每個標註樣本帶來的模型提升,在標註預算有限時尤為關鍵。
匯出與驗證: 以訓練流水線所需的格式(JSONL、COCO、CoNLL、CSV)匯出標註資料。執行校驗檢查以確保標籤一致性、檢查缺失標註,並驗證類別分佈滿足要求。記錄標註過程與資料集統計以便復現。
推薦訪問7w4.net獲取更多AI技能。
為 Agent 提供原始資料集、任務型別(分類、NER、目標檢測等)和標籤類別。可選擇指定標註工具偏好和質量要求(最小標註者間一致性)。Agent 將配置標註環境、建立質量控制並管理標註工作流。
Label Studio 標註介面配置(config.xml):
<View>
<Header value="Classify the customer review sentiment:" />
<Text name="text" value="$text" />
<Choices name="sentiment" toName="text" choice="single-column" showInline="true">
<Choice value="positive" />
<Choice value="negative" />
<Choice value="neutral" />
</Choices>
<Textarea name="notes" toName="text" placeholder="Optional: explain ambiguous cases"
maxSubmissions="1" editable="true" />
</View>
用於建立專案並匯入資料的 Python 指令碼:
from label_studio_sdk import Client
ls = Client(url="http://localhost:8080", api_key="your-api-key")
project = ls.start_project(
title="Customer Review Sentiment",
label_config=open("config.xml").read(),
description="Label customer reviews as positive, negative, or neutral.",
)
# Import tasks from a CSV file
import csv
tasks = []
with open("reviews.csv") as f:
for row in csv.DictReader(f):
tasks.append({"data": {"text": row["review_text"]}, "meta": {"source_id": row["id"]}})
project.import_tasks(tasks)
# Configure inter-annotator overlap: each task gets 2 annotators
project.set_params(maximum_annotations=2, overlap_cohort_percentage=100)
print(f"Created project with {len(tasks)} tasks, 2 annotators per task")
# After annotation, export results
annotations = project.export_tasks(export_type="JSON")
# Compute agreement
from sklearn.metrics import cohen_kappa_score
labels_a1 = [a["annotations"][0]["result"][0]["value"]["choices"][0] for a in annotations if len(a["annotations"]) >= 2]
labels_a2 = [a["annotations"][1]["result"][0]["value"]["choices"][0] for a in annotations if len(a["annotations"]) >= 2]
print(f"Cohen's kappa: {cohen_kappa_score(labels_a1, labels_a2):.3f}")
import pandas as pd
import numpy as np
from snorkel.labeling import labeling_function, PandasLFApplier, LFAnalysis
from snorkel.labeling.model import LabelModel
SPAM = 1
HAM = 0
ABSTAIN = -1
df = pd.DataFrame({
"text": [
"Congratulations! You've won a free iPhone!", "Meeting at 3pm tomorrow",
"URGENT: claim your prize now!!!", "Can you review the Q3 report?",
"Buy cheap meds online fast", "Lunch plans for Thursday?",
"Click here for a free vacation", "Project deadline is next Friday",
]
})
@labeling_function()
def lf_contains_free(x):
return SPAM if "free" in x.text.lower() else ABSTAIN
@labeling_function()
def lf_contains_urgent(x):
return SPAM if "urgent" in x.text.lower() else ABSTAIN
@labeling_function()
def lf_contains_click(x):
return SPAM if "click" in x.text.lower() else ABSTAIN
@labeling_function()
def lf_excessive_punctuation(x):
return SPAM if x.text.count("!") >= 3 else ABSTAIN
@labeling_function()
def lf_contains_meeting(x):
return HAM if any(w in x.text.lower() for w in ["meeting", "project", "report", "deadline"]) else ABSTAIN
@labeling_function()
def lf_short_and_casual(x):
return HAM if len(x.text.split()) < 8 and "?" in x.text else ABSTAIN
lfs = [lf_contains_free, lf_contains_urgent, lf_contains_click,
lf_excessive_punctuation, lf_contains_meeting, lf_short_and_casual]
applier = PandasLFApplier(lfs=lfs)
L_train = applier.apply(df=df)
print(LFAnalysis(L=L_train, lfs=lfs).lf_summary())
# Train the label model to combine noisy labeling functions
label_model = LabelModel(cardinality=2, verbose=True)
label_model.fit(L_train=L_train, n_epochs=500, log_freq=100, seed=42)
# Get probabilistic labels
probs = label_model.predict_proba(L=L_train)
df["label"] = label_model.predict(L=L_train)
df["confidence"] = np.max(probs, axis=1)
# Filter out low-confidence samples for manual review
confident = df[df["confidence"] > 0.8]
needs_review = df[df["confidence"] <= 0.8]
print(f"Confidently labeled: {len(confident)}, needs manual review: {len(needs_review)}")
這個技能質量不錯,內容專業且實用。它完整覆蓋了資料標註的各種場景和方法,從基礎的人工標註到進階的主動學習和弱監督都有涉及。程式碼示例豐富,最佳實踐建議很有參考價值。美中不足的是README過於簡略,缺少直觀的使用引導,且沒有配套的示例資料檔案供使用者快速上手體驗。