4. 多变量特征交叉:从笛卡尔积到业务逻辑

特征交叉,说白了就是把两个或多个原始特征「揉」在一起,生成新的特征。我刚开始做特征工程时,总觉得原始特征已经够用了,直到有一次做CTR预估模型,单特征AUC死活上不去。后来加了一组交叉特征,AUC直接涨了3个点。嗯,从那以后我再也不敢小看特征交叉了。

这一章我们聊聊三种主流的交叉方式:数学交叉、组合交叉、业务交叉。每种都有它的适用场景和坑。

4.1 笛卡尔积与多项式交叉

先说说最基础的——笛卡尔积交叉。假设你有两个离散特征:城市(北京、上海)和时段(早、晚)。笛卡尔积会生成4个新特征:北京_早、北京_晚、上海_早、上海_晚。说白了就是把所有可能组合都列出来。

核心思路:笛卡尔积适合离散特征,多项式交叉适合连续特征。两者本质都是「组合爆炸」,但处理的数据类型不同。

多项式交叉更常见。比如你有特征x1和x2,二阶多项式交叉会生成x1²、x2²、x1*x2。我习惯用sklearn的PolynomialFeatures来实现:

from sklearn.preprocessing import PolynomialFeatures
import numpy as np

# 原始特征:两列连续值
X = np.array([[2, 3], [1, 4], [5, 2]])

# 生成二阶多项式特征(包含偏置项)
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)

print(X_poly)
# 输出:[[2., 3., 4., 6., 9.],
#        [1., 4., 1., 4., 16.],
#        [5., 2., 25., 10., 4.]]
# 顺序:x1, x2, x1^2, x1*x2, x2^2

注意维度爆炸:degree=3时,10个原始特征会生成约286个交叉特征。degree=5时,这个数字会变成3003。我曾经在一个项目里不小心设了degree=6,结果内存直接爆了。建议先用小规模数据试跑,再决定是否上高阶交叉。

为什么多项式交叉有效?因为它能捕捉特征之间的非线性关系。线性模型学不到x1*x2这种交互效应,但多项式特征可以帮它学到。你想想看,房价预测里,面积和房间数的乘积(总居住面积)往往比单独的面积或房间数更有解释力。

4.2 特征组合:求和、求积、求差

除了笛卡尔积和多项式,还有更轻量的组合方式。我把它分成三类:

组合方式 公式 适用场景 我的经验
求和 f = a + b 总量型特征(如:总收入=工资+奖金) 适合数值量纲一致的特征
求积 f = a * b 交互效应(如:面积×单价=总价) 注意量纲放大问题
求差 f = a - b 变化量/偏差(如:实际值-预测值) 适合时序或对比场景

举个例子。我在做电商推荐时,用户有两个特征:近7天点击次数和近30天点击次数。直接丢进模型,效果一般。后来我加了一个差值特征:近30天点击 - 近7天点击,代表「更早之前的点击行为」。这个特征对冷启动用户特别有用——如果差值很大,说明用户曾经活跃但最近变冷淡了。

import pandas as pd

df = pd.DataFrame({
    'click_7d': [5, 12, 3, 20],
    'click_30d': [18, 35, 10, 45]
})

# 求差:近30天 - 近7天 = 更早之前的点击
df['click_early'] = df['click_30d'] - df['click_7d']

# 求积:点击密度(假设有曝光量特征)
# df['click_density'] = df['click_7d'] * df['exposure_7d']

# 求和:总点击
df['click_total'] = df['click_7d'] + df['click_30d']

print(df)

小技巧:求差特征对异常值很敏感。如果两个特征量级差异大,建议先做标准化再求差。我习惯用MinMaxScaler或StandardScaler预处理一下。

4.3 基于业务逻辑的交叉特征

这是我最喜欢的一类交叉特征。为什么?因为它不需要模型去「猜」特征之间的关系,而是直接把业务知识编码进特征里。说白了,就是告诉模型:「嘿,这两个特征一起看才有意义」。

最经典的例子就是点击率(CTR):

# CTR = 点击次数 / 曝光次数
df['CTR'] = df['clicks'] / (df['impressions'] + 1)  # 加1防除零

你想想看,单独看点击次数100次,能说明什么?如果曝光是1000次,CTR=10%,算不错;如果曝光是10000次,CTR=1%,那就很差了。点击率把两个维度的信息压缩成一个比率,模型学起来轻松多了。

我在项目中遇到过类似的场景——金融风控。用户有两个特征:申请金额和月收入。单独看都没问题,但组合成负债收入比 = 申请金额 / 月收入后,这个特征直接成了模型Top 3重要特征。为什么?因为银行审批贷款时,看的不是金额,而是「你还得起吗」这个比率。

常见的业务交叉特征包括:

  • 比率型:点击率、转化率、通过率、坏账率
  • 密度型:人均消费、每平米价格、每用户活跃天数
  • 占比型:某品类消费占比、某渠道来源占比
  • 增速型:环比增长率、同比增长率、周活跃度变化

避坑指南:我曾经在计算CTR时,直接用clicks/impressions,结果很多用户impressions=0,导致除零错误。后来养成了习惯,分母一律加一个极小值(比如1e-8或1)。另外,如果样本量太小(比如曝光只有几次),CTR的方差会很大,建议做平滑处理。

4.4 知识体系总览

下面这张图总结了本章的核心逻辑。三种交叉方式从数学到业务,复杂度递增,但可解释性也递增。

多变量特征交叉知识体系 数学交叉 组合交叉 业务交叉 笛卡尔积(离散) 多项式交叉(连续) 求和(总量) 求积(交互) 求差(变化) 比率型(CTR) 密度型(人均) 占比/增速型 ⚠️ 注意事项 维度爆炸 → 控制degree / 特征选择 除零错误 → 分母加平滑项 / 样本量过滤 核心原则:业务理解 + 数学工具 = 好特征

4.5 实战建议

说了这么多,到底怎么选?我个人的经验是:

  1. 先做业务交叉:跟业务方聊,找出那些「两个特征一起看才有意义」的组合。这一步性价比最高。
  2. 再做简单组合:求和、求差、求积,试试看哪些组合能提升模型效果。
  3. 最后考虑多项式:如果数据量够大、特征数不多,可以试试二阶多项式。三阶以上慎用。

我的习惯:每次加交叉特征后,都会用特征重要性(比如树模型的特征重要性或SHAP值)检查一下。如果新特征重要性很低,说明这个交叉没意义,果断删掉。别让无效特征拖累模型训练速度。

特征交叉不是越多越好。好的交叉特征,往往来自对业务的理解。你想想看,一个懂业务的工程师,可能只用3-5个精心设计的交叉特征,就能打败一个盲目堆了100个交叉特征的模型。嗯,这就是经验的价值。