Spark ML构建保留嵌套数组结构的features特征列方法
问题解答
VectorAssembler 本身无法生成嵌套结构的特征列。Spark MLlib 内置的 Vector 类型(稠密向量/稀疏向量)本质是一维数值结构,设计上仅支持扁平化存储,不存在嵌套向量的定义,因此无法通过调整VectorAssembler配置得到[[x1,y1],[x2,y2],[x3,y3]]格式的输出。
你可以根据后续业务场景选择以下两种实现方案:
方案1:直接生成嵌套数组类型特征列
如果后续流程不强制要求MLlib Vector类型输入,无需使用VectorAssembler,直接用内置array函数合并多列坐标数组即可,代码如下:
import org.apache.spark.sql.functions.array // 直接基于原始Seq类型列合并,无需提前转换为Vector val df_out = df.withColumn("features", array(col("f1"), col("f2"), col("f3"))) df_out.show(false)
运行后输出的features列完全匹配你需要的嵌套结构:
+----------+-----------+------------+------------------------------------+ |f1 |f2 |f3 |features | +----------+-----------+------------+------------------------------------+ |[1.0, 2.0]|[3.0, 4.0] |[5.0, 6.0] |[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]| |[7.0, 8.0]|[9.0, 10.0]|[11.0, 12.0]|[[7.0, 8.0], [9.0, 10.0], [11.0, 12.0]]| +----------+-----------+------------+------------------------------------+
方案2:适配Spark ML Pipeline的二维矩阵实现
如果后续需要对接Spark ML中要求二维数值输入的组件(如部分深度学习特征处理器、卷积相关算子),请使用MLlib原生支持的Matrix类型存储嵌套坐标,不要使用自定义嵌套Vector,可通过UDF实现转换:
import org.apache.spark.ml.linalg.Matrices import org.apache.spark.sql.functions.col // 定义UDF将3组二维坐标转换为3行2列的稠密矩阵 val coordsToMatrix = udf((f1: Seq[Double], f2: Seq[Double], f3: Seq[Double]) => { val allValues = f1 ++ f2 ++ f3 // 入参依次为:行数、列数、数值数组、是否按行优先存储 Matrices.dense(3, 2, allValues.toArray) }) val df_matrix_out = df.withColumn("features", coordsToMatrix(col("f1"), col("f2"), col("f3")))
该方案生成的Matrix类型是Spark ML官方支持的二维结构,可正常接入标准Pipeline流程,不会出现类型校验报错。
注意:不要尝试将Vector对象作为元素嵌套存入另一个Vector,Spark MLlib的Vector实现不支持非数值类型元素,强行构造会导致下游计算组件抛出类型不匹配异常。
内容的提问来源于stack exchange,提问作者durranaik
相关产品推荐
相关产品推荐

