【问题标题】:pyspark: sparse vectors to scipy sparse matrixpyspark:稀疏向量到 scipy 稀疏矩阵
【发布时间】:2017-03-26 06:00:51
【问题描述】:

我有一个包含一列短句和一列包含分类变量的 spark 数据框。我想在句子上执行tf-idf,在分类变量上执行one-hot-encoding,然后在它的大小小得多(对于scikit-learn模型)时将其输出到我的驱动程序上的稀疏矩阵。

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

还要记住,tf_idf 值实际上是一列稀疏数组。理想情况下,将所有这些特征整合到一个大型稀疏矩阵中会很好。

【问题讨论】:

    标签: apache-spark scipy pyspark tf-idf


    【解决方案1】:

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

    • 将特征转换为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]))
      

      或collect和vstack

      mat = vstack(mats.collect())
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 2013-11-13
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多