【问题标题】:Remove tag from words after using postagger in java在java中使用postagger后从单词中删除标签
【发布时间】:2013-03-08 23:00:12
【问题描述】:

我使用斯坦福大学的 NLP postagger 在我的程序中标记名词、形容词。

    interest_NN 
    bui_NNS 
    ground_VBP
     avail_NN 
    respond_NN
     detail_NN 
    like_IN 
    quickli_NNS
    current_JJ 

现在我必须只选择那些带有标签 _NN,_NNS,_JJ 的单词,并从单词中删除这些标签。

    quickli
    current
    avail

我尝试这样从单词中删除 -NN 标记。但它删除了前 2words 标签并从中获得了异常

           while(tagread.hasNext())
           {
        String s=tagread.next();

        int flag=1;
        jTextArea2.append("\n" +s.toLowerCase());


        String ofInterest2 = s.substring(0, s.indexOf("_NN"));


         for(int i=0;i<s.length();i++){
             if(s.equals(ofInterest2))
                 {
                 flag=0;
                 }
         }
         if(flag!=0)
         {
             System.out.println(ofInterest2);

         }
    }

例外:

 java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)

那么我的方法有什么问题?或者如何进一步进行?

【问题讨论】:

    标签: java string nlp


    【解决方案1】:

    不要使用字符串方法来删除标记文本;使用 NLP 的 API 提取词性进行比较。

    生成List of TaggedWord 对象,然后使用TaggedWord API 直接提取词性:

    // Call the API to parse your sentence.
    List<TaggedWord> words = tagger.tagSentence( ... );
    
    // For each word tagged in the sentence...
    for( TaggedWord word : words ) {
      String tag = word.tag();
    
      // Check the part-of-speech directly, without having to parse the string.
      if( "NN".equalsIgnoreCase( tag ) ) {
        System.out.printf( "%s is a noun\n", word.word() );
      }
    }
    

    另请参阅斯坦福的 NLP API:

    要检查名词,应避免以下情况:

    if( "NN".equalsIgnoreCase( tag ) ) {
      System.out.printf( "%s is a noun\n", word.word() );
    }
    

    这是因为词性可以通过多种方式进行标记(例如,NN、NNS)。您可以使用正则表达式或startsWith

    您应该要求TaggedWord 的作者提供isNounisVerbisNounPlural 等此类方法。也就是说,是的,您可以使用正则表达式来匹配字符串。我还在我的代码中使用startsWith 来检查名词,因为它比正则表达式更快。例如:

    if( tag != null && tag.toUpperCase().startsWith( "NN" ) ) {
      System.out.printf( "%s is a noun\n", word.word() );
    }
    

    要真正实现 OO,请注入 TaggedWord 的子类以供标注器使用。然后子类将公开isNoun 方法。

    【讨论】:

    • 你能提供简单的例子吗?我用的是斯坦福邮递员。给我一些 NLProcessing API。谢谢
    • 根据您的建议,我尝试另一种方式。就像使用正则表达式来检查字符串的结尾,比如像 _NNP、_VRB 等这样的结尾,然后使用全部替换来删除整个字符串。这个方法对吗?
    【解决方案2】:

    indexOf 在字符串中找不到您提供的参数时返回 -1。在这一行:

    String ofInterest2 = s.substring(0, s.indexOf("_NN"));
    

    s.indexOf 可能在字符串s 中没有找到“_NN”。然后,当您请求从 s 的 0-1 的子字符串时,这没有任何意义,因此您会得到一个异常。

    【讨论】:

      【解决方案3】:

      您试图获取整个文本“ground_VBP”的子字符串,但您传入了s.indexOf("_NN") 的结果。未找到子字符串,因此它返回 -1。但是-1 不是substring 函数的有效索引,所以substring 抛出了你报告的StringIndexOutOfBoundsException

      只有在 indexOf 方法返回 0 或更大的值(即找到)时,才应该使用子字符串。

      【讨论】:

      • 除了我的方法还有什么更好的方法吗?
      • 可能有一个“postagger”方法来做到这一点;我不知道。我不熟悉它。我刚刚看到了您的方法导致StringIndexOutOfBoundsException 的原因。
      猜你喜欢
      • 1970-01-01
      • 2016-07-31
      • 2017-06-13
      • 2015-05-25
      • 2017-09-22
      • 2023-03-06
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多