EmoticonRatio extends FeatureExtractorResource_ImplBase implements FeatureExtractor { @Override public Set<Feature> extract(JCas jCas, TextClassificationTarget aTarget) throws TextClassificationException { int nrOfEmoticons = JCasUtil.selectCovered(jCas, POS_EMO.class, aTarget).size(); int nrOfTokens = JCasUtil.selectCovered(jCas, Token.class, aTarget).size(); double ratio = (double) nrOfEmoticons / nrOfTokens; return new Feature(EmoticonRatio.class.getSimpleName(), ratio, FeatureType.NUMERIC).asSet(); }  @Override Set<Feature> extract(JCas jCas, TextClassificationTarget aTarget);  }
@Test public void emoticonRatioFeatureExtractorTest() throws Exception { AnalysisEngineDescription desc = createEngineDescription(NoOpAnnotator.class); AnalysisEngine engine = createEngine(desc); TokenBuilder<Token, Sentence> builder = TokenBuilder.create(Token.class, Sentence.class); JCas jcas = engine.newJCas(); jcas.setDocumentLanguage("en"); builder.buildTokens(jcas, "This is a very emotional tweet ;-)"); POS_EMO emo = new POS_EMO(jcas); emo.setBegin(31); emo.setEnd(34); emo.addToIndexes(); engine.process(jcas); TextClassificationTarget aTarget = new TextClassificationTarget(jcas, 0, jcas.getDocumentText().length()); aTarget.addToIndexes(); EmoticonRatio extractor = new EmoticonRatio(); List<Feature> features = new ArrayList<Feature>(extractor.extract(jcas, aTarget)); Assert.assertEquals(1, features.size()); for (Feature feature : features) { assertFeature(EmoticonRatio.class.getSimpleName(), 0.14, feature, 0.01); } }