我试图在hadoop上运行mapreduce作业,读取制表符分隔文件的第五个条目(第五个条目是用户评论),然后对它们进行一些情绪分析和字数统计。
但是,正如您所知,用户评论通常包括换行符和空行。我的代码遍历每个评论的单词来查找关键字,并检查是否找到关键字。
问题是,当代码在评审中迭代时,它会给我 ArrayIndexOutofBoundsException
由于一次审阅中出现这些换行符和空行而导致的错误。
我试过使用 replaceAll("\r", " ")
以及 replaceAll("\n", " ")
无济于事。
我也试过了 if(tokenizer.countTokens() == 2){ word.set(tokenizer.nextToken());} else { }
也无济于事。下面是我的代码:
public class KWSentiment_Mapper extends Mapper<LongWritable, Text, Text, IntWritable> {
ArrayList<String> keywordsList = new ArrayList<String>();
ArrayList<String> posWordsList = new ArrayList<String>();
ArrayList<String> tokensList = new ArrayList<String>();
int e;
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
String Review = line[4].replaceAll("[\\-\\+\\\\)\\.\\(\"\\{\\$\\^:,]", "").toLowerCase();
StringTokenizer tokenizer = new StringTokenizer(Review);
while (tokenizer.hasMoreTokens()) {
// 1- first read the review line and store the tokens in an arraylist, 2-
// iterate through review to check for KW if found
// 3-check if there's PosWord near (upto +3 and -2)
// 4- setWord & context.write 5- null the review line arraylist
String CompareString = tokenizer.nextToken();
tokensList.add(CompareString);
}
{
for (int i = 0; i < tokensList.size(); i++)
{
for (int j = 0; j < keywordsList.size(); j++) {
boolean flag = false;
if (tokensList.get(i).startsWith(keywordsList.get(j)) == true) {
for (int e = Math.max(0, i - 2); e < Math.min(tokensList.size(), i + 4); e++) {
if (posWordsList.contains(tokensList.get(e))) {
word.set(keywordsList.get(j));
context.write(word, one);
flag = true;
break; // breaks out of e loop }}
}
}
}
if (flag)
break;
}
}
tokensList.clear();
}
}
预期结果如下:以发生错误的两个评审案例为例:
案例一:“漂亮宽敞!
我强烈推荐这个地方和伟大的主人。”
案例2:“一般来说,这个地方真的很安静,但我们没有被留下来的感觉。
除此之外,浴室很大,淋浴也很好,但也有问题。”
系统应该将整个评论作为一行来阅读,并遍历其中的单词。但是,它在发现换行符或空行时停止,如案例2所示。
案例1应该是这样的:“美丽而宽敞!我强烈推荐这个地方和伟大的主人。”
第二种情况应该是:“一般来说,这个地方真的很安静,但我们没有被留下来的感觉。除此之外,浴室很大,淋浴也很好,但也有问题。”
我的时间不多了,非常感谢您的帮助。
谢谢!
2条答案
按热度按时间2o7dmzc51#
所以,我希望我能理解你的意图。。。。如果我正确地阅读了上面的内容,那么传递到上面map函数中的'value'的值包含您想要解析用户评论的分隔值。如果是这样的话,我相信我们可以利用opencsv库中的转义功能,使用制表符作为分隔符而不是逗号来正确填充用户评论字段:http://opencsv.sourceforge.net
在本例中,我们从传入的输入中读取一行,并根据制表符将其解析为“columns”,然后将结果放入“nextline”数组。这将允许我们在不读取实际文件的情况下使用csvreader的转义功能,而使用传递到map函数中的文本值。
在上面粘贴的示例中,我认为即使拆分(“\n”)也是有问题的,因为用户审阅中的选项卡除了新行被视为新记录外,还拆分为结果中的两个结果。但是,这两个字符都是合法的,只要它们在引号内(因为它们应该在正确转义的文件中,并且在您的示例中也是如此)。csvreader应该处理所有这些。
vjrehmav2#
在开始时验证每一行
map
方法,让你知道line[4]
存在且不为空。至于换行符,您需要显示一些示例输入。默认情况下,mapreduce将每一行传递到
map
方法,因此如果确实希望将多行作为一条消息读取,则必须编写一个自定义的InputSplit
,或预先格式化数据,以便每次审阅的所有数据都在同一行上。