public LogicalForm(Derivation derivation, Map<String, Object> map) { this.derivation = derivation; this.map = map; fields = fields(map); score = derivation.score; }
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; }
@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; }
@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)); } }