gpt4 book ai didi

apache-spark - 在大型记录上,Spark StringIndexer.fit非常慢

转载 作者:行者123 更新时间:2023-12-04 04:28:33 34 4
gpt4 key购买 nike

我有格式化为以下示例的大数据记录:

// +---+------+------+
// |cid|itemId|bought|
// +---+------+------+
// |abc| 123| true|
// |abc| 345| true|
// |abc| 567| true|
// |def| 123| true|
// |def| 345| true|
// |def| 567| true|
// |def| 789| false|
// +---+------+------+
ciditemId是字符串。

有965,964,223条记录。

我正在尝试使用 cidStringIndexer转换为整数,如下所示:
dataset.repartition(50)
val cidIndexer = new StringIndexer().setInputCol("cid").setOutputCol("cidIndex")
val cidIndexedMatrix = cidIndexer.fit(dataset).transform(dataset)

但是这些代码行非常慢(大约需要30分钟)。问题在于它是如此之大,以至于我在那之后再也无能为力了。

我正在使用具有2个节点(61 GB内存)的R4 2XLarge集群的Amazon EMR集群。

有什么可以做得更好的性能改进吗?任何帮助都感激不尽。

最佳答案

如果列的基数很高,则这是预期的行为。作为训练过程的一部分,StringIndexer收集所有标签,并创建标签-索引映射(使用Spark的o.a.s.util.collection.OpenHashMap)。

在最坏的情况下,此过程需要O(N)内存,并且在计算和内存上都很耗时。

如果列的基数很高,并且其内容将用作功能,则最好应用 FeatureHasher (Spark 2.3或更高版本)。

import org.apache.spark.ml.feature.FeatureHasher

val hasher = new FeatureHasher()
.setInputCols("cid")
.setOutputCols("cid_hash_vec")
hasher.transform(dataset)

它不能保证唯一性,并且不可逆,但是对于许多应用程序来说已经足够好了,并且不需要调整过程。

对于不会用作功能的列,您还可以使用 hash函数:

import org.apache.spark.sql.functions.hash

dataset.withColumn("cid_hash", hash($"cid"))

关于apache-spark - 在大型记录上,Spark StringIndexer.fit非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51485569/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com