package de.uni_mannheim.minie.annotation; import edu.stanford.nlp.ling.IndexedWord; import edu.stanford.nlp.semgraph.SemanticGraph; import edu.stanford.nlp.semgraph.SemanticGraphEdge; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.io.IOException; import de.uni_mannheim.constant.CHARACTER; import de.uni_mannheim.constant.POS_TAG; import de.uni_mannheim.constant.SEPARATOR; import de.uni_mannheim.utils.coreNLP.CoreNLPUtils; import de.uni_mannheim.utils.Dictionary; /** * Annotation for polarity * * @author Kiril Gashteovski */ public class Polarity { /** Annotations for polarity, can be just "POSTIIVE" or "NEGATIVE" */ public enum Type {POSITIVE, NEGATIVE} /** Static strings for polarity **/ public static String ST_POSITIVE = "POSITIVE"; public static String ST_PLUS = "+"; public static String ST_NEGATIVE = "NEGATIVE"; public static String ST_MINUS = "-"; /** List of negative words and edges (if found any) **/ private ObjectArrayList<IndexedWord> negativeWords; private ObjectArrayList<SemanticGraphEdge> negativeEdges; /** Polarity type **/ private Polarity.Type polarityType; /** A set of all negative words **/ public static Dictionary NEG_WORDS; static { try { NEG_WORDS = new Dictionary("/minie-resources/neg-words.dict"); } catch (IOException e) { throw new Error(e); } } /** A set of negative adverbs **/ public static Dictionary NEG_ADVERBS; static { try { NEG_ADVERBS = new Dictionary("/minie-resources/neg-adverbs.dict"); } catch (IOException e) { throw new Error(e); } } /** Set of negative determiners **/ public static Dictionary NEG_DETERMINERS; static { try { NEG_DETERMINERS = new Dictionary("/minie-resources/neg-determiners.dict"); } catch (IOException e) { throw new Error(e); } } /** Default constructor. Assumes positive polarity type by default **/ public Polarity(){ this.polarityType = Type.POSITIVE; this.negativeEdges = new ObjectArrayList<>(); this.negativeWords = new ObjectArrayList<>(); } /** * Constructor given the polarity type. Creates empty lists for negative words and edges * @param t: polarity type */ public Polarity(Polarity.Type t){ this.polarityType = t; this.negativeEdges = new ObjectArrayList<>(); this.negativeWords = new ObjectArrayList<>(); } /** * Copy constructor * @param p: polarity object */ public Polarity(Polarity p){ this.polarityType = p.getType(); this.negativeEdges = p.getNegativeEdges(); this.negativeWords = p.getNegativeWords(); } /** * Parametric constructor, given the polarity types, negative words, negative edges * @param t: polarity type * @param negWords: list of negative words * @param negEdges: list of negative edges */ public Polarity(Polarity.Type t, ObjectArrayList<IndexedWord> negWords, ObjectArrayList<SemanticGraphEdge> negEdges){ this.polarityType = t; this.negativeEdges = negEdges; this.negativeWords = negWords; } /** Getters **/ public Polarity.Type getType(){ return this.polarityType; } public ObjectArrayList<IndexedWord> getNegativeWords(){ return this.negativeWords; } public ObjectArrayList<SemanticGraphEdge> getNegativeEdges(){ return this.negativeEdges; } /** Setters **/ public void setType(Polarity.Type t){ this.polarityType = t; } public void setNegativeWords(ObjectArrayList<IndexedWord> negWords){ this.negativeWords = negWords; } public void setNegativeEdges(ObjectArrayList<SemanticGraphEdge> negEdges){ this.negativeEdges = negEdges; } /** Adding elements to lists **/ public void addNegativeEdge(SemanticGraphEdge e){ this.negativeEdges.add(e); } public void addNegativeWord(IndexedWord w){ this.negativeWords.add(w); } /** Clear the polarity object, i.e. set its default values (type = positive, neg. words and edges are empty lists) */ public void clear(){ this.polarityType = Type.POSITIVE; this.negativeEdges = new ObjectArrayList<>(); this.negativeWords = new ObjectArrayList<>(); } /** * Given a phrase and its sentence semantic graph, detect the polarity type. If negative polarity is found, add the * negative words and edges to their appropriate lists from the Polarity class. * * @param phrase: phrase (essentially, list of words, which are part of some sentence) * @param sentenceSemGraph: the semantic graph of the phrase's sentence * @return polarity object */ public static Polarity getPolarity(AnnotatedPhrase phrase, SemanticGraph sentenceSemGraph){ Polarity pol = new Polarity(); for (int i = 0; i < phrase.getWordList().size(); i++){ // Check for negative adverbs if (CoreNLPUtils.isAdverb(phrase.getWordList().get(i).tag())){ if (Polarity.NEG_ADVERBS.contains(phrase.getWordList().get(i).lemma())){ Polarity.setNegPol(pol, phrase.getWordList().get(i), sentenceSemGraph.getEdge( sentenceSemGraph.getParent(phrase.getWordList().get(i)), phrase.getWordList().get(i))); } } // Check for negative determiners else if (phrase.getWordList().get(i).tag().equals(POS_TAG.DT)){ if (Polarity.NEG_DETERMINERS.contains(phrase.getWordList().get(i).lemma())){ Polarity.setNegPol(pol, phrase.getWordList().get(i), sentenceSemGraph.getEdge( sentenceSemGraph.getParent(phrase.getWordList().get(i)), phrase.getWordList().get(i))); } } } return pol; } /** * Given a polarity object, negative word and a negative edge, set the polarity type to "negative" and add the * negative words and edges to their appropriate lists * * @param pol: polarity object * @param negWord: negative word * @param negEdge: negative edge */ private static void setNegPol(Polarity pol, IndexedWord negWord, SemanticGraphEdge negEdge){ pol.setType(Polarity.Type.NEGATIVE); pol.addNegativeWord(negWord); pol.addNegativeEdge(negEdge); } /** Given a polarity object, convert it into a string */ @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append(CHARACTER.LPARENTHESIS); if (this.polarityType == Polarity.Type.POSITIVE) sb.append(CHARACTER.PLUS); else { sb.append(CHARACTER.MINUS); sb.append(CHARACTER.COMMA); sb.append(SEPARATOR.SPACE); for (SemanticGraphEdge edge: this.negativeEdges){ sb.append(edge.toString()); sb.append(CHARACTER.COMMA); sb.append(SEPARATOR.SPACE); } } sb.append(CHARACTER.RPARENTHESIS); return sb.toString().trim(); } }