Java 基于文本的词边界检测

Java 基于文本的词边界检测,java,algorithm,data-structures,text,word-boundary,Java,Algorithm,Data Structures,Text,Word Boundary,我在单词边界识别方面遇到了这个问题。我删除了维基百科文档的所有标记,现在我想得到一个实体列表(有意义的术语)。我打算取两克,三克的文档,检查字典(wordnet)中是否有。有没有更好的方法来实现这一点 下面是示例文本。我想标识实体(显示为用双引号括起来) 火神是虚构的“星际迷航”宇宙中的一个类人物种,在火神星球上进化而来,以其试图在不受外界干扰的情况下凭理性和逻辑生活而闻名 他们是第一个正式与人类接触的地外物种,后来成为“行星联合会”的创始成员之一我认为你所说的仍然是一个新兴研究的主题,而不是一

我在单词边界识别方面遇到了这个问题。我删除了维基百科文档的所有标记,现在我想得到一个实体列表(有意义的术语)。我打算取两克,三克的文档,检查字典(wordnet)中是否有。有没有更好的方法来实现这一点

下面是示例文本。我想标识实体(显示为用双引号括起来)

火神是虚构的“星际迷航”宇宙中的一个类人物种,在火神星球上进化而来,以其试图在不受外界干扰的情况下凭理性和逻辑生活而闻名

他们是第一个正式与人类接触的地外物种,后来成为“行星联合会”的创始成员之一

我认为你所说的仍然是一个新兴研究的主题,而不是一个应用成熟算法的简单问题

我不能给你一个简单的“做这个”的答案,但这里是我脑海中的一些提示:

  • 我认为使用WordNet是可行的(但不确定Bigram/Trigram是从哪里来的),但是你应该将WordNet查找视为混合系统的一部分,而不是发现命名实体的全部
  • 然后,首先应用一些简单的常识标准(大写单词的序列;尝试将频繁出现的小写虚词,如“of”;由“已知标题”加上大写单词组成的序列)
  • 寻找那些在统计学上你不希望作为实体候选出现在一起的单词序列
  • 你能内置动态网页查找功能吗?(您的系统会发现大写的序列“IBM”,并查看是否找到例如带有文本模式“IBM是…[组织|公司|…]”的wikipedia条目
  • 看看这里和“信息提取”文献中的内容是否能给您提供一些想法:

事实上,当你看那些文献时,人们似乎并没有使用非常复杂、成熟的算法。因此,我认为有很大的空间来查看你的数据、探索,并看看你能想出什么……祝你好运!

如果我理解正确,你是在寻找子对象由双引号(“)分隔的字符串。可以在正则表达式中使用捕获组:

    String text = "Vulcans are a humanoid species in the fictional \"Star Trek\"" +
        " universe who evolved on the planet Vulcan and are noted for their " +
        "attempt to live by reason and logic with no interference from emotion" +
        " They were the first extraterrestrial species officially to make first" +
        " contact with Humans and later became one of the founding members of the" +
        " \"United Federation of Planets\"";
    String[] entities = new String[10];                 // An array to hold matched substrings
    Pattern pattern = Pattern.compile("[\"](.*?)[\"]"); // The regex pattern to use
    Matcher matcher = pattern.matcher(text);            // The matcher - our text - to run the regex on
    int startFrom   = text.indexOf('"');                // The index position of the first " character
    int endAt       = text.lastIndexOf('"');            // The index position of the last " character
    int count       = 0;                                // An index for the array of matches
    while (startFrom <= endAt) {                        // startFrom will be changed to the index position of the end of the last match
        matcher.find(startFrom);                        // Run the regex find() method, starting at the first " character
        entities[count++] = matcher.group(1);           // Add the match to the array, without its " marks
        startFrom = matcher.end();                      // Update the startFrom index position to the end of the matched region
    }
在这两种情况下,示例文本都是为了示例而硬编码的,并且假定存在相同的变量(名为
text
的字符串变量)

如果要测试
实体
数组的内容:

    int i = 0;
    while (i < count) {
        System.out.println(entities[i]);
        i++;
    }
请注意,如果
numQuotes
恰好是
0
,此方法仍然返回
true
(因为任何数字的0模等于0,所以
(计数%2==0)
将是
true
),尽管如果没有“字符”,您不想继续解析,所以您希望在某个地方检查此条件


希望这能有所帮助!

其他人也问了一个类似的问题。你应该阅读答案。特别是,博洛的答案指向了一篇有趣的文章,这篇文章使用了一个词的出现密度来决定它有多重要——观察到当一篇文章谈论某件事时,它通常指的是相当重要的某件事十、本文很有趣,因为该技术不需要事先了解正在处理的文本(例如,您不需要针对特定词典的词典)

本文提出了两种算法

第一种算法根据单个单词(如“Federation”或“Trek”等)的测量重要性对其进行评级。实现起来很简单,我甚至可以用Python提供一个(不是很优雅的)实现


第二种算法更有趣,因为它提取名词短语(如《星际迷航》等)完全忽略空格,使用树结构来决定如何分割名词短语。该算法应用于达尔文关于进化论的开创性文本时给出的结果非常令人印象深刻。然而,我承认实现该算法需要更多的思考,因为文中给出的描述相当难以捉摸,还有什么更多作者似乎有点难以追踪。也就是说,我没有花太多时间,所以你可能会有更好的运气。

这很有趣。我用双引号包围了实体。@Algorist:因为我有一个类似的误解,澄清你关于引号使用的问题可能是有用的。你可能不想去掉标记,而想用n在语义分析中遵循各种排版惯例。推断您已明确引用了希望在其他未标记文本中关联的短语是否正确?斯坦福NLP命名实体识别器应该是您的第一关。它将在第一次运行时为您提供很多价值,您可以查看代码并学习如何从那里改进它。
    int i = 0;
    while (i < count) {
        System.out.println(entities[i]);
        i++;
    }
    static int countQuoteChars(String text) {
        int nextQuote = text.indexOf('"');              // Find the first " character
        int count = 0;                                  // A counter for " characters found
        while (nextQuote != -1) {                       // While there is another " character ahead
            count++;                                    // Increase the count by 1
            nextQuote = text.indexOf('"', nextQuote+1); // Find the next " character
        }
        return count;                                   // Return the result
    }

    static boolean quoteCharacterParity(int numQuotes) {
        if (numQuotes % 2 == 0) { // If the number of " characters modulo 2 is 0
            return true;          // Return true for even
        }
        return false;             // Otherwise return false
    }