package edu.stanford.nlp.sempre.tables.baseline; import java.util.*; import edu.stanford.nlp.sempre.*; import edu.stanford.nlp.sempre.tables.*; import edu.stanford.nlp.sempre.tables.features.*; import fig.basic.*; /** * Compute features for BaselineParser * * @author ppasupat */ public class TableBaselineFeatureComputer implements FeatureComputer { public static class Options { @Option(gloss = "Verbosity") public int verbosity = 0; } public static Options opts = new Options(); @Override public void extractLocal(Example ex, Derivation deriv) { if (!deriv.isRoot(ex.numTokens())) return; if (!FeatureExtractor.containsDomain("table-baseline")) return; List<PhraseInfo> phraseInfos = PhraseInfo.getPhraseInfos(ex); // Find the list of all entities mentioned in the question Set<String> mentionedEntities = new HashSet<>(), mentionedProperties = new HashSet<>(); for (PhraseInfo phraseInfo : phraseInfos) { for (String s : phraseInfo.fuzzyMatchedPredicates) { // s is either an ENTITY or a BINARY SemType entityType = TableTypeSystem.getEntityTypeFromId(s); SemType propertyType = TableTypeSystem.getPropertyTypeFromId(s); if (entityType != null) mentionedEntities.add(s); if (propertyType != null) mentionedProperties.add(s); } } // Find the base cell(s) TableKnowledgeGraph graph = (TableKnowledgeGraph) ex.context.graph; List<Value> values = ((ListValue) deriv.value).values; if (opts.verbosity >= 2) LogInfo.logs("%s", values); if (values.get(0) instanceof NumberValue) { values = graph.joinSecond(TableTypeSystem.CELL_NUMBER_VALUE, values); } else if (values.get(0) instanceof DateValue) { values = graph.joinSecond(TableTypeSystem.CELL_DATE_VALUE, values); } else { values = new ArrayList<>(values); } if (opts.verbosity >= 2) LogInfo.logs("%s", values); List<String> predictedEntities = new ArrayList<>(); for (Value value : values) { predictedEntities.add(((NameValue) value).id); } // Define features for (String predicted : predictedEntities) { List<String> pCols = graph.getColumnsOfCellId(predicted); // TODO: use all columns in pCols String pProp = pCols.get(0); List<Integer> pRows = graph.getRowsOfCellId(predicted); if (opts.verbosity >= 2) LogInfo.logs("[p] %s %s %s", predicted, pCols, pRows); for (String mentioned : mentionedEntities) { List<String> mCols = graph.getColumnsOfCellId(mentioned); // TODO: use all columns in mCols String mProp = mCols.get(0); List<Integer> mRows = graph.getRowsOfCellId(mentioned); if (opts.verbosity >= 2) LogInfo.logs("[m] %s %s %s", mentioned, mProp, mRows); // Same column as ENTITY + offset if (pProp != null && mProp != null && pProp.equals(mProp)) { defineAllFeatures(deriv, "same-column", phraseInfos); if (pRows != null && pRows.size() == 1 && mRows != null && mRows.size() == 1) { defineAllFeatures(deriv, "same-column;offset=" + (pRows.get(0) - mRows.get(0)), phraseInfos); } } // Same row as ENTITY if (mRows != null && pRows != null) { for (int pRow : pRows) { if (mRows.contains(pRow)) { defineAllFeatures(deriv, "same-row", phraseInfos); break; } } } } for (String mentioned : mentionedProperties) { // match column name BINARY if (opts.verbosity >= 2) LogInfo.logs("%s %s", pProp, mentioned); if (mentioned.equals(pProp)) { defineAllFeatures(deriv, "match-column-binary", phraseInfos); } } // Row index (first or last) if (pRows != null && pRows.contains(0)) defineAllFeatures(deriv, "first-row", phraseInfos); if (pRows != null && pRows.contains(graph.numRows() - 1)) defineAllFeatures(deriv, "last-row", phraseInfos); } } private void defineAllFeatures(Derivation deriv, String name, List<PhraseInfo> phraseInfos) { defineUnlexicalizedFeatures(deriv, name); defineLexicalizedFeatures(deriv, name, phraseInfos); } private void defineUnlexicalizedFeatures(Derivation deriv, String name) { deriv.addFeature("table-baseline", name); } private void defineLexicalizedFeatures(Derivation deriv, String name, List<PhraseInfo> phraseInfos) { for (PhraseInfo phraseInfo : phraseInfos) { deriv.addFeature("table-baseline", "phrase=" + phraseInfo.lemmaText + ";" + name); } } }