/* $Log: IntensitiesDefinition.java,v $ Revision 1.1 2011-02-18 08:29:37 johansson Polarities on sentences. */ package mpqareader; import java.io.Serializable; import se.lth.cs.nlp.nlputils.ml_long.*; /** * @author Richard Johansson (richard@cs.lth.se) */ public class IntensitiesDefinition extends ProblemDefinition implements Serializable { private static final long serialVersionUID = 1L; private SparseVectorClassEncoder enc; public IntensitiesDefinition() { super(); enc = new SparseVectorClassEncoder(); } public void setMaxFeatureIndex(int index) { // ignored } private double cost(SparseVector x, Intensities y, int pos, int neu, int neg) { double distsum = 0; distsum += (pos - y.pos) * (pos - y.pos); distsum += (neu - y.neu) * (neu - y.neu); distsum += (neg - y.neg) * (neg - y.neg); distsum = Math.sqrt(distsum); double polsum = 0; polsum += (sgn(pos) != sgn(y.pos))? 1.0: 0.0; polsum += (sgn(neu) != sgn(y.neu))? 1.0: 0.0; polsum += (sgn(neg) != sgn(y.neg))? 1.0: 0.0; if(pos == MIN && y.pos > MIN) polsum += 4.0; if(neu > MIN && y.neu == MIN) polsum += 4.0; //if(neg > MIN && y.neg == MIN) // polsum += 1.0; //System.out.println("Returning " + (polsum + 0.1*distsum)); //System.exit(0); return polsum + 0.1*distsum; } public double cost(SparseVector x, Intensities y, Intensities ybar) { return cost(x, y, ybar.pos, ybar.neu, ybar.neg); } protected boolean frozen = false; public void freeze() { if(frozen) System.err.println("Warning: already frozen"); else { enc.freeze(); } } private static final int POS_OFFSET = 0; private static final int NEU_OFFSET = 3; private static final int NEG_OFFSET = 6; private static final int POS_SGN_OFFSET = 10; private static final int NEU_SGN_OFFSET = 12; private static final int NEG_SGN_OFFSET = 14; private void addClassEncoding(SparseVector x, int cl, SparseVector sv) { enc.encode(x, cl, sv); // does not clear the sv } private static final SparseVector SINGLE_UNIT = new SparseVector(); static { SINGLE_UNIT.put(1, 2.0); } private void addClassEncodingSingle(int cl, SparseVector sv) { enc.encode(SINGLE_UNIT, cl, sv); // does not clear the sv } private static int sgn(int i) { return i == BOWPolSubjSentClassifier.NONE? 1: 2; } private void encode(SparseVector x, int pos, int neu, int neg, SparseVector sv) { sv.clear(); // Approach 1: Each intensity independently addClassEncoding(x, pos << POS_OFFSET, sv); addClassEncoding(x, sgn(pos) << POS_SGN_OFFSET, sv); addClassEncoding(x, neu << NEU_OFFSET, sv); addClassEncoding(x, sgn(neu) << NEU_SGN_OFFSET, sv); addClassEncoding(x, neg << NEG_OFFSET, sv); addClassEncoding(x, sgn(neg) << NEG_SGN_OFFSET, sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neu) << NEU_SGN_OFFSET), sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((sgn(neu) << NEU_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neu << NEU_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neg << NEG_OFFSET), sv); addClassEncodingSingle((neu << NEU_OFFSET) | (neg << NEG_OFFSET), sv); } public void encode(SparseVector x, Intensities y, SparseVector sv) { encode(x, y.pos, y.neu, y.neg, sv); } private static final int MIN = BOWPolSubjSentClassifier.NONE; private static final int MAX = BOWPolSubjSentClassifier.HIGH; public Intensities argmax(SparseVector x, Model model, SparseVector sv, double[] result) { double max = Double.NEGATIVE_INFINITY; int maxpos = Integer.MIN_VALUE, maxneu = Integer.MIN_VALUE, maxneg = Integer.MIN_VALUE; for(int pos = MIN; pos <= MAX; pos++) { sv.clear(); addClassEncoding(x, pos << POS_OFFSET, sv); addClassEncoding(x, sgn(pos) << POS_SGN_OFFSET, sv); int posIndex = sv.index; for(int neu = MIN; neu <= MAX; neu++) { if(neu == 1) continue; sv.index = posIndex; addClassEncoding(x, neu << NEU_OFFSET, sv); addClassEncoding(x, sgn(neu) << NEU_SGN_OFFSET, sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neu) << NEU_SGN_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neu << NEU_OFFSET), sv); int neuIndex = sv.index; for(int neg = MIN; neg <= MAX; neg++) { if(pos == MIN && neg == MIN && neu == MIN) // special case continue; sv.index = neuIndex; addClassEncoding(x, neg << NEG_OFFSET, sv); addClassEncoding(x, sgn(neg) << NEG_SGN_OFFSET, sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((sgn(neu) << NEU_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neg << NEG_OFFSET), sv); addClassEncodingSingle((neu << NEU_OFFSET) | (neg << NEG_OFFSET), sv); double score = model.score(sv); if(score > max) { max = score; maxpos = pos; maxneu = neu; maxneg = neg; } } } } /* for(int pos = MIN; pos <= MAX; pos++) for(int neu = MIN; neu <= MAX; neu++) { if(neu == 1) continue; for(int neg = MIN; neg <= MAX; neg++) { if(pos == MIN && neg == MIN && neu == MIN) // special case continue; encode(x, pos, neu, neg, sv); double score = model.score(sv); if(score > max) { max = score; maxpos = pos; maxneu = neu; maxneg = neg; } } }*/ result[0] = max; encode(x, maxpos, maxneu, maxneg, sv); return new Intensities(maxpos, maxneu, maxneg); } public int findNBest(SparseVector x, Model model, int n, Intensities[] ybars, SparseVector[] svs, double[] scores) { throw new UnsupportedOperationException("unsupported"); } public Intensities maxLoss(SparseVector x, Intensities y, Model model, SparseVector sv, double[] result) { double maxLoss = Double.NEGATIVE_INFINITY; int maxpos = Integer.MIN_VALUE, maxneu = Integer.MIN_VALUE, maxneg = Integer.MIN_VALUE; double maxScore = Double.NEGATIVE_INFINITY; double maxCost = Double.NEGATIVE_INFINITY; /* for(int pos = MIN; pos <= MAX; pos++) for(int neu = MIN; neu <= MAX; neu++) { if(neu == 1) continue; for(int neg = MIN; neg <= MAX; neg++) { if(pos == MIN && neg == MIN && neu == MIN) // special case continue; encode(x, pos, neu, neg, sv); double score = model.score(sv); double cost = cost(x, y, pos, neu, neg); double loss = score + Math.sqrt(cost); if(loss > maxLoss) { maxLoss = loss; maxScore = score; maxCost = cost; maxpos = pos; maxneu = neu; maxneg = neg; } } } */ for(int pos = MIN; pos <= MAX; pos++) { sv.clear(); addClassEncoding(x, pos << POS_OFFSET, sv); addClassEncoding(x, sgn(pos) << POS_SGN_OFFSET, sv); int posIndex = sv.index; for(int neu = MIN; neu <= MAX; neu++) { if(neu == 1) continue; sv.index = posIndex; addClassEncoding(x, neu << NEU_OFFSET, sv); addClassEncoding(x, sgn(neu) << NEU_SGN_OFFSET, sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neu) << NEU_SGN_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neu << NEU_OFFSET), sv); int neuIndex = sv.index; for(int neg = MIN; neg <= MAX; neg++) { if(pos == MIN && neg == MIN && neu == MIN) // special case continue; sv.index = neuIndex; addClassEncoding(x, neg << NEG_OFFSET, sv); addClassEncoding(x, sgn(neg) << NEG_SGN_OFFSET, sv); addClassEncodingSingle((sgn(pos) << POS_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((sgn(neu) << NEU_SGN_OFFSET) | (sgn(neg) << NEG_SGN_OFFSET), sv); addClassEncodingSingle((pos << POS_OFFSET) | (neg << NEG_OFFSET), sv); addClassEncodingSingle((neu << NEU_OFFSET) | (neg << NEG_OFFSET), sv); double score = model.score(sv); double cost = cost(x, y, pos, neu, neg); double loss = score + Math.sqrt(cost); if(loss > maxLoss) { maxLoss = loss; maxScore = score; maxCost = cost; maxpos = pos; maxneu = neu; maxneg = neg; } } } } encode(x, maxpos, maxneu, maxneg, sv); result[0] = maxScore; result[1] = maxCost; return new Intensities(maxpos, maxneu, maxneg); } public Decomposition decompose(SparseVector x, Integer y) { throw new UnsupportedOperationException("unsupported"); } }