Нормализация слов с помощью RDD

Может быть, этот вопрос немного странный... Но я попробую его задать.

Все, кто писал приложения с использованием Lucene API, видели что-то подобное:

public static String removeStopWordsAndGetNorm(String text, String[] stopWords, Normalizer normalizer) throws IOException
{
    TokenStream tokenStream = new ClassicTokenizer(Version.LUCENE_44, new StringReader(text));
    tokenStream = new StopFilter(Version.LUCENE_44, tokenStream, StopFilter.makeStopSet(Version.LUCENE_44, stopWords, true));
    tokenStream = new LowerCaseFilter(Version.LUCENE_44, tokenStream);
    tokenStream = new StandardFilter(Version.LUCENE_44, tokenStream);
    tokenStream.reset();
    String result = "";
    while (tokenStream.incrementToken()) 
    {
        CharTermAttribute token = tokenStream.getAttribute(CharTermAttribute.class);
        try
        {
            //normalizer.getNormalForm(...) - stemmer or lemmatizer
            result += normalizer.getNormalForm(token.toString()) + " ";
        }
        catch(Exception e)
        {
            //if something went wrong
        }
    }
    return result;
}

Можно ли переписать нормализацию слов с помощью RDD? Может быть у кого-то есть пример такого преобразования, или может указать веб-ресурс об этом?

Благодарю вас.


person dimson    schedule 15.11.2014    source источник


Ответы (1)


Я недавно использовал подобный пример для разговора. Он показывает, как удалить стоп-слова. У него нет фазы нормализации, но если этот normalizer.getNormalForm исходит из библиотеки, которую можно повторно использовать, его должно быть легко интегрировать.

Этот код может быть отправной точкой:

// source text
val rdd = sc.textFile(...)  
// stop words src
val stopWordsRdd = sc.textFile(...) 
// bring stop words to the driver to broadcast => more efficient than rdd.subtract(stopWordsRdd)
val stopWords = stopWordsRdd.collect.toSet
val stopWordsBroadcast = sc.broadcast(stopWords)
val words = rdd.flatMap(line => line.split("\\W").map(_.toLowerCase))
val cleaned = words.mapPartitions{iterator => 
    val stopWordsSet = stopWordsBroadcast.value
    iterator.filter(elem => !stopWordsSet.contains(elem))
    }
// plug the normalizer function here
val normalized = cleaned.map(normalForm(_)) 

Примечание. Это с точки зрения задания Spark. Я не знаком с Lucene.

person maasg    schedule 15.11.2014
comment
Спасибо, чувак! Попробую использовать и сообщу о результатах! - person dimson; 15.11.2014
comment
Мужчина! Нужен совет... Как Вы считаете - какой подход эффективнее - взять документы и разбросать их по узлам, затем токенизировать и нормализовать слова каждого документа, либо последовательно взять каждый документ, токенизировать его и нормализовать слова, разбросав их по узлам , где каждый узел будет иметь копию функции нормализатора? Спасибо! - person dimson; 23.11.2014