public LogicalForm(Derivation derivation, Map<String, Object> map) { this.derivation = derivation; this.map = map; fields = fields(map); score = derivation.score; }
public LogicalForm computeLogicalForm(Derivation d){ LogicalForm lf = new LogicalForm(d, applySemantics(d).get(0)); lf.updateScore(weights); return lf; }
float computeTarget(LogicalForm lf, Example e){ return lf.match(e.label) ? 1 : -1; }
@Override public float optimize(Example e) { List<LogicalForm> candidates = parser.parse(e.input); if(candidates.isEmpty()) return 1; LogicalForm lf = randomCandidate(e, candidates); Derivation d = lf.getDerivation(); Map<String, Integer> features = d.getRuleFeatures(); features.putAll(lf.fields().stream().collect(Collectors.toMap(Function.identity(), k -> 1))); float target = computeTarget(lf, e); float loss = hingeLoss(features, target); if(loss > 0) updateWeights(features, target, learnRate); updateL2Penalty(learnRate, l2Penalty); return loss; }
for(LogicalForm lf: lfs){ if(first) score += lf.getDerivation().getScore(); if(lf.match(e.label)){ if(first) { acc++;
@Test void parse() { List<Rule> rules = Arrays.asList( new Rule("$A", "a"), new Rule("$B", "b"), new Rule("$C", "$A $B", "{e:@first, f:@last}") ); Grammar grammar = new Grammar(rules, "$C"); Parser p = new Parser(grammar, s -> Arrays.asList(s.split(" ")), Collections.emptyList()); Map<String, Object> expected = new HashMap<String, Object>(){{ put("e", "a"); put("f", "b"); }}; List<LogicalForm> actual = p.parse("a b"); assertEquals(1, actual.size()); assertEquals(expected, actual.get(0).getMap()); }
static List<String> fields(Map<String, Object> hashMap){ List<String> keys = new ArrayList<>(hashMap.keySet()); for(Map.Entry<String, Object> entry: hashMap.entrySet()) { if(entry.getValue() instanceof HashMap<?, ?>) for(String f: fields((HashMap<String, Object>)entry.getValue())) keys.add(String.format("%s:%s", entry.getKey(), f)); } return keys; }
LogicalForm randomCandidate(Example e, List<LogicalForm> candidates){ LogicalForm correct = null; if(random.nextFloat() < correctProb){ for(LogicalForm lf: candidates){ if(lf.match(e.label)){ correct = lf; break; } } } if(correct != null) return correct; else return candidates.get(random.nextInt(candidates.size())); } }
@Test void fields() { Map<String, Object> map = new HashMap<String, Object>(){{ put("a", 1); put("b", 2); put("c", new HashMap<String, Object>(){{ put("d", 4); put("e", new HashMap<String, Object>(){{ put("f", 5); }}); }}); }}; List<String> expected = Arrays.asList( "a", "b", "c", "c:d", "c:e", "c:e:f" ); assertEquals(expected, LogicalForm.fields(map)); } }