#java #hadoop #mapreduce
#java #hadoop #mapreduce
Вопрос:
У меня есть простой вариант использования. В моем входном файле мне просто нужно рассчитать процентное распределение общего количества слов. Например, word1 присутствует 10 раз, word2 присутствует 5 раз и т.д., А Общее количество слов равно 100, Тогда мне просто нужно отобразить % word1 = 10%, % word2 = 5% и т.д. Поэтому всякий раз, когда я сталкиваюсь со словом, я просто помещаю context.write(word, 1) в map() и в reduce суммирую отдельные подсчеты. Но для вычисления процента нам требуется общее количество слов. Я также вычисляю это.
Следовательно, перед получением ключей для word1 или word2 в reduce я должен получить ключ общего количества слов для вычисления процента для каждого слова. Но при сокращении я получаю этот ключ total words после некоторых других ключей. Следовательно, я не могу вычислить процент.
Я также пытался установить это общее количество в конфигурации map, используя context.getConfiguration().SetFloat(«общее количество»,count); Но в reduce я не могу получить это значение из конфигурации. Он просто возвращает null.
Пожалуйста, добавьте любые предложения.
Спасибо..
Комментарии:
1. Вы могли бы попробовать использовать счетчик вместо установки значений в конфигурации. Для каждого слова в картографах просто увеличьте счетчик, затем получите значение в редукторах.
2. Кстати, порядок ввода ключей сортируется на основе компаратора по умолчанию. Итак, если это текст, то в лексикографическом порядке. Однако каждый ключ будет использоваться только в одном редукторе, поэтому вы не можете просто вывести общее количество слов в качестве ключа, если хотите, чтобы ваш код работал с несколькими редукторами.
Ответ №1:
Сначала вам нужно переварить ваш документ, вот так:
class WordCounter {
Map<String, Integer> totals = new HashMap<String, Integer>();
int wordCount;
void digest(String document) {
for (String word : document.split("\w ")) {
wordCount ;
Integer count = totals.get(word);
if (count == null)
totals.put(word, 1);
else
totals.put(word, count);
}
}
}
Затем вы можете выполнить второй проход по своему документу, делая то, что вам нравится, с собранной вами информацией, возможно, используя что-то вроде этого метода для каждого слова:
String decorateWithPercent(String word) {
return word " (" (totals.get(word) / wordCount) "%)";
}
Или для печати частот, что-то вроде:
void printFrequencies() {
for (Map.Entry<String, Integer> wordCount : totals.entrySet()) {
System.out.println(wordCount.getKey() " " wordCount.getValue());
}
}
Комментарии:
1. Спасибо за ваше предложение. Я хочу реализовать логику в map reduce, используя один проход, поскольку файл, который я хочу отсканировать, составляет 15 ГБ.