返回博客列表

特征工程:从原始数据到模型输入

详细介绍推荐系统中的特征工程技术,包括特征提取、转换、编码等关键步骤。

2024-02-027 分钟阅读Yaron
#特征工程#机器学习#工程实践

嘿!欢迎来到推荐系统的"厨房重地"——特征工程。如果说推荐模型是五星大厨,那特征工程就是把一堆原始食材(数据)变成大厨能用的、处理得干干净净的顶级配料(特征)的过程。配料准备得好不好,直接决定了最后这道"推荐大餐"好不好吃!

1. 什么是特征?——给机器看的"标签"

简单来说,特征就是我们从原始数据里提炼出来的、用来描述人或事物的**"标签",而且这些标签必须是机器能看懂的数字**。

想象一下,我们要向模型描述一个课程,我们不能直接说"这是一个超赞的英语课",模型听不懂。我们得把它翻译成一堆数字标签,比如:

  • 学科标签=3 (假设3代表英语)
  • 价格标签=2333.0
  • 难度标签=2 (假设2代表中等难度)

我们主要会制作以下四种类型的"数字标签":

数值型 (Numerical): 【就是数字本身】

例子:课程价格2333.0元,总共8个课时。这种本身就是数字的,我们直接拿来用就行,顶多做个"缩放"(比如把所有价格都缩放到0-1之间,防止某个天价课程影响过大),简单直接!

类别型 (Categorical): 【给选项编号】

例子:课程的"学科"是一个选择题,选项有"数学"、"英语"、"物理"。我们不能把"英语"这两个汉字给模型,所以我们给它一个编号,比如英语=3。同理,"初一"、"初二"这些年级,也各自有一个独一无二的数字编号。

向量型 (Embedding): 【最神奇的魔法标签】

例子:系统里有100万个学生,每个学生都有一个userId。如果只给每个ID编个号,信息量太少了。所以我们施展一个魔法,给每个学生一个独特的"能力雷达图",这个雷达图由一串数字(比如[0.1, -0.4, 0.8, 0.2])表示,这就是Embedding向量。

这个"雷达图"能描述学生的隐藏特性,比如"数学学霸"、"文艺青年"、"拖延症晚期"等。两个学生的"雷达图"越像,说明他们品味越接近。这个神奇的雷达图是模型自己"画"出来的!我们后面会专门讲。

序列型 (Sequence): 【用户的行为日记】

例子:一个用户最近的操作记录:[点击了A课程, 观看了B视频, 购买了C课程]。这个按时间顺序排列的"行为日记"能告诉我们用户的"心路历程",对于预测他下一步想干嘛至关重要。

2. 案例实战:把你的数据变成"数字大餐"

好了,理论讲完,我们来亲手处理一下您给的JSON数据,看看怎么把它变成模型能吃的"数字大餐"。

"食材"准备:

  • 学员U: 一个叫"董云彰"的初一学生,他的userId是"fef93efd..."。
  • 商品I: 一个叫"智慧空间暑假G7"的初二英语课,classCode是"GA261008Q1"。
  • 场景C: 假设是在一个寂寞的周二晚上8点,系统决定为他推荐点什么。

步骤一:拿出我们的"密码本" (ID映射)

首先,我们需要一本"密码本",把所有中文和代号都翻译成数字ID。

  • 年级密码本: {"初一": 862, "初二": 863}
  • 学科密码本: {"英语": 3}
  • 教师密码本: {"T2024...": 101} (金鑫老师的代号)
  • 用户密码本: {"fef93efd...": 54321} (董云彰同学的代号)
  • 班级密码本: {"GA261008Q1": 98765} (智慧空间课程的代号)

步骤二:开工!逐个"贴标签"

来源原始字段和值特征名 (贴的标签)转化后的具体数值特征类型
学员 (U)"studentGrade": "初一"user_grade_id862类别ID
学员 (U)"classCount": 8user_class_count8.0数值
学员 (U)"userId": "fef93efd..."user_id54321类别ID
商品 (I)"dfee": 2333.0item_price2333.0数值
商品 (I)"lessonCount": "8"item_lesson_count8.0数值
商品 (I)"currentCount": 29item_popularity29.0数值
商品 (I)"gradeName": "初二"item_grade_id863类别ID
商品 (I)"subjectName": "英语"item_subject_id3类别ID
商品 (I)"teachers": [...]teacher_id101类别ID
商品 (I)"classCode": "GA261008Q1"item_id98765类别ID
场景 (C)周二晚上8点context_day_of_week2类别ID
场景 (C)周二晚上8点context_hour20.0数值

特别提醒:像"董云彰"、"134****9198"这种个人隐私,我们必须像对待烫手山芋一样,在第一步就扔掉,绝不能让模型看到!

3. 最终形态:一份给模型的"超级简历"

最后一步,我们要把上面所有零散的"数字标签"整理成一份工整的、长长的"超级简历",也就是特征向量。

最关键的是,那些ID类的标签,比如user_id: 54321,需要通过"Embedding魔法"变成我们说过的"能力雷达图"(向量)。

  • user_id: 54321 --> user_embedding = [0.1, -0.4, 0.8, 0.2]
  • item_id: 98765 --> item_embedding = [-0.5, 0.2, 0.1, -0.7]
  • teacher_id: 101 --> teacher_embedding = [0.9, 0.6, -0.3, 0.0]

现在,我们把所有数字"砖块"拼接起来!

处理流程图:

  1. 准备好的"砖块"

    • 数值型砖块:8.0, 2333.0, ...
    • 类别ID砖块:862, 3, 54321, ...
  2. 模型里的加工厂

    • Embedding魔法:将类别ID转换为向量
    • 超级拼接机:将所有特征拼接
  3. 最终输出

    • 最终的"超级简历":一个长长的数字向量

这份"超级简历"可能长这样:

[8.0, 2333.0, 8.0, 29.0, 20.0, ..., 0.1, -0.4, 0.8, 0.2, -0.5, 0.2, 0.1, -0.7, ...]

就是这个长长的、由纯数字组成的向量,才是模型 f(U, I, C) 真正需要的输入!