使用 MapReduce 和 InfoSphere BigInsights 对各种文档类型进行处理和内容分析(5)
 
- UID
- 1066743
|

使用 MapReduce 和 InfoSphere BigInsights 对各种文档类型进行处理和内容分析(5)
清单 18. Jaql Tika 转换的输出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ::::::::::::::
part-00000
::::::::::::::
"review1.doc"|"I do not care for the camera. "
"review10.doc"|"It was very reliable "
"review2.doc"|"The product was simply bad. "
"review3.doc"|"The user interface was simply atrocious. "
"review4.doc"|"The product interface is simply broken. "
...
::::::::::::::
part-00001
::::::::::::::
"review5.doc"|"The Windows client is simply crappy. "
"review6.doc"|"I liked the camera. It is a good product. "
"review7.doc"|"It is a phenomenal camera. "
"review8.doc"|"Just an awesome product. "
"review9.doc"|"I really liked the Camera. It is excellent. "
...
|
现在,可以使用其他工具(比如 Hive、Pig、MapReduce 或 Jaql)轻松地分析文档内容。每个映射任务都有一个部分文件。
使用 Jaql,只能从 HDFS 读取文件。通过将输入路径替换为指向(Jaql 实例的)一个本地磁盘的路径,可以从本地文件系统读取文件,并使用 write() 方法将它们复制到 HDFS 中,如 清单 19 中所示。这种方法可以在单个步骤中将文档加载到 InfoSphere BigInsights 中并进行转换。转换不是并行完成的(因为最初未并行读取数据),但如果数据量不是太高,此方法还是很方便。
如果操作受到 CPU 限制,那么您还可以使用在 MapReduce 中运行的正常读取操作。但是,此方法需要您将文件放在网络文件系统上,并该系统挂载到所有数据节点上。localRead 命令在一个本地任务中运行转换。
清单 19. 使用 Jaql 将数据加载到 HDFS 中1
2
3
| import tika(*);
localRead(tikaRead("file:///home/biadmin/Tika/CameraReviews"))
-> write(seq("/tmp/output"));
|
可以看到,这里的惟一区别是本地文件路径。Jaql 非常灵活,它可以动态地从在 MapReduce 中运行更改为本地运行模式。您可以在一个步骤中继续执行所有数据转换和分析。但是,Jaql 不会并行运行这些任务,因为本地文件系统不是并行的。请注意,在上面的示例中,输出格式被更改为 Jaql 序列文件。此方法是二进制的,而且更快,所以不需要替换原始文本中的字符。但是,不足之处在于,输出文件是人类无法理解的。此格式非常适合用作中间文件的高效、临时存储。
清单 20 中的最后一个示例展示了如何在一组二进制输入文档中运行情绪检测算法。(这里省略了为此用途创建 AQL 文本分析代码的步骤,因为已有其他综合性文章和参考资料进行了更详细的介绍。具体地讲,请参阅 developerWorks 文章 “” 和 。
清单 20. 使用 Jaql 执行文本分析1
2
3
4
5
6
7
8
9
| import tika(*);
import systemT;
read(tikaRead("/tmp/reviews"))
-> transform { label: $.path, text: $.content }
-> transform { label: $.label, sentiments:
systemT::annotateDocument( $, ["EmotiveTone"],
["file:///home/biadmin/Tika/"],
tokenizer="multilingual",
outputViews=["EmotiveTone.AllClues"])};
|
简单地讲,前几节中的命令可以读取二进制输入文档,从中提取文本内容,并使用 AQL 应用一个简单的情绪语气检测注释器。输出结果类似于 清单 21。
清单 21. Jaql 输出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| [
{
"label": "review1.doc",
"sentiments": {
"EmotiveTone.AllClues": [
{
"clueType": "dislike",
"match": "not care for"
}
],
"label": "review1.doc",
"text": "I do not care for the camera. "
}
},
{
"label": "review10.doc",
"sentiments": {
"EmotiveTone.AllClues": [
{
"clueType": "positive",
"match": "reliable"
}
],
"label": "review10.doc",
"text": "It was very reliable "
}
},
...
|
现在可以使用 Jaql 进一步聚合结果,比如按照产品统计积极和消极情绪来执行更深入的分析查询,以及直接将结果上传到数据库来执行更深入的分析查询。有关创建自己的 AQL 文件或在 Jaql 中使用它们的更多细节,请参阅 developerWorks 文章 “” 和 。
归档文件前面已经提到过,HDFS 无法高效地存储许多小文件。HDFS 中存储的每个数据块都需要 HDFS NameNode 中的少量内存(约为 100B)。因此,过量的小文件可能会增加 NameNode 上使用的内存量。因为您已经实现了一个解决方案来读取小二进制文件,并将它们转换为大文件作为输出,所以现在可以删除原始的小文件。但是,您在以后可能希望使用不同的方法重新分析二进制文件。通过使用 Hadoop Archive (HAR),可以将所选的小文件打包为更大的文件,从而减少 NameNodes 上的内存使用。它基本上等效于 Linux® TAR 格式或 Windows™ CAB 文件,但它位于 HDFS 上。
可以使用下面的模板运行 archive 命令。
清单 22. Archive 命令1
2
| hadoop archive -archiveName archive_name.har -p /path_to_input_files
/path_to_output_directory
|
第一个参数指定了输出文件名,第二个参数指定了来源目录。这个示例仅包含一个来源目录,但此工具可以接受多个目录。
在创建归档后,可以浏览内容文件。
清单 23. 列出 HAR 文件1
| hadoop fs -lsr har:///path_to_output_directory/archive_name.har
|
因为您拥有 HAR 格式的输入文件,所以现在可删除原始的小文件,以便实现此流程的用途。
一定要注意的是,HAR 文件可用作 MapReduce 的输入。但是,处理许多小文件(甚至在一个 HAR 中)仍然效率低下,因为没有可感知归档的 InputFormat 来将包含多个小文件的 HAR 文件转换为一个 MapReduce 碎片。此限制意味着只能将 HAR 文件用作一种备份方法,作为减少 NameNode 上的内存使用的一种方法,而不是分析任务的输入的理想选择。出于这个原因,在创建 HAR 备份之前,需要提取原始文件的文本内容。 |
|
|
|
|
|