背景:
我正在尝试使用 MapReduce 在 Hadoop 上的 Java 中创建一个“文档项”矩阵。文档术语矩阵就像一个巨大的表格,其中每一行代表一个文档,每一列代表一个可能的单词/术语。
问题陈述:
假设我已经有一个术语索引列表(以便我知道哪个术语与哪个列号相关联),那么在每个文档中查找每个术语的索引的最佳方法是什么,以便我可以逐行构建矩阵-row(即,逐个文档)?
到目前为止,我可以想到两种方法:
方法#1:
将术语索引列表存储在 Hadoop 分布式文件系统上。每次映射器读取一个新文档以进行索引时,都会产生一个新的 MapReduce 作业——文档中每个唯一单词都有一个作业,其中每个作业都在分布式术语列表中查询其术语。这种方法听起来有点矫枉过正,因为我猜测启动新工作会产生一些开销,而且这种方法可能需要数千万个工作。另外,我不确定是否可以在另一个 MapReduce 作业中调用 MapReduce 作业。
方法#2:
将术语索引列表附加到每个文档,以便每个映射器最终得到术语索引列表的本地副本。这种方法在存储方面非常浪费(术语索引列表的副本与文档的数量一样多)。另外,我不确定如何将术语索引列表与每个文档合并——我会将它们合并到映射器还是减速器中?
问题更新 1
输入文件格式:
输入文件将是一个包含所有文档(产品评论)的 CSV(逗号分隔值)文件。文件中没有列标题,但每个评论的值按以下顺序显示:product_id、review_id、review、stars。下面是一个假的例子:
“产品 A”、“1”、“产品 A 非常非常昂贵。”、“2”</p>
“产品 G”、“2”、“很棒的产品!!”、“5”</p>
术语索引文件格式:
术语索引文件中的每一行包含以下内容:索引号、制表符和单词。每个可能的单词在索引文件中只列出一次,因此术语索引文件类似于 SQL 表的主键(单词)列表。对于特定文档中的每个单词,我的初步计划是遍历术语索引文件的每一行,直到找到该单词。然后将该单词的列号定义为与该单词关联的列/术语索引。下面是术语索引文件的示例,它是使用前面提到的两个示例产品评论构建的。
1 真棒
2 产品
3个
4 是
5 非常
6贵
输出文件格式:
我希望输出采用“矩阵市场”(MM)格式,这是压缩具有许多零的矩阵的行业标准。这是理想的格式,因为大多数评论只包含所有可能单词的一小部分,因此对于特定文档,只需要指定非零列。
MM 格式的第一行有三个制表符分隔值:文档总数、单词列总数和 MM 文件中不包括标题的总行数。在标题之后,每个附加行都包含与特定条目关联的矩阵坐标,以及条目的值,按以下顺序排列:reviewID、wordColumnID、条目(该词在评论中出现的次数)。有关 Matrix Market 格式的更多详细信息,请参阅此链接: http: //math.nist.gov/MatrixMarket/formats.html。
每个评论的 ID 将等于其在文档术语矩阵中的行索引。这样我就可以在 Matrix Market 格式中保留评论的 ID,这样我仍然可以将每条评论与其星级相关联。我的最终目标——这超出了这个问题的范围——是建立一个自然语言处理算法来根据其文本预测新评论中的星数。
使用上面的示例,最终输出文件将如下所示(我无法让 Stackoverflow 显示制表符而不是空格):
2 6 7
1 2 1
1 3 1
1 4 1
1 5 2
1 6 1
2 1 1
2 2 1