MapReduce подсчет слов, который находит конкретное слово в наборе данных - PullRequest
0 голосов
/ 21 октября 2018

Я работаю над простой программой сокращения карт, использующей набор данных Kaggle https://www.kaggle.com/datasnaek/youtube-new

Набор данных содержит 40950 записей видео с 16 переменными, такими как video_id, trending_date, title, channel_title, category_id, publish_time, теги, просмотры, лайки, антипатии, comment_count, описание и т. д.

Цель моей программы MapReduce - найти все видео, которые содержат «iPhoneX» в своем описании и имеют не менее 10 000 лайков.Окончательный вывод должен содержать только (заголовок, количество видео)

пакетное решение класса драйверов;

public class Driver extends Configured implements Tool{
    @Override
    public int run(String[] args) throws Exception{
        if(args.length != 2){
        System.out.printf("Usage: Driver <input dir> <output dir> \n");
        return -1;
        }
        Job job = new Job(getConf());
        job.setJarByClass(Driver.class);
        job.setJobName("iPhoneX");

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.setMapperClass(Mapper.class);
        job.setReducerClass(Reducer.class);

        //Specify Combiner as the combiner class

        job.setCombinerClass(Reducer.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        if(job.getCombinerClass() == null){
            throw new Exception("Combiner not set");
        }

        boolean success = job.waitForCompletion(true);
        return success ? 0 : 1; 

    }
    /* The main method calls the ToolRunner.run method,
     * which calls the options parser that interprets Hadoop terminal
     * options and puts them into a config object
     * */
    public static void main(String[] args) throws Exception{

        int exitCode = ToolRunner.run(new Configuration(), new Driver(),args);
        System.exit(exitCode);
    }
}

класс редукторов

package solution;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class Reducer extends Reducer<Text, IntWritable, Text, IntWritable>{

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

        int video_count = 0;
        for(IntWritable value : values){
            video_count += value.get();
        }
        context.write(key, new IntWritable(video_count));
    }
}

класс картографических данных

public class Mapper extends Mapper<LongWritable, Text, Text, IntWritable> {

    private Text description = new Text();
    private IntWritable likes = new IntWritable();
    @Override
    public void map(LongWritable key, Text value, Context context)

    throws IOException, InterruptedException{

        String line = value.toString();
        String str[] = line.split("\t");

        if(str.length > 3){
            description.set(str[8]);
        }

// Testing how many times the iPhoneX word is located in the data set       
//      StringTokenizer itr = new StringTokenizer(line);
//      
//      while(itr.hasMoreTokens()){
//          String token = itr.nextToken();
//          if(token.contains("iPhoneX")){
//              word.set("iPhoneX Count");
//              context.write(word, new IntWritable(1));
//          }
//      }
    }
}

1 Ответ

0 голосов
/ 21 октября 2018

Ваш код выглядит нормально, но вам нужно будет раскомментировать ту часть маппера, которая выводит какие-либо данные, однако ключ маппера должен быть просто «iPhone», и вы, вероятно, хотите маркировать описание, а не всюline

Вы также захотите извлечь количество лайков и отфильтровать только те, которые соответствуют перечисленному условию поставленной задачи.

Кстати, вам нужно как минимум 9 элементов, чтобы получитьэта позиция, а не только три, поэтому измените условие здесь

if(str.length >= 9){
    description.set(str[8]);

    likes = Integer.parseInt(str[...]);
    if (likes >= 10000) {
        // TODO: find when description string contains iPhoneX 
        context.write("IPhoneX", count);
    } 
} else {
    return; // skip line 
}

В качестве альтернативы, вместо предварительной агрегации в маппере, вы можете просто записать (токен, 1) для каждого токена, который является «iPhoneX», тогда пусть сумматор и редуктор сделают суммирование для вас

...