pyspark:scipy稀疏矩阵的稀疏向量

时间:2016-11-11 23:07:11

标签: apache-spark scipy pyspark tf-idf

我有一个带有一列短句的火花数据框,以及一个带有分类变量的列。我想对分类变量上的句子tf-idf执行one-hot-encoding,然后将其输出到我的驱动程序上的稀疏矩阵(一旦它的尺寸小得多(对于scikit-learn模型))。

以稀疏形式从火花中获取数据的最佳方法是什么?似乎稀疏向量上只有toArray()方法,它输出numpy个数组。但是,文档确实说scipy稀疏数组can be used in the place of spark sparse arrays.

请记住,tf_idf值实际上是一列稀疏数组。理想情况下,将所有这些功能集成到一个大的稀疏矩阵中会很好。

1 个答案:

答案 0 :(得分:11)

一种可能的解决方案可以表达如下:

  • 将要素转换为RDD并提取向量:

    from pyspark.ml.linalg import SparseVector
    from operator import attrgetter
    
    df = sc.parallelize([
        (SparseVector(3, [0, 2], [1.0, 3.0]), ),
        (SparseVector(3, [1], [4.0]), )
    ]).toDF(["features"])
    
    features = df.rdd.map(attrgetter("features"))
    
  • 添加行索引:

    indexed_features = features.zipWithIndex()
    
  • 展平为元组(i, j, value)的RDD:

    def explode(row):
        vec, i = row
        for j, v in zip(vec.indices, vec.values):
            yield i, j, v
    
    entries = indexed_features.flatMap(explode)
    
  • 收集并重塑:

    row_indices, col_indices, data = zip(*entries.collect())
    
  • 计算形状:

    shape = (
        df.count(),
        df.rdd.map(attrgetter("features")).first().size
    )
    
  • 创建稀疏矩阵:

    from scipy.sparse import csr_matrix
    
    mat = csr_matrix((data, (row_indices, col_indices)), shape=shape)
    
  • 快速健全检查:

    mat.todense()
    

    预期结果:

    matrix([[ 1.,  0.,  3.],
            [ 0.,  4.,  0.]])
    

另一个:

  • features的每一行转换为矩阵:

    import numpy as np
    
    def as_matrix(vec):
        data, indices = vec.values, vec.indices
        shape = 1, vec.size
        return csr_matrix((data, indices, np.array([0, vec.values.size])), shape)
    
    mats = features.map(as_matrix)
    
  • 并使用vstack缩小:

    from scipy.sparse import vstack
    
    mat = mats.reduce(lambda x, y: vstack([x, y]))
    

    collectvstack

    mat = vstack(mats.collect())