多观测行分类:长表转宽表是否始终高效?求替代方案
交易级分类预测的数据集预处理方案探讨
一、pivot_table转宽表并非始终最优
当产品种类繁多、交易包含的产品组合复杂时,这种方法会生成高维稀疏特征矩阵,带来明显弊端:
- 内存占用急剧膨胀,尤其是唯一产品值数量大时,宽表列数会呈指数级增长
- 稀疏特征会降低逻辑回归等线性模型的训练效率,甚至容易引发过拟合
- 仅能实现简单的数值堆叠,无法捕捉产品之间的交互关联信息
二、高效的替代预处理方案
1. 聚合统计特征(最实用的基础方案)
对每个交易分组,计算数值型字段的核心统计量,同时对产品类别做频次统计。既保留交易级的整体信息,又不会产生过多冗余列。
示例代码:
import pandas as pd df = pd.DataFrame({'deal': ['deal1', 'deal1', 'deal2', 'deal2', 'deal3', 'deal3'], 'product': ['prd_1', 'prd_2', 'prd_1', 'prd_2', 'prd_1', 'prd_2'], 'Quantity': [2, 1, 5, 3, 6, 7], 'Total Price': [10, 7, 25, 24, 30, 56], 'Result': ['Won', 'Won', 'Lost','Lost', 'Won', 'Won']}) # 按交易聚合生成统计特征 agg_df = df.groupby('deal').agg( total_quantity=('Quantity', 'sum'), avg_quantity=('Quantity', 'mean'), max_single_price=('Total Price', 'max'), total_revenue=('Total Price', 'sum'), unique_product_count=('product', 'nunique'), prd_1_purchase_count=('product', lambda x: (x == 'prd_1').sum()), deal_result=('Result', 'first') ).reset_index() print(agg_df)
2. 嵌入编码(适配类别特征极多的场景)
如果产品类别数量极大,可以用Word2Vec、FastText等工具,或模型内置的嵌入层(如TensorFlow/PyTorch中的Embedding层),将每个交易的产品序列转化为低维稠密向量。这种方法既能捕捉产品间的关联关系,又能避免高维稀疏问题。
核心步骤:
- 提取每个交易对应的产品列表:
deal_product_sequences = df.groupby('deal')['product'].apply(list).reset_index() - 用产品序列训练嵌入模型,对每个交易的产品向量做平均/求和,得到交易级的稠密特征
- 结合数值统计特征共同输入模型
3. 目标编码(挖掘类别特征的预测价值)
针对产品类别,用该类别对应的交易标签(Result)的统计量进行编码,比如某产品对应的交易胜率,再对每个交易内的产品编码做聚合(均值、总和等)。这种方法能将类别特征转化为有预测意义的数值特征,且维度极低。
示例代码:
# 计算每个产品对应的交易胜率 product_win_rate = df.groupby('product')['Result'].apply(lambda x: (x == 'Won').mean()).reset_index(name='win_rate') # 合并编码后按交易聚合 df_encoded = df.merge(product_win_rate, on='product') agg_target_encoded = df_encoded.groupby('deal').agg( total_quantity=('Quantity', 'sum'), avg_product_win_rate=('win_rate', 'mean'), deal_result=('Result', 'first') ).reset_index() print(agg_target_encoded)
4. 使用支持序列输入的模型
如果不想做复杂的特征工程,可以直接选用支持序列数据输入的模型,比如LSTM、Transformer,或是梯度提升模型的序列扩展(如LightGBM的多值类别处理、XGBoost的categorical_feature参数)。直接将每个交易的产品序列和数值特征作为输入,让模型自动学习特征表示。
内容的提问来源于stack exchange,提问作者Salih
相关产品推荐
相关产品推荐

