首页 > 解决方案 > svd 性能 pyspark 与 scipy

问题描述

使用 pyspark 计算 SVD:

rdd = MLUtils.convertVectorColumnsFromML(df.select("ID", "TF_IDF")).rdd
index_mat = IndexedRowMatrix(rdd)

print('index_mat rows = {}'.format(index_mat.numRows()))
print('index_mat columns = {}'.format(index_mat.numCols()))

svd = index_mat.computeSVD(k=100, computeU=True)

输出:

index_mat 行 = 2000

index_mat 列 = 6000

sparkdf有 100 个分区,我正在用 20 个执行程序运行这项工作。

需要一个多小时。虽然使用 scipy 的类似代码在 1 分钟内运行。

from scipy.sparse.linalg import svds

u, s, vt = svds(tfidf_sparse, k=100)

标签: apache-sparkmachine-learningscipysvd

解决方案


对于小型数据集,像 Spark 这样的分布式系统有一个缺点。当您要处理的数据不适合单台机器的内存时,它们就开始有用了。

以下是 spark 比 scipy 慢的其他潜在原因的不完整列表:

  1. 首先是因为网络通信时间:

    对于适合单个机器内存的小型数据集,使用单个节点的 pandas、numpy 和 scipy 等工具将花费更少的时间移动数据并专注于实际计算。而您在 spark 中使用的 20 个执行程序将不得不花费更多时间通过网络移动数据。因此,对于分布式系统,网络速度、带宽和拥塞程度等其他因素都会影响性能。

  2. 与使用最佳设置安装 spark 相比,使用最佳设置安装 scipy 更容易:

    与为 spark 安装相同的依赖项相比,使用 BLAS 安装/配置 Scipy 更容易:一组加速的线性代数例程。例如,如果您通过 conda(来自anaconda发行版)使用 Scipy,它已经带有配置良好的 blas 依赖项。然而,Spark 默认使用线性代数运算的 vanilla java 实现,并要求您自己(在每个执行程序上)配置 blas 以获得更好的性能(检查mllib 依赖项以获取更多信息)。您的系统可能没有安装 BLAS 依赖项。

  3. 您正在使用旧的基于 RDD 的机器学习库:mllib API。

    您应该使用更新的 ML API 版本。几个 Stack-overflow 线程解释了为什么应该迁移到更新的 API。您可以查看这个以了解总体思路:Spark ML 和 MLLIB 包之间有什么区别

    通常,您应该使用 pyspark.ml 中的 API 而不是 pypsark.mllib(如果您使用的是 scala,则应使用 org.apache.spark.ml 而不是 org.apache.spark.mllib)。因此,请尝试使用ml API重写您的代码并再次进行基准测试。

更不用说 spark 在每次执行开始时等待资源,这可能会根据集群的容量减慢作业的整体时间。

如果您需要更多详细信息,请提供可重复的示例,包括数据和有关数据集大小的更多信息(观察次数和大小(以 GB 为单位))。


推荐阅读