模型实战准备(二) | 模型特征、训练样本的处理
模型实战准备(二) | 模型特征、训练样本的处理
讲述:王喆
时长14:15大小13.01M
为什么选择 Spark 为 TensorFlow 处理特征和样本?
物品和用户特征都有哪些?
最终的训练样本是什么样的?
如何在生成样本时避免引入“未来信息”?
如何把特征数据存入线上供模型服务用?
小结
课后思考
赞 15
提建议
精选留言(18)
- onepencil2020-11-16线上会组装当前访问时的历史序列及历史平均值等,可以利用flink实时落盘这些线上特征,这样线下就不用再离线生成,也就杜绝了特征穿越问题
作者回复: 赞,这是业界的解决方法之一,存储特征的snapshot。
共 3 条评论52 - Sebastian2020-11-16老师好,想问下使用hset把用户和物品的特征存入redis的场景下,如果用户上亿物品也上亿的话,存入redis会使用很大的资源。实际场景下并不是所有用户都是活跃用户,很多情况下可能用不上。那是否是在redis只存入活跃用户的特征呢?但是如果这样解决,遇到非活跃用户是否就没有特征值了? 从您的实践经验里有什么好的方法吗?展开
作者回复: 我在存储模块那节课说过,SparrowRecsys项目确实对存储模块进行了一定程度的简化,实际应用中还是要多考虑分级存储,redis实际上当作一个缓存层来使用。 关于大量数据key value数据的存储和线上查找,可以多调研rocksdb,cassandra,dynamodb和mongodb。
共 2 条评论11 - AI2021-03-01老师好,为什么用户id和电影id要作为特征进行输入,我的理解是id不是相当于一个索引吗?
作者回复: 用户id和电影id都是非常重要的特征,因为他们之间的关系包含了用户的历史行为信息,其中又隐含了非常多的用户的兴趣偏好。
共 2 条评论8 - 那时刻2020-11-17把评分大于等于 3.5 分的样本标签标识为 1,意为“喜欢”,评分小于 3.5 分的样本标签标识为 0,意为“不喜欢”。这样可以完全把推荐问题转换为 CTR 预估问题。请问老师,3.5分这个值是怎么来的呢? 另外一个问题,我们把评分时间戳作为代表时间场景的特征放到特征工程中。请问把时间戳用于特征工程,有木有需要注意的地方?比如是否是周末,假日等?老师在实际应用中有哪些实践么?展开
作者回复: 两个问题都很好,希望大家都有这样实践中的思考。 第一个问题。基本原则是我在分析完分数的总体分布后得出的,3.5分基本是正负样本比例1:1的分界线,另外大于3.5分也符合我们直观意义上的高分,所以认为3.5分是比较合理的。 第二个问题。确实像你说的这样,我们实践中经常从时间戳中提取出周末,假日,季节这些特征,因为这些时间特征往往影响着数据的一些潜在模式,所以还是非常有价值的。
共 4 条评论9 - 萬里長空2020-11-20老师,问一个spark-udf的问题,看官网上定义udf的时候要使用register,但是您这里并没有使用,是sql与DataFrame的区别吗?
作者回复: 是的,是spark sql和直接操作dataframe的区别。直接操作dataframe不用register
6 - 倪钰鑫2021-01-23老师好,我想问下用户行为的时间序列,最一开始的那个用户行为的历史数据我们都是置0吗?比如您上面所说的“userAvgRating”,在B上是填A的打分3,那么在A上呢?因为这里收集到的信息A是最前面的,那此时就是置为0吗?还是说可以选一个全局中值填进去呢?
作者回复: 这是个好问题,涉及到默认值选取的问题。常规做法是把全局的均值填进去,但其实没有什么统一的最好的方法。
共 2 条评论5 - ZLZ2021-05-18王老师,请问我在训练CTR模型过程中,有两种训练样本处理方式,第一种是使用T-1天的数据进行shuffle,其中80%作为train dataset,20%作为训练过程中的val dataset,即使用T-1天的数据进行模型训练,针对T天的数据进行线上预测;第二种方式是使用T-2天的数据作为train dataset,T-1天的数据作为val dataset,即2使用T-2天的数据进行模型训练,针对第T天的数据进行线上预测;我理解第一种方式是不是容易造成信息穿越,例如在某一天有某个活动,但是第二天没有这个活动,那模型在第二天会效果不好,但是第二种方式线上是采用T-2天的模型,相比于第一种方式(线上使用的是第T-1的模型),是不是效果会打折扣展开
作者回复: 是这样,第一种方式是不建议采用的。第二种我建议缩短数据分割的粒度,比如改成T-1小时
共 3 条评论5 - 榕2021-01-26//add rating features val movieRatingFeatures = samplesWithMovies3.groupBy(col("movieId")) .agg(count(lit(1)).as("movieRatingCount"), format_number(avg(col("rating")), NUMBER_PRECISION).as("movieAvgRating"), stddev(col("rating")).as("movieRatingStddev")) .na.fill(0).withColumn("movieRatingStddev",format_number(col("movieRatingStddev"), NUMBER_PRECISION)) 老师,特征处理中电影的打分特征应该也是要做window处理吧,谢谢~展开
作者回复: 是这样,最好要进行window处理。可以自行修改提交PR
2 - abc-web2021-01-24王老师,想问一下,如果标签或其他属性是中文内容需要进行特征处理还是直接进行word2vec?谢谢!
作者回复: 先分词再word2vec
3 - Jay2020-11-18刚入坑,好像一直没有看到关于特征组合的内容,这个点一直没有理解清楚,啥时候会讲讲呢?
作者回复: 组合特征当然可以通过人工组合的手段进行组合,这点我们仍然可以沿用之前传统机器学习的经验。 对于深度学习模型来说,也可以交由模型的内部结构来组合,这一点后面关于模型的讲解还会涉及到。
共 2 条评论2 - Geek_3c29c32021-04-27老师,由于用户有上亿个,在训练样本时,只是有一部分用户的usrid去进行训练,在模型上线时,不在模型训练所用的usrid里面,一般来说都有哪些处理方法呢?
作者回复: 可以参考我的这篇文章https://zhuanlan.zhihu.com/p/351390011
1 - fsc20162020-11-18老师,有俩个问题请教您: 1,前面章节生成了用户和物品的embding,这些embding也会作为一个特征字段加入到本节生成的用户和物品特征中嘛 2,本节提取了用户和物品特征,那进行ctr预估的话,是根据rateing表中,为每条记录添加对应提取出的用户特征和物品特征,作为一条训练记录。这样组合的话,是不是使用未来信息了?关于如何组装成一条训练记录进行ctr预估,该怎么做了展开
作者回复: 1. 可以的,也是常用的做法,就是预训练embedding+深度模型的做法 2. 这个问题不是特别理解,我已经在这节专门讲了如何用window函数生成用户和物品特征,来消除未来信息,应该是回答了你这个问题?
共 2 条评论1 - Geek_84e43e2022-05-28王喆老师,我在学习您的课程的时候遇到了这个问题:在您使用window函数规避数据穿越问题这一节,我观察到您在切分数据集的时候还是采用的随机分割的方式?那假设我在测试集中是11月3号的数据,但是训练集中包含了11月1日和11月5日这两天的数据,这也就是说我会使用11月1号和5号的数据来训练,最后使用11月3号来测试模型效果,这不会同样带来数据穿越的问题吗?1
- คิดถึง2021-08-31王老师好,如果我想在数据集中添加其他特征,类似用户年龄、性别等,该修改哪些地方呢?
- ZLZ2021-05-18还有一个问题,电商领域中,在一个新的推荐场景,初期采用的是热门推荐进行积累数据的,就几乎没有用到什么特征,在用户行为数据积累量足够的情况下,准备训练样本,上推荐模型,模型用到的特征有离线特征(根据T-1天用户行为加工得到) + 实时特征(例如最近五分钟的点击次数),但是在离线训练模型时,无法拿到线上真实的实时特征(因为热门推荐没有用到实时特征,但是用户的行为日志是写入hive了),所以我通过历史的用户行为日志(例如:用户在某个时刻点击了某个商品)模拟复现出用户行为时刻的实时特征值,作为离线模型的训练集,这样做合理么,会有什么问题么,对于这种新场景,第一次上推荐模型的时候缺失真实实时特征该如何处理呢展开
作者回复: 合理 确实真实特征是冷启动的问题,可以查阅一些冷启动方面的文章。
- Sanders2021-02-04"咱们课程中讲了基于 userId 的 window 函数方法,你觉得还有哪些方法也能避免引入未来信息吗?"可以通过构建分区表的方式记录总的rattings,ratting次数以及日期分区
- 灯灯灯2021-01-27老师请问 对于像movielens的数据集给出具体评分的数据集 不把评分分为是否》3.5的两类而是直接对评分做预测 是否会得到更准确地预测呢?
作者回复: 当然可以去尝试,这里只为大家理解原理提供一种方法。
- Wiiki2020-11-19王老师,我按照您的示例代码,将用户特征存入redis(调用extractAndSaveUserFeaturesToRedis(samplesWithUserFeatures)的时候报错了,首先是报错:java.lang.Integer cannot be cast to java.lang.String,我在调试的过程中发现valueMap("userAvgReleaseYear") = sample.getAs[String]("userAvgReleaseYear")这个字段并没有将年份转换成String,还是原来的Int类型,所以改成 valueMap("userAvgReleaseYear") = sample.getAs[Int]("userAvgReleaseYear").toString,这个异常解决了,然后又报错:Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: ERR wrong number of arguments for 'hset' command,定位到return client.getIntegerReply()这个代码出错了。目前没有找到具体原因,麻烦老师帮忙解答一下呀~ 谢谢展开
作者回复: 第一个问题确实是个bug,我已经提交了修改。 第二个问题我这边不存在,可能还需要你来debug一下。确认本地的redis环境都配置好了吧?
共 4 条评论