Wendy-Fly commited on
Commit
bf13d1c
·
verified ·
1 Parent(s): 588cdd6

simplify: only add one estimated_position column (int)

Browse files
Files changed (1) hide show
  1. add_estimated_position.py +47 -75
add_estimated_position.py CHANGED
@@ -1,21 +1,16 @@
1
  #!/usr/bin/env python3
2
- """把 top100 match 估出来的"均值 position" 写回 golden_set.csv。
3
 
4
- 逻辑:
5
- - 每条 golden 样本(共 1000 条)已经在 golden_top100.jsonl 里有 100 个最近邻 ruler item
6
- - 对这 100 个邻居的 rank 求均值(也可以 sim-加权),作为 embedding 估出的 position
7
- - 通过 task_id 把这个值合并回 csv,新列:estimated_position_top100
8
- - 同时也保留几个有用的衍生字段:weighted_position / median_position / mean_score
9
 
10
- 输出:
11
- - golden_set_with_estimated.csv (默认;不覆盖原文件)
12
 
13
  用法:
14
  python3 add_estimated_position.py
15
- python3 add_estimated_position.py \
16
- --csv /mnt/.../aipf_golden_set.csv \
17
- --jsonl golden_top100.jsonl \
18
- --output golden_set_with_estimated.csv
19
  """
20
  import argparse
21
  import json
@@ -30,22 +25,24 @@ DEFAULTS = dict(
30
  jsonl = "golden_top100.jsonl",
31
  output = "golden_set_with_estimated.csv",
32
  id_col = "task_id",
 
33
  )
34
 
35
 
36
  def parse_args():
37
  p = argparse.ArgumentParser()
38
- p.add_argument("--csv", default=DEFAULTS["csv"])
39
- p.add_argument("--jsonl", default=DEFAULTS["jsonl"])
40
- p.add_argument("--output", default=DEFAULTS["output"])
41
- p.add_argument("--id-col", default=DEFAULTS["id_col"])
 
42
  return p.parse_args()
43
 
44
 
45
  def main():
46
  args = parse_args()
47
 
48
- # 1) 读 jsonl,按 task_id 算各种聚合
49
  print(f"[1] read jsonl: {args.jsonl}")
50
  estimated = {}
51
  with open(args.jsonl, "r", encoding="utf-8") as f:
@@ -54,77 +51,52 @@ def main():
54
  if not line:
55
  continue
56
  r = json.loads(line)
57
- ranks = np.array([t["rank"] for t in r["topk"]], dtype=float)
58
- sims = np.array([t["sim"] for t in r["topk"]], dtype=float)
59
- scores = np.array([t["score"] for t in r["topk"]], dtype=float)
60
- wsim = sims.sum()
61
-
62
- mean_pos = ranks.mean()
63
- weighted_pos = (sims * ranks).sum() / max(wsim, 1e-12)
64
- median_pos = np.median(ranks)
65
- estimated[str(r["task_id"])] = {
66
- # position 类一律 round 成整数(和 AIPF 的 ruler_position 对齐)
67
- "estimated_position_top100": int(round(mean_pos)),
68
- "estimated_position_top100_weighted": int(round(weighted_pos)),
69
- "estimated_position_top100_median": int(round(median_pos)),
70
- # score 保留浮点
71
- "estimated_score_top100_mean": float(scores.mean()),
72
- "estimated_score_top100_weighted": float((sims * scores).sum() / max(wsim, 1e-12)),
73
- "top1_rank": int(ranks[0]),
74
- "top1_sim": float(sims[0]),
75
- }
76
- print(f" -> {len(estimated)} rows in jsonl")
77
 
78
  # 2) 读 csv
79
  print(f"[2] read csv: {args.csv}")
80
  df = pd.read_csv(args.csv, keep_default_na=False)
81
- print(f" -> {len(df)} rows, {len(df.columns)} cols")
82
- print(f" columns: {list(df.columns)}")
83
 
84
  if args.id_col not in df.columns:
85
- raise ValueError(f"id column '{args.id_col}' not in csv. available: {list(df.columns)}")
86
-
87
- # 3) merge
88
- print(f"[3] merge by {args.id_col}")
89
- new_cols = [
90
- "estimated_position_top100",
91
- "estimated_position_top100_weighted",
92
- "estimated_position_top100_median",
93
- "estimated_score_top100_mean",
94
- "estimated_score_top100_weighted",
95
- "top1_rank",
96
- "top1_sim",
97
- ]
98
- for col in new_cols:
99
- df[col] = df[args.id_col].astype(str).map(lambda k: estimated.get(k, {}).get(col))
100
-
101
- matched = df["estimated_position_top100"].notna().sum()
102
- missing = len(df) - matched
103
- print(f" matched: {matched}/{len(df)}")
104
- if missing:
105
- print(f" ⚠️ missing {missing} task_id(jsonl 里没有这些 id)")
106
-
107
- # 4) 写出
108
  print(f"[4] write: {args.output}")
109
  df.to_csv(args.output, index=False)
110
- print(f" done")
111
 
112
- # 5) sanity: 看几行
113
- print("\n[preview] 前 3 行新列:")
114
- cols_show = [args.id_col, "label"] + new_cols
115
- cols_show = [c for c in cols_show if c in df.columns]
116
- print(df[cols_show].head(3).to_string(index=False))
117
 
118
  # 6) 简单 stats
119
- print("\n[stats] estimated_position_top100 分布:")
120
- s = pd.to_numeric(df["estimated_position_top100"], errors="coerce")
121
- print(f" min={s.min():.2f} max={s.max():.2f} mean={s.mean():.2f} median={s.median():.2f}")
122
-
123
  if "label" in df.columns:
124
- print("\n[stats] 按 label 分组:")
125
  for lab, sub in df.groupby("label"):
126
- ss = pd.to_numeric(sub["estimated_position_top100"], errors="coerce")
127
- print(f" label={lab!r:>4} n={len(sub):>4} mean={ss.mean():.2f} median={ss.median():.2f}")
128
 
129
 
130
  if __name__ == "__main__":
 
1
  #!/usr/bin/env python3
2
+ """把 top100 match 估出来的整数 position 写回 golden_set.csv。
3
 
4
+ 每条 case:
5
+ - 从 golden_top100.jsonl 取它的 100 个最近邻 ruler 的 rank
6
+ - 求均值,round 成整数
7
+ - 作为新列 estimated_position 写回 csv
 
8
 
9
+ 输出:golden_set_with_estimated.csv(不覆盖原文件)
 
10
 
11
  用法:
12
  python3 add_estimated_position.py
13
+ python3 add_estimated_position.py --csv /path/to.csv --jsonl /path/to.jsonl
 
 
 
14
  """
15
  import argparse
16
  import json
 
25
  jsonl = "golden_top100.jsonl",
26
  output = "golden_set_with_estimated.csv",
27
  id_col = "task_id",
28
+ new_col = "estimated_position",
29
  )
30
 
31
 
32
  def parse_args():
33
  p = argparse.ArgumentParser()
34
+ p.add_argument("--csv", default=DEFAULTS["csv"])
35
+ p.add_argument("--jsonl", default=DEFAULTS["jsonl"])
36
+ p.add_argument("--output", default=DEFAULTS["output"])
37
+ p.add_argument("--id-col", default=DEFAULTS["id_col"])
38
+ p.add_argument("--new-col", default=DEFAULTS["new_col"])
39
  return p.parse_args()
40
 
41
 
42
  def main():
43
  args = parse_args()
44
 
45
+ # 1) 读 jsonl,每条样本算 top-100 rank 均值 → 整数
46
  print(f"[1] read jsonl: {args.jsonl}")
47
  estimated = {}
48
  with open(args.jsonl, "r", encoding="utf-8") as f:
 
51
  if not line:
52
  continue
53
  r = json.loads(line)
54
+ ranks = np.array([t["rank"] for t in r["topk"]], dtype=float)
55
+ estimated[str(r["task_id"])] = int(round(ranks.mean()))
56
+ print(f" -> {len(estimated)} cases estimated")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  # 2) 读 csv
59
  print(f"[2] read csv: {args.csv}")
60
  df = pd.read_csv(args.csv, keep_default_na=False)
61
+ print(f" -> {len(df)} rows")
 
62
 
63
  if args.id_col not in df.columns:
64
+ raise ValueError(f"'{args.id_col}' not in csv. cols: {list(df.columns)}")
65
+
66
+ # 3) 给每条 case 加 estimated_position 列
67
+ print(f"[3] add column: {args.new_col}")
68
+ df[args.new_col] = df[args.id_col].astype(str).map(estimated)
69
+
70
+ n_total = len(df)
71
+ n_matched = df[args.new_col].notna().sum()
72
+ n_missing = n_total - n_matched
73
+ print(f" matched: {n_matched}/{n_total}")
74
+ if n_missing:
75
+ print(f" ⚠️ {n_missing} 条 case 在 jsonl 里没找到对应 task_id")
76
+ else:
77
+ # 全部匹配上 → 转成 Int64(pandas 的可空整数类型,不会因为没 NaN 变 float)
78
+ df[args.new_col] = df[args.new_col].astype("Int64")
79
+
80
+ # 4) 写
 
 
 
 
 
 
81
  print(f"[4] write: {args.output}")
82
  df.to_csv(args.output, index=False)
83
+ print(f" done. csv 现在有 {len(df.columns)} 列(多了 1 列:{args.new_col})")
84
 
85
+ # 5) 预览
86
+ print(f"\n[preview] 前 5 行:")
87
+ cols = [args.id_col, "label", args.new_col]
88
+ cols = [c for c in cols if c in df.columns]
89
+ print(df[cols].head(5).to_string(index=False))
90
 
91
  # 6) 简单 stats
92
+ s = pd.to_numeric(df[args.new_col], errors="coerce")
93
+ print(f"\n[stats] {args.new_col}:")
94
+ print(f" min={int(s.min())} max={int(s.max())} mean={s.mean():.1f} median={int(s.median())}")
 
95
  if "label" in df.columns:
96
+ print("\n按 label 分组:")
97
  for lab, sub in df.groupby("label"):
98
+ ss = pd.to_numeric(sub[args.new_col], errors="coerce")
99
+ print(f" label={lab!r:>4} n={len(sub):>4} mean={ss.mean():.1f} median={int(ss.median())}")
100
 
101
 
102
  if __name__ == "__main__":