深度学习推荐系统实战
王喆
Roku 推荐系统架构负责人,前 hulu 高级研究员,《深度学习推荐系统》作者
33298 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
深度学习推荐系统实战
15
15
1.0x
00:00/00:00
登录|注册

05 | 特征处理:如何利用Spark解决特征处理问题?

Spark中的MinMaxScaler和QuantileDiscretizer
分桶
特征的分布问题
归一化
特征的尺度问题
Multi-hot编码
Spark中的OneHotEncoderEstimator
One-hot编码
类别、ID型特征
Spark的工作过程
Spark的架构
Spark的特点
课后思考
小结
数值型特征的处理-归一化和分桶
如何利用One-hot编码处理类别型特征
业界主流的大数据处理利器:Spark
如何利用Spark解决特征处理问题?

该思维导图由 AI 生成,仅供参考

你好,我是王喆。
上节课,我们知道了推荐系统要使用的常用特征有哪些。但这些原始的特征是无法直接提供给推荐模型使用的,因为推荐模型本质上是一个函数,输入输出都是数字或数值型的向量。那么问题来了,像动作、喜剧、爱情、科幻这些电影风格,是怎么转换成数值供推荐模型使用的呢?用户的行为历史又是怎么转换成数值特征的呢?
而且,类似的特征处理过程在数据量变大之后还会变得更加复杂,因为工业界的数据集往往都是 TB 甚至 PB 规模的,这在单机上肯定是没法处理的。那业界又是怎样进行海量数据的特征处理呢?这节课,我就带你一起来解决这几个问题。

业界主流的大数据处理利器:Spark

既然要处理海量数据,那选择哪个数据处理平台就是我们首先要解决的问题。如果我们随机采访几位推荐系统领域的程序员,问他们在公司用什么平台处理大数据,我想最少有一半以上会回答是 Spark。作为业界主流的大数据处理利器,Spark 的地位毋庸置疑。所以,今天我先带你了解一下 Spark 的特点,再一起来看怎么用 Spark 处理推荐系统的特征。
Spark 是一个分布式计算平台。所谓分布式,指的是计算节点之间不共享内存,需要通过网络通信的方式交换数据。Spark 最典型的应用方式就是建立在大量廉价的计算节点上,这些节点可以是廉价主机,也可以是虚拟的 Docker Container(Docker 容器)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了如何利用Spark解决推荐系统中的特征处理问题。首先介绍了Spark的特点和架构,强调了其在处理海量数据时的优势。然后详细解释了Spark的计算过程,包括并行计算、shuffle操作和reduce操作。接着,重点讨论了如何利用One-hot编码处理类别型特征,以及如何在SparrowRecsys项目中利用Spark的MLlib库完成One-hot特征的处理。文章还提到了Multi-hot编码的应用,以及如何在SparrowRecsys中实现该过程。此外,还介绍了数值型特征的处理方法,包括归一化和分桶。最后,总结了特征处理的原则,强调了特征处理没有标准答案,需要根据模型效果实践出真知。整体而言,本文为读者提供了清晰的技术指导,使其能够快速了解推荐系统特征处理的方法和原则。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深度学习推荐系统实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(57)

  • 最新
  • 精选
  • JustDoDT
    Normalizer、StandardScaler、RobustScaler、MinMaxScaler 都是用让数据无量纲化 Normalizer: 正则化;(和Python的sklearn一样是按行处理,而不是按列[每一列是一个特征]处理,原因是:Normalization主要思想是对每个样本计算其p-范数,然后对该样本中每个元素除以该范数,这样处理的结果是使得每个处理后样本的p-范数(l1-norm,l2-norm)等于1。)针对每行样本向量:l1: 每个元素/样本中每个元素绝对值的和,l2: 每个元素/样本中每个元素的平方和开根号,lp: 每个元素/每个元素的p次方和的p次根,默认用l2范数。 StandardScaler:数据标准化;(xi - u) / σ 【u:均值,σ:方差】当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布)。 RobustScaler: (xi - median) / IQR 【median是样本的中位数,IQR是样本的 四分位距:根据第1个四分位数和第3个四分位数之间的范围来缩放数据】 MinMaxScaler:数据归一化,(xi - min(x)) / (max(x) - min(x)) ;当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到 [0,1]之间

    作者回复: 非常棒,推荐其他同学参考。

    2020-10-12
    5
    76
  • 李@君
    对训练数据进行平方或者开方,是为了改变训练数据的分布。训练数据的分布被改变后,训练出来的模型岂不是不能正确拟合训练数据了。

    作者回复: 这是个好问题。但不应该这样理解,本质上是改变了特征的分布,特征的分布和训练数据的分布没有本质的联系。只要你不改变训练数据label的分布,最终预测出的结果都应该是符合数据本身分布的。因为你要预测的是label,并不是特征本身。

    2020-10-16
    5
    26
  • JustDoDT
    Multiple编码 顾名思义,Multiple编码特征将多个属性同时编码到一个特征中。在推荐场景中,单个用户对哪些物品感兴趣的特征就是一种Multiple编码特征,如,表示某用户对产品1、产品2、产品3、产品4是否感兴趣,则这个特征可能有多个取值,如用户A对产品1和产品2感兴趣,用户B对产品1和产品4感兴趣,用户C对产品1、产品3和产品4感兴趣,则用户兴趣特征为 用户 UserInterests A [1, 2] B [1, 4] C [1, 3, 4] Multiple编码采用类似oneHot编码的形式进行编码,根据物品种类数目,展成物品种类数目大小的向量,当某个用户感兴趣时,对应维度为1,反之为0,如下 用户 UserInterests A [1, 1, 0, 0] B [1, 0, 0, 1] C [1, 0, 1, 1] 如何使用Multiple编码呢? 我们将多个属性同时编码到同一个特征中,目的就是同时利用多个属性的特征。经过Multiple编码后的特征大小为[batch_size, num_items],记作U,构建物品items的Embedding矩阵,该矩阵维度为[num_items, embedding_size],记作V,将矩阵U和矩阵V相乘,我们就得到了大小为[batch_size, embedding_size]的多属性表示。 参考资料:https://www.codeleading.com/article/97252516619/#_OneHot_19

    作者回复: 不错的文章,也推荐大家学习。

    2020-10-12
    3
    18
  • twzd
    老师请教一下,movieIdVector列输出结果中(1001,[1],[1.0]),每一列表示什么含义啊

    作者回复: 这是一个稀疏向量表示,1001维,第1维的值为1.0

    2020-11-10
    2
    13
  • Geek_ddf8b1
    老师 我看您FeatureEngForRecModel.scala代码中将特征写入redis是以哈希表的格式写入的,而且有些特征直接是类别型的文本数据。 这种方式线上读取特征再后续处理输入排序模型预估的时候会不会效率很低,预估打分时间较长?比如取出文本特征做onehot 或者multihot变换等等,是否可以将文本特征onehot 或者multihot处理后再写入redis? 还有特征除了以hash表形式还可以以其它数据结构存到redis,比如以probuf对象、libsvm数据格式的特征索引:特征值的字符串存到redis 您对这几种存储方式怎么看?哪种更好?

    作者回复: 你好,其实你提的不是问题,提的是自己的思考,我觉得都非常好,他们确实都是我们在实际工作中需要解决的问题。 这些问题没有什么所谓答案,自己去思考,自己去尝试就好了。 我自己的经验是存onehot和muilthot的index,存储结构用protobuf。

    2020-12-06
    10
  • Capricornus
    我使用的spark3.0的环境,脱离老师的项目,单独建立的用来学习。 1. 下载Scala支持,[下载链接](https://www.scala-lang.org/download/2.12.12.html) 2. 解压后放在指定的目录 ```bash vi ~/.bash_profile export PATH="$PATH:/Library/Scala/scala-2.12.12/bin" ``` 3. 在IDEA的项目中引入,点击“+”号,根据路径添加 4. 右键项目的目录,添加框架支持 5. 添加IDEA的插件,preferences中 6. porm.xml的环境依赖 ```xml <dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.12</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-mllib_2.12</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.12</artifactId> <version>3.0.0</version> </dependency> </dependencies> ``` **注意:路径中不要包括中文,否则可能会出现路径不存在的问题。** 然后有两处需要更改 val oneHotEncoder = new OneHotEncoder() .setInputCols(Array("movieIdNumber")) .setOutputCols(Array("movieIdVector")) .setDropLast(false) // 官网的说法:OneHotEncoder which is deprecated in 2.3,is removed in 3.0 and OneHotEncoderEstimator is now renamed to OneHotEncoder. val movieFeatures = samples.groupBy(col("movieId")) .agg(count(lit(1)).as("ratingCount"), avg(col("rating")).as("avgRating"), functions.variance(col("rating")).as("ratingVar")) .withColumn("avgRatingVec", double2vec(col("avgRating")))

    作者回复: 赞,使用spark3.0的同学可以参考

    2021-01-05
    6
  • 张弛 Conor
    请教老师,像在电影评分这样的离散数值(且比较稀疏)例子中,如果需要取得分桶数较多,而导致分位数附近均是同一数值的情况下,如何使用分桶的方法呢? 比如按照分桶法首先排序得到评分为5,5,4,4,4,4,4,4,3,3,3,3,2,2,1(共15个)。取桶数为3时,第一个桶内有前两个5,而后面的6个4中应该选择哪3个来分到第一个桶呢?

    作者回复: 其实不建议这种离散数值,取值数量有比较少的特征进行分桶操作。把相同分值强制分到两个桶里,不仅没有意义,而且引入噪声。

    2020-10-14
    2
    6
  • 神经蛙
    --- 看了几位同学的留言,受益匪浅啊。希望大家多多交流~ 1.请你查阅一下 Spark MLlib 的编程手册,找出 Normalizer、StandardScaler、RobustScaler、MinMaxScaler 这个几个特征处理方法有什么不同。 Normalizer 是规范化,根据所传的p值,做p范数归一化(默认p=2)。它是作用在每个样本的向量内部的。无需训练。 eg:x:[v1,v2,v3],p1=sum(abs(vi)), 经过normalizer, x:[v1/p1,v2/p1,v3/p1] StandardScaler 标准化,将样本的每个特征的标准差变为1.或者可以设置将均值变换为0(默认setMean是False)。这里计算标准差(计算均值)是样本集的每个维度单独计算。所以需要fit操作。计算后保存每个样本标准差、均值后。对每个样本第i个维度除以第i个维度的标准差(如此计算后,该维度均值也会自动被除以标准差,经过标准差公式,则新的标准差为1)。如果setMean == True, 则在变幻是需要先减去均值之后再除以标准差。 RobustScaler 我看spark3才有,具体没弄出来,看文档大概意思是将数据变换到1/4~3/4分为之间。好像是让数据变得稠密了。 MinMaxScaler 将数据变为到[0,1]之间,也需要训练,得到每个维度的最大最小值。然后变化Y= (X-X_min)/(X_max-X_min) 2.你能试着运行一下 SparrowRecSys 中的 FeatureEngineering 类,从输出的结果中找出,到底哪一列是我们处理好的 One-hot 特征和 Multi-hot 特征吗?以及这两个特征是用 Spark 中的什么数据结构来表示的呢? 处理好的One-hot特征 movieIdVector 处理好的Multi-hot特征 vector 数据结构: SparseVector 其中的数据分别是:(类别数量,索引数组,值数组)。索引数组长度必须等于值数组长度。

    作者回复: 总结的好,赞

    2020-12-03
    2
    4
  • fsc2016
    第二个问题: One-hot特征是调用OneHotEncoderEstimator对movieId转换,生成了特征movieIdVector Multi-hot 特征是调用Vectors.sparse方法,对处理后的genreIndexes转换,生成vector。 这俩个特征都是稀疏向量表示,不是稠密向量

    作者回复: 非常好。比之前的回答更准确一些,推荐大家参考。

    2020-10-16
    2
    4
  • Yvonne
    谢谢老师!在读youtube论文的时候,当时没有特别理解为什么要将原值,开方,平方都放进去,解释是:In addition to the raw normalized feature ˜x, we also input powers ˜x2 and √x˜, giving the network more expressive power by allowing it to easily form super- and sub-linear functions of the feature. Feeding powers of continuous features was found to improve offline accuracy.…… 当时没能理解为什么。您提到可以用于改变分布特征,突然就理解了XD

    作者回复: 赞

    2021-04-25
    3
收起评论
显示
设置
留言
57
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部