Определение границы слова из текста
У меня есть эта проблема с идентификацией границы слова. Я удалил всю разметку из документа википедии, теперь я хочу получить список объектов (значимые термины). Я планирую взять биграммы, триграммы документа и проверить, существует ли он в словаре (wordnet). Есть ли лучший способ добиться этого.
Ниже приведен пример текста. Я хочу идентифицировать сущности (показаны в двойных кавычках)
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"
Спасибо бала
3 ответа
Я думаю, что то, о чем вы говорите, все еще является предметом бурных исследований, а не простым вопросом применения хорошо зарекомендовавших себя алгоритмов.
Я не могу дать вам простой ответ "сделай это", но вот несколько советов в моей голове:
- Я думаю, что использование WordNet может сработать (хотя я не уверен, откуда биграммы / триграммы в него входят), но вы должны рассматривать поиск WordNet как часть гибридной системы, а не как первоочередную задачу для определения именованных объектов.
- затем начните с применения некоторых простых критериев здравого смысла (последовательности заглавных слов; попробуйте и в них поместите часто встречающиеся в нижнем регистре функциональные слова, такие как 'of'; последовательности, состоящие из "известного названия" плюс слова (заглавных букв));
- ищите последовательности слов, которые по статистике вы не ожидаете, что случайно окажетесь рядом друг с другом в качестве кандидатов на сущности;
- Вы можете встроить динамический поиск в Интернете? (ваша система выделяет заглавную последовательность "IBM" и видит, находит ли она, например, запись в википедии с текстовым шаблоном "IBM is ... [organization|company|...]".
- Посмотрите, есть ли что-нибудь здесь и в литературе по "извлечению информации" в целом, дает вам некоторые идеи: http://www-nlpir.nist.gov/related_projects/muc/proceedings/muc_7_toc.html
Правда в том, что когда вы смотрите на то, какая литература существует, не похоже, что люди используют ужасно сложные, устоявшиеся алгоритмы. Поэтому я думаю, что есть много места, чтобы посмотреть на ваши данные, изучить и посмотреть, что вы можете придумать... Удачи!
Если я правильно понимаю, вы ищете для извлечения подстрок, разделенных двойными кавычками ("). Вы можете использовать группы захвата в регулярных выражениях:
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
}
ИЛИ напишите "парсер" с функциями String:
int startFrom = text.indexOf('"'); // The index-position of the first " character
int nextQuote = text.indexOf('"', startFrom+1); // The index-position of the next " character
int count = 0; // An index for the array of matches
while (startFrom > -1) { // Keep looping as long as there is another " character (if there isn't, or if it's index is negative, the value of startFrom will be less-than-or-equal-to -1)
entities[count++] = text.substring(startFrom+1, nextQuote); // Retrieve the substring and add it to the array
startFrom = text.indexOf('"', nextQuote+1); // Find the next " character after nextQuote
nextQuote = text.indexOf('"', startFrom+1); // Find the next " character after that
}
В обоих случаях образец текста жестко закодирован для примера, и предполагается, что присутствует одна и та же переменная (переменная String с именем text
).
Если вы хотите проверить содержимое entities
массив:
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
}
Обратите внимание, что если numQuotes
бывает 0
этот метод все еще возвращает true
(потому что 0 по модулю любое число равно 0, так (count % 2 == 0)
будет true
) хотя вы не захотите продолжать синтаксический анализ, если в нем нет символов, поэтому вам нужно где-то проверить это условие.
Надеюсь это поможет!
Кто-то еще задал похожий вопрос о том, как найти "интересные" слова в корпусе текста. Вы должны прочитать ответы. В частности, ответ Боло указывает на интересную статью, которая использует плотность появления слова, чтобы решить, насколько это важно - используя наблюдение, что, когда текст говорит о чем-то, он обычно ссылается на это что-то довольно часто. Эта статья интересна тем, что метод не требует предварительных знаний о тексте, который обрабатывается (например, вам не нужен словарь, нацеленный на конкретную лексику).
В статье предлагается два алгоритма.
Первый алгоритм оценивает отдельные слова (такие как "Федерация" или "Трек" и т. Д.) В соответствии с их измеренной важностью. Это просто реализовать, и я мог бы даже представить (не очень элегантную) реализацию в Python.
Второй алгоритм более интересен, так как он извлекает существительные фразы (такие как "Звездный путь" и т. Д.), Полностью игнорируя пробелы и используя древовидную структуру, чтобы решить, как разделять существительные фразы. Результаты этого алгоритма применительно к основному тексту Дарвина об эволюции очень впечатляют. Тем не менее, я признаю, что реализация этого алгоритма потребовала бы немного больше внимания, так как описание, данное в статье, довольно неуловимо, и что еще авторы, кажется, немного трудно отследить. Тем не менее, я не тратил много времени, так что, возможно, вам повезет больше.