Стоп слова и stemmer в Java - PullRequest
4 голосов
/ 25 мая 2011

Я подумываю о том, чтобы добавить в мою программу-подобие стоп-слова, а затем использовать стеммер (выбор портера 1 или 2 зависит от того, что проще всего реализовать)

Мне было интересно, так как я читаю свой текст из файлов как целые строки и сохраняю их как длинную строку, так что, если я получу две строки, например.

String one = "I decided buy something from the shop.";
String two = "Nevertheless I decidedly bought something from a shop.";

Теперь, когда я получил эти строки

Сдерживание: Могу ли я просто использовать алгоритмы Stemermer непосредственно на нем, сохранить его как String, а затем продолжить работу над сходством, как я делал до реализации Steammer в программе, например, запустив one.stem (); Такие вещи?

Стоп слово: Как это работает? o.o Я просто использую; one.replaceall («Я», «»); или есть какой-то конкретный способ использовать для этого процесса? Я хочу продолжать работать со строкой и получить строку, прежде чем использовать алгоритмы подобия для нее, чтобы получить сходство. Вики мало что говорит.

Надеюсь, ты поможешь мне! Благодарю.

Редактировать: Это для школьного проекта, в котором я пишу статью о сходстве между различными алгоритмами, поэтому я не думаю, что мне разрешено использовать lucene или другие библиотеки, которые работают для меня. Кроме того, я хотел бы попытаться понять, как это работает, прежде чем я начну использовать библиотеки, такие как Lucene и co. Надеюсь, это не слишком беспокоит ^^

Ответы [ 3 ]

11 голосов
/ 25 мая 2011

Если вы не реализуете это по академическим причинам, вам следует рассмотреть возможность использования библиотеки Lucene .В любом случае это может быть полезно для справки.У него есть классы для токенизации, фильтрации стоп-слов, прохождения и сходства.Вот краткий пример использования Lucene 3.0 для удаления стоп-слов и ввода входной строки:

public static String removeStopWordsAndStem(String input) throws IOException {
    Set<String> stopWords = new HashSet<String>();
    stopWords.add("a");
    stopWords.add("I");
    stopWords.add("the");

    TokenStream tokenStream = new StandardTokenizer(
            Version.LUCENE_30, new StringReader(input));
    tokenStream = new StopFilter(true, tokenStream, stopWords);
    tokenStream = new PorterStemFilter(tokenStream);

    StringBuilder sb = new StringBuilder();
    TermAttribute termAttr = tokenStream.getAttribute(TermAttribute.class);
    while (tokenStream.incrementToken()) {
        if (sb.length() > 0) {
            sb.append(" ");
        }
        sb.append(termAttr.term());
    }
    return sb.toString();
}

Который, если он используется в ваших строках, как это:

public static void main(String[] args) throws IOException {
    String one = "I decided buy something from the shop.";
    String two = "Nevertheless I decidedly bought something from a shop.";
    System.out.println(removeStopWordsAndStem(one));
    System.out.println(removeStopWordsAndStem(two));
}

Получает этот вывод:

decid bui someth from shop
Nevertheless decidedli bought someth from shop
0 голосов
/ 25 мая 2011

Вам не нужно иметь дело со всем текстом. Просто разделите его, примените фильтр стоп-слов и алгоритм стволовых символов, затем снова соберите строку, используя StringBuilder:

StrinBuilder builder = new StringBuilder(text.length());
String[] words = text.split("\\s+");
for (String word : words) {
    if (stopwordFilter.check(word)) { // Apply stopword filter.
        word = stemmer.stem(word); // Apply stemming algorithm.
        builder.append(word);
    }
}
text = builder.toString();
0 голосов
/ 25 мая 2011

Да, вы можете обернуть любой стеммер, чтобы вы могли написать что-то вроде

String stemmedString = stemmer.stemAndRemoveStopwords(inputString, stopWordList);

Внутренне ваш ствол AndRemoveStopwords будет

  • Поместите все стоп-слова в карту для быстрого ознакомления
  • инициализировать пустой StringBuilder для хранения выходной строки
  • перебрать все слова во входной строке и для каждого слова
    • искать его в stopWordList; если найдено, переходите к началу цикла
    • в противном случае обведите его, используя предпочитаемый стеммер, и добавьте его к выходной строке
  • вернуть строку вывода
...