Java 向SUTime添加用于分析季度的自定义规则

Java 向SUTime添加用于分析季度的自定义规则,java,nlp,stanford-nlp,sutime,Java,Nlp,Stanford Nlp,Sutime,我下面介绍了为财政年度季度(如第一季度、第二季度、第三季度和第四季度)添加自定义SUTime规则的内容 我使用默认的defs.sutime.txt和english.sutime.txt作为我自己规则文件的模板 将以下代码附加到mydefs.sutime.txt之后 // Financial Quarters FYQ1 = { type: QUARTER_OF_YEAR, label: "FYQ1", value: TimeWithRange(TimeR

我下面介绍了为财政年度季度(如第一季度、第二季度、第三季度和第四季度)添加自定义SUTime规则的内容

我使用默认的
defs.sutime.txt
english.sutime.txt
作为我自己规则文件的模板

将以下代码附加到my
defs.sutime.txt之后

  // Financial Quarters
  FYQ1 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ1",
      value: TimeWithRange(TimeRange(IsoDate(ANY,10,1), IsoDate(ANY,12,31), QUARTER))
  }
  FYQ2 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ2",
      value: TimeWithRange(TimeRange(IsoDate(ANY,1,1), IsoDate(ANY,3,31), QUARTER))
  }
  FYQ3 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ3",
      value: TimeWithRange(TimeRange(IsoDate(ANY,4,1), IsoDate(ANY,6,30), QUARTER))
  }
  FYQ4 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ4",
      value: TimeWithRange(TimeRange(IsoDate(ANY,7,1), IsoDate(ANY,9,30), QUARTER))
  }
  # Financial Quarters
  FISCAL_YEAR_QUARTER_MAP = {
    "Q1": FYQ1,
    "Q2": FYQ2,
    "Q3": FYQ3,
    "Q4": FYQ4
  }
  FISCAL_YEAR_QUARTER_YEAR_OFFSETS_MAP = {
    "Q1": 1,
    "Q2": 0,
    "Q3": 0,
    "Q4": 0
  }
  $FiscalYearQuarterTerm = CreateRegex(Keys(FISCAL_YEAR_QUARTER_MAP))

  {
    matchWithResults: TRUE,
    pattern: ((/$FiscalYearQuarterTerm/) (FY)? (/(FY)?([0-9]{4})/)),
    result:  TemporalCompose(INTERSECT, IsoDate(Subtract({type: "NUMBER", value: $$3.matchResults[0].word.group(2)}, FISCAL_YEAR_QUARTER_YEAR_OFFSETS_MAP[$1[0].word]), ANY, ANY), FISCAL_YEAR_QUARTER_MAP[$1[0].word])
  }

  {
    pattern: ((/$FiscalYearQuarterTerm/)),
    result: FISCAL_YEAR_QUARTER_MAP[$1[0].word]
  }
并将以下代码附加到my
english.sutime.txt

  // Financial Quarters
  FYQ1 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ1",
      value: TimeWithRange(TimeRange(IsoDate(ANY,10,1), IsoDate(ANY,12,31), QUARTER))
  }
  FYQ2 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ2",
      value: TimeWithRange(TimeRange(IsoDate(ANY,1,1), IsoDate(ANY,3,31), QUARTER))
  }
  FYQ3 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ3",
      value: TimeWithRange(TimeRange(IsoDate(ANY,4,1), IsoDate(ANY,6,30), QUARTER))
  }
  FYQ4 = {
      type: QUARTER_OF_YEAR,
      label: "FYQ4",
      value: TimeWithRange(TimeRange(IsoDate(ANY,7,1), IsoDate(ANY,9,30), QUARTER))
  }
  # Financial Quarters
  FISCAL_YEAR_QUARTER_MAP = {
    "Q1": FYQ1,
    "Q2": FYQ2,
    "Q3": FYQ3,
    "Q4": FYQ4
  }
  FISCAL_YEAR_QUARTER_YEAR_OFFSETS_MAP = {
    "Q1": 1,
    "Q2": 0,
    "Q3": 0,
    "Q4": 0
  }
  $FiscalYearQuarterTerm = CreateRegex(Keys(FISCAL_YEAR_QUARTER_MAP))

  {
    matchWithResults: TRUE,
    pattern: ((/$FiscalYearQuarterTerm/) (FY)? (/(FY)?([0-9]{4})/)),
    result:  TemporalCompose(INTERSECT, IsoDate(Subtract({type: "NUMBER", value: $$3.matchResults[0].word.group(2)}, FISCAL_YEAR_QUARTER_YEAR_OFFSETS_MAP[$1[0].word]), ANY, ANY), FISCAL_YEAR_QUARTER_MAP[$1[0].word])
  }

  {
    pattern: ((/$FiscalYearQuarterTerm/)),
    result: FISCAL_YEAR_QUARTER_MAP[$1[0].word]
  }
我仍然无法正确解析像“Q12020”这样的东西

如何正确添加分析会计年度季度(例如“Q1”)的规则

以下是我的完整代码:

import java.util.List;
import java.util.Properties;

import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.pipeline.*;
import edu.stanford.nlp.time.*;
import edu.stanford.nlp.util.CoreMap;

public class SUTimeSoExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.setProperty("sutime.includeRange", "true");
        props.setProperty("sutime.markTimeRanges", "true");
        props.setProperty("sutime.rules", "./defs.sutime.txt,./english.sutime.txt");

        AnnotationPipeline pipeline = new AnnotationPipeline();
        pipeline.addAnnotator(new TokenizerAnnotator(false));
        pipeline.addAnnotator(new WordsToSentencesAnnotator(false));
        pipeline.addAnnotator(new POSTaggerAnnotator(false));
        pipeline.addAnnotator(new TimeAnnotator("sutime", props));

        String input = "Stuff for Q1 2020";

        Annotation annotation = new Annotation(input);
        annotation.set(CoreAnnotations.DocDateAnnotation.class, "2020-06-01");
        pipeline.annotate(annotation);
        System.out.println(annotation.get(CoreAnnotations.TextAnnotation.class));
        List<CoreMap> timexAnnsAll = annotation.get(TimeAnnotations.TimexAnnotations.class);
        for (CoreMap cm : timexAnnsAll) {
            System.out.println(cm // match
                    + " --> " + cm.get(TimeExpression.Annotation.class).getTemporal() // parsed value
            );
        }
    }
}
import java.util.List;
导入java.util.Properties;
导入edu.stanford.nlp.ling.core注释;
导入edu.stanford.nlp.pipeline.*;
导入edu.stanford.nlp.time.*;
导入edu.stanford.nlp.util.CoreMap;
公共类sutimesoe示例{
公共静态void main(字符串[]args){
Properties props=新属性();
props.setProperty(“sutime.includeRange”、“true”);
props.setProperty(“sutime.markTimeRanges”、“true”);
props.setProperty(“sutime.rules”,“/defs.sutime.txt,./english.sutime.txt”);
AnnotationPipeline=新的AnnotationPipeline();
pipeline.addAnnotator(新tokenizeranotator(false));
pipeline.addAnnotator(新单词stosentencesannotator(false));
pipeline.addAnnotator(新的POSTaggerAnnotator(false));
addAnnotator(新的时间注释器(“sutime”,props));
String input=“2020年第1季度的材料”;
注释=新注释(输入);
注释集(CoreAnnotations.DocDateAnnotation.class,“2020-06-01”);
管道注释(注释);
System.out.println(annotation.get(CoreAnnotations.TextAnnotation.class));
List timexAnnsAll=annotation.get(TimeAnnotations.TimexAnnotations.class);
for(CoreMap cm:timexAnnsAll){
System.out.println(cm//match
+“-->”+cm.get(TimeExpression.Annotation.class).getTemporal()//解析值
);
}
}
}

请注意,我从stanford corenlp models JAR中删除了deafult
defs.sutime.txt
english.sutime.txt
文件,以避免出现以下Java代码示例:

如果您遵循该示例,主要是以以下方式构建管道,它应该会起作用:

props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner");
props.setProperty("ner.docDate.usePresent", "true");
// this will shut off the statistical models if you only want to run SUTime only
props.setProperty("ner.rulesOnly", "true");
// add your sutime properties as in your example
...
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
并确保使用版本4.0.0

如果只想运行SUTime而不运行统计模型,则可以仅将
ner.rules
设置为true


您可以为
ner.docDate
使用多个属性之一,也可以在运行之前在批注中设置文档日期。

注意,如果设置了ner.docDate.usePresent,它将覆盖您的代码直接设置的文档日期,因此不要同时执行这两个操作。谢谢。升级到4.0.0修复了我的问题。我甚至不需要提供自定义的
defs.sutime.txt
english.sutime.txt
,因为4.0.0中的默认文件已经包含解析会计年度季度的规则。