spark的计算过程

stage内部数据高效并行计算,stage边界处进行消耗资源的Shuffle操作或者最终的reduce操作。

one hot编码处理特征

对于类别型特征,用one hot编码,其他维度置为0,当前id维度置为1。

对于如标签特征,用multi hot编码。

对数据值类型特征,要做归一化和注意特征分布。归一化,如电影平均评分和电影评价次数,两个值域差异极大,电影评分基本上就不会影响特征。特征分布其一,比如一个电影评分,大多数人评分集中在3.5分中庸偏上,这不利于模型学习,可以用分桶形式解决不均衡,将样本按照特征的值从高到底排序,按照桶数量找到分位数,将样本分到各自的桶中。特征分布其二,我们可以把一个特征进行缩放,让模型自己选择学习更有价值的信息,比如YouTube在编码视频观看时间间隔、视频曝光量时,将他们处理成了三个特征,原始特征值x、特征值平方、特征值的开方。

embedding

Netflix用矩阵分解方法生成的电影和用户的embedding,embedding向量保存了电影之间的相似性关系,基于他做电影推荐就非常容易。

为什么embedding重要?

首先,embedding能处理特征稀疏问题。他可以把稀疏高维特征转为稠密低纬特征向量。其次,embedding可以再进行编码,他本身还是特征向量。

word2vec

他是生成对词的向量表达的模型。他用滑动窗口一一截取词组,把词组内的词转换为训练样本。word2vec模型的结构是三层神经网络。word2vec模型中的输入向量矩阵的行向量,就是embedding。

图结构数据

常见的图数据:社交网络(有意见领袖,社区),知识图谱(有知识主题比如人物和地点,以及附着在知识主体上的属性如人物描述和物品特点,以及主体和主体、主体和属性之间的关系),行为关系类图数据(是用户和物品组成的二部图)。

deep walk图embedding

deep walk在由物品组成的图结构上进行随机游走,产生大量物品序列,然后将物品序列作为训练样本输入word2vec训练,得到物品的embedding。deep walk可以看做连接序列embedding和graph embedding的过渡方法。

deep walk的算法流程。首先,基于原始用户行为序列(用户购买物品序列、观看视频序列)构建物品关系图,如果后续产生更多条相同的有向边,则有边的权重被加强。然后,用随机游走选择起始点,重新产生物品序列。最后,将随机游走产生的物品序列输入word2vec模型,生成embedding向量。

deep walk算法需要定义随机游走跳转概率,他就是跳转边的权重占所有相关出边权重之和的比例。

node2vec

node2vec对deep walk做了改进。他改进随机游走跳转概率,让图embedding在网络的同质性和结构性进行权衡。同质性是距离相近节点的embedding尽量近似,结构性是结构上相似节点尽量接近,node2vec用bfs让图embedding的结果倾向于结构性,用dfs让图embedding的结果倾向于同质性。具体地,node2vec定义从节点v跳到下一节点x(v的上一个节点是t)的概率等于阿尔法乘以w,w是原始权重,而阿尔法的取值为p分之一,1和q分之一,当且仅当节点x就是t、节点x分别是和节点t直接相连、节点x不和节点t直接相连。p是返回参数,p越小,随机游走回到节点t的可能性更大。q是进出参数,q越小,随机游走到远方节点的可能性更大。

embedding怎么应用到推荐系统中?

直接应用、预训练应用、end2end应用。

直接应用,得到embedding向量后,用embedding向量相似性实现推荐系统功能,如用物品embedding和用户embedding相似性实现猜你喜欢,也可以用物品embedding实现推荐系统召回层。

预训练应用,把这些embedding向量作为特征向量一部分,跟其他特征向量拼接起来,作为推荐模型的输入参与训练。

end2end应用,把embedding的训练和深度学习推荐模型结合起来,用统一的方式一起训练如wide and deep。

spark训练word2vec

指定setVectorSize、setWindowSize和setNumIterations。setVectorSize设定生成的embedding向量维度,setWindowSize设定在序列数据上采样的滑动窗口大小,setNumIterations设定训练迭代次数。

spark中flatMap操作和map操作的区别

map对于输入x1,x2,x3,有函数f x到y,y是单值,输出是f x1,f x2,生成了一个大小相同的新RDD。

flatMap对于输入x1,x2,x3,有函数g x到sequence y1 y2等等,可以返回零或多个y。输出是一个连续序列。最终的RDD是所有序列拼在一起的序列,即y1,y2,y3,y4等等。

为什么深度学习的结构特点不利于稀疏特征向量的处理?

一方面,稀疏特征会导致网络收敛非常慢,因为每个样本的学习只有极少数权重会得到更新,这样在样本有限情况下会导致模型不收敛。另一方面,one hot稀疏特征维度非常大,如果直接送入深度学习网络,那整个模型参数非常大,算力要求高。

怎么搭建高并发的推荐服务?

用负载均衡服务器进行分配任务、缓存减少推荐次数(如同一个用户请求同样的推荐服务,把第一次推荐结果缓存,后续请求直接返回)、服务降级(发生缓存雪崩时,推荐直接用基于规则的方法生成推荐列表)。

特征存储

线上QPS压力大,推荐服务器一定要快。其次用户数和物品数规模大,应该用分级存储。

召回层的实现

召回层要快速、准确过滤相关物品,缩小候选集。召回层的实现:单策略召回方法、多路召回、基于embedding召回。

单策略召回是制定规则或用简单模型快速召回相关物品。多路召回是采用不同策略、特征或简单模型,分别召回一部分候选集,然后把候选集混合在一起供给后续排序模型使用的策略。基于embedding召回,所有相似度都在同一向量空间,同一度量下得出,分值连续且可比。

局部敏感哈希,快速找到与一个embedding最相似的embedding

如果用户和物品embedding在k维度embedding空间中,物品总数为n,则计算一个用户和所有物品相似度时间复杂度为O k乘以n,线上服务不能承受。

解决方案,k means、kd树索引、局部敏感哈希。k means聚类,随机指定k个中心点,每个中心点代表一个类,把所有点按距离远近指定给距离最近的中心点代表的类,计算每个类包含点的平均值作为新的中心点的位置,确定新中心点位置后,再计算距离,直到中心点位置收敛。

kd树索引。他把空间中的点不停一分为二,直到每个片区只剩下一个点,完成空间索引的构建。但kd树会遗漏最近邻点。

局部敏感哈希。让相邻的点落入同一个桶。欧式空间中,高维空间的点映射到低维空间,原本接近的点在低维空间仍然接近,但原本远的点可能变成近的点。比如用内积构建局部敏感哈希桶,用内积把v向量映射到一维空间。局部敏感哈希可以用多桶策略,用“或”和“与”处理多个分桶之间的关系。

局部敏感哈希,分桶函数选择多少个,以及每个分桶函数分多少个桶的策略:1.点数越多,越应该增加每个分桶函数分桶的个数。2.embedding向量维数越大,越应该增加哈希函数数量。

如果让你在推荐服务器内部的召回层实现最近邻搜索过程,你会怎样存储和使用我们在离线产生的分桶数据,以及怎样设计线上的搜索过程呢?

离线分桶数据的生成。1.embedding计算,为所有候选对象计算固定维度向量,用二级召回模型或特征模型在离线批处理平台(Hadoop、spark、flink)中完成数据向量化,如<itemid,embeddingvector,时间戳>。2.哈希分桶,将向量映射到多段二进制上。3.序列化,把bucketid,itemid,embedding写入足够大的kv表作为索引文件,可以用protobuf序列化。其次用元数据记录索引版本、构建时间、embedding维度、聚类数k、哈希参数。4.存储部署位置,offline将索引按天、小时存入hdfs,线上将序列化结果压缩成tar包,配置k8s config map刷到召回服务的磁盘,也写入redis,存热门bucketid。

线上搜索过程。1.查询用户embedding,从实时流日志如点击曝光搜索关键词等经过二级召回模型在线算出最新向量。对embedding做归一化,如果离线做的是PQ,则embedding也需拆分子向量、量化。如果用lsh,则先计算embedding在各个哈希函数上签名,得到bucketid。2.定位候选bucket,到本地内存或ssd索引批量读取bucketid下item列表3.召回阶段,批量读取候选embedding,计算相似度。如果候选数量不大,则在cpu做批量距离计算。如果离线生成时我们把每个向量做product quantization,那么候选embedding是若干pq码块,根据embedding先计算子向量到pq子码表的查表距离,累加得到近似距离。

模型服务

预存embedding结果、预训练embedding加轻量级线上模型、PMML模型、TensorFlow serving。

预存embedding结果,他要存用户乘以物品乘以应用场景的组合推荐结果,在规模过大后,会发生组合爆炸。且无法引入线上场景context上下文特征。

预训练embedding加轻量级线上模型,用复杂深度学习网络离线训练生成embedding,存入内存数据库,再在线上实现逻辑回归或浅层神经网络拟合优化目标。如阿里MIMN。

PMML模型,如spark mlib模型的训练,jpmml序列化和解析PMML文件中的库,JPMML项目分为spark和Java server部分。spark部分的库完成spark MLib模型序列化,生成PMML文件。Java server负责完成PMML模型解析,生成预估模型,完成和业务逻辑的整合。PMML模型表示能力有限,不支持复杂深度学习模型。

TensorFlow serving,如用TensorFlow的keras接口完成模型构建和训练,再用TensorFlow serving载入模型,用docker作为服务容器,在jetty推荐服务器发出请求到TensorFlow serving,获得模型推断结果,推荐服务利用结果完成推荐排序。

推荐的实现

1.特征工程,用item2vec训练embedding,或用deep walk和node2vec把图数据生成graph embedding。

2.用redis作为特征数据库。以及预训练embedding,embedding加轻量级线上模型,TensorFlow serving,三种模型服务方式。

3.召回和排序。召回有单策略召回,多路召回,基于embedding召回。排序有基于embedding排序等。

4.推荐结果评估。方法一,人肉测试,抽样看基于embedding的推荐结果是否符合自己的常识。方法二,指定ground truth。方法三,用商业指标评估,思考推荐功能目的是什么,即尽量提高点击率、播放量。

推荐系统冷启动

他是推荐系统在没有可用信息或可用信息很少情况下怎么推荐的问题,分为用户冷启动和物品冷启动。

用户冷启动是用户没有可用的行为历史问题。要考虑有哪些用户特征可以使用,如注册时信息,访问app的地点、时间信息,为用户聚类,返回推荐列表。也可以用冷启动特征,构建简单冷启动模型。

物品冷启动,用物品分类找到相似物品,如果相似物品已有预训练embedding,采取相似物品embedding平均的方式,确定冷启动物品的embedding。

在电商领域下,如何解决 EGES 训练非常慢的问题?

方案一,把商品embedding预训练,再和其他side information特征输入eges,不用直接在eges中加embedding层进行端到端训练。

方案二,把商品聚类再输入eges网络,大幅减少商品数量量级。

协同过滤算法的原理

协同大家的反馈,评价对海量信息过滤,从中筛选出用户可能感兴趣的信息的算法。

步骤:1.用用户行为历史,创建共现矩阵。2.找到相似用户。3.用相似用户喜欢的物品,推荐。

矩阵分解和他不同,用分解共现矩阵生成用户向量和物品矩阵向量矩阵,得到用户隐向量和物品隐向量。

常见的深度学习推荐模型

神经网络加协同过滤:NeuralCF。神经网络加embedding,deep crossing。神经网络加乘积层,PNN。深度网络加浅层网络,wide&deep,deep fm,dcn。神经网络加注意力机制,din,afm。神经网络加序列模型,dien。深度学习加强化学习,drn。

双塔模型

双塔模型通过丰富物品侧和用户侧的特征,让模型能融入除了用户id和物品id外更丰富的信息。他的优势是模型服务的便捷性,最终的互操作层是简单内积操作或浅层神经网络。因此我们可以把物品塔的输出当做物品embedding,用户塔的输出当做用户embedding存入特征数据库,在线上只要实现简单的互操作过程即可。

双塔模型把物品侧embedding和用户侧embedding存起来进行线上服务。如果我们把一些场景特征,如当前时间、当前地点加入用户侧或物品侧,那我们还能用这种方式进行模型服务吗?

在双塔结构能在离线预先计算并在线上并在线上进行简单交互,关键在于塔内输入特征是固定的,如果把当前时间、当前地点也放入用户侧或物品侧,则离线和在线使用时,他们的特征是不同的,在线操作时,还需要再处理一次。

deep FM

他用FM层专门处理特征之间交叉问题,用点积、元素积让不同特征之间进行两两组合,再把组合后的结果输入到神经元中。

深度强化学习推荐模型DRN

DRN是双塔结构,用户塔输入特征是用户特征和场景特征,物品塔输入向量是所有用户、环境、用户-新闻交叉特征。在强化学习框架下,用户塔特征向量代表了用户所处的状态,被视为状态向量。物品塔特征向量代表系统下一步要选择的新闻,选择新闻的过程是智能体的行动,所以物品塔特征向量被称为行动向量。双塔模型通过对状态向量和行动向量分别用MLP处理,再用互操作层生成最终行动质量得分Q(s,a),智能体用这一得分的高低,选择做出哪些行动。

DRN的更新方式

DRN用微更新实时学习用户奖励反馈,更新推荐模型,再用阶段性“主更新”学习全量样本,更新模型。DRN微更新时用竞争梯度下降算法,比较原网络和探索网络的实时效果,更新模型参数。

DRN的微更新用到了竞争梯度下降算法,此算法有什么弊端?

算法工程师正确的工作方法

要避免学生思维,不能总是在寻求一个问题的标准答案。

通用的算法工程师的工作流程:1.问题提出,清除领导提出的问题,或自己发现的问题。2.数据和业务探索,动手解决问题之前,要花时间弄清楚业务的逻辑,动手用一些脚本程序弄清楚自己可利用的数据量、数据特点、提取一些特征并分析特征和标签之间的相关性。3.初始解决方案。4.解决方案调优,进行参数调优。5.工程落地调整,能简勿繁。6.生产环境上线。7.迭代与复盘,根据生产环境结果迭代优化,继续发现问题,解决问题。

离线评估

Holdout实验,将原始样本集随机划分成训练集和测试集。缺点是随机性。

交叉检验法,将原始样本划分为k个子集,顺序遍历,当遍历到当前子集时,其他子集作为训练集。k的经验值是10。Holdout和交叉检验缺点是样本划分训练和测试会导致训练集减小,当样本规模小时,这个问题更大。

自助法,对于总数n的样本集合,先进行n次有放回的随机抽样,作为训练集。再将没有被抽到的样本作为验证集。自助法缺点是改变了原有数据的分布。

时间切割,避免发生用t n时间窗口的数据,预测t 0的时间。方法是如有30天的样本,从第25天末开始切割,前25天样本作为训练集,后5天作为测试集。缺点是整个评估过程是静态的,模型不会随着评估进行而更新。

离线replay,在离线状态下对线上更新过程进行仿真。先根据产生时间对样本由早到晚排序,再让模型根据样本时间先后进行预测。在模型更新的时间点,模型要增量学习更新时间点之前的所有样本,更新模型后,再继续评估更新点之后的样本。

chatGPT的训练过程

1.用570GB文本数据训练出有1750亿参数的超大规模预训练模型GPT。 2.用人工生成的约1万5千个prompt和预期输出样本对GPT微调。 3.准备20万个prompt集合,用初步微调的GPT模型对每个prompt生成4-9个回答,再根据回答质量、准确度进行人工排序,生成20万个奖励模型训练样本。 4.用20万个排序样本进行奖励模型训练,使模型具备判断回答优劣的能力,奖励模型中的文本编码器复用预训练好的GPT模型。 5.用奖励模型和用户反馈微调GPT模型,最终成为具备精准回答不同人类问题的chatGPT模型。

大模型推荐系统

1.亚马逊PALR,构造自然语言prompt,把所有用户行为历史、用户画像、候选物品列表告诉大模型,让大模型根据这些输入进行候选物品的排序并得出最终的推荐列表。 2.华为ClickPrompt,有CTR模型和大预言模型,将CTR模型输出转化为prompt embedding,和大模型融合起来。