Luk*_*uke 8 scipy tf-idf apache-spark pyspark
我有一个带有一列短句的火花数据框和一个带有分类变量的列.我想tf-idf对句子执行one-hot-encoding分类变量,然后将其输出到我的驱动程序上的稀疏矩阵,一旦它的尺寸小得多(对于scikit-learn模型).
以稀疏形式从火花中获取数据的最佳方法是什么?看起来toArray()稀疏矢量只有一种方法,它输出numpy数组.但是,文档确实说scipy稀疏数组可以用于代替spark sparse数组.
还要记住,tf_idf值实际上是一列稀疏数组.理想情况下,将所有这些功能集成到一个大型稀疏矩阵中会很不错.
use*_*411 13
一种可能的解决方案可表示如下:
将要素转换为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"))
Run Code Online (Sandbox Code Playgroud)添加行索引:
indexed_features = features.zipWithIndex()
Run Code Online (Sandbox Code Playgroud)扁平化为元组的RDD (i, j, value):
def explode(row):
vec, i = row
for j, v in zip(vec.indices, vec.values):
yield i, j, v
entries = indexed_features.flatMap(explode)
Run Code Online (Sandbox Code Playgroud)收集和重塑:
row_indices, col_indices, data = zip(*entries.collect())
Run Code Online (Sandbox Code Playgroud)计算形状:
shape = (
df.count(),
df.rdd.map(attrgetter("features")).first().size
)
Run Code Online (Sandbox Code Playgroud)创建稀疏矩阵:
from scipy.sparse import csr_matrix
mat = csr_matrix((data, (row_indices, col_indices)), shape=shape)
Run Code Online (Sandbox Code Playgroud)快速健全检查:
mat.todense()
Run Code Online (Sandbox Code Playgroud)
预期结果:
matrix([[ 1., 0., 3.],
[ 0., 4., 0.]])
Run Code Online (Sandbox Code Playgroud)另一个:
将每一行转换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)
Run Code Online (Sandbox Code Playgroud)减少vstack:
from scipy.sparse import vstack
mat = mats.reduce(lambda x, y: vstack([x, y]))
Run Code Online (Sandbox Code Playgroud)
或collect与vstack
mat = vstack(mats.collect())
Run Code Online (Sandbox Code Playgroud)