使用pyspark.ml的VectorAssembler为何未产生预期变化?
使用pyspark.ml的VectorAssembler为何未产生预期变化?
嘿,我完全懂你的困惑!你现在遇到的问题其实是对VectorAssembler和OneHotEncoder的默认行为理解不到位导致的~
先帮你拆解下原因:
OneHotEncoder默认输出的是稀疏向量(就是你看到的(6,[2],[1.0])这种格式,目的是节省内存空间)VectorAssembler的核心作用是把多个特征列(比如数值列、向量列)合并成一个统一的特征向量,但你只传入了一个向量列,所以它根本没做任何转换,只是把这个稀疏向量原样放到features列里,自然和ohe_ptype看起来一模一样。
那怎么得到你想要的稠密向量呢?给你两个简单可行的办法:
方法一:让OneHotEncoder直接输出稠密向量
这是最直接高效的方式,修改你的OneHotEncoder初始化代码,加上outputVectorType="dense"参数就行:
ohe = OneHotEncoder(inputCol='index_ptype', outputCol='ohe_ptype', handleInvalid="keep", outputVectorType="dense")
这样ohe_ptype列输出的就是[0.0,0.0,1.0,0.0,0.0,0.0]这种稠密格式,后续再用VectorAssembler处理,features列就会和你预期的完全一致。
方法二:把已有的稀疏向量转成稠密向量
如果你不想修改OneHotEncoder的原有设置,也可以通过自定义UDF把稀疏向量转换为稠密向量,代码示例如下:
from pyspark.sql.functions import udf from pyspark.ml.linalg import Vector, DenseVector # 定义转换UDF sparse_to_dense = udf(lambda v: DenseVector(v.toArray()), Vector()) # 生成稠密向量列 ohe_df_dense = ohe_df.withColumn("dense_ohe", sparse_to_dense("ohe_ptype")) # 再用VectorAssembler处理稠密列 assembler = VectorAssembler(inputCols=['dense_ohe'], outputCol="features") result_df_dense = assembler.transform(ohe_df_dense)
不过这种方法多了一步转换操作,整体效率不如第一种方法。
总结一下:VectorAssembler本身不负责稀疏向量到稠密向量的转换,它只是做特征合并工作。要得到稠密向量,要么让上游的OneHotEncoder直接输出,要么额外增加一步转换逻辑~
备注:内容来源于stack exchange,提问作者Jonathan Roy
相关产品推荐
相关产品推荐

