如何找到多个向量都为零的索引

问题描述 投票:0回答:1

初学者 pySpark 问题在这里:

如何找到所有向量都为零的索引?

经过一系列转换后,我有一个 spark df,行数约为 2.5M,tfidf 稀疏向量的长度约为 262K。我想执行 PCA 降维以使该数据更易于管理多层感知器模型拟合,但 pyspark 的 PCA 限制为最多 65,535 列。

+--------------------+
|      tfidf_features| df.count() >>> 2.5M 
+--------------------+ Example Vector:
|(262144,[1,37,75,...| SparseVector(262144, {7858: 1.7047, 12326: 1.2993, 15207: 0.0953, 
|(262144,[0],[0.12...|      24112: 0.452, 40184: 1.7047,...255115: 1.2993, 255507: 1.2993})
|(262144,[0],[0.12...|
|(262144,[0],[0.12...|
|(262144,[0,6,22,3...|
+--------------------+

因此,我想删除稀疏 tfidf 向量的索引或列,这些索引或列对于所有 ~2.5M 文档(行)都为零。这有望让我达到 PCA 的最大值 65,535。

我的计划是创建一个 udf,它 (1) 将稀疏向量转换为密集向量(或 np 数组)(2)搜索所有向量以找到所有向量都为零的索引(3)删除索引。但是,我正在为第二部分而苦苦挣扎(找到所有向量都为零的索引)。这是我到目前为止的位置,但我认为我的攻击计划太耗时而且不是很 pythonic(尤其是对于这么大的数据集):

import numpy as np    
row_count = df.count()
def find_zero_indicies(df):
     vectors = df.select('tfidf_features').take(row_count)[0]
     zero_indices = []
     to_delete = []
     for vec in vectors:
          vec = vec.toArray()
          for value in vec:
               if value.nonzero():
                    zero_indices.append(vec.index(value))
     for value in zero_indices:
          if zero_inices.count(value) == row_count:
               to_delete.append(value)
return to_delete

任何建议或帮助表示赞赏!

python numpy apache-spark pyspark sparse-matrix
1个回答
5
投票

如果有的话,找到应该保留的索引更有意义:

from pyspark.ml.linalg import DenseVector, SparseVector
from pyspark.sql.functions import explode, udf
from operator import itemgetter

@udf("array<integer>")
def indices(v):
    if isinstance(v, DenseVector):
        return [i for i in range(len(v))]
    if isinstance(v, SparseVector):
        return v.indices.tolist()
    return []

indices_list = (df
    .select(explode(indices("tfidf_features")))
    .distinct()
    .rdd.map(itemgetter(0))
    .collect())

并使用

VectorSlicer

from pyspark.ml.feature import VectorSlicer

slicer = VectorSlicer(
    inputCol="tfidf_features",
    outputCol="tfidf_features_subset", indices=indices_list)

slicer.transform(df)

但是在实践中,我建议使用固定大小的向量,或者使用

HashingTF
:

HashingTF(inputCol="words", outputCol="tfidf_features", numFeatures=65535)

CountVectorizer

CountVectorizer(inputCol="words", outputCol="vectorizer_features", 
    vocabSize=65535)

在这两种情况下,您都可以将其与

StopWordsRemover
结合使用。

© www.soinside.com 2019 - 2024. All rights reserved.