code wiki / _hdl_build / nx_dr_fuse.nx
nx_dr_fuse.nx source
↩ module page · 122 lines · 4742 B
1// nx_dr_fuse.nx -- LEARNED signal combiner for the deep-research judge (DR-12).
2// Two hand-reasoned refinements to the count model were measured and REJECTED (a domain-
3// augmented vocabulary made discrimination worse; IDF weighting was a dead heat). What had
4// never been tried is LEARNING how to combine the signals we already compute, from the real
5// labels ServiceNow publishes.
6//
7// Model: score = w0*lexical + w1*semantic + w2*semantic_idf (integer, deterministic).
8// Fitting: EXHAUSTIVE GRID SEARCH over integer weights on a TRAINING task range, scored by
9// pairwise ranking accuracy (every insight must outrank every distractor within its own task,
10// which is exactly the matched-precision metric the judge is graded on). Grid search rather
11// than gradient descent: no learning rate, no convergence failure, and bit-reproducible.
12//
13// ★HONEST EVALUATION BY CONSTRUCTION: weights are fitted ONLY on the training task range and
14// reported ONLY on a DISJOINT held-out range. Fitting and scoring on the same tasks would be
15// the rigged-gate sin; the split is a parameter so the gate can prove the separation.
16// Every func <=6 params (NAS nx_cc >6-arg skew, seq239). No hardware writes (Rule 26).
17//
18// module: nishi-core.research.dr_fuse
19// depends: nx_syscalls.nx
20// genealogy_id: linear_rank_fusion + perceptron_ranking
21import "nx_syscalls.nx"
22const FU_MAGIC_1000000000: i64 = 1000000000
23
24// record layout: 5 i64 per candidate -- [task, label(1=insight), lexical, semantic, semantic_idf]
25const FU_STRIDE: i64 = 5
26
27func fu_task(r: *i64, i: i64) -> i64 { return r[i * FU_STRIDE] }
28func fu_label(r: *i64, i: i64) -> i64 { return r[i * FU_STRIDE + 1] }
29
30// combined score under weights w[3]
31func fu_score(r: *i64, i: i64, w: *i64) -> i64 {
32 let b: i64 = i * FU_STRIDE
33 return w[0] * r[b + 2] + w[1] * r[b + 3] + w[2] * r[b + 4]
34}
35
36// pairwise ranking accuracy (permille) over tasks in [lo,hi): of all (insight,distractor)
37// pairs inside a task, how many does `w` order correctly?
38func fu_pairacc(r: *i64, n: i64, w: *i64, lo: i64, hi: i64) -> i64 {
39 var good: i64 = 0
40 var tot: i64 = 0
41 var i: i64 = 0
42 while i < n {
43 let t: i64 = fu_task(r, i)
44 if t >= lo { if t < hi { if fu_label(r, i) == 1 {
45 let si: i64 = fu_score(r, i, w)
46 var j: i64 = 0
47 while j < n {
48 if fu_task(r, j) == t { if fu_label(r, j) == 0 {
49 tot = tot + 1
50 if si > fu_score(r, j, w) { good = good + 1 }
51 } }
52 j = j + 1
53 }
54 } } }
55 i = i + 1
56 }
57 if tot < 1 { return 0 }
58 return (good * 1000) / tot
59}
60
61// mean insight-recall at 100% distractor-avoidance over tasks in [lo,hi): per task, threshold
62// just above the highest-scoring distractor, then count insights strictly above it.
63func fu_recall(r: *i64, n: i64, w: *i64, lo: i64, hi: i64) -> i64 {
64 var sum: i64 = 0
65 var tasks: i64 = 0
66 var t: i64 = lo
67 while t < hi {
68 var maxd: i64 = 0 - FU_MAGIC_1000000000
69 var ni: i64 = 0
70 var seen: i64 = 0
71 var i: i64 = 0
72 while i < n {
73 if fu_task(r, i) == t {
74 seen = 1
75 if fu_label(r, i) == 0 { let s: i64 = fu_score(r, i, w); if s > maxd { maxd = s } }
76 else { ni = ni + 1 }
77 }
78 i = i + 1
79 }
80 if seen == 1 { if ni > 0 {
81 var hit: i64 = 0
82 i = 0
83 while i < n {
84 if fu_task(r, i) == t { if fu_label(r, i) == 1 {
85 if fu_score(r, i, w) > maxd { hit = hit + 1 }
86 } }
87 i = i + 1
88 }
89 sum = sum + (hit * 1000) / ni
90 tasks = tasks + 1
91 } }
92 t = t + 1
93 }
94 if tasks < 1 { return 0 }
95 return sum / tasks
96}
97
98// Fit w[3] by exhaustive integer grid search on tasks [lo,hi), maximising pairwise accuracy.
99// Deterministic: ties keep the FIRST (lowest) weight vector, so the result is reproducible.
100// Returns the best training pairwise accuracy achieved.
101func fu_fit(r: *i64, n: i64, w: *i64, lo: i64, hi: i64) -> i64 {
102 let cand: *i64 = sys_mmap(3 * 8) as *i64
103 var best: i64 = 0 - 1
104 var a: i64 = 0
105 while a <= 10 {
106 var b: i64 = 0
107 while b <= 10 {
108 var c: i64 = 0
109 while c <= 10 {
110 if a + b + c > 0 {
111 cand[0] = a; cand[1] = b; cand[2] = c
112 let acc: i64 = fu_pairacc(r, n, cand, lo, hi)
113 if acc > best { best = acc; w[0] = a; w[1] = b; w[2] = c }
114 }
115 c = c + 1
116 }
117 b = b + 1
118 }
119 a = a + 1
120 }
121 return best
122}