code wiki / (root) / nx_absa_seq.nx

nx_absa_seq.nx

buildroot/runtime/nx_absa_seq.nx

70273 B1447 linesdepth 6pulls 16 transitivereach 2 importersview sourcekind librarytopic absa
docsdependenciesstructsconstsfunctions

about

nx_absa_seq.nx -- rung IM28: a SUPERVISED SEQUENCE model for aspect-term extraction (SemEval-2014 Task 4 SB1), the step that closes the gap from the dictionary baseline (~46 F1) toward the CRF winners (74-84 F1). It is an AVERAGED STRUCTURED PERCEPTRON with Viterbi BIO decoding -- integer weights only, so it runs in the nofloat estate; the CRF winners add a probabilistic objective and POS/parse features, which we do not have a tagger for, so this is the honest reachable model, not a claim of parity. Trained on the TRAIN split, decoded on the TEST split, scored by the same set-overlap F1 (nx_absa_lib) the other arms use so the numbers are comparable. FEATURES per token (the hashing trick, one big integer weight table): word, 3-char prefix and suffix, previous and next word, a has-digit shape, dictionary membership (the supervised dictionary signal folded in as a feature), and a bias. TRANSITIONS between BIO tags, with I only reachable from B or I. Averaging is the standard lazy scheme (a weight's average is its running sum plus its current value times the time since it last changed); for the Viterbi argmax the common divisor is dropped. license_tier: ORIGINAL No hw writes (Rule 26). LIB.

dependencies 8 imports · 2 importers

nx_syscalls.nx nx_reviewmine_lib.nx nx_absa_lib.nx nx_postag.nx nx_depparse.nx nx_wordclust.nx nx_logadd_lib.nx nx_embfeat_lib.nx nx_absa_seq.nx nx_absa_seq_gate.nx nx_absa_seqextract.nx

imports: nx_syscalls.nxnx_reviewmine_lib.nxnx_absa_lib.nxnx_postag.nxnx_depparse.nxnx_wordclust.nxnx_logadd_lib.nxnx_embfeat_lib.nx

imported by: nx_absa_seq_gate.nxnx_absa_seqextract.nx

structs

none

consts

22const SP_W: i64 = 1048576 // 2^20 feature-weight slots
23const SP_WMASK: i64 = 1048575
24const SP_NTAGS: i64 = 3
25const SP_O: i64 = 0
26const SP_B: i64 = 1
27const SP_I: i64 = 2
28const SP_NTRANS: i64 = 9 // SP_NTAGS * SP_NTAGS
29const SP_EPOCHS: i64 = 16 // 8 left a third of sentences still updating; doubled for convergence
30const SP_TOK_CAP: i64 = 256 // tokens per sentence
31const SP_TOKBUF: i64 = 16384
32const SP_FEATBUF: i64 = 128
33const SP_NFEAT: i64 = 53 // 8 base + prev2, next2, prev+cur, cur+next, 4-char suffix, dictionary reliability, 5 POS, 5 parse, 5 cluster, 24 embedding
38const SP_PFX_EMB: i64 = 108 // 'l' embedding coordinate families (the payload carries the coordinate index)
39const SP_EMB_BASE: i64 = 29 // first embedding feature index
40const SP_EMB_DIMS: i64 = 24 // the table's coordinate count; a table of another width refuses the mode
45const SP_PFX_CL0: i64 = 90 // 'Z' this token's cluster at the coarsest level
46const SP_PFX_CL1: i64 = 97 // 'a' this token's cluster at the middle level
47const SP_PFX_CL2: i64 = 105 // 'i' this token's cluster at the finest level
48const SP_PFX_CLP: i64 = 106 // 'j' previous token's cluster, middle level
49const SP_PFX_CLN: i64 = 107 // 'k' next token's cluster, middle level
50const SP_CLUST_BASE: i64 = 24 // first cluster feature index
51const SP_CL_MID: i64 = 1 // the middle granularity's level index
60const SP_CRF_ETA_NUM: i64 = 1
61const SP_CRF_ETA_DEN: i64 = 4
62const SP_NPAIR: i64 = 9 // SP_NTAGS * SP_NTAGS pair marginals per position
63const SP_CRF_NLL_SLACK: i64 = 8 // Q10 units a chain of log-adds may lose: a sentence NLL below -slack is impossible and counted
68const SP_PFX_REL: i64 = 82 // 'R' relation to the head
69const SP_PFX_HW: i64 = 72 // 'H' head word ('^' for the root)
70const SP_PFX_HT: i64 = 71 // 'G' head tag ('$' for the root)
71const SP_PFX_RELT: i64 = 74 // 'J' relation + own tag
72const SP_PFX_CHR: i64 = 75 // 'K' relations of the leftmost and rightmost dependents
73const SP_PARSE_BASE: i64 = 19 // first parse feature index
78const SP_PFX_POS: i64 = 84 // 'T' tag of this token
79const SP_PFX_POSP: i64 = 85 // 'U' previous token's tag
80const SP_PFX_POSN: i64 = 86 // 'V' next token's tag
81const SP_PFX_POSPC: i64 = 88 // 'X' previous+current tag bigram
82const SP_PFX_POSCN: i64 = 89 // 'Y' current+next tag bigram
83const SP_POS_BASE: i64 = 14 // first POS feature index
89const SP_BUCKETS: i64 = 4 // reliability quantised to fifths: 0..4 of SP_BUCKETS
90const SP_PFX_E: i64 = 101 // 'e' dictionary reliability bucket
91const SP_CH_DASH: i64 = 45 // '-' the bucket of a token not in the dictionary
92const SP_MAJ_NUM: i64 = 2 // gold * 2 >= seen <=> an aspect in at least half its occurrences
93const SP_AFF: i64 = 3 // affix length
94const SP_AFF4: i64 = 4 // the longer suffix (a second affix family, not a replacement)
95const SP_NEG: i64 = 0 - 1000000000 // Viterbi -infinity
96const SP_GRAM_CAP: i64 = 512
98const SP_PFX_W: i64 = 119 // 'w'
99const SP_PFX_P: i64 = 112 // 'p' prefix
100const SP_PFX_S: i64 = 115 // 's' suffix
101const SP_PFX_PW: i64 = 80 // 'P' previous word
102const SP_PFX_NW: i64 = 78 // 'N' next word
103const SP_PFX_SH: i64 = 104 // 'h' shape
104const SP_PFX_D: i64 = 100 // 'd' dictionary membership
105const SP_PFX_B: i64 = 98 // 'b' bias
106const SP_PFX_PW2: i64 = 81 // 'Q' word two back
107const SP_PFX_NW2: i64 = 77 // 'M' word two ahead
108const SP_PFX_PC: i64 = 99 // 'c' previous+current conjunction
109const SP_PFX_CN: i64 = 67 // 'C' current+next conjunction
110const SP_PFX_S4: i64 = 83 // 'S' 4-char suffix
111const SP_CH_DIGIT0: i64 = 48
112const SP_CH_DIGIT9: i64 = 57
113const SP_CH_ONE: i64 = 49
114const SP_CH_ZERO: i64 = 48
115const SP_CH_CARET: i64 = 94 // '^' BOS
116const SP_CH_DOLLAR2: i64 = 36 // '$' EOS
118const SP_O_INTER: i64 = 0
119const SP_O_NS: i64 = 1
120const SP_O_NG: i64 = 2
121const SP_O_P: i64 = 3
122const SP_O_R: i64 = 4
123const SP_O_F1: i64 = 5
124const SP_O_DICT: i64 = 6
125const SP_O_TRAINREC: i64 = 7 // train records used (term found and labelled)
126const SP_O_TRAINSKIP: i64 = 8 // train records skipped (term not a contiguous token run)
127const SP_O_TESTREC: i64 = 9
128const SP_O_EPOCHS: i64 = 10
129const SP_O_UPDATES: i64 = 11 // perceptron updates in the last epoch
130const SP_O_TRAINSENT: i64 = 12 // MERGED training sentences (consecutive same-sentence records folded into one)
133const SP_O_U_INTER: i64 = 13
134const SP_O_U_NS: i64 = 14
135const SP_O_U_P: i64 = 15
136const SP_O_U_R: i64 = 16
137const SP_O_U_F1: i64 = 17
141const SP_O_OC_TP: i64 = 18
142const SP_O_OC_NS: i64 = 19
143const SP_O_OC_NG: i64 = 20
144const SP_O_OC_P: i64 = 21
145const SP_O_OC_R: i64 = 22
146const SP_O_OC_F1: i64 = 23
147const SP_O_OCU_TP: i64 = 24
148const SP_O_OCU_NS: i64 = 25
149const SP_O_OCU_P: i64 = 26
150const SP_O_OCU_R: i64 = 27
151const SP_O_OCU_F1: i64 = 28
152const SP_O_TESTSENT: i64 = 29 // merged test sentences
153const SP_O_DICT_MAJ: i64 = 30 // dictionary terms passing the majority rule (an aspect in >= half their training occurrences)
154const SP_O_POS: i64 = 31 // 1 when a treebank was set and the tagger trained, else 0
155const SP_O_POS_TOK: i64 = 32 // tagger training tokens (0 without a treebank)
156const SP_O_PARSE: i64 = 33 // 1 when the parser trained and every sentence was parsed, else 0
157const SP_O_PARSE_SENT: i64 = 34 // parser training sentences (0 without a treebank or with the parse switch off)
158const SP_O_GROUPS: i64 = 35 // merged-sentence groups the first pass recorded (the shuffle's unit; counts unusable ones too)
159const SP_O_SHUF: i64 = 36 // 1 when epochs 1 and later walked the shuffled order, 0 in file order (the default)
160const SP_O_CLUST: i64 = 37 // 1 when a PPMI model was set, loaded and the vocabulary clustered, else 0
161const SP_O_CLUST_VOCAB: i64 = 38 // training vocabulary words the clusterer holds
162const SP_O_CLUST_INMODEL: i64 = 39 // of those, words the PPMI model knows
163const SP_O_CRF: i64 = 40 // 1 when the CRF objective trained the weights, 0 for the perceptron (the default)
164const SP_O_CRF_NLL_FIRST: i64 = 41 // epoch-0 total negative log-likelihood, Q10 (0 in perceptron mode)
165const SP_O_CRF_NLL_LAST: i64 = 42 // last-epoch total negative log-likelihood, Q10
166const SP_O_CRF_MARGDEV: i64 = 43 // largest |sum of a token's marginals - S| seen, Q10 (a partition witness)
167const SP_O_CRF_NEGNLL: i64 = 44 // sentences whose partition read below their gold path score beyond the slack (must be 0)
168const SP_O_EMB: i64 = 45 // 1 when the embedding table was set, loaded at the declared width and its features were on
169const SP_O_EMB_DIM: i64 = 46 // the loaded table's coordinate count (0 when none)
170const SP_O_EMB_LOOKUPS: i64 = 47 // training-pass token lookups against the vocabulary
171const SP_O_EMB_HITS: i64 = 48 // of those, tokens the vocabulary knows (coverage numerator)
176const SP_O_EC_UNTOK: i64 = 49 // missed and not tokenisable in its own sentence
177const SP_O_EC_UNSEEN1: i64 = 50 // missed, single-token, absent from the training dictionary
178const SP_O_EC_UNSEENM: i64 = 51 // missed, multi-token, absent from the training dictionary
179const SP_O_EC_SEEN1: i64 = 52 // missed, single-token, present in the training dictionary
180const SP_O_EC_SEENM: i64 = 53 // missed, multi-token, present in the training dictionary
181const SP_O_EC_UNIONMISS: i64 = 54 // gold occurrences the UNION arm missed too
182const SP_O_N: i64 = 55
183const SP_CH_SPACE: i64 = 32
188const SP_GROUP_CAP: i64 = 65536 // groups the shuffle can hold (SemEval restaurants train is 2018)
190const SL_BUF: i64 = 0
191const SL_OFFS: i64 = 1
192const SL_LENS: i64 = 2
193const SL_COUNT: i64 = 3
194const SL_USED: i64 = 4
195const SL_FIELDS: i64 = 5
196const SL_CAP: i64 = 64 // spans per sentence
197const SL_BUFCAP: i64 = 8192
198const SP_CTR_N: i64 = 4 // first-pass flag + records used + records skipped + merged sentences

functions

258func sp_set_shuffle(on: i64) -> i64 { sp_shuffle_want = on; return 0 }
called by 2: mainmain
263func sp_set_clusters(path: *u8) -> i64 { sp_clust_model = path; return 0 }
called by 2: mainmain
265func sp_clust_vocab(train: *u8) -> i64
298func sp_set_crf(on: i64) -> i64 { sp_crf_want = on; return 0 }
called by 2: mainmain
307func sp_set_embed(ppmi: *u8, emb: *u8) -> i64 { sp_emb_ppmi = ppmi; sp_emb_path = emb; return 0 }
called by 2: mainmain
313func sp_set_treebank(path: *u8) -> i64 { sp_treebank = path; sp_parse_want = 0; return 0 }
called by 2: mainmain
315func sp_set_parse(on: i64) -> i64 { sp_parse_want = on; return 0 }
called by 2: mainmain
318func sp_tag_sentence(cnt: i64) -> i64
326func sl_new() -> *i64
called by 1: sp_reset calls 1: sys_mmap
335func sl_reset(h: *i64) -> i64 { h[SL_COUNT] = 0; h[SL_USED] = 0; return 0 }
336func sl_has(h: *i64, s: *u8, n: i64) -> i64
353func sl_add(h: *i64, s: *u8, n: i64) -> i64
369func sl_inter(a: *i64, b: *i64) -> i64
called by 1: sp_eval calls 1: sl_has
379func sp_reset() -> i64
called by 1: sp_eval calls 2: sys_mmapsl_new
434func sp_acc_reset() -> i64
440func sp_acc_or(cnt: i64) -> i64
445func sp_same_sent(rbuf: *u8, rl: i64) -> i64
452func sp_flush(cnt: i64, dic: *i64) -> i64
478func sp_tokenize(sent: *u8, n: i64) -> i64
498func sp_fh(pfx: i64, s: *u8, n: i64) -> i64
called by 1: sp_feats calls 1: rm_hash
504func sp_has_digit(s: *u8, n: i64) -> i64
called by 1: sp_feats
510func sp_feats(cnt: i64, i: i64, dic: *i64) -> i64
660func sp_w_at(idx: i64, useavg: i64) -> i64
called by 1: sp_emission
664func sp_bump(idx: i64, delta: i64) -> i64
670func sp_tw_at(pt: i64, t: i64, useavg: i64) -> i64
675func sp_tbump(pt: i64, t: i64, delta: i64) -> i64
682func sp_emission(i: i64, tag: i64, useavg: i64) -> i64
called by 2: sp_viterbisp_crf_fb calls 1: sp_w_at
690func sp_viterbi(cnt: i64, useavg: i64) -> i64
called by 2: sp_flushsp_eval calls 2: sp_emissionsp_tw_at
733func sp_gold_bio(cnt: i64, term: *u8, tlen: i64) -> i64
774func sp_update(cnt: i64) -> i64
called by 1: sp_flush calls 2: sp_bumpsp_tbump
806func sp_crf_fb(cnt: i64) -> i64
907func sp_crf_gold_score(cnt: i64) -> i64
called by 1: sp_flush calls 1: sp_tw_at
918func sp_crf_update(cnt: i64) -> i64
called by 1: sp_flush calls 2: sp_bumpsp_tbump
953func sp_extract_list(cnt: i64, lst: *i64) -> i64
called by 1: sp_eval calls 2: rm_catnsl_add
973func sp_dict_majority(slot: i64) -> i64
980func sp_dict_list(cnt: i64, dic: *i64, lst: *i64, majority: i64) -> i64
1005func sp_dict_stats(train: *u8, dic: *i64) -> i64
1046func sp_dict_stats_flush(dic: *i64) -> i64
called by 1: sp_dict_stats calls 1: hs_slot_raw
1068func sp_extract(cnt: i64, pred_set: *i64) -> i64
called by 1: sp_eval calls 3: rm_catnhs_has_rawhs_add_raw
1089func sp_train_pass(train: *u8, dic: *i64, first: *i64) -> i64
1144func sp_train_group(b: *u8, n: i64, start: i64, dic: *i64) -> i64
1170func sp_eval(train: *u8, test: *u8, out: *i64) -> i64