如何让hadoop映射器读取整个句子

时间:2016-03-15 01:21:43

标签: hadoop mapreduce

我试图在mapreduce项目中一次一个句子地为我的mapper提供一些文本分析。这段文字看起来像是:

  

尼古拉斯惊讶地看着她的脸。这是他的脸   投射到骨骺软骨。这种安排有利于   在阅读的整个过程中,凝视着他细腻的手指   边疆。    说服不可接受的对抗迅速付出了笑话   医院。这一个和另一个可以作为一种消遣。但那是什么   首席官员。

然而hadoops fileinputformat读取以下内容:

input

如何编写hadoop的inputformat来读取由“。”提交的整个句子。 ?我尝试使用键值inputformat但hadoop似乎总是剪切一个句子和一个断裂线。

3 个答案:

答案 0 :(得分:0)

您可以使用TextInputFormat并在配置中设置textinputformat.record.delimiter属性。

conf.set("textinputformat.record.delimiter", ".");

// EDIT

以下代码使用上面的属性提供您想要的输出:

package dotdelimiter;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class App extends Configured implements Tool {
    public static class SimpleMapper
            extends Mapper<LongWritable, Text, NullWritable, Text> {
        @Override
        protected void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {
            String val = "START\n" + value.toString() + "\nEND";
            context.write(NullWritable.get(), new Text(val));
        }
    }

    public static void main(String[] args) {
        int result = 1;
        try {
            result = ToolRunner.run(new App(), args);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.exit(result);
        }
    }


    public int run(String[] args) throws Exception {
        Job job = Job.getInstance(getConf(), "Dotdelimiter Job");
        job.setJarByClass(getClass());

        Configuration conf = job.getConfiguration();

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

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

        job.setMapOutputKeyClass(LongWritable.class);
        job.setMapOutputValueClass(Text.class);

        job.setMapperClass(SimpleMapper.class);
        job.setNumReduceTasks(0);

        conf.set("textinputformat.record.delimiter", ".");

        return job.waitForCompletion(true) ? 0 : 1;
    }
}

输出:

  

START

     

尼古拉斯惊讶地看着她的脸

     

END

     

START

     

这是他对骨骺软骨投射的那张脸

     

END

     

START

     

这种安排有利于在整个阅读期间,凝视着他精致的手指边界

     

END

     

START

     说服不可接受的对抗迅速付出笑话即时医院

     

END

     

START

     

这一个可以作为消遣

     

END

     

START

     

但主要官员是什么

     

END

答案 1 :(得分:0)

您可以创建自定义输入格式来读取由“。”分隔的句子。

为此你需要创建一个RecordReader,一个类让我们说MyValue实现了writeableComparable接口。

您可以使用此类在映射器中作为值类型传递。

我会尝试在我的最后实现这一点,将在未来几天更新这篇文章。了解自定义输入数据,您可以自己获得解决方案。

答案 2 :(得分:-1)

你不能使标准的hadoop输入格式成为句子边界检测器。如果你想要重要的(统计)句子破坏,你需要一个单独的地图工作来完成句子分割,然后你将句子作为单位。您可以为此目的集成任意数量的开源NLP库。如果你想要一些简单的错误缩写句子,你可以把它推到输入格式。