All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.nlp.ie.machinereading.structure.RelationMention Maven / Gradle / Ivy

Go to download

Stanford CoreNLP provides a set of natural language analysis tools which can take raw English language text input and give the base forms of words, their parts of speech, whether they are names of companies, people, etc., normalize dates, times, and numeric quantities, mark up the structure of sentences in terms of phrases and word dependencies, and indicate which noun phrases refer to the same entities. It provides the foundational building blocks for higher level text understanding applications.

There is a newer version: 4.5.7
Show newest version
package edu.stanford.nlp.ie.machinereading.structure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import edu.stanford.nlp.util.CoreMap;
import edu.stanford.nlp.util.IdentityHashSet;

/**
 * Each relation has a type and set of arguments
 * 
 * @author Andrey Gusev
 * @author Mihai
 * @author David McClosky
 * 
 */
public class RelationMention extends ExtractionObject {

  private static final long serialVersionUID = 8962289597607972827L;
  public static final Logger logger = Logger.getLogger(RelationMention.class.getName());

  // index of the next unique id
  private static int MENTION_COUNTER = 0;
  
  public static final String UNRELATED = "_NR";

  /**
   * List of argument names in this relation
   */
  protected List argNames;
  
  /** 
   * List of arguments in this relation
   * If unnamed, arguments MUST be stored in semantic order, e.g., ARG0 must be a person in a employed-by relation
   */
  protected List args;
  
  /** 
   * A signature for a given relation mention, e.g., a concatenation of type and argument strings
   * This is used in KBP, where we merge all RelationMentions corresponding to the same abstract relation 
   */
  protected String signature;
  
  public RelationMention(String objectId, 
      CoreMap sentence,
      Span span,
      String type,
      String subtype,
      List args) {
    super(objectId, sentence, span, type, subtype);
    this.args = args;
    this.argNames = null;
    this.signature = null;
  }
  
  public RelationMention(String objectId, 
      CoreMap sentence,
      Span span,
      String type,
      String subtype,
      List args,
      List argNames) {
    super(objectId, sentence, span, type, subtype);
    this.args = args;
    this.argNames = argNames;
    this.signature = null;
  }
  
  public RelationMention(String objectId, 
      CoreMap sentence, 
      Span span,
      String type,
      String subtype,
      ExtractionObject... args) {
    this(objectId, sentence, span, type, subtype, Arrays.asList(args));
  }

  public boolean argsMatch(RelationMention rel) {
    return argsMatch(rel.getArgs());
  }
  
  public boolean argsMatch(ExtractionObject... inputArgs) {
    return argsMatch(Arrays.asList(inputArgs));
  }

  /**
   * Verifies if the two sets of arguments match
   * @param inputArgs List of arguments
   */
  public boolean argsMatch(List inputArgs) {
    if (inputArgs.size() != this.args.size()) {
      return false;
    }

    for (int ind = 0; ind < this.args.size(); ind++) {
      ExtractionObject a1 = this.args.get(ind);
      ExtractionObject a2 = inputArgs.get(ind);
      if(! a1.equals(a2)) return false;
    }

    return true;
  }

  public List getArgs() {
    return Collections.unmodifiableList(this.args);
  }
  public void setArgs(List args) {
    this.args = args;
  }
  
  /**
   * Fetches the arguments of this relation that are entity mentions
   * @return List of entity-mention args sorted in semantic order
   */
  public List getEntityMentionArgs() {
    List ents = new ArrayList<>();
    for(ExtractionObject o: args) {
      if(o instanceof EntityMention){
        ents.add((EntityMention) o);
      }
    }
    return ents;
  }

  public ExtractionObject getArg(int argpos) {
    return this.args.get(argpos);
  }
  
  public List getArgNames() {
    return argNames;
  }
  
  public void setArgNames(List argNames) {
    this.argNames = argNames;
  }
  
  public void addArg(ExtractionObject a) {
    this.args.add(a);
  }
  
  public boolean isNegativeRelation() {
    return isUnrelatedLabel(getType());
  }

  /**
   * Find the left-most position of an argument's syntactic head
   */
  public int getFirstSyntacticHeadPosition() {
    int pos = Integer.MAX_VALUE;
    for (ExtractionObject obj : args) {
      if(obj instanceof EntityMention){
        EntityMention em = (EntityMention) obj;
        if(em.getSyntacticHeadTokenPosition() < pos) {
          pos = em.getSyntacticHeadTokenPosition();
        }
      }
    }
    if(pos != Integer.MAX_VALUE) return pos;
    return -1;
  }

  /**
   * Find the right-most position of an argument's syntactic head
   */
  public int getLastSyntacticHeadPosition() {
    int pos = Integer.MIN_VALUE;
    for (ExtractionObject obj : args) {
      if(obj instanceof EntityMention){
        EntityMention em = (EntityMention) obj;
        if(em.getSyntacticHeadTokenPosition() > pos) {
          pos = em.getSyntacticHeadTokenPosition();
        }
      }
    }
    if(pos != Integer.MIN_VALUE) return pos;
    return -1;
  }
  
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("RelationMention [type=" + type
      + (subType != null ? ", subType=" + subType : "")
      + ", start=" + getExtentTokenStart() + ", end=" + getExtentTokenEnd());
    if(typeProbabilities != null){
      sb.append(", " + probsToString());
    }
    
    if(args != null){
      for(int i = 0; i < args.size(); i ++){
        sb.append("\n\t");
        if(argNames != null) sb.append(argNames.get(i) + " ");
        sb.append(args.get(i));
      }
    }
    sb.append("\n]");
    return sb.toString();
  }
  
  /**
   * Replaces the arguments of this relations with equivalent mentions from the predictedMentions list
   * This works only for arguments that are EntityMention!
   * @param predictedMentions
   */
  public boolean replaceGoldArgsWithPredicted(List predictedMentions) {
  	List newArgs = new ArrayList<>();
  	for(ExtractionObject arg: args){
  		if(! (arg instanceof EntityMention)){
  			continue;
  		}
  		EntityMention goldEnt = (EntityMention) arg;
  		EntityMention newArg = null;
  		for(EntityMention pred: predictedMentions){
  			if(goldEnt.textEquals(pred)){
  				newArg = pred;
  				break;
  			}
  		}
  		if(newArg != null){
  			newArgs.add(newArg);
  			logger.info("Replacing relation argument: [" + goldEnt + "] with predicted mention [" + newArg + "]");
  		} else {
  			/*
  			logger.info("Failed to match relation argument: " + goldEnt);
  			return false;
  			*/
  			newArgs.add(goldEnt);
  			predictedMentions.add(goldEnt);
  			logger.info("Failed to match relation argument, so keeping gold: " + goldEnt);
  		}
  	}
  	this.args = newArgs;
  	return true;
  }
  
  public void removeArgument(ExtractionObject argToRemove, boolean removeParent) {
    Set thisEvent = new IdentityHashSet<>();
    thisEvent.add(argToRemove);
    removeArguments(thisEvent, removeParent);
  }
  
  public void removeArguments(Set argsToRemove, boolean removeParent) {
    List newArgs = new ArrayList<>();
    List newArgNames = new ArrayList<>();
    for(int i = 0; i < args.size(); i ++){
      ExtractionObject a = args.get(i);
      String n = argNames.get(i);
      if(! argsToRemove.contains(a)){
        newArgs.add(a);
        newArgNames.add(n);
      } else {
        if(a instanceof EventMention && removeParent){
          ((EventMention) a).removeParent(this);
        }
      }
    }
    args = newArgs;
    argNames = newArgNames;
  }
  
  public boolean printableObject(double beam) {
    return printableObject(beam, RelationMention.UNRELATED);
  }
  
  public void setSignature(String s) { signature = s; }
  public String getSignature() { return signature; }
  
  /*
   * Static utility functions
   */

  public static Collection filterUnrelatedRelations(Collection relationMentions) {
    Collection filtered = new ArrayList<>();
    for (RelationMention relation : relationMentions) {
      if (!relation.getType().equals(UNRELATED)) {
        filtered.add(relation);
      }
    }
    return filtered;
  }
  
  /**
   * Creates a new unique id for a relation mention
   * @return the new id
   */
  public static synchronized String makeUniqueId() {
    MENTION_COUNTER++;
    return "RelationMention-" + MENTION_COUNTER;
  }
  
  public static RelationMention createUnrelatedRelation(RelationMentionFactory factory, ExtractionObject ... args) {
    return createUnrelatedRelation(factory, "",args);
  }
  
  private static RelationMention createUnrelatedRelation(RelationMentionFactory factory, String type, ExtractionObject ... args) {
    return factory.constructRelationMention(
        RelationMention.makeUniqueId(), args[0].getSentence(), ExtractionObject.getSpan(args),
        RelationMention.UNRELATED + type, null, Arrays.asList(args), null);
  }
  
  public static boolean isUnrelatedLabel(String label) {
    return label.startsWith(UNRELATED);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof RelationMention)) return false;
    if (!super.equals(o)) return false;

    RelationMention that = (RelationMention) o;

    if (argNames != null ? !argNames.equals(that.argNames) : that.argNames != null) return false;
    if (args != null ? !args.equals(that.args) : that.args != null) return false;
    if (signature != null ? !signature.equals(that.signature) : that.signature != null) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = argNames != null ? argNames.hashCode() : 0;
    result = 31 * result + (args != null ? args.hashCode() : 0);
    result = 31 * result + (signature != null ? signature.hashCode() : 0);
    return result;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy