我正在尝试构建一个应用程序来索引 Elasticsearch 中的一堆文档,并通过布尔查询将文档检索到 Spark 中以进行机器学习。我正在尝试通过 Python 通过 pySpark 和 elasticsearch-py 来完成这一切。
对于机器学习部分,我需要使用每个文本文档中的标记来创建特征。为此,我需要处理/分析每个文档的典型内容,例如小写、词干、删除停用词等。
所以基本上我需要"Quickly the brown fox is getting away."
变成类似"quick brown fox get away"
or的东西["quick", "brown", "fox", "get", "away"]
。我知道您可以通过各种 Python 包和函数轻松地做到这一点,但我想使用 Elasticsearch 分析器来做到这一点。此外,我需要以对大数据集有效的方式进行操作。
基本上,我想直接从 Elasticsearch 中提取文本的分析版本或分析的标记,并在 Spark 框架中以有效的方式进行。作为相对的 ES 新手,我想出了如何通过调整 elasticsearch-hadoop 插件直接从 Spark 查询文档:
http://blog.qbox.io/elasticsearch-in-apache-spark-python
基本上是这样的:
read_conf = {
'es.nodes': 'localhost',
'es.port': '9200',
'es.resource': index_name + '/' + index_type,
'es.query': '{ "query" : { "match_all" : {} }}',
}
es_rdd = sc.newAPIHadoopRDD(
inputFormatClass = 'org.elasticsearch.hadoop.mr.EsInputFormat',
keyClass = 'org.apache.hadoop.io.NullWritable',
valueClass = 'org.elasticsearch.hadoop.mr.LinkedMapWritable',
conf = read_conf)
此代码将或多或少地从 ES 检索文本的未分析原始存储版本。我还没有弄清楚如何以有效的方式查询分析的文本/标记。到目前为止,我已经想出了两种可能的方法:
- 将 elasticsearch-py 提供的 es.termvector() 函数映射到 RDD 的每条记录上,以检索分析的令牌。
- 将elasticsearch-py提供的es.indices.analyze()函数映射到RDD的每条记录上,对每条记录进行分析。
请参阅相关:Elasticsearch analyze() not compatible with Spark in Python?
据我了解,这两种方法对于大型数据集来说效率都非常低,因为它们涉及到对 RDD 中的每条记录的 ES 的 REST 调用。
因此,我的问题是
- 是否有另一种有效的方法可以从 ES 中提取分析的文本/标记,而无需为每条记录进行 REST 调用?也许是 ES 设置将分析的文本与原始文本一起存储在字段中?或者能够在查询本身中请求分析的令牌/文本,以便我可以将其包含在 elasticsearch-hadoop 配置中。
- 对于我的问题,是否有替代或更好的解决方案可以利用 Spark 的并行机器学习功能和类似 ES 的查询/存储/分析功能?