Вычисление вероятности появления всех алфавитов на карте уменьшить

Пытаюсь посчитать вероятность появления каждой буквы в файле с помощью программы Map-reduce.

Я использую следующую структуру для уменьшения карты. 1 сопоставитель для сопоставления всех символов, например ('a', 1). 1 объединитель для вычисления общего количества вхождений каждого символа. 1 редуктор для вычисления среднего.

Однако я не могу вычислить среднее значение в редукторе. Итак, я добавил фиктивный символ, который будет записан один раз всякий раз, когда новый символ отображается картографом.

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

Например, ниже приведены выходные данные объединителя.

# 10
a 2
b 2
c 2
d 4

Я пробовал с 1 редуктором, который не дает результата.

Мне особенно нужно знать логику, которая должна быть написана в редюсере.

public void reduce(Text key, Iterable<DoubleWritable> values, Context context)
        throws IOException, InterruptedException {

    int wordCount = 0;
    double total = 1;
    System.out.println("In Reducer now!");
    double avg = 0;
    total = values.iterator().next().get();

    avg = values.get() / total;
    context.write(key, new DoubleWritable(avg));
}

Приведенный выше код ничего не записывает на выходе.

Картограф

public void map(LongWritable key, Text value, Context context)
        throws IOException, InterruptedException {

    String s = value.toString();

    char[] arrayofChar = s.toCharArray();
    for (char ch : arrayofChar) {
        System.out.print(ch);
        if (Character.isLetter(ch)) {
            context.write(new Text(String.valueOf(ch)), new DoubleWritable(1));
            context.write(new Text("#"), new DoubleWritable(1));

        }
    }
}

Комбайнер

public void reduce(Text key, Iterable<DoubleWritable> values, Context context)
        throws IOException, InterruptedException {

    double total = 0;
    System.out.println("In Combiner now!");
    for (DoubleWritable value : values) {
        total += value.get();
    }
    context.write(key, new DoubleWritable(total));
}

person Aparna Bhat    schedule 28.02.2021    source источник
comment
Вы пытались запустить свой код? Вы должны предоставить больше информации об объектах, которые использовали идентификатор: переменная значений, класс DoubleWritable...   -  person Sergey Afinogenov    schedule 28.02.2021
comment
Я добавил код для Reducer, Combiner и Mapper.   -  person Aparna Bhat    schedule 28.02.2021


Ответы (1)


Чтобы убрать это, я написал отдельный потребитель:

public class Test {
    public static void main(String[] arg) throws Exception{
        String s= "aabccdaaab"; 
        Averager av = s.chars().collect(Averager::new,Averager::accept, Averager::combine);
        System.out.println(av.averages());
    }
}

class Averager implements IntConsumer  {
    private int count = 0;
    private Map<Character,Integer> data = new HashMap<>();
        
    public  Map<Character, Double>averages() {
        Map<Character, Double> result = new HashMap<>();
        for(Character c : data.keySet()) {
            double d = (double)data.get(c)/count;
            result.put(c,d);
        }
        return result;
    }
        
    public void accept(int c) { 
        Character cc = new Character((char)c);
        count++;
        if(data.containsKey(cc)) {
            int i = data.get(cc);
            i++;
            data.put(cc, i);
        } else {
            data.put(cc, 1);
        }
    }

    public void combine(Averager other) {
        for(Character c : data.keySet()) {
            if(other.data.containsKey(c)) {
                int sum = data.get(c) + other.data.get(c);
                other.data.put(c, sum);
            } else {
                other.data.put(c, data.get(c));
            }
        }
        data = other.data;
    }
}

Выход:

{a=0.5, b=0.2, c=0.2, d=0.1}
person onkar ruikar    schedule 28.02.2021
comment
Да, это решение с использованием Java Streams, однако OP, по-видимому, использует Hadoop MapReduce (имена типов соответствуют его коду). - person Piotr P. Karwasz; 28.02.2021
comment
Спасибо. Однако требуемый результат для данного входа равен {a=.2,b=.2,c=.2d=.4}. Кроме того, я пытаюсь решить вопрос с помощью MapReduce. - person Aparna Bhat; 28.02.2021
comment
Было бы здорово, если бы вы привели формулы/примеры в OP :) В моем коде я использовал ввод aabccdaaab. - person onkar ruikar; 28.02.2021
comment
Я отредактировал свой оригинальный пост сейчас. Фактический ввод я читаю из файла через класс драйвера. - person Aparna Bhat; 28.02.2021