Voltline's picture
Release vimeml-tiny-zh-v1 (step 844730): FP32 bundle, INT8 Core ML packages, source snapshot (part 2)
99297d7 verified
Raw History Blame Contribute Delete
4.65 kB
"""Cluster-aware paired statistics for frozen IME tracks.
Items written by the same author, or built from the same sentence template, tend to
flip together, so the effective sample is smaller than the item count and per-item
McNemar p-values are optimistic. Clusters join items that share an author/document
group (the homophone group on the challenge track) or whose NFKC targets (digits masked) have character-trigram Jaccard >= TEMPLATE.
Paired tests then resample or sign-flip whole clusters.
"""
import random
import re
import unicodedata
from math import comb
TEMPLATE = 0.5
_DIGITS = re.compile(r'[0-90-9]+')
def exact_mcnemar(gain, loss):
n, k = gain + loss, min(gain, loss)
return min(1.0, 2 * sum(comb(n, i) for i in range(k + 1)) / 2 ** n) if n else 1.0
def _trigrams(text):
text = _DIGITS.sub('0', unicodedata.normalize('NFKC', text))
return {text[i:i + 3] for i in range(max(1, len(text) - 2))}
def _group(row):
p = row.get('provenance') or {}
if str(p.get('group_id', '')).startswith('homophone:'):
return p['group_id'] # paired items of one homophone group
for key in ('author_id', 'source_doc_id'):
if p.get(key) is not None:
return f"{row.get('source', '')}:{key}:{p[key]}"
return None
def clusters(rows, template=TEMPLATE):
"""Cluster label per row: union of shared author/document group and template similarity."""
parent = list(range(len(rows)))
def find(i):
while parent[i] != i:
parent[i] = parent[parent[i]]
i = parent[i]
return i
def union(i, j):
parent[find(i)] = find(j)
first = {}
for i, row in enumerate(rows):
group = _group(row)
if group is not None:
union(i, first.setdefault(group, i))
if template is not None:
grams = [_trigrams(r['answers'][0]) for r in rows]
for i in range(len(rows)):
for j in range(i):
if len(grams[i] & grams[j]) >= template * len(grams[i] | grams[j]):
union(i, j)
return [find(i) for i in range(len(rows))]
def _cluster_sums(diff, labels):
sums = {}
for d, c in zip(diff, labels):
sums[c] = sums.get(c, 0) + d
return list(sums.values())
def sign_flip_p(diff, labels, draws=20000, seed=0):
"""Two-sided paired permutation p-value flipping the sign of whole clusters."""
sums = [s for s in _cluster_sums(diff, labels) if s]
observed = abs(sum(sums))
if not sums:
return 1.0
if len(sums) <= 20:
hits = sum(abs(sum(s if mask >> i & 1 else -s for i, s in enumerate(sums))) >= observed
for mask in range(2 ** len(sums)))
return hits / 2 ** len(sums)
rng = random.Random(seed)
hits = sum(abs(sum(s if rng.random() < .5 else -s for s in sums)) >= observed for _ in range(draws))
return (hits + 1) / (draws + 1)
def bootstrap_interval(diff, labels, draws=10000, seed=0, level=.95):
"""Percentile interval of the net paired difference, resampling clusters with replacement."""
sums = _cluster_sums(diff, labels)
rng = random.Random(seed)
totals = sorted(sum(rng.choice(sums) for _ in sums) for _ in range(draws))
tail = (1 - level) / 2
return totals[int(tail * draws)], totals[min(draws - 1, int((1 - tail) * draws))]
def _cluster_sizes(labels):
sizes = {}
for c in labels:
sizes[c] = sizes.get(c, 0) + 1
return sizes
def design_effect(diff, labels):
"""Variance of the paired total under clustering relative to independent items."""
mean = sum(diff) / len(diff)
iid = sum((d - mean) ** 2 for d in diff)
sums, sizes = {}, _cluster_sizes(labels)
for d, c in zip(diff, labels):
sums[c] = sums.get(c, 0) + d
clustered = sum((s - mean * sizes[c]) ** 2 for c, s in sums.items())
return clustered / iid if iid else 1.0
def paired(before, after, labels, seed=0):
"""Paired comparison of two boolean outcome lists on the same frozen cases."""
gain = sum(b and not a for a, b in zip(before, after))
loss = sum(a and not b for a, b in zip(before, after))
diff = [int(b) - int(a) for a, b in zip(before, after)]
low, high = bootstrap_interval(diff, labels, seed=seed)
return {'gain': gain, 'loss': loss, 'net': gain - loss, 'exact_mcnemar_p': exact_mcnemar(gain, loss),
'clusters': len(set(labels)), 'discordant_clusters': sum(1 for s in _cluster_sums(diff, labels) if s),
'cluster_sign_flip_p': sign_flip_p(diff, labels, seed=seed),
'cluster_bootstrap_95': [low, high], 'design_effect': design_effect(diff, labels)}