!7 static Guesser best; static double bestScore; sS key = "verb"; concept Sentence { S text; SS data; S get(S s) { ret data.get(s); } S subject() { ret get("subject"); } S verb() { ret get(key); } } sclass Input { L tok; IntRange subject; *() {} *(L *tok, IntRange *subject) {} } Input > Example { new L verbs; *() {} *(L *tok, IntRange *subject, L *verbs) {} toString { ret quote(joinWithSpaces(tok)) + " => " + map(verbs, func(IntRange r) { joinWithSpaces(subList(tok, r.start, r.end)) }); } } abstract sclass GuesserBase { void learn(L material) { for (Example e : material) learn(e); } void learn(Example e) {} } abstract sclass Guesser extends GuesserBase { abstract L getVerbTokens(Input input); } Guesser > GWordAfterSubject { L getVerbTokens(Input input) { IntRange r = input.subject; ret r == null ? null : ll(intRange(r.end, r.end+1)); } } p { loadConceptsFrom(#1008692); L material = learningMaterial(); pnlStruct(material); // This yields the empty learner Pair p = bestLearner(material, ll(new GWordAfterSubject), 50, 3, true); // Now we train it with all data for in-program use if (p.a != null) p.a.learn(material); // Print and store print("Best learner: " + formatDouble(p.b, 1) + "% - " + struct(p.a)); best = p.a; bestScore = p.b; } sbool printDetails, printSuccesses; static double checkGuesser(L testMaterial, Guesser g) { print(); int score = 0, n = 0; for (final Example e : testMaterial) { L r = cast pcall(g, "getVerbTokens", e.tok); bool ok = eq(r, e.verbs); if (ok) ++score; ++n; if (printDetails || ok && printSuccesses) if (ok) print("OK " + e); else print("FAIL " + (r == null ? "-" : map(r, func(IntRange r) { joinWithSpaces(subList(e.tok, r)) })) + " for " + e); } printScore(shortClassName(g), score, n); ret ratioToPercent(score, n); } static double checkGuesserAfterRandomizedPartialLearn(L testMaterial, Guesser g, double percentToLearn, bool hardMode) { Pair> p = getRandomPercent2(testMaterial, percentToLearn); g.learn(p.a); ret checkGuesser(hardMode ? p.b : testMaterial, g); } // best learner with randomized x% training material // returns guesser, percentage solved // hardMode = only count scores on untrained examples static Pair bestLearner(final L material, L guessers, final double percent, int repetitions, final bool hardMode) { new Best best; for (final Guesser g : guessers) best.put(g, repeatAndAdd_double(repetitions, func { checkGuesserAfterRandomizedPartialLearn(material, cloneObject(g), percent, hardMode) })/repetitions); ret best.pair(); } static L learningMaterial() { L out = new L; for (Sentence s) { if (s.verb() == null) continue; L r = ai_parseVerbAction(s.verb()); if (r != null) { L tok = nlTok5(s.text); IntRange subject = ai_parseSubjectAction(s.subject()); subject = charRangeToCodeTokens(tok, subject); r = charRangeToCodeTokens(tok, r); tok = codeTokens(tok); out.add(Example(tok, subject, r)); } } ret out; } // to be called from applications - works on character level static void callGuesser(Guesser g, S sentence, SS data) { L tok = nlTok5(sentence); L r = g.getVerbTokens(new Input(codeTokens(tok), charRangeToCodeTokens(tok, ai_parseAction(data.get("subject"))))); if (r == null) ret; data.put(key, ai_renderAction(sentence, codeTokenRangeToChars(tok, first/*XX*/(r)))); }