File size: 3,413 Bytes
1a36f9f
904b30e
1a36f9f
904b30e
 
 
1a36f9f
 
904b30e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env python3
"""按已登记的分类,从固定版本的团队预览池分层抽样。

python tools/import_team_previews.py --per 12
来源与版本见 data/preview_sources.json;完整素材池见 data/preview_pool.json。
主分类在数据集内部轮转,分类内部均衡来源已提供的手别和视角。
"""
from pathlib import Path
from collections import Counter
import argparse, hashlib, json

SITE=Path(__file__).resolve().parent.parent
ap=argparse.ArgumentParser(description=__doc__)
ap.add_argument('--per',type=int,default=12)
quota=ap.parse_args().per
data=json.loads((SITE/'data/preview_pool.json').read_text())
selected={}
audit={'target_per_dataset':quota,'seed':'20261027','scope':'已取得的公开预览池','strategy':f'各数据集最多 {quota} 组;按主分类轮转,分类内部再均衡已提供的手别、视角等分类。素材不足时全部展示。','dimensions_note':'分类来自来源子集、序列、相机和手别元数据。姿态与抓握类别尚未建立统一标签。','datasets':{}}
for key,items in data.items():
 dimensions=['来源子集','序列','视角','手别','受试者']
 primary=next((dim for dim in dimensions if len({p['strata'].get(dim) for p in items if p['strata'].get(dim)})>1),None)
 chosen=[];remaining=items.copy();counts={dim:Counter() for dim in dimensions};conditional=Counter();primary_counts=Counter()
 while len(chosen)<min(quota,len(items)):
  def score(p):
   group=p['strata'].get(primary,'未提供分类')
   return (primary_counts[group],sum(conditional[(group,dim,p['strata'][dim])] for dim in dimensions if dim in p['strata'] and dim!=primary),sum(counts[dim][p['strata'][dim]] for dim in dimensions if dim in p['strata'] and dim!=primary),hashlib.sha256(('20261027/'+p['id']).encode()).hexdigest())
  p=min(remaining,key=score);remaining.remove(p);chosen.append(p)
  group=p['strata'].get(primary,'未提供分类');primary_counts[group]+=1
  for dim,value in p['strata'].items(): counts[dim][value]+=1;conditional[(group,dim,value)]+=1
 selected[key]=chosen
 audit['datasets'][key]={'pool':len(items),'selected':len(chosen),'primary_dimension':primary or '可用素材全部展示','categories':{dim:{v:{'pool':sum(p['strata'].get(dim)==v for p in items),'selected':sum(p['strata'].get(dim)==v for p in chosen)} for v in sorted({p['strata'][dim] for p in items if dim in p['strata']})} for dim in dimensions if any(dim in p['strata'] for p in items)},'missing_dimensions':[dim for dim in ['受试者','动作类别','抓握类别','三维姿态类别'] if not any(dim in p['strata'] for p in items)]}
 if primary and primary!='手别' and all('手别' in p['strata'] for p in items):
  joint=lambda p:p['strata'].get(primary,'未提供')+' / '+p['strata']['手别']
  audit['datasets'][key]['categories'][primary+' × 手别']={v:{'pool':sum(joint(p)==v for p in items),'selected':sum(joint(p)==v for p in chosen)} for v in sorted({joint(p) for p in items})}
(SITE/'data/previews.json').write_text(json.dumps(selected,ensure_ascii=False,indent=1)+'\n')
audit['videos']=json.loads((SITE/'data/sampling.json').read_text())['videos']
(SITE/'data/sampling.json').write_text(json.dumps(audit,ensure_ascii=False,indent=1)+'\n')
print('POOL',sum(map(len,data.values())),'SELECTED',sum(map(len,selected.values())))
for key,v in audit['datasets'].items(): print(key,v['primary_dimension'],v['selected'],v['pool'])