每行的词袋

时间:2016-02-16 07:10:05

标签: java csv hadoop

我目前有一个巨大的csv文件。其中包含reddit帖子标题。我想为每个帖子创建一个特征向量。

假设帖子图块为"to be or not to be"且属于"some_category"。 csv文件格式如下。

"some_category1", "some title1"

"some_category2", "some title2"

"some_category1", "some title3"

我想创建一个如下的特征向量。

"some_category" : to(2) be(2) or(1) not(1).

我需要在hadoop上完成这一切。我陷入了第一步,我如何将每一行转换为一个特征向量(我觉得它类似于字数,但我如何将它应用于每一行)。

我对这个问题的初步想法是每一行的关键(即每个帖子的标题和类别)是帖子的类别,而值是标题的特征向量(即标题的字数)。

对于如何解决此问题,我们非常感谢。

2 个答案:

答案 0 :(得分:1)

回答你的第一部分: 在这篇文章中回答了在Hadoop中逐行读取csv:StackOverflow:how-to-read-first-line-in-hadoop-hdfs-file-efficiently-using-java。 只需将最后一行更改为:

final Scanner sc = new Scanner(input);
while (sc.hastNextLine()) {
    //doStuff with sc.nextLine()!
}

要创建特征向量,我会使用您提到的计数策略:

/**
* We will use Java8-Style to do that easily
* 0) Split each line by space separated (split("\\s")
* 1) Create a stream: Arrays.stream(Array)
* 2) Collect the input (.collect) and group it by every identical word (Function.identity) to the corresponding amount (Collectors.counting)
*
* @param title the right hand side after the comma
* @return a map mapping each word to its count
**/
private Map<String, Long> createFeatureVectorForTitle(String title) {
    return Arrays.stream(title.split("\\s").collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}

将每个类别键入创建的特征向量的想法听起来是合法的。虽然我对Hadoop不太熟悉,但也许有人可以指出更好的解决方案。

答案 1 :(得分:0)

我使用两个map reduce函数解决了这个问题,并添加了索引以使每一行都是唯一的进行处理。

1, "some_category1", "some title1"

2, "some_category2", "some title2"

3, "some_category1", "some title3"

第一张地图的输出减少

"1, some_category" to 2
"1, some_category" be 2
"1, some_category" or 3
"1, some_category" not 1

其中index和category是值的关键,即标题中的单词。

在第二张地图中,减少它的最终输出是这种格式。

"some_category" : to(2) be(2) or(1) not(1).