pyspark计算稀疏向量的距离矩阵

时间:2017-08-08 12:32:30

标签: python apache-spark scipy pyspark sparse-matrix

我试图建立一种通用的方法来计算许多稀疏向量的距离矩阵(100k向量,长度为250k)。在我的例子中,数据以scipy csr矩阵表示。这就是我正在做的事情:

首先,我定义了一个将csr行转换为pyspark SparseVectors的方法:

def csr_to_sparse_vector(row):
    return SparseVector(row.shape[1], sorted(row.indices), row.data)

现在我将行转换为向量并将它们保存到列表中,然后将其提供给SparkContext:

sparse_vectors = [csr_to_sparse_vector(row) for row in refs_sample]
rdd = sc.parallelize(sparse_vectors)

在下一步中,我使用笛卡尔函数构建所有对(类似于这篇文章:Pyspark calculate custom distance between all vectors in a RDD

在这个实验中,我想使用相应定义的Jaccard相似性:

def jacc_sim(pair):
    dot_product = pair[0].dot(pair[1])
    try:
        sim = dot_product / (pair[0].numNonzeros() + pair[1].numNonzeros())
    except ZeroDivisionError:
        return 0.0
    return sim

现在我应该映射函数并收集结果:

distance_matrix = rdd2.map(lambda x: jacc_sim(x)).collect()

我在一个小样本上运行此代码,两者上只有100个文档,一台本地计算机和一个包含180个节点的集群。任务需要永远,最后崩溃:https://pastebin.com/UwLUXvUZ

有什么建议可能出错吗?

此外,如果距离度量是对称的sim(x,y)== sim(y,x),我们只需要矩阵的上三角形。我找到了一篇通过过滤(Upper triangle of cartesian in spark for symmetric operations: `x*(x+1)//2` instead of `x**2`)来解决这个问题的帖子:

rdd2 = rdd.cartesian(rdd).filter(lambda x: x[0] < x[1])

但这对SparseVectors列表不起作用。

1 个答案:

答案 0 :(得分:0)

列表是否存在问题,或者SparseVectors是否包含该列表?一种想法是尝试将SparseVectors转换为DenseVectors,这是我在这里找到的一个建议(Convert Sparse Vector to Dense Vector in Pyspark)。计算结果没有什么不同,只是Spark如何处理它。