1、特征列入门:什么是特征列、为什么需要特征列、特征列在TensorFlow中的角色
大家好,我是你们的老朋友。今天咱们来聊聊特征列。
说实话,我刚接触TensorFlow那会儿,看到“特征列”这三个字,第一反应是:这不就是特征工程那一套吗?搞个新名词干嘛?
后来踩了不少坑,才明白——特征列不是新瓶装旧酒,它是TensorFlow专门为结构化数据设计的一套“数据预处理管线”。
1.1 什么是特征列?
简单说,特征列就是告诉模型:你的输入数据长什么样,以及该怎么处理它。
举个例子。你有一张表格,里面有年龄、性别、收入。这些数据格式不一样:
- 年龄是数值,比如25、30
- 性别是字符串,比如“男”、“女”
- 收入是浮点数,比如12000.5
模型只认识数字。那字符串怎么转?数值要不要归一化?这些事,特征列帮你搞定。
核心理解:特征列是输入数据和模型之间的“翻译官”。它把原始数据转成模型能吃的张量。
我个人习惯把特征列分成两类:
- 数值列:直接拿数字用,比如年龄、收入
- 类别列:需要做one-hot或embedding,比如性别、城市
嗯,这里要注意:特征列不是数据本身,而是对数据的描述。你定义好特征列,TensorFlow就知道怎么处理每一列。
1.2 为什么需要特征列?
你可能会问:我自己写代码做预处理不行吗?
当然可以。但我在项目中遇到过一个问题:训练时和预测时的预处理逻辑不一致。
比如你训练时把“性别”转成了0和1。预测时来了新数据,你忘了做同样的转换。模型直接报错。
特征列解决了这个痛点:
- 一致性:训练和预测用同一套特征列,不会出错
- 可组合:你可以把多个特征列组合成新的特征,比如“年龄×收入”
- 可复用:定义一次,到处使用
避坑指南:我曾经在项目里手动写预处理代码,结果训练集和测试集的归一化参数不一样。模型上线后效果暴跌。后来改用特征列,再也没出过这种问题。
说白了,特征列就是帮你把“数据预处理”这件事标准化、自动化了。你想想看,如果每个项目都手写预处理,那得重复造多少轮子?
1.3 特征列在TensorFlow中的角色
在TensorFlow 2.x中,特征列是tf.feature_column模块的核心。它扮演三个角色:
- 数据描述者:告诉模型每个字段的类型和取值范围
- 预处理执行者:自动完成编码、归一化、分桶等操作
- 特征组合器:支持交叉特征、组合特征等高级操作
来看个最简单的例子:
import tensorflow as tf
# 定义特征列
age = tf.feature_column.numeric_column('age')
gender = tf.feature_column.categorical_column_with_vocabulary_list(
'gender', ['男', '女']
)
# 把特征列传给模型
feature_columns = [age, gender]
# 创建输入函数
def input_fn():
# 模拟数据
data = {
'age': [25, 30, 35],
'gender': ['男', '女', '男']
}
labels = [0, 1, 0]
return tf.data.Dataset.from_tensor_slices((data, labels)).batch(2)
# 构建模型
model = tf.keras.Sequential([
tf.keras.layers.DenseFeatures(feature_columns),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy')
model.fit(input_fn, epochs=5)
看到没?DenseFeatures层直接接收特征列,自动完成所有预处理。你不需要写任何编码逻辑。
注意:特征列只适用于结构化数据。图像、文本这些非结构化数据,请用其他方法。
我记得刚开始用特征列时,总觉得它多此一举。后来发现,它最大的价值是让数据预处理变得可维护、可测试。你想想看,一个项目里可能有几十个特征,每个特征的处理逻辑都写在特征列里,一目了然。
最后总结一下:
| 角色 | 说明 | 示例 |
|---|---|---|
| 数据描述者 | 定义字段类型和取值范围 | numeric_column('age') |
| 预处理执行者 | 自动完成编码、归一化 | categorical_column_with_vocabulary_list |
| 特征组合器 | 支持交叉特征、组合特征 | crossed_column |
下一章,我们会深入每种特征列的用法。到时候我会分享一些实战中的小技巧,比如怎么处理缺失值、怎么选择embedding维度。敬请期待。