You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by cl...@apache.org on 2014/10/28 22:01:07 UTC
svn commit: r1634983 [1/3] - in
/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal: ae/
ae/feature/ eval/ pipelines/
Author: clin
Date: Tue Oct 28 21:01:06 2014
New Revision: 1634983
URL: http://svn.apache.org/r1634983
Log:
the latest event-time event-event evaluation code and Annotator
Add self-training annotator for event-time relation
Added:
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfEventEventThymeRelations.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfSelfEventTimeRelations.java
Modified:
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfEventTimeRelations.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfTemporalRelations.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfTemporalRelations_ImplBase.java
ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/pipelines/FullTemporalExtractionPipeline.java
Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -21,6 +21,7 @@ package org.apache.ctakes.temporal.ae;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -29,14 +30,35 @@ import org.apache.ctakes.relationextract
import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.DependencyParseUtils;
import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.CoordinateFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependingVerbsFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventInBetweenPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventOutsidePropertyExtractor;
+import org.apache.ctakes.temporal.ae.feature.SpecialAnnotationRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+import org.apache.ctakes.temporal.ae.feature.TokenPropertyFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DeterminerRelationFeaturesExtractor;
import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventsInTheSameSentenceExtractor;
import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
import org.apache.ctakes.temporal.ae.feature.UmlsFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
import org.apache.ctakes.typesystem.type.relation.RelationArgument;
import org.apache.ctakes.typesystem.type.relation.TemporalTextRelation;
+//import org.apache.ctakes.typesystem.type.syntax.ConllDependencyNode;
import org.apache.ctakes.typesystem.type.textsem.EventMention;
import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
import org.apache.ctakes.typesystem.type.textspan.Sentence;
@@ -56,61 +78,80 @@ import com.google.common.collect.Lists;
public class EventEventRelationAnnotator extends RelationExtractorAnnotator {
- public static AnalysisEngineDescription createDataWriterDescription(
- Class<? extends DataWriter<String>> dataWriterClass,
- File outputDirectory,
- double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
- return AnalysisEngineFactory.createEngineDescription(
- EventEventRelationAnnotator.class,
- CleartkAnnotator.PARAM_IS_TRAINING,
- true,
- DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
- dataWriterClass,
- DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
- outputDirectory,
- RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
- // not sure why this has to be cast; something funny going on in uimaFIT maybe?
- (float) probabilityOfKeepingANegativeExample);
- }
-
- public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
- throws ResourceInitializationException {
- return AnalysisEngineFactory.createEngineDescription(
- EventEventRelationAnnotator.class,
- CleartkAnnotator.PARAM_IS_TRAINING,
- false,
- GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
- modelPath);
- }
-
- /**
- * @deprecated use String path instead of File.
- * ClearTK will automatically Resolve the String to an InputStream.
- * This will allow resources to be read within from a jar as well as File.
- */
- public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
- throws ResourceInitializationException {
- return AnalysisEngineFactory.createEngineDescription(
- EventEventRelationAnnotator.class,
- CleartkAnnotator.PARAM_IS_TRAINING,
- false,
- GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
- new File(modelDirectory, "model.jar"));
- }
-
- @Override
- protected List<RelationFeaturesExtractor> getFeatureExtractors() {
- return Lists.newArrayList(
- new TokenFeaturesExtractor()
- , new PartOfSpeechFeaturesExtractor()
-// , new EventArgumentPropertyExtractor()
- , new SectionHeaderRelationExtractor()
- , new NearbyVerbTenseRelationExtractor()
- , new CheckSpecialWordRelationExtractor()
- , new UmlsFeatureExtractor()
- , new DependencyPathFeaturesExtractor()
- );
- }
+ public static AnalysisEngineDescription createDataWriterDescription(
+ Class<? extends DataWriter<String>> dataWriterClass,
+ File outputDirectory,
+ double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventEventRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ true,
+ DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
+ dataWriterClass,
+ DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
+ outputDirectory,
+ RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
+ // not sure why this has to be cast; something funny going on in uimaFIT maybe?
+ (float) probabilityOfKeepingANegativeExample);
+ }
+
+ public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
+ throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventEventRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ false,
+ GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+ modelPath);
+ }
+
+ /**
+ * @deprecated use String path instead of File.
+ * ClearTK will automatically Resolve the String to an InputStream.
+ * This will allow resources to be read within from a jar as well as File.
+ */
+ @SuppressWarnings("dep-ann")
+ public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
+ throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventEventRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ false,
+ GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+ new File(modelDirectory, "model.jar"));
+ }
+
+ @Override
+ protected List<RelationFeaturesExtractor> getFeatureExtractors() {
+ return Lists.newArrayList(
+ new TokenFeaturesExtractor()
+ // new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
+ , new PartOfSpeechFeaturesExtractor()
+ // , new TemporalPETExtractor()
+ , new EventArgumentPropertyExtractor()
+ , new NumberOfEventTimeBetweenCandidatesExtractor()
+ , new SectionHeaderRelationExtractor()
+ , new NearbyVerbTenseRelationExtractor()
+ , new CheckSpecialWordRelationExtractor()
+ , new UmlsFeatureExtractor()
+ , new DependencyPathFeaturesExtractor()
+ , new CoordinateFeaturesExtractor()
+ , new OverlappedHeadFeaturesExtractor()
+ , new SRLRelationFeaturesExtractor()
+ , new NumberOfEventsInTheSameSentenceExtractor()
+ , new EventPositionRelationFeaturesExtractor() //not helpful
+ , new TimeXRelationFeaturesExtractor() //not helpful
+ , new ConjunctionRelationFeaturesExtractor()
+ , new DeterminerRelationFeaturesExtractor()
+ , new EventTimeRelationFeatureExtractor()
+ , new TokenPropertyFeaturesExtractor()
+ , new DependingVerbsFeatureExtractor()
+ , new SpecialAnnotationRelationExtractor() //not helpful
+ , new TemporalPETFlatExtractor()
+ // , new EventInBetweenPropertyExtractor()
+ // , new EventOutsidePropertyExtractor()
+ );
+ }
@Override
protected Class<? extends Annotation> getCoveringClass() {
@@ -120,18 +161,74 @@ public class EventEventRelationAnnotator
@Override
protected List<IdentifiedAnnotationPair> getCandidateRelationArgumentPairs(
JCas jCas, Annotation sentence) {
- List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
- List<EventMention> events = new ArrayList<EventMention>(JCasUtil.selectCovered(jCas, EventMention.class, sentence));
- for (int i = 0; i < events.size(); i++){
- if(!events.get(i).getClass().equals(EventMention.class)) continue;
- for(int j = i+1; j < events.size(); j++){
- if(!events.get(j).getClass().equals(EventMention.class)) continue;
- pairs.add(new IdentifiedAnnotationPair(events.get(i), events.get(j)));
- }
- }
- return pairs;
+
+ Map<EventMention, Collection<EventMention>> coveringMap =
+ JCasUtil.indexCovering(jCas, EventMention.class, EventMention.class);
+
+ List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
+ List<EventMention> events = new ArrayList<>(JCasUtil.selectCovered(jCas, EventMention.class, sentence));
+ //filter events:
+ List<EventMention> realEvents = Lists.newArrayList();
+ for( EventMention event : events){
+ if(event.getClass().equals(EventMention.class)){
+ realEvents.add(event);
+ }
+ }
+ events = realEvents;
+
+ int eventNum = events.size();
+
+ for (int i = 0; i < eventNum-1; i++){
+ for(int j = i+1; j < eventNum; j++){
+ EventMention eventA = events.get(j);
+ EventMention eventB = events.get(i);
+ boolean eventAValid = false;
+ boolean eventBValid = false;
+ for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, eventA)){
+ if(!event.getClass().equals(EventMention.class)){
+ eventAValid = true;
+ break;
+ }
+ }
+ for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, eventB)){
+ if(!event.getClass().equals(EventMention.class)){
+ eventBValid = true;
+ break;
+ }
+ }
+ if(eventAValid && eventBValid){
+ if(this.isTraining()){
+ for (EventMention event1 : coveringMap.get(eventA)){
+ for(EventMention event2 : coveringMap.get(eventB)){
+ pairs.add(new IdentifiedAnnotationPair(event1, event2));
+ }
+ }
+ }
+ pairs.add(new IdentifiedAnnotationPair(eventA, eventB));
+ }
+ }
+ }
+
+
+ // if(eventNum >= 2){
+ // for ( int i = 0; i< eventNum -1 ; i ++){
+ // EventMention evI = events.get(i);
+ // for(int j = i+1; j< eventNum; j++){
+ // EventMention evJ = events.get(j);
+ // if(j-i==1 || j-i==eventNum-1){//if two events are consecutive, or major events
+ // pairs.add(new IdentifiedAnnotationPair(evJ, evI));
+ // }else if(ifDependent(jCas, evI, evJ)){//if the event pairs are dependent// eventNum < 7 &&
+ // pairs.add(new IdentifiedAnnotationPair(evJ, evI));
+ // }else{// if the
+ // continue;
+ // }
+ // }
+ // }
+ // }
+
+ return pairs;
}
-
+
@Override
protected void createRelation(JCas jCas, IdentifiedAnnotation arg1,
IdentifiedAnnotation arg2, String predictedCategory) {
@@ -149,7 +246,7 @@ public class EventEventRelationAnnotator
relation.setCategory(predictedCategory);
relation.addToIndexes();
}
-
+
@Override
protected String getRelationCategory(
Map<List<Annotation>, BinaryTextRelation> relationLookup,
@@ -157,13 +254,18 @@ public class EventEventRelationAnnotator
IdentifiedAnnotation arg2) {
BinaryTextRelation relation = relationLookup.get(Arrays.asList(arg1, arg2));
String category = null;
- if (relation != null) {
+ if (relation != null && relation instanceof TemporalTextRelation) {
category = relation.getCategory();
} else {
relation = relationLookup.get(Arrays.asList(arg2, arg1));
- if (relation != null) {
+ if (relation != null && relation instanceof TemporalTextRelation) {
if(relation.getCategory().equals("OVERLAP")){
category = relation.getCategory();
+ // }else if (relation.getCategory().equals("BEFORE")){
+ // category = "AFTER";
+ // }else if (relation.getCategory().equals("AFTER")){
+ // category = "BEFORE";
+ // }
}else{
category = relation.getCategory() + "-1";
}
Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -28,14 +28,29 @@ import org.apache.ctakes.relationextract
import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyFeatureExtractor;
import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventIndexOfSameSentenceRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
import org.apache.ctakes.temporal.ae.feature.NearestFlagFeatureExtractor;
-import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TimeWordTypeRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXPropertyRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
//import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
//import org.apache.ctakes.temporal.ae.feature.treekernel.EventTimeFlatTreeFeatureExtractor;
//import org.apache.ctakes.temporal.ae.feature.treekernel.EventVerbRelationTreeExtractor;
-import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPathExtractor;
import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
import org.apache.ctakes.typesystem.type.relation.RelationArgument;
@@ -77,7 +92,7 @@ public class EventTimeRelationAnnotator
(float) probabilityOfKeepingANegativeExample);
}
- public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
+ public static AnalysisEngineDescription createEngineDescription(String modelPath)
throws ResourceInitializationException {
return AnalysisEngineFactory.createEngineDescription(
EventTimeRelationAnnotator.class,
@@ -86,12 +101,13 @@ public class EventTimeRelationAnnotator
GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
modelPath);
}
- /**
- * @deprecated use String path instead of File.
- * ClearTK will automatically Resolve the String to an InputStream.
- * This will allow resources to be read within from a jar as well as File.
- */
- public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
+ /**
+ * @deprecated use String path instead of File.
+ * ClearTK will automatically Resolve the String to an InputStream.
+ * This will allow resources to be read within from a jar as well as File.
+ */
+ @Deprecated
+ public static AnalysisEngineDescription createEngineDescription(File modelDirectory)
throws ResourceInitializationException {
return AnalysisEngineFactory.createEngineDescription(
EventTimeRelationAnnotator.class,
@@ -105,18 +121,31 @@ public class EventTimeRelationAnnotator
protected List<RelationFeaturesExtractor> getFeatureExtractors() {
return Lists.newArrayList(
new TokenFeaturesExtractor()
+ // new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
, new PartOfSpeechFeaturesExtractor()
- // , new TemporalAttributeFeatureExtractor()
+ , new TemporalAttributeFeatureExtractor()
// , new EventTimeFlatTreeFeatureExtractor()
- , new TemporalPETExtractor()
- // , new TemporalPathExtractor()
+ // , new TemporalPETExtractor()
+ //, new TemporalPathExtractor()
// , new EventVerbRelationTreeExtractor()
- , new SectionHeaderRelationExtractor()
+ , new NumberOfEventTimeBetweenCandidatesExtractor()
+ // , new SectionHeaderRelationExtractor()
, new NearbyVerbTenseRelationExtractor()
, new CheckSpecialWordRelationExtractor()
, new NearestFlagFeatureExtractor()
, new DependencyPathFeaturesExtractor()
- // , new DependencyFeatureExtractor()
+ , new DependencyFeatureExtractor()
+ // , new SRLRelationFeaturesExtractor()// tried, but not helpful
+ , new EventArgumentPropertyExtractor()
+ , new OverlappedHeadFeaturesExtractor()
+ // , new EventTimeRelationFeatureExtractor()
+ , new ConjunctionRelationFeaturesExtractor()
+ // , new EventPositionRelationFeaturesExtractor() //tried, but not helpful
+ , new TimeXRelationFeaturesExtractor()
+ , new TemporalPETFlatExtractor()
+ , new TimeXPropertyRelationFeaturesExtractor()
+ // , new TimeWordTypeRelationExtractor() //tried, but not helpful
+ // , new EventIndexOfSameSentenceRelationFeaturesExtractor() //tried, but not helpful
);
}
@@ -133,9 +162,18 @@ public class EventTimeRelationAnnotator
for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, sentence)) {
// ignore subclasses like Procedure and Disease/Disorder
if (event.getClass().equals(EventMention.class)) {
- for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
- pairs.add(new IdentifiedAnnotationPair(event, time));
- }
+// boolean eventValid = false;
+// for (EventMention ev : JCasUtil.selectCovered(jCas, EventMention.class, event)){
+// if(!ev.getClass().equals(EventMention.class)){// if there is an valid UMLS type in the same span, then true
+// eventValid = true;
+// break;
+// }
+// }
+// if(eventValid){
+ for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+ pairs.add(new IdentifiedAnnotationPair(event, time));
+ }
+// }
}
}
@@ -196,6 +234,11 @@ public class EventTimeRelationAnnotator
if (relation != null) {
if(relation.getCategory().equals("OVERLAP")){
category = relation.getCategory();
+ // }else if (relation.getCategory().equals("BEFORE")){
+ // category = "AFTER";
+ // }else if (relation.getCategory().equals("AFTER")){
+ // category = "BEFORE";
+ // }
}else{
category = relation.getCategory() + "-1";
}
Added: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java?rev=1634983&view=auto
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java (added)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -0,0 +1,249 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ctakes.temporal.ae;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ctakes.relationextractor.ae.RelationExtractorAnnotator;
+import org.apache.ctakes.relationextractor.ae.features.PartOfSpeechFeaturesExtractor;
+import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
+import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventIndexOfSameSentenceRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NearestFlagFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TimeWordTypeRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXPropertyRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.EventTimeFlatTreeFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.EventVerbRelationTreeExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPathExtractor;
+import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
+import org.apache.ctakes.typesystem.type.relation.RelationArgument;
+import org.apache.ctakes.typesystem.type.relation.TemporalTextRelation;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.ctakes.typesystem.type.textsem.TimeMention;
+import org.apache.ctakes.typesystem.type.textspan.Sentence;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.cleartk.ml.CleartkAnnotator;
+import org.cleartk.ml.DataWriter;
+import org.cleartk.ml.jar.DefaultDataWriterFactory;
+import org.cleartk.ml.jar.DirectoryDataWriterFactory;
+import org.cleartk.ml.jar.GenericJarClassifierFactory;
+import org.apache.uima.fit.factory.AnalysisEngineFactory;
+import org.apache.uima.fit.util.JCasUtil;
+
+import com.google.common.collect.Lists;
+
+public class EventTimeSelfRelationAnnotator extends RelationExtractorAnnotator {
+
+ public static AnalysisEngineDescription createDataWriterDescription(
+ Class<? extends DataWriter<String>> dataWriterClass,
+ File outputDirectory,
+ double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventTimeSelfRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ true,
+ DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
+ dataWriterClass,
+ DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
+ outputDirectory,
+ RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
+ // not sure why this has to be cast; something funny going on in uimaFIT maybe?
+ (float) probabilityOfKeepingANegativeExample);
+ }
+
+ public static AnalysisEngineDescription createEngineDescription(String modelPath)
+ throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventTimeSelfRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ false,
+ GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+ modelPath);
+ }
+ /**
+ * @deprecated use String path instead of File.
+ * ClearTK will automatically Resolve the String to an InputStream.
+ * This will allow resources to be read within from a jar as well as File.
+ */
+ @Deprecated
+ public static AnalysisEngineDescription createEngineDescription(File modelDirectory)
+ throws ResourceInitializationException {
+ return AnalysisEngineFactory.createEngineDescription(
+ EventTimeSelfRelationAnnotator.class,
+ CleartkAnnotator.PARAM_IS_TRAINING,
+ false,
+ GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+ new File(modelDirectory, "model.jar"));
+ }
+
+ @Override
+ protected List<RelationFeaturesExtractor> getFeatureExtractors() {
+ return Lists.newArrayList(
+ new TokenFeaturesExtractor()
+ // new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
+ , new PartOfSpeechFeaturesExtractor()
+ , new TemporalAttributeFeatureExtractor()
+ // , new EventTimeFlatTreeFeatureExtractor()
+ // , new TemporalPETExtractor()
+ //, new TemporalPathExtractor()
+ // , new EventVerbRelationTreeExtractor()
+ , new NumberOfEventTimeBetweenCandidatesExtractor()
+ // , new SectionHeaderRelationExtractor()
+ , new NearbyVerbTenseRelationExtractor()
+ , new CheckSpecialWordRelationExtractor()
+ , new NearestFlagFeatureExtractor()
+ , new DependencyPathFeaturesExtractor()
+ , new DependencyFeatureExtractor()
+ // , new SRLRelationFeaturesExtractor()// tried, but not helpful
+ , new EventArgumentPropertyExtractor()
+ , new OverlappedHeadFeaturesExtractor()
+ // , new EventTimeRelationFeatureExtractor()
+ , new ConjunctionRelationFeaturesExtractor()
+ // , new EventPositionRelationFeaturesExtractor() //tried, but not helpful
+ , new TimeXRelationFeaturesExtractor()
+ , new TemporalPETFlatExtractor()
+ , new TimeXPropertyRelationFeaturesExtractor()
+ // , new TimeWordTypeRelationExtractor() //tried, but not helpful
+ // , new EventIndexOfSameSentenceRelationFeaturesExtractor() //tried, but not helpful
+ );
+ }
+
+ @Override
+ protected Class<? extends Annotation> getCoveringClass() {
+ return Sentence.class;
+ }
+
+ @Override
+ public List<IdentifiedAnnotationPair> getCandidateRelationArgumentPairs(
+ JCas jCas,
+ Annotation sentence) {
+ Map<EventMention, Collection<EventMention>> coveringMap =
+ JCasUtil.indexCovering(jCas, EventMention.class, EventMention.class);
+
+ List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
+ for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, sentence)) {
+ // ignore subclasses like Procedure and Disease/Disorder
+ if(this.isTraining()){//if training mode, train on both gold event and nearby system events
+
+ if (event.getClass().equals(EventMention.class)) {
+ for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+ Collection<EventMention> eventList = coveringMap.get(event);
+ for(EventMention covEvent : eventList){
+ pairs.add(new IdentifiedAnnotationPair(covEvent, time));
+ }
+ pairs.add(new IdentifiedAnnotationPair(event, time));
+ }
+ }
+ }else{//if testing mode, only test on system generated events
+ if (event.getClass().equals(EventMention.class)) {
+ for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+ pairs.add(new IdentifiedAnnotationPair(event, time));
+ }
+ }
+ }
+ }
+
+ return pairs;
+ }
+
+ @Override
+ protected void createRelation(JCas jCas, IdentifiedAnnotation arg1,
+ IdentifiedAnnotation arg2, String predictedCategory) {
+ RelationArgument relArg1 = new RelationArgument(jCas);
+ relArg1.setArgument(arg1);
+ relArg1.setRole("Arg1");
+ relArg1.addToIndexes();
+ RelationArgument relArg2 = new RelationArgument(jCas);
+ relArg2.setArgument(arg2);
+ relArg2.setRole("Arg2");
+ relArg2.addToIndexes();
+ TemporalTextRelation relation = new TemporalTextRelation(jCas);
+ relation.setArg1(relArg1);
+ relation.setArg2(relArg2);
+ relation.setCategory(predictedCategory);
+ relation.addToIndexes();
+ }
+
+
+ @Override
+ protected String getRelationCategory(
+ Map<List<Annotation>, BinaryTextRelation> relationLookup,
+ IdentifiedAnnotation arg1,
+ IdentifiedAnnotation arg2) {
+ BinaryTextRelation relation = relationLookup.get(Arrays.asList(arg1, arg2));
+ String category = null;
+ if (relation != null) {
+ category = relation.getCategory();
+ } else {
+ relation = relationLookup.get(Arrays.asList(arg2, arg1));
+ if (relation != null) {
+ if(relation.getCategory().equals("OVERLAP")){
+ category = relation.getCategory();
+ // }else if (relation.getCategory().equals("BEFORE")){
+ // category = "AFTER";
+ // }else if (relation.getCategory().equals("AFTER")){
+ // category = "BEFORE";
+ // }
+ }else{
+ category = relation.getCategory() + "-1";
+ }
+ }
+ }
+
+ if(category!=null){
+ if(!((EventMention)arg1).getClass().equals(EventMention.class)){
+ System.out.println("find system-event relations: "+ arg1.getCoveredText() + " -"+category+"- " + arg2.getCoveredText());
+ }else{
+ System.out.println("find gold-event relations: "+ arg1.getCoveredText() + " -"+category+"- " + arg2.getCoveredText());
+ }
+ }
+
+ if (category == null && coin.nextDouble() <= this.probabilityOfKeepingANegativeExample) {
+ category = NO_RELATION_CATEGORY;
+ }
+
+ return category;
+ }
+}
Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java Tue Oct 28 21:01:06 2014
@@ -18,65 +18,152 @@
*/
package org.apache.ctakes.temporal.ae.feature;
+import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
-import java.util.Map;
import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
-import org.apache.ctakes.typesystem.type.syntax.WordToken;
-import org.apache.ctakes.typesystem.type.textsem.EventMention;
import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
-import org.apache.ctakes.typesystem.type.textspan.Sentence;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.jcas.JCas;
import org.cleartk.ml.Feature;
-import org.apache.uima.fit.util.JCasUtil;
+import org.cleartk.timeml.util.TimeWordsExtractor;
+import org.springframework.util.StringUtils;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.io.Resources;
public class CheckSpecialWordRelationExtractor implements RelationFeaturesExtractor{
-
- final static List<String> specialWd = Arrays.asList("before","prior","previous","previously","ago","soon","earlier","early","after","later","subsequent","follow","following","followed","post","since","back","start","started","by","past","starting");
+
+ //final static List<String> specialWd = Arrays.asList("before","prior","previous","previously","ago","soon","earlier","early","after","later","subsequent","follow","following","followed","post","since","back","start","started","by","past","starting");
+ private static final String LOOKUP_PATH = "/org/apache/ctakes/temporal/TimeLexicon.csv";
+
+ private Multimap<String, String> specialWd;
+
+ public CheckSpecialWordRelationExtractor() {
+ this.specialWd = ArrayListMultimap.create();
+ URL url = TimeWordsExtractor.class.getResource(LOOKUP_PATH);
+ try {
+ for (String line : Resources.readLines(url, Charsets.US_ASCII)) {
+ String[] WordAndType = line.split(",");
+ if (WordAndType.length != 2) {
+ throw new IllegalArgumentException("Expected '<word>,<type>', found: " + line);
+ }
+ this.specialWd.put(WordAndType[0], WordAndType[1]);
+ }
+ } catch (IOException e) {
+ System.err.println("TimeLexicon resource initialization error.");
+ }
+ }
@Override
public List<Feature> extract(JCas jcas, IdentifiedAnnotation arg1,
IdentifiedAnnotation arg2) throws AnalysisEngineProcessException {
- List<Feature> feats = new ArrayList<Feature>();
+ List<Feature> feats = new ArrayList<>();
- //find event
- EventMention event = null;
- if(arg1 instanceof EventMention){
- event = (EventMention) arg1;
- }else if(arg2 instanceof EventMention){
- event = (EventMention) arg2;
+ // swap the order if necessary:
+ if(isBefore(arg2,arg1)){
+ IdentifiedAnnotation temp = arg1;
+ arg1 = arg2;
+ arg2 = temp;
+ }else if(isBefore(arg1,arg2)){
+ //keep the order of arg1 arg2
}else{
- return feats;
+ return feats; //don't do anything if arg1 overlap arg2
}
//1 get covering sentence:
- Map<EventMention, Collection<Sentence>> coveringMap =
- JCasUtil.indexCovering(jcas, EventMention.class, Sentence.class);
- Collection<Sentence> sentList = coveringMap.get(event);
-
- //2 get Verb Tense
- if (sentList != null && !sentList.isEmpty()){
- for(Sentence sent : sentList) {
- for ( WordToken wt : JCasUtil.selectCovered(jcas, WordToken.class, sent)) {
- if (wt != null){
- String wdtext = wt.getCoveredText().toLowerCase();
- if (specialWd.contains(wdtext)){
- Feature feature = new Feature("SpecialWd", wdtext);
- feats.add(feature);
- }
- }
- }
-
- //logger.info("found nearby verb's pos tag: "+ verbTP);
+// Map<IdentifiedAnnotation, Collection<Sentence>> coveringMap =
+// JCasUtil.indexCovering(jcas, IdentifiedAnnotation.class, Sentence.class);
+//
+ int begin = arg1.getEnd();
+ int end = arg2.getBegin();
+// int window = 30;
+//
+// //get two covering sentences for arg1 and arg2, two arguments could come from different sentences.
+// List<Sentence> sentList = new ArrayList<>();
+// sentList.addAll(coveringMap.get(arg1));
+// if(sentList.isEmpty()) return feats;
+// Sentence arg1Sent = sentList.get(0);
+//
+// sentList = new ArrayList<>();
+// sentList.addAll(coveringMap.get(arg2));
+// if(sentList.isEmpty()) return feats;
+// Sentence arg2Sent = sentList.get(0);
+
+
+ String textInBetween = null;
+ // String textAfterArg1 = null;
+ // String textBeforeArg2 = null;
+ // if(end-begin <= 2* window){
+ textInBetween = jcas.getDocumentText().substring(begin, end).replaceAll("[\r\n]", " ").toLowerCase();
+ // }else{
+ // int arg1tail = Math.min(begin + window, arg1Sent.getEnd());
+ // textAfterArg1 = jcas.getDocumentText().substring(begin, arg1tail).replaceAll("[\r\n]", " ").toLowerCase();
+ // int arg2head = Math.max(end - window, arg2Sent.getBegin());
+ // textBeforeArg2 = jcas.getDocumentText().substring(arg2head, end).replaceAll("[\r\n]", " ").toLowerCase();
+ // }
+// int arg1head = Math.max(arg1.getBegin()-window, arg1Sent.getBegin());
+// String textBeforeArg1 = jcas.getDocumentText().substring(arg1head, arg1.getBegin()).replaceAll("[\r\n]", " ").toLowerCase();
+// int arg2tail = Math.min(arg2.getEnd()+window, arg2Sent.getEnd());
+// String textAfterArg2 = jcas.getDocumentText().substring(arg2.getEnd(), arg2tail).replaceAll("[\r\n]", " ").toLowerCase();
+ String textInArg1 = jcas.getDocumentText().substring(arg1.getBegin(), arg1.getEnd()).replaceAll("[\r\n]", " ").toLowerCase();
+ String textInArg2 = jcas.getDocumentText().substring(arg2.getBegin(), arg2.getEnd()).replaceAll("[\r\n]", " ").toLowerCase();
+
+ for(String lexicon : specialWd.keySet()){
+ if( textInBetween != null && textInBetween.matches(".*\\b"+lexicon+"\\b.*")){
+ String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+ Feature feature = new Feature("SpecialWd_InBetween", type);
+ feats.add(feature);
}
-
+// if( textBeforeArg1.matches(".*\\b"+lexicon+"\\b.*")){
+// String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+// Feature feature = new Feature("SpecialWd_BeforeArg1", type);
+// feats.add(feature);
+// }
+ if( textInArg1.matches(".*\\b"+lexicon+"\\b.*")){
+ String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+ Feature feature = new Feature("SpecialWd_InArg1", type);
+ feats.add(feature);
+ }
+ // if( textAfterArg1 != null && textAfterArg1.matches(".*\\b"+lexicon+"\\b.*")){
+ // String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+ // Feature feature = new Feature("SpecialWd_AfterArg1", type);
+ // feats.add(feature);
+ // }
+ // if( textBeforeArg2 != null && textBeforeArg2.matches(".*\\b"+lexicon+"\\b.*")){
+ // String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+ // Feature feature = new Feature("SpecialWd_BeforeArg2", type);
+ // feats.add(feature);
+ // }
+ if( textInArg2.matches(".*\\b"+lexicon+"\\b.*")){
+ String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+ Feature feature = new Feature("SpecialWd_InArg2", type);
+ feats.add(feature);
+ }
+// if( textAfterArg2.matches(".*\\b"+lexicon+"\\b.*")){
+// String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+// Feature feature = new Feature("SpecialWd_AfterArg2", type);
+// feats.add(feature);
+// }
}
+
+ //logger.info("found nearby verb's pos tag: "+ verbTP);
return feats;
}
+ private static boolean isBefore(IdentifiedAnnotation arg1,
+ IdentifiedAnnotation arg2) {
+ if(arg1.getBegin()<arg2.getBegin()){
+ if(arg1.getEnd()<arg2.getBegin()){
+ return true;
+ }
+ }
+ return false;
+ }
+
}
Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java Tue Oct 28 21:01:06 2014
@@ -85,7 +85,7 @@ RelationFeaturesExtractor {
TimeMention admissionTime = null;
//may need better way to identify Discharge Time other than relative span information:
for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, 15, 30)) {
- if(time.getTimeClass().equals("DATE")){
+ if(time.getTimeClass() != null && time.getTimeClass().equals("DATE")){
admissionTime = time;
break;
}
@@ -94,7 +94,7 @@ RelationFeaturesExtractor {
TimeMention dischargeTime = null;
//may need better way to identify Discharge Time other than relative span information:
for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, 40, 60)) {
- if(time.getTimeClass().equals("DATE")){
+ if(time.getTimeClass() != null && time.getTimeClass().equals("DATE")){
dischargeTime = time;
break;
}
Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java Tue Oct 28 21:01:06 2014
@@ -72,10 +72,10 @@ RelationFeaturesExtractor {
int arg2Index = -1;
for(int i=0; i< eventsNum; i++){
EventMention currentEvent = events.get(i);
- if(currentEvent==arg1){
+ if(hasOverlappingSpan(currentEvent,arg1)){
arg1Index = i;
}
- if(currentEvent==arg2){
+ if(hasOverlappingSpan(currentEvent,arg2)){
arg2Index = i;
}
if(arg1Index!=-1 && arg2Index!=-1){
@@ -107,4 +107,16 @@ RelationFeaturesExtractor {
return feats;
}
+ private static boolean hasOverlappingSpan(EventMention cevent,
+ IdentifiedAnnotation arg) {
+ if(cevent.getBegin()==arg.getBegin() && arg.getEnd()>=cevent.getEnd()){
+ return true;
+ }else if(arg.getBegin()<=cevent.getBegin() && cevent.getEnd()==arg.getEnd()){
+ return true;
+ }else if(arg.getBegin()<=cevent.getBegin() && arg.getEnd()>=cevent.getEnd()){ //if argument cover current (gold) event mention.
+ return true;
+ }
+ return false;
+ }
+
}