我使用Python创建逻辑回归,并转向mllib以获得更好的性能
我安装了Spark和PySpark。
我的数据存储在NumPy数组中,我可以轻松地将其转换为Pandas数据框。
我尝试创建一个Spark数据框来供模型使用,但创建数据框的速度太慢,而使用常规的Sklearn整体速度更快
我发现使用Arrow算法和以下配置
(‘spark.sql.execution.arrow.enabled’, ‘true’)
可以使其更快,但速度仍然太慢,甚至没有充分利用内核(我检查了我的配置,执行器和驱动程序都设置为使用多个内核,但它们并未被利用)
我尝试使用RDD而不是数据框,代码如下
d = [row.tolist() for row in encoded_data] d = [LabeledPoint(label, row) for label, row in zip(y_train, d)]rdd = spark.parallelize(d)lr.fit(rdd)
但我一直收到这个错误
AttributeError: ‘RDD’对象没有属性 ‘_jdf’
我找到了这个StackOverflow问题,涉及类似的问题,但它不适合我的情况,我的数据不是来自文本文件,而是来自NumPy数组,我可以将数据写入文件然后读取,但这在我的使用场景中没有意义。
我想找到一种更好的方法来使用来自NumPy数组的数据 – 我有两个数组 – 一个是大小为(n*m)的特征数组encoded_data,另一个是大小为(n*1)的标签数组y_train。我需要将其输入到逻辑回归中以提高我的训练时间。
数据是密集的有其原因,这些是数值特征向量,不是独热编码,我转向Spark的理由是利用本地内核,这些内核在Sklearn训练中未被利用。
谢谢。
回答:
错误的来源是使用了不兼容的API。
Spark提供了两个ML API:
- 旧的
pyspark.mllib
,设计用于与RDD
一起工作 - 新的
pyspark.ml
,设计用于与DataFrame
一起工作
您的lr
对象显然属于后者,而parallelize
是一个RDD
。请参见Spark ML和MLLIB包有什么区别,如评论中所建议。
此外,您的整个前提是错误的。如果您的模型可以轻松地在本地数据上进行训练,在单个节点上使用标准Python库,那么Spark ML在这里没有任何胜算。Spark的全部意义在于将您的过程扩展到大型数据集,而不是减少延迟。
请参见为什么Apache-Spark – Python在本地与Pandas相比速度如此慢?
此外,使用密集结构(我假设您指的是NumPy数组)来表示独热编码数据是非常低效的,并且通常会显著影响性能(Spark自带其Pipeline API,其中包括其他工具,提供独热编码器,生成稀疏表示)。
最后,并行化本地集合是测试和开发工具,而不是生产解决方案。