private RoleVar createRoleVar( int parent, int child, IntSet knownPreds, List<String> roleStateNames) { RoleVar roleVar; String roleVarName = "Role_" + parent + "_" + child; if (!prm.makeUnknownPredRolesLatent || knownPreds.contains((Integer) parent)) { roleVar = new RoleVar( VarType.PREDICTED, roleStateNames.size(), roleVarName, roleStateNames, parent, child); } else { roleVar = new RoleVar( VarType.LATENT, roleStateNames.size(), roleVarName, roleStateNames, parent, child); } return roleVar; }
/** Adds factors and variables to the given factor graph. */ public void build( List<String> words, List<String> lemmas, IntSet knownPreds, List<String> roleStateNames, Map<String, List<String>> psMap, ObsFeatureExtractor obsFe, ObsFeatureConjoiner ofc, FactorGraph fg) { // Check for null arguments. if (prm.roleStructure == RoleStructure.PREDS_GIVEN && knownPreds == null) { throw new IllegalArgumentException("knownPreds must be non-null"); } if (prm.predictSense && (lemmas == null || psMap == null)) { throw new IllegalArgumentException("lemmas and psMap must be non-null"); } if (prm.roleStructure == RoleStructure.PREDS_GIVEN && prm.predictPredPos) { throw new IllegalStateException( "PREDS_GIVEN assumes that the predicate positions are always observed."); } this.n = words.size(); // Create the Role variables. roleVars = new RoleVar[n][n]; if (prm.roleStructure == RoleStructure.PREDS_GIVEN) { // CoNLL-friendly model; preds given IntIter iter = knownPreds.iterator(); while (iter.hasNext()) { int i = iter.next(); for (int j = 0; j < n; j++) { if (i == j && !prm.allowPredArgSelfLoops) { continue; } roleVars[i][j] = createRoleVar(i, j, knownPreds, roleStateNames); } } } else if (prm.roleStructure == RoleStructure.ALL_PAIRS) { // n**2 model for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j && !prm.allowPredArgSelfLoops) { continue; } roleVars[i][j] = createRoleVar(i, j, knownPreds, roleStateNames); } } } else { throw new IllegalArgumentException("Unsupported model structure: " + prm.roleStructure); } // Create the Sense variables. senseVars = new SenseVar[n]; for (int i = 0; i < n; i++) { // Only look at the knownPreds if the predicate positions are given. if (prm.roleStructure == RoleStructure.PREDS_GIVEN && !knownPreds.contains(i)) { // Skip non-predicate positions. continue; } if (prm.roleStructure == RoleStructure.ALL_PAIRS && prm.predictSense && prm.predictPredPos) { // Sense and position. List<String> senseStateNames = psMap.get(lemmas.get(i)); if (senseStateNames == null) { senseStateNames = CorpusStatistics.SENSES_FOR_UNK_PRED; } // Include the state of "no predicate". senseStateNames = Lists.cons("_", senseStateNames); senseVars[i] = createSenseVar(i, senseStateNames); } else if (prm.predictSense) { // Sense without positions. List<String> senseStateNames = psMap.get(lemmas.get(i)); if (senseStateNames == null) { senseStateNames = CorpusStatistics.SENSES_FOR_UNK_PRED; } senseVars[i] = createSenseVar(i, senseStateNames); } else if (prm.predictPredPos) { // Positions without sense. senseVars[i] = createSenseVar(i, CorpusStatistics.PRED_POSITION_STATE_NAMES); } } // Add the factors. for (int i = -1; i < n; i++) { // Get the lemma or UNK if we don't know it. String lemmaForTk = null; if (i >= 0) { if (prm.predictSense && psMap.get(lemmas.get(i)) != null) { // The template key must include the lemma appended, so that // there is a unique set of model parameters for each predicate. lemmaForTk = lemmas.get(i); } else { // If we've never seen this predicate, just give it to the (untrained) unknown classifier. lemmaForTk = CorpusStatistics.UNKNOWN_SENSE; } } // Add the unary factors for the sense variables. if (i >= 0 && senseVars[i] != null && senseVars[i].getType() != VarType.OBSERVED) { String templateKey = SrlFactorTemplate.SENSE_UNARY + "_" + lemmaForTk; fg.addFactor( new ObsFeTypedFactor( new VarSet(senseVars[i]), SrlFactorTemplate.SENSE_UNARY, templateKey, ofc, obsFe)); } // Add the role factors. for (int j = 0; j < n; j++) { if (i != -1) { // Add unary factors on Roles. if (prm.unaryFactors && roleVars[i][j] != null) { fg.addFactor( new ObsFeTypedFactor( new VarSet(roleVars[i][j]), SrlFactorTemplate.ROLE_UNARY, ofc, obsFe)); } // Add binary factors between Role and Sense variables. if (prm.binarySenseRoleFactors && senseVars[i] != null && roleVars[i][j] != null) { String templateKey = SrlFactorTemplate.SENSE_ROLE_BINARY + "_" + lemmaForTk; fg.addFactor( new ObsFeTypedFactor( new VarSet(senseVars[i], roleVars[i][j]), SrlFactorTemplate.SENSE_ROLE_BINARY, templateKey, ofc, obsFe)); } } } } }