在Spark中连接稀疏向量?

roc*_*oon 4 scala apache-spark

假设你有两个稀疏矢量.举个例子:

val vec1 = Vectors.sparse(2, List(0), List(1)) // [1, 0]
val vec2 = Vectors.sparse(2, List(1), List(1)) // [0, 1]
Run Code Online (Sandbox Code Playgroud)

我想连接这两个向量,以便结果相当于:

val vec3 = Vectors.sparse(4, List(0, 2), List(1, 1)) // [1, 0, 0, 1]
Run Code Online (Sandbox Code Playgroud)

Spark有没有这样的方便方法呢?

小智 8

如果你有a中的数据DataFrame,那么VectorAssembler使用它是正确的.例如:

from pyspark.ml.feature import VectorAssembler

dataset = spark.createDataFrame(
    [(0, Vectors.sparse(10, {0: 0.6931, 5: 0.0, 7: 0.5754, 9: 0.2877}), Vectors.sparse(10, {3: 0.2877, 4: 0.6931, 5: 0.0, 6: 0.6931, 8: 0.6931}))],
["label", "userFeatures1", "userFeatures2"])

assembler = VectorAssembler(
    inputCols=["userFeatures1", "userFeatures2"],
    outputCol="features")

output = assembler.transform(dataset)
output.select("features", "label").show(truncate=False)
Run Code Online (Sandbox Code Playgroud)

你会得到以下输出:

+---------------------------------------------------------------------------+-----+
|features                                                                   |label|
+---------------------------------------------------------------------------+-----+
|(20,[0,7,9,13,14,16,18],    [0.6931,0.5754,0.2877,0.2877,0.6931,0.6931,0.6931])|0|
+---------------------------------------------------------------------------+-----+
Run Code Online (Sandbox Code Playgroud)


Alb*_*nto 3

我认为你的理解有点问题SparseVectors。因此我将对它们做一些解释,第一个参数是特征的数量| 专栏 | 数据的维度,此外List第二个参数中的每个条目都代表特征的位置,第三个参数中的值List代表该列的值,因此SparseVectors是局部敏感的,从我的角度来看,你的方法是不正确的。

如果您更加注意,您正在对具有相同维度的两个向量进行求和或组合,因此实际结果会有所不同,第一个参数告诉我们该向量只有 2 维,因此[1,0] + [0,1] => [1,1]正确的表示将是Vectors.sparse(2, [0,1], [1,1]),而不是四个维度。

另一方面,如果每个向量都有两个不同的维度,并且您试图将它们组合起来并在更高维度的空间中表示它们,比如说四个,那么您的操作可能是有效的,但是SparseVector类不提供此功能,并且你必须编写一个函数来做到这一点,比如(有点命令式,但我接受建议):

def combine(v1:SparseVector, v2:SparseVector):SparseVector = {
    val size = v1.size + v2.size
    val maxIndex = v1.size
    val indices = v1.indices ++ v2.indices.map(e => e + maxIndex)
    val values = v1.values ++ v2.values
    new SparseVector(size, indices, values)
}
Run Code Online (Sandbox Code Playgroud)