Skip to content

Commit

Permalink
#2696 - Document-level recommendations
Browse files Browse the repository at this point in the history
- Continue moving extraction logic into the suggestion supports
  • Loading branch information
reckart committed Dec 25, 2023
1 parent 7bde883 commit a34fcff
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Feature;
import org.apache.uima.jcas.cas.AnnotationBase;
import org.apache.uima.jcas.cas.TOP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
Expand All @@ -51,6 +52,7 @@
import de.tudarmstadt.ukp.inception.recommendation.api.model.LearningRecordUserAction;
import de.tudarmstadt.ukp.inception.recommendation.api.model.MetadataSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionGroup;
import de.tudarmstadt.ukp.inception.recommendation.api.recommender.ExtractionContext;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationException;
import de.tudarmstadt.ukp.inception.schema.api.adapter.TypeAdapter;
Expand Down Expand Up @@ -277,4 +279,27 @@ public Optional<SuggestionRenderer> getRenderer()
{
return Optional.empty();
}

public static void extractSuggestion(ExtractionContext ctx, TOP predictedFS)
{
var autoAcceptMode = getAutoAcceptMode(predictedFS, ctx.getModeFeature());
var labels = getPredictedLabels(predictedFS, ctx.getLabelFeature(), ctx.isMultiLabels());
var score = predictedFS.getDoubleValue(ctx.getScoreFeature());
var scoreExplanation = predictedFS.getStringValue(ctx.getScoreExplanationFeature());

for (var label : labels) {
var suggestion = MetadataSuggestion.builder() //
.withId(MetadataSuggestion.NEW_ID) //
.withGeneration(ctx.getGeneration()) //
.withRecommender(ctx.getRecommender()) //
.withDocumentName(ctx.getDocument().getName()) //
.withLabel(label) //
.withUiLabel(label) //
.withScore(score) //
.withScoreExplanation(scoreExplanation) //
.withAutoAcceptMode(autoAcceptMode) //
.build();
ctx.getResult().add(suggestion);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@

import org.apache.uima.cas.AnnotationBaseFS;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.fit.util.FSUtil;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationEventPublisher;

import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.inception.recommendation.api.event.RecommendationAcceptedEvent;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AutoAcceptMode;
import de.tudarmstadt.ukp.inception.recommendation.api.model.LearningRecordChangeLocation;
import de.tudarmstadt.ukp.inception.recommendation.api.model.LearningRecordUserAction;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
Expand Down Expand Up @@ -95,4 +99,29 @@ protected void commmitLabel(String aSessionOwner, SourceDocument aDocument, Stri
annotation, aFeature, aSuggestion.getLabel()));
}
}

private static final String AUTO_ACCEPT_ON_FIRST_ACCESS = "on-first-access";

public static AutoAcceptMode getAutoAcceptMode(FeatureStructure aFS, Feature aModeFeature)
{
var autoAcceptMode = AutoAcceptMode.NEVER;
var autoAcceptFeatureValue = aFS.getStringValue(aModeFeature);
if (autoAcceptFeatureValue != null) {
switch (autoAcceptFeatureValue) {
case AUTO_ACCEPT_ON_FIRST_ACCESS:
autoAcceptMode = AutoAcceptMode.ON_FIRST_ACCESS;
}
}
return autoAcceptMode;
}

public static String[] getPredictedLabels(FeatureStructure predictedFS,
Feature predictedFeature, boolean isStringMultiValue)
{
if (isStringMultiValue) {
return FSUtil.getFeature(predictedFS, predictedFeature, String[].class);
}

return new String[] { predictedFS.getFeatureValueAsString(predictedFeature) };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public static <V extends AnnotationSuggestion> SuggestionDocumentGroup<V> groups
* the list to retrieve suggestions from
* @return a SuggestionDocumentGroup where only suggestions of type V are added
*/
public static Map<Class<? extends AnnotationSuggestion>, SuggestionDocumentGroup<? extends AnnotationSuggestion>> groupByType(
List<AnnotationSuggestion> aSuggestions)
public static Map<Class<? extends AnnotationSuggestion>, SuggestionDocumentGroup<? extends AnnotationSuggestion>> //
groupByType(List<AnnotationSuggestion> aSuggestions)
{
if (aSuggestions == null || aSuggestions.isEmpty()) {
return Collections.emptyMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.tudarmstadt.ukp.inception.recommendation.service;
package de.tudarmstadt.ukp.inception.recommendation.api.recommender;

import static de.tudarmstadt.ukp.inception.recommendation.api.RecommendationService.FEATURE_NAME_AUTO_ACCEPT_MODE_SUFFIX;
import static de.tudarmstadt.ukp.inception.recommendation.api.RecommendationService.FEATURE_NAME_IS_PREDICTION;
Expand Down Expand Up @@ -191,4 +191,4 @@ public List<AnnotationSuggestion> getResult()
{
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@
import de.tudarmstadt.ukp.inception.recommendation.api.model.RelationPosition;
import de.tudarmstadt.ukp.inception.recommendation.api.model.RelationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionGroup;
import de.tudarmstadt.ukp.inception.recommendation.service.ExtractionContext;
import de.tudarmstadt.ukp.inception.recommendation.service.SuggestionExtraction;
import de.tudarmstadt.ukp.inception.recommendation.api.recommender.ExtractionContext;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationComparisonUtils;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationException;
Expand Down Expand Up @@ -380,10 +379,8 @@ public Optional<SuggestionRenderer> getRenderer()

public static void extractSuggestion(ExtractionContext ctx, TOP predictedFS)
{
var autoAcceptMode = SuggestionExtraction.getAutoAcceptMode(predictedFS,
ctx.getModeFeature());
var labels = SuggestionExtraction.getPredictedLabels(predictedFS, ctx.getLabelFeature(),
ctx.isMultiLabels());
var autoAcceptMode = getAutoAcceptMode(predictedFS, ctx.getModeFeature());
var labels = getPredictedLabels(predictedFS, ctx.getLabelFeature(), ctx.isMultiLabels());
var score = predictedFS.getDoubleValue(ctx.getScoreFeature());
var scoreExplanation = predictedFS.getStringValue(ctx.getScoreExplanationFeature());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,80 +17,23 @@
*/
package de.tudarmstadt.ukp.inception.recommendation.service;

import java.lang.invoke.MethodHandles;
import java.util.List;

import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.fit.util.FSUtil;
import org.apache.uima.jcas.cas.TOP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.inception.annotation.layer.relation.RelationLayerSupport;
import de.tudarmstadt.ukp.inception.annotation.layer.span.SpanLayerSupport;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AutoAcceptMode;
import de.tudarmstadt.ukp.inception.recommendation.api.model.MetadataSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.Recommender;
import de.tudarmstadt.ukp.inception.recommendation.api.recommender.ExtractionContext;
import de.tudarmstadt.ukp.inception.recommendation.relation.RelationSuggestionSupport;
import de.tudarmstadt.ukp.inception.recommendation.span.SpanSuggestionSupport;
import de.tudarmstadt.ukp.inception.ui.core.docanno.layer.DocumentMetadataLayerSupport;
import de.tudarmstadt.ukp.inception.ui.core.docanno.sidebar.MetadataSuggestionSupport;

public class SuggestionExtraction
{
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final String AUTO_ACCEPT_ON_FIRST_ACCESS = "on-first-access";

public static AutoAcceptMode getAutoAcceptMode(FeatureStructure aFS, Feature aModeFeature)
{
var autoAcceptMode = AutoAcceptMode.NEVER;
var autoAcceptFeatureValue = aFS.getStringValue(aModeFeature);
if (autoAcceptFeatureValue != null) {
switch (autoAcceptFeatureValue) {
case AUTO_ACCEPT_ON_FIRST_ACCESS:
autoAcceptMode = AutoAcceptMode.ON_FIRST_ACCESS;
}
}
return autoAcceptMode;
}

public static String[] getPredictedLabels(FeatureStructure predictedFS,
Feature predictedFeature, boolean isStringMultiValue)
{
if (isStringMultiValue) {
return FSUtil.getFeature(predictedFS, predictedFeature, String[].class);
}

return new String[] { predictedFS.getFeatureValueAsString(predictedFeature) };
}

static void extractDocumentMetadataSuggestion(ExtractionContext ctx, TOP predictedFS)
{
var autoAcceptMode = getAutoAcceptMode(predictedFS, ctx.getModeFeature());
var labels = getPredictedLabels(predictedFS, ctx.getLabelFeature(), ctx.isMultiLabels());
var score = predictedFS.getDoubleValue(ctx.getScoreFeature());
var scoreExplanation = predictedFS.getStringValue(ctx.getScoreExplanationFeature());

for (var label : labels) {
var suggestion = MetadataSuggestion.builder() //
.withId(MetadataSuggestion.NEW_ID) //
.withGeneration(ctx.getGeneration()) //
.withRecommender(ctx.getRecommender()) //
.withDocumentName(ctx.getDocument().getName()) //
.withLabel(label) //
.withUiLabel(label) //
.withScore(score) //
.withScoreExplanation(scoreExplanation) //
.withAutoAcceptMode(autoAcceptMode) //
.build();
ctx.getResult().add(suggestion);
}
}

public static List<AnnotationSuggestion> extractSuggestions(int aGeneration, CAS aOriginalCas,
CAS aPredictionCas, SourceDocument aDocument, Recommender aRecommender)
{
Expand All @@ -112,7 +55,7 @@ public static List<AnnotationSuggestion> extractSuggestions(int aGeneration, CAS
break;
}
case DocumentMetadataLayerSupport.TYPE: {
extractDocumentMetadataSuggestion(ctx, predictedFS);
MetadataSuggestionSupport.extractSuggestion(ctx, predictedFS);
break;
}
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@
import de.tudarmstadt.ukp.inception.recommendation.api.model.RelationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SpanSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionGroup;
import de.tudarmstadt.ukp.inception.recommendation.api.recommender.ExtractionContext;
import de.tudarmstadt.ukp.inception.recommendation.config.RecommenderProperties;
import de.tudarmstadt.ukp.inception.recommendation.service.ExtractionContext;
import de.tudarmstadt.ukp.inception.recommendation.service.SuggestionExtraction;
import de.tudarmstadt.ukp.inception.recommendation.util.OverlapIterator;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationException;
Expand Down Expand Up @@ -463,10 +462,8 @@ public Optional<SuggestionRenderer> getRenderer()

public static void extractSuggestion(ExtractionContext ctx, TOP predictedFS)
{
var autoAcceptMode = SuggestionExtraction.getAutoAcceptMode(predictedFS,
ctx.getModeFeature());
var labels = SuggestionExtraction.getPredictedLabels(predictedFS, ctx.getLabelFeature(),
ctx.isMultiLabels());
var autoAcceptMode = getAutoAcceptMode(predictedFS, ctx.getModeFeature());
var labels = getPredictedLabels(predictedFS, ctx.getLabelFeature(), ctx.isMultiLabels());
var score = predictedFS.getDoubleValue(ctx.getScoreFeature());
var scoreExplanation = predictedFS.getStringValue(ctx.getScoreExplanationFeature());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency;
import de.tudarmstadt.ukp.inception.recommendation.api.LearningRecordService;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.relation.RelationSuggestionSupport;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;

@ExtendWith(MockitoExtension.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import de.tudarmstadt.ukp.inception.recommendation.api.model.Offset;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SpanSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionDocumentGroup;
import de.tudarmstadt.ukp.inception.recommendation.span.SpanSuggestionSupport;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;

@ExtendWith(MockitoExtension.class)
Expand Down

0 comments on commit a34fcff

Please sign in to comment.