/** * The default evaluation method simply computes the score for the example and returns a * {@link DiscretePrimitiveStringFeature} set to either the second value from the label * classifier's array of allowable values if the score is greater than or equal to * {@link #threshold} or the first otherwise. * * @param exampleFeatures The example's array of feature indices * @param exampleValues The example's array of feature values * @return The computed feature (in a vector). **/ public String discreteValue(int[] exampleFeatures, double[] exampleValues) { int index = score(exampleFeatures, exampleValues) >= threshold ? 1 : 0; return allowableValues[index]; }
/** * Computes the score for the specified example vector which will be thresholded to make the * binary classification. * * @param example The example object. * @return The score for the given example vector. **/ public double score(Object example) { Object[] exampleArray = getExampleArray(example, false); return score((int[]) exampleArray[0], (double[]) exampleArray[1]); }
/** * Returns the classification of the given example as a single feature instead of a * {@link FeatureVector}. * * @param f The features array. * @param v The values array. * @return The classification of the example as a feature. **/ public Feature featureValue(int[] f, double[] v) { int index = score(f, v) >= threshold ? 1 : 0; return predictions.get(index); }
/** * An LTU returns two scores; one for the negative classification and one for the positive * classification. By default, the score for the positive classification is the result of * {@link #score(Object)} minus the {@link #threshold}, and the score for the negative * classification is the opposite of the positive classification's score. * * @param exampleFeatures The example's array of feature indices * @param exampleValues The example's array of feature values * @return Two scores as described above. **/ public ScoreSet scores(int[] exampleFeatures, double[] exampleValues) { double s = score(exampleFeatures, exampleValues) - threshold; ScoreSet result = new ScoreSet(); result.put(allowableValues[0], -s); result.put(allowableValues[1], s); return result; }
/** * Returns the classification of the given example as a single feature instead of a * {@link FeatureVector}. * * @param f The features array. * @param v The values array. * @return The classification of the example as a feature. **/ public Feature featureValue(int[] f, double[] v) { double bestScore = Double.NEGATIVE_INFINITY; int bestValue = -1; int N = network.size(); for (int l = 0; l < N; l++) { LinearThresholdUnit ltu = (LinearThresholdUnit) network.get(l); if (ltu == null) continue; double score = ltu.score(f, v); if (score > bestScore) { bestValue = l; bestScore = score; } } return bestValue == -1 ? null : predictions.get(bestValue); }
/** * This method is a surrogate for {@link #scores(int[],double[],Collection)} when the labeler is * known to produce conjunctive features. It is necessary because when given a string label from * the collection, we will not know how to construct the appropriate conjunctive feature key for * lookup in the label lexicon. So, we must go through each feature in the label lexicon and use * {@link Feature#valueEquals(String)}. * * @param exampleFeatures The example's array of feature indices. * @param exampleValues The example's array of feature values. * @param I An iterator over the set of labels to choose from. * @return The label chosen by this classifier or <code>null</code> if the network did not * contain any of the specified labels. **/ protected ScoreSet conjunctiveScores(int[] exampleFeatures, double[] exampleValues, Iterator I) { ScoreSet result = new ScoreSet(); int N = network.size(); while (I.hasNext()) { String label = (String) I.next(); for (int i = 0; i < N; ++i) { LinearThresholdUnit ltu = (LinearThresholdUnit) network.get(i); if (ltu == null || !labelLexicon.lookupKey(i).valueEquals(label)) continue; double score = ltu.score(exampleFeatures, exampleValues); result.put(label.toString(), score); break; } } return result; }
if (ltu == null || !predictions.get(i).valueEquals(label)) continue; double score = ltu.score(exampleFeatures, exampleValues); if (score > bestScore) { bestScore = score;
if (ltu == null || !labelLexicon.lookupKey(i).valueEquals(label)) continue; double score = ltu.score(exampleFeatures, exampleValues); if (score > bestScore) { bestScore = score;
/** * This method is a surrogate for {@link #scores(int[],double[],Collection)} when the labeler is * known to produce conjunctive features. It is necessary because when given a string label from * the collection, we will not know how to construct the appropriate conjunctive feature key for * lookup in the label lexicon. So, we must go through each feature in the label lexicon and use * {@link edu.illinois.cs.cogcomp.lbjava.classify.Feature#valueEquals(String)}. * * @param exampleFeatures The example's array of feature indices. * @param exampleValues The example's array of feature values. * @param I An iterator over the set of labels to choose from. * @return The label chosen by this classifier or <code>null</code> if the network did not * contain any of the specified labels. **/ protected ScoreSet conjunctiveScores(int[] exampleFeatures, double[] exampleValues, Iterator I) { ScoreSet result = new ScoreSet(); int N = network.size(); while (I.hasNext()) { String label = (String) I.next(); for (int i = 0; i < N; ++i) { LinearThresholdUnit ltu = (LinearThresholdUnit) network.get(i); if (ltu == null || !labelLexicon.lookupKey(i).valueEquals(label)) continue; double score = ltu.score(exampleFeatures, exampleValues); result.put(label, score); break; } } return result; }
/** * Returns a separate feature for each {@link LinearThresholdUnit} whose score on the example * object exceeds the threshold. * * @param exampleFeatures The example's feature indices. * @param exampleValues The feature values. * @return A vector containing the features described above. **/ public FeatureVector classify(int[] exampleFeatures, double[] exampleValues) { FeatureVector result = new FeatureVector(); for (int i = 0; i < network.size(); ++i) { LinearThresholdUnit ltu = (LinearThresholdUnit) network.get(i); double score = ltu.score(exampleFeatures, exampleValues); if (score >= 0) result.addFeature(predictions.get(i)); } return result; }
/** * The default training algorithm for a linear threshold unit consists of evaluating the example * object with the {@link #score(Object)} method and {@link #threshold}, checking the result of * evaluation against the label, and, if they are different, promoting when the label is * positive or demoting when the label is negative. * * <p> * This method does not call {@link #classify(Object)}; it calls {@link #score(Object)} * directly. * * @param exampleFeatures The example's array of feature indices * @param exampleValues The example's array of feature values * @param exampleLabels The example's label(s) * @param labelValues The labels' values **/ public void learn(int[] exampleFeatures, double[] exampleValues, int[] exampleLabels, double[] labelValues) { assert exampleLabels.length == 1 : "Example must have a single label."; assert exampleLabels[0] == 0 || exampleLabels[0] == 1 : "Example has unallowed label value."; boolean label = (exampleLabels[0] == 1); double s = score(exampleFeatures, exampleValues); if (shouldPromote(label, s, threshold, positiveThickness)) promote(exampleFeatures, exampleValues, computeLearningRate(exampleFeatures, exampleValues, s, label)); if (shouldDemote(label, s, threshold, negativeThickness)) demote(exampleFeatures, exampleValues, computeLearningRate(exampleFeatures, exampleValues, s, label)); }
/** * Produces a set of scores indicating the degree to which each possible discrete classification * value is associated with the given example object. These scores are just the scores of each * LTU's positive classification as produced by <code>LinearThresholdUnit.scores(Object)</code>. * * @see LinearThresholdUnit#scores(Object) * @param exampleFeatures The example's array of feature indices. * @param exampleValues The example's array of feature values. * @return The set of scores produced by the LTUs **/ public ScoreSet scores(int[] exampleFeatures, double[] exampleValues) { ScoreSet result = new ScoreSet(); int N = network.size(); for (int l = 0; l < N; l++) { LinearThresholdUnit ltu = (LinearThresholdUnit) network.get(l); if (ltu == null) continue; result.put(labelLexicon.lookupKey(l).getStringValue(), ltu.score(exampleFeatures, exampleValues) - ltu.getThreshold()); } return result; }