Skip to content

Commit

Permalink
#5008 - Cannot reject relation from relation recommender
Browse files Browse the repository at this point in the history
- Fix exception when trying to reject a relation suggestion
  • Loading branch information
reckart committed Sep 1, 2024
1 parent d86ed3f commit aed9f31
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@
import java.util.Optional;

import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.fit.util.CasUtil;
import org.apache.wicket.Component;
Expand Down Expand Up @@ -993,10 +991,11 @@ private void actionSelectHistoryItem(AjaxRequestTarget aTarget, LearningRecord a

private Optional<AnnotationFS> getMatchingAnnotation(CAS aCas, LearningRecord aRecord)
{
Type type = CasUtil.getType(aCas, alStateModel.getObject().getLayer().getName());
Feature feature = type.getFeatureByBaseName(aRecord.getAnnotationFeature().getName());
var type = CasUtil.getType(aCas, alStateModel.getObject().getLayer().getName());
var feature = type.getFeatureByBaseName(aRecord.getAnnotationFeature().getName());
return selectAt(aCas, type, aRecord.getOffsetBegin(), aRecord.getOffsetEnd()).stream()
.filter(fs -> aRecord.getAnnotation().equals(fs.getFeatureValueAsString(feature)))
.filter(fs -> Objects.equals(aRecord.getAnnotation(),
fs.getFeatureValueAsString(feature)))
.findFirst();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import static org.apache.uima.fit.util.CasUtil.selectCovered;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -84,7 +83,7 @@ public void train(RecommenderContext aContext, List<CAS> aCasses) throws Recomme

private MultiValuedMap<Pair<String, String>, String> trainModel(List<Triple> aData)
{
MultiValuedMap<Pair<String, String>, String> model = new ArrayListValuedHashMap<>();
var model = new ArrayListValuedHashMap<Pair<String, String>, String>();

for (var t : aData) {
var key = Pair.of(t.governor, t.dependent);
Expand All @@ -98,7 +97,7 @@ private MultiValuedMap<Pair<String, String>, String> trainModel(List<Triple> aDa
public Range predict(PredictionContext aContext, CAS aCas, int aBegin, int aEnd)
throws RecommendationException
{
MultiValuedMap<Pair<String, String>, String> model = aContext.get(KEY_MODEL).orElseThrow(
var model = aContext.get(KEY_MODEL).orElseThrow(
() -> new RecommendationException("Key [" + KEY_MODEL + "] not found in context"));

var sampleUnitType = getType(aCas, SAMPLE_UNIT);
Expand All @@ -116,8 +115,13 @@ public Range predict(PredictionContext aContext, CAS aCas, int aBegin, int aEnd)
// whole document for potential relations, we only need to look at those units that overlap
// with the current prediction request area
var units = selectOverlapping(aCas, sampleUnitType, aBegin, aEnd);

if (model.isEmpty()) {
return Range.rangeCoveringAnnotations(units);
}

for (var sampleUnit : units) {
Collection<AnnotationFS> baseAnnotations = selectCovered(attachType, sampleUnit);
var baseAnnotations = selectCovered(attachType, sampleUnit);
for (var governor : baseAnnotations) {
for (var dependent : baseAnnotations) {

Expand Down Expand Up @@ -151,7 +155,7 @@ public Range predict(PredictionContext aContext, CAS aCas, int aBegin, int aEnd)
}
}

return new Range(units);
return Range.rangeCoveringAnnotations(units);
}

@Override
Expand Down Expand Up @@ -218,22 +222,22 @@ public EvaluationResult evaluate(List<CAS> aCasses, DataSplitter aDataSplitter)

private List<Triple> getTrainingData(List<CAS> aCasses)
{
List<Triple> data = new ArrayList<>();
var data = new ArrayList<Triple>();

for (CAS cas : aCasses) {
Type predictedType = getPredictedType(cas);
Feature governorFeature = predictedType.getFeatureByBaseName(FEAT_REL_SOURCE);
Feature dependentFeature = predictedType.getFeatureByBaseName(FEAT_REL_TARGET);
Feature predictedFeature = getPredictedFeature(cas);
Feature attachFeature = getAttachFeature(cas);
for (var cas : aCasses) {
var predictedType = getPredictedType(cas);
var governorFeature = predictedType.getFeatureByBaseName(FEAT_REL_SOURCE);
var dependentFeature = predictedType.getFeatureByBaseName(FEAT_REL_TARGET);
var predictedFeature = getPredictedFeature(cas);
var attachFeature = getAttachFeature(cas);

for (AnnotationFS relation : select(cas, predictedType)) {
AnnotationFS governor = (AnnotationFS) relation.getFeatureValue(governorFeature);
AnnotationFS dependent = (AnnotationFS) relation.getFeatureValue(dependentFeature);
for (var relation : select(cas, predictedType)) {
var governor = (AnnotationFS) relation.getFeatureValue(governorFeature);
var dependent = (AnnotationFS) relation.getFeatureValue(dependentFeature);

String relationLabel = relation.getStringValue(predictedFeature);
String governorLabel = governor.getStringValue(attachFeature);
String dependentLabel = dependent.getStringValue(attachFeature);
var relationLabel = relation.getStringValue(predictedFeature);
var governorLabel = governor.getStringValue(attachFeature);
var dependentLabel = dependent.getStringValue(attachFeature);

if (isBlank(governorLabel) || isBlank(dependentLabel) || isBlank(relationLabel)) {
continue;
Expand Down Expand Up @@ -268,7 +272,7 @@ private Type getAttachType(CAS aCas)

private Feature getAttachFeature(CAS aCas)
{
Type attachType = getAttachType(aCas);
var attachType = getAttachType(aCas);
return attachType.getFeatureByBaseName(traits.getAdjunctFeature());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
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.recommendation.api.model.SpanSuggestion;
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 @@ -146,7 +145,7 @@ public void rejectSuggestion(String aSessionOwner, SourceDocument aDocument, Str
AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aLocation)
throws AnnotationException
{
var suggestion = (SpanSuggestion) aSuggestion;
var suggestion = aSuggestion;

// Hide the suggestion. This is faster than having to recalculate the visibility status
// for the entire document or even for the part visible on screen.
Expand All @@ -160,9 +159,8 @@ var record = toLearningRecord(aDocument, aDataOwner, aSuggestion, feature, REJEC
learningRecordService.logRecord(aSessionOwner, record);

// Send an application event that the suggestion has been rejected
applicationEventPublisher.publishEvent(new RecommendationRejectedEvent(this, aDocument,
aDataOwner, suggestion.getBegin(), suggestion.getEnd(), suggestion.getCoveredText(),
feature, suggestion.getLabel()));
applicationEventPublisher.publishEvent(
new RecommendationRejectedEvent(this, aDocument, aDataOwner, feature, suggestion));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;

public class RecommendationRejectedEvent
extends ApplicationEvent
Expand All @@ -30,31 +31,18 @@ public class RecommendationRejectedEvent

private final SourceDocument document;
private final String user;
private final int begin;
private final int end;
private final String text;
private final AnnotationSuggestion suggestion;
private final AnnotationFeature feature;
private final Object recommendedValue;

public RecommendationRejectedEvent(Object aSource, SourceDocument aDocument, String aUser,
AnnotationFeature aFeature, Object aRecommendedValue)
{
this(aSource, aDocument, aUser, -1, -1, null, aFeature, aRecommendedValue);
}

public RecommendationRejectedEvent(Object aSource, SourceDocument aDocument, String aUser,
int aBegin, int aEnd, String aText, AnnotationFeature aFeature,
Object aRecommendedValue)
AnnotationFeature aFeature, AnnotationSuggestion aSuggestion)
{
super(aSource);

document = aDocument;
user = aUser;
begin = aBegin;
end = aEnd;
text = aText;
feature = aFeature;
recommendedValue = aRecommendedValue;
suggestion = aSuggestion;
}

@Override
Expand All @@ -69,31 +57,16 @@ public String getUser()
return user;
}

public int getBegin()
{
return begin;
}

public int getEnd()
public AnnotationSuggestion getSuggestion()
{
return end;
}

public String getText()
{
return text;
return suggestion;
}

public AnnotationFeature getFeature()
{
return feature;
}

public Object getRecommendedValue()
{
return recommendedValue;
}

@Override
public String toString()
{
Expand All @@ -106,16 +79,10 @@ public String toString()
builder.append(user);
builder.append(", ");
}
builder.append("begin=");
builder.append(begin);
builder.append("end=");
builder.append(end);
builder.append("text=");
builder.append(text);
builder.append(", feature=");
builder.append(feature.getName());
builder.append(", recommendedValue=");
builder.append(recommendedValue);
builder.append(", suggestion=");
builder.append(suggestion);
builder.append("]");
return builder.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,4 @@ public int compareTo(T o)
.append(getTargetBegin(), o.getTargetBegin()) //
.append(getTargetEnd(), o.getTargetEnd()).toComparison();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import de.tudarmstadt.ukp.inception.log.model.AnnotationDetails;
import de.tudarmstadt.ukp.inception.log.model.FeatureChangeDetails;
import de.tudarmstadt.ukp.inception.recommendation.api.event.RecommendationRejectedEvent;
import de.tudarmstadt.ukp.inception.recommendation.api.model.LinkSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.RelationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SpanSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.config.RecommenderServiceAutoConfiguration;
import de.tudarmstadt.ukp.inception.support.json.JSONUtil;

Expand Down Expand Up @@ -62,15 +65,28 @@ public String getAnnotator(RecommendationRejectedEvent aEvent)
@Override
public String getDetails(RecommendationRejectedEvent aEvent) throws IOException
{
AnnotationDetails annotation = new AnnotationDetails();
annotation.setBegin(aEvent.getBegin());
annotation.setEnd(aEvent.getEnd());
annotation.setText(aEvent.getText());
var suggestion = aEvent.getSuggestion();

var annotation = new AnnotationDetails();
annotation.setType(aEvent.getFeature().getLayer().getName());

FeatureChangeDetails details = new FeatureChangeDetails();
if (suggestion instanceof SpanSuggestion spanSuggestion) {
annotation.setBegin(spanSuggestion.getBegin());
annotation.setEnd(spanSuggestion.getEnd());
annotation.setText(spanSuggestion.getCoveredText());
}
else if (suggestion instanceof RelationSuggestion relationSuggestion) {
annotation.setBegin(relationSuggestion.getPosition().getTargetBegin());
annotation.setEnd(relationSuggestion.getPosition().getTargetEnd());
}
else if (suggestion instanceof LinkSuggestion linkSuggestion) {
annotation.setBegin(linkSuggestion.getPosition().getTargetBegin());
annotation.setEnd(linkSuggestion.getPosition().getTargetEnd());
}

var details = new FeatureChangeDetails();
details.setAnnotation(annotation);
details.setValue(aEvent.getRecommendedValue());
details.setValue(suggestion.getLabel());

return JSONUtil.toJsonString(details);
}
Expand Down

0 comments on commit aed9f31

Please sign in to comment.