【问题标题】:What is the effective method to handle word contractions using Java?使用 Java 处理单词收缩的有效方法是什么?
【发布时间】:2011-05-06 11:34:03
【问题描述】:

我有一个文件中的单词列表。它们可能包含诸如谁,没有等词。因此,在从中阅读时,我需要使它们正确,例如“谁是”和“没有”。这必须在 Java 中完成。我需要在不浪费太多时间的情况下做到这一点。

这实际上是为了在使用 solr 的搜索期间处理此类查询。

下面是我尝试使用哈希映射的示例代码

Map<String, String> con = new HashMap<String, String>();
        con.put("'s", " is");
        con.put("'d", " would");
        con.put("'re", " are");
        con.put("'ll", " will");
        con.put("n't", " not");
        con.put("'nt", " not");

        String temp = null;
        String str = "where'd you're you'll would'nt hello";

        String[] words = str.split(" ");
        int index = -1 ;
        for(int i = 0;i<words.length && (index =words[i].lastIndexOf('\''))>-1;i++){
            temp = words[i].substring(index);
            if(con.containsKey(temp)){
                 temp = con.get(temp);
            }
            words[i] = words[i].substring(0, index)+temp;
            System.out.println(words[i]);           
        }

【问题讨论】:

  • 我喜欢ain't -> are not ;)
  • “他决定去”表明“的”可以是“他有”。还有,何苦呢?你知道宫缩在某种程度上是不恰当的吗?你打算如何处理“'tisn't”或“wouldn't've”?
  • @tchrist 是对的,这取决于上下文。您可以设计并考虑到算法,但是如果您想正确执行此操作,则可能必须进行完整解析。这可能不值得付出努力,因为无论如何你从这个扩展中得到的大部分东西都在停止名单上。
  • @larsmans 是的。在这方面付出那么多努力是不值得的。我担心的是我不想在索引中搜索“re”“ve”等没有意义的词
  • 或者实际上,完全解析可能不是必需的,但需要一些 NLP 复杂性(结果仍然是矫枉过正)。

标签: java solr nlp


【解决方案1】:

如果您担心包含例如“谁”的查询会查找包含例如“谁是”的文档,那么您应该考虑使用专为此目的设计的词干分析器。

您可以在 solr 配置中轻松添加一个词干分析器,将其配置为过滤器。见http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters

编辑:
SnowballPorterFilterFactory 可能会为您完成这项工作。

【讨论】:

  • 当前使用 solr.PorterStemFilterFactory。在这里,例如“you're”的查询变为“you re”,因此它在索引中搜索“you”和“re”,但找不到匹配项。如果“you're”被设为“you are”,那么它会搜索“you”(as are 是一个常用词)并返回结果。这似乎是现在的问题。
  • @user608167 如果词干分析器正在拆分“you're”->“youre”,我会感到惊讶。你确定你的分词器在词干分析器发挥作用之前没有这样做吗?你能发布你的 配置吗?
  • 我是 solr 的初学者。我是从更高的层面来看的。标记器使您成为->您成为。词干分析器的输出也是“you re”。所以索引搜索you+re。如何处理?
  • @user608167 你有两个选择; 1)在标记之前词干 2)不要在撇号上标记。 2) 对我来说更有意义。
  • 从我可以通过调试看到的,例如你的查询通过 up.parse(userQuery);存在于 DisMaxQParser.java 中。在那条线之后,它变成了你。我确信词干是在这里完成的。上面的解析方法指向“lucene-core-2.9.3.jar”。在此之前查询未标记化。
【解决方案2】:

接着@James Jithin 的最后一句话:

  • 如果单词是所有格形式,则 "'s" -> "is" 转换不正确。
  • “'d”->“would”转换在古代形式中是不正确的,其中“'d”可能是“ed”的缩写。
  • “'nt” -> “not” 转换不正确,因为这实际上只是“n't”收缩的拼写错误。 (我的意思是“不会”完全是错误的......不是吗。)

因此,在我看来,实现这一点的最佳方法是列举少数常见且有效的缩略词,而忽略其余部分。这还有一个优点,您可以使用简单的字符串匹配而不是后缀匹配来实现它。

【讨论】:

    【解决方案3】:

    代码可以写成

    Map<String, String> con = new HashMap<String, String>();
        con.put("'s", " is");
        con.put("'d", " would");
        con.put("'re", " are");
        con.put("'ll", " will");
        con.put("n't", " not");
        con.put("'nt", " not");
    
        String str = "where'd you're you'll would'nt hello";
    
        for(String key : con.keySet()) {
            str = str.replaceAll(key + "\\b" , con.get(key));
        }
    

    按照你的逻辑。但是假设它的script's是一个表示占有的词,把它改成script is就会改变意思。

    【讨论】:

      猜你喜欢
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多