在PySpark中如何创建两个分类列的交互特征?
PySpark生成多分类列全组合交互特征的方法
问题场景
我有一个PySpark DataFrame df,包含两个多分类列:
dow:星期几,取值为1-7的整数(共7个类别)type:观测类型,取值为1-4的整数(共4个类别)
需要生成这两列的全组合交互特征(共7×4=28种可能组合),尝试过OneHotEncoder但返回稀疏向量,不清楚如何得到所有组合的特征。示例DataFrame结构如下:
| dow | type | target |
|---|---|---|
| 1 | 1 | 200 |
| 1 | 2 | 222 |
| 1 | 7 | 229 |
方法1:使用Interaction转换器(推荐)
pyspark.ml.feature.Interaction是Spark内置工具,专门用于生成多列特征的交互项,可基于独热编码后的向量直接生成所有交叉组合特征。步骤如下:
- 对两个分类列分别执行字符串索引+独热编码(需设置
dropLast=False保留所有类别) - 用
VectorAssembler合并两个独热向量为输入向量 - 用
Interaction生成交互特征,每个组合对应一个特征位
代码示例:
from pyspark.ml.feature import StringIndexer, OneHotEncoder, VectorAssembler, Interaction from pyspark.ml import Pipeline # 1. 字符串索引(确保分类列的类别映射稳定) indexer_dow = StringIndexer(inputCol="dow", outputCol="dow_idx") indexer_type = StringIndexer(inputCol="type", outputCol="type_idx") # 2. 独热编码,dropLast=False保留全部类别 encoder_dow = OneHotEncoder(inputCol="dow_idx", outputCol="dow_onehot", dropLast=False) encoder_type = OneHotEncoder(inputCol="type_idx", outputCol="type_onehot", dropLast=False) # 3. 合并两个独热向量 assembler = VectorAssembler(inputCols=["dow_onehot", "type_onehot"], outputCol="combined_vec") # 4. 生成交互特征 interaction = Interaction(inputCol="combined_vec", outputCol="interaction_features") # 组装Pipeline并执行转换 pipeline = Pipeline(stages=[indexer_dow, indexer_type, encoder_dow, encoder_type, assembler, interaction]) result_df = pipeline.fit(df).transform(df)
生成的interaction_features是长度为28的稀疏向量,匹配到的组合对应位置值为1,其余为0。
方法2:拼接分类列后独热编码
更直观的方式是将dow和type拼接成新的字符串列(每个值代表一种组合),再对该列做独热编码,直接得到28个特征:
代码示例:
from pyspark.sql.functions import concat_ws from pyspark.ml.feature import StringIndexer, OneHotEncoder # 1. 拼接两个分类列,生成组合标识列 df_with_comb = df.withColumn("dow_type_comb", concat_ws("_", "dow", "type")) # 2. 字符串索引 indexer = StringIndexer(inputCol="dow_type_comb", outputCol="comb_idx") # 3. 独热编码,dropLast=False保留全部28种组合 encoder = OneHotEncoder(inputCol="comb_idx", outputCol="interaction_features", dropLast=False) # 执行转换 result_df = encoder.fit(indexer.fit(df_with_comb).transform(df_with_comb)).transform(df_with_comb)
这种方法逻辑更易懂,适合需要明确查看组合类别的场景,生成的interaction_features同样是28维稀疏向量。
注意事项
- 两种方法都必须将
OneHotEncoder的dropLast参数设为False,否则会丢失最后一个类别,导致组合数量不足28种。 - 若原始分类列已是字符串类型,可跳过
StringIndexer直接使用OneHotEncoder(Spark 3.0+支持直接对字符串列做独热编码)。
内容的提问来源于stack exchange,提问作者Arturo Sbr
相关产品推荐
相关产品推荐

