真实数据集扩产与被动语料接入
- scripts/expand_real_dataset.py:AutoWeakS 全量 2215 条 + 500 条分层评测集 + 简历扩量(seed=2026 可复现) - pipeline 被动语料机制(passive_sources):真实无日期 JD 参与接入/清洗/抽取验证(2915 条命中率 99.8%),不进图谱/演化/发现 - 新岗位发现第四指标'差异度'与双年窗口增长率口径 - 评测新增 real_jd_500 维度(99.91%);测试会话隔离 jd_extra_dirs 防止本机配置拖慢套件
This commit is contained in:
+32
-7
@@ -9,8 +9,9 @@
|
||||
|
||||
两个真实数据维度(data/real/,与合成集分开报告、不混算):
|
||||
4. 真实 JD(AutoWeakS 初标+抽检 silver gold)—— 对 jd_sample.jsonl 重新抽取,
|
||||
与 gold_answers.json 算技能/场景字段级 F1;
|
||||
5. 真实简历(AIStudio CC0)—— 对 50 份简历解析,姓名/电话命中率 + 技能 F1。
|
||||
与 gold_answers.json 算技能/场景字段级 F1;另按 jd_eval_500.jsonl /
|
||||
gold_answers_500.json 报告 500 条分层口径(real_jd_500,包含原 200 条);
|
||||
5. 真实简历(AIStudio CC0)—— 对 200 份简历解析,姓名/电话命中率 + 技能 F1。
|
||||
|
||||
输出 reports/metrics.json 与控制台报告。
|
||||
"""
|
||||
@@ -115,15 +116,14 @@ def eval_match() -> dict:
|
||||
return {"accuracy": round(hit / len(pairs), 4), "pairs": len(pairs), "detail": detail}
|
||||
|
||||
|
||||
def eval_real_jd() -> dict:
|
||||
def _eval_real_jd(records_path: Path, gold_path: Path) -> dict:
|
||||
"""真实 JD(AutoWeakS):从文本重新抽取,与 silver gold(初标+抽检)字段级比对。
|
||||
|
||||
真实 JD 是自由文本、无编号版面,gold 的 responsibilities/preferred_skills 为空,
|
||||
口径 = 全文词表技能(required_skills)+ 应用场景 + 启发式岗位名,见 data/real/README.md。
|
||||
"""
|
||||
records, errors = load_jd_file(ROOT / "data" / "real" / "autoweaks_jd" / "jd_sample.jsonl")
|
||||
gold = json.loads(
|
||||
(ROOT / "data" / "real" / "autoweaks_jd" / "gold_answers.json").read_text(encoding="utf-8"))
|
||||
records, errors = load_jd_file(records_path)
|
||||
gold = json.loads(gold_path.read_text(encoding="utf-8"))
|
||||
extractor = OfflineExtractor(load_lexicon())
|
||||
|
||||
fields = ["required_skills", "preferred_skills", "scenarios"]
|
||||
@@ -143,7 +143,9 @@ def eval_real_jd() -> dict:
|
||||
|
||||
detail, active_f1 = {}, []
|
||||
for f in fields:
|
||||
if not gold_n[f] and not pred[f]:
|
||||
# 真实 JD 的 gold 口径:responsibilities/preferred_skills 为空即不参与评分
|
||||
# (即使抽取器从"优先考虑"字样产出加分候选,也不计入,口径见 data/real/README.md)
|
||||
if not gold_n[f]:
|
||||
detail[f] = None # 该字段在真实语料中无标注口径,不参与
|
||||
continue
|
||||
p, r, f1 = prf(tp[f], pred[f], gold_n[f])
|
||||
@@ -157,6 +159,20 @@ def eval_real_jd() -> dict:
|
||||
"fields": detail, "samples": len(records), "bad_lines": len(errors)}
|
||||
|
||||
|
||||
def eval_real_jd() -> dict:
|
||||
"""真实 JD 200 条口径(历史基线)。"""
|
||||
return _eval_real_jd(
|
||||
ROOT / "data" / "real" / "autoweaks_jd" / "jd_sample.jsonl",
|
||||
ROOT / "data" / "real" / "autoweaks_jd" / "gold_answers.json")
|
||||
|
||||
|
||||
def eval_real_jd_500() -> dict:
|
||||
"""真实 JD 500 条分层口径(含原 200 条,见 scripts/expand_real_dataset.py)。"""
|
||||
return _eval_real_jd(
|
||||
ROOT / "data" / "real" / "autoweaks_jd" / "jd_eval_500.jsonl",
|
||||
ROOT / "data" / "real" / "autoweaks_jd" / "gold_answers_500.json")
|
||||
|
||||
|
||||
def eval_real_resume() -> dict:
|
||||
"""真实简历(AIStudio CC0):姓名/电话命中率(脱敏形态比对)+ 技能 F1。"""
|
||||
gold = json.loads(
|
||||
@@ -194,6 +210,7 @@ def main() -> None:
|
||||
resume = eval_resume()
|
||||
match = eval_match()
|
||||
real_jd = eval_real_jd()
|
||||
real_jd_500 = eval_real_jd_500()
|
||||
real_resume = eval_real_resume()
|
||||
metrics = {
|
||||
"jd_extraction_accuracy": jd["accuracy"],
|
||||
@@ -203,6 +220,7 @@ def main() -> None:
|
||||
"resume_detail": resume["detail"],
|
||||
"match_detail": match["detail"],
|
||||
"real_jd": real_jd,
|
||||
"real_jd_500": real_jd_500,
|
||||
"real_resume": real_resume,
|
||||
}
|
||||
out = ROOT / "reports"
|
||||
@@ -225,6 +243,13 @@ def main() -> None:
|
||||
print("真实数据维度(data/real/,与合成集分开报告)")
|
||||
print(f"真实 JD(AutoWeakS 初标+抽检): 综合 F1 {real_jd['accuracy']:.2%}"
|
||||
f" (样本 {real_jd['samples']} 条)")
|
||||
print(f"真实 JD(500 条分层) : 综合 F1 {real_jd_500['accuracy']:.2%}"
|
||||
f" (样本 {real_jd_500['samples']} 条)")
|
||||
for f, d in real_jd_500["fields"].items():
|
||||
if d is None:
|
||||
print(f" - {f:<18} (真实语料无标注口径,不参与)")
|
||||
else:
|
||||
print(f" - {f:<18} P={d['precision']:.2%} R={d['recall']:.2%} F1={d['f1']:.2%}")
|
||||
for f, d in real_jd["fields"].items():
|
||||
if d is None:
|
||||
print(f" - {f:<18} (真实语料无标注口径,不参与)")
|
||||
|
||||
Reference in New Issue
Block a user