特征工程概述:节点特征的重要性

做图神经网络这几年,我越来越觉得一个道理:模型结构决定上限,特征质量决定下限。

你想想看,GraphSAGE 也好,GCN 也罢,它们的核心都是在做一件事——聚合邻居信息。但如果你的节点特征本身就很拉胯,邻居再怎么聚合,也变不出花来。我在项目中遇到过一个典型的例子:某电商的推荐场景,大家疯狂调模型层数、改聚合函数,效果死活上不去。最后我一查,用户特征全是些稀疏得不能再稀疏的 ID 向量。说白了,你给模型吃的是沙拉,却指望它长出牛排?

节点特征到底长什么样?

在图数据里,每个节点都附带一组属性。比如社交网络中的用户:年龄、性别、注册天数、发帖数量。这些数值就是原始节点特征。我把它们分成三大类:

特征类型 常见例子 典型问题
连续型 年龄、收入、点击次数、停留时长 量纲差异大,可能存在长尾分布
离散型 性别、学历、设备类型、城市编码 取值过多时容易过拟合
文本/类别嵌入 用户昵称、商品标题的向量化表示 维度高、含义模糊

嗯,这里要注意:GraphSAGE 的输入层直接吃的是原始浮点向量,所以任何特征最终都要转成数值。我们的分箱调优,核心就是处理上面表格里的第一行——连续型特征。

特征质量对模型的影响有多大?

我做过一组对比实验,印象很深。同一个 GraphSAGE 模型,用相同的超参数,只改特征预处理方式:

  • 不做任何处理:训练 loss 震荡剧烈,验证集 AUC 在 0.65 左右
  • 标准归一化:loss 收敛了,AUC 涨到 0.72
  • 简单等宽分箱(5箱):AUC 升到 0.75
  • 基于业务理解的分箱:AUC 直接干到 0.79

差别在哪?分箱实际上是在帮模型做「特征的非线性映射」。连续值进模型,模型只能学到线性关系。但现实中的用户行为,哪有那么简单?

我的习惯:拿到一个连续特征,先画分布直方图。如果分布有明显的峰值或断崖,基本可以判断——这个特征天生适合分箱。

我曾经在一个金融风控项目里犯过傻。用户「近30天借款次数」这个特征,值域 0~30。我上来就直接归一化扔进模型。结果模型学到的规律是「借款次数越多,违约概率越高」。但实际业务逻辑是:借款 1~3 次的是正常用户,4~8 次的是高风险,大于 15 次的反而是刷单分子。这是一个明显的非线性关系,归一化完全无法表达。后来分了箱,AUC 从 0.71 直接提到 0.83。

特征工程的基本流程

我个人习惯把节点特征工程拆成四个步骤:

  1. 特征收集与清洗:去掉异常值、补全缺失值
  2. 特征探索与理解:画分布图、算统计量、理解业务含义
  3. 特征变换与编码:分箱、归一化、对数变换、类别编码
  4. 特征验证:用小模型快速验证特征有效性

你看,分箱调优是第 3 步的核心环节。而且它不像归一化那样「无脑可用」,分箱的箱数、边界、编码方式全都要根据特征分布和业务场景来定。这就是我们这门课要深入的东西。

避坑提醒:不要一上来就对所有特征做分箱。有些特征本身是线性可用的,强行分箱反而破坏了信息。比如用户的「年龄」,在很多场景下它就是单调的,分箱反而丢失了年龄的连续梯度信息。

从特征到 GraphSAGE 的完整链路

下面这张图展示了特征从原始值到模型输入的完整路径,以及分箱在其中扮演的角色:

节点特征处理到 GraphSAGE 输入的完整链路 原始节点特征 [连续/离散/类别] 清洗 + 探索 异常值/分布理解 分箱调优 等宽/等频/树模型 业务自定义 特征向量 [浮点数序列] GraphSAGE 输入层 聚合邻居特征 模型输出 节点分类/链接预测/推荐 分箱调优发生在特征工程的中段,直接影响 GraphSAGE 对连续特征的表达能力 好的分箱=帮模型预先画好非线性决策边界

你看,从原始数据到 GraphSAGE 输入层,中间有一个明确的关键节点——分箱调优。它不是锦上添花,而是实实在在决定模型能不能学到有效模式的核心环节。

小结一下这章的核心

  • 节点特征的质量决定了 GraphSAGE 的天花板
  • 连续型特征是分箱调优的主要对象
  • 分箱的本质是帮模型捕捉非线性关系
  • 特征工程有固定流程,分箱是其中最有技巧性的一环

一句话记住本章:别急着调模型,先看看你的节点特征值不值钱。特征好了,模型自然会好。