作者:赖博先
最近准备为神盾推荐系统做一些特征工程相关的插件,整理了一些特征工程相关的方法,在这里跟大家分享,希望对大家有帮助!后期也会把插件的工程实践经验跟大家分享!
随着我们底层特征库中特征数目的不断增长,如何组合特征,如何针对不同场景选择适合的特征,如何评估特征优劣?这些问题已经日益凸显,所以这次想梳理现有的特征工程方法,并将通用的模块抽象成工具,封装到神盾离线计算平台。
对于一个推荐场景,特征构造主要是根据业务目标来扩展的,也就是说哪些因素会对业务目标产生影响,那么就可能是我们需要构造的特征(笔者理解的所谓特征其实就是一系列独立存在,且可以被测量或者描述的属性);举个例子,假如你现在想在人群中找到你的朋友;这个场景的目标是找到你的朋友,那么你会怎么来找呢?当然你会根据你朋友的长相、身高、穿着、说话声音等等来进行判断,综合这些因素,你或许可以完成你的场景目标——找到你的朋友。
再举一个实际业务场景例子,比如游戏列表推荐,要构造这个场景的特征,首先可以分析出这个场景是由三个成分组成的:受众(用户)、推荐内容(游戏)、平台(业务场景),那么我们在构造特征也是从三者入手,比如用户有什么特征,年龄、性别、学历、地域等等,这些是用户画像,对应数据中心的达芬奇系统;游戏呢!有品类、游戏 ARPU、付费参透率等;场景特征,PU,UV,点击,下载量等;除了单个成分去提取之外,还可以组合提取,也就是把用户的单特征和游戏、平台的单特征可以进行两两组合。比如用户 VS 游戏,如不同年龄、性别对游戏的偏好;平台 VS 游戏,某个游戏或者某个品类的游戏在这个场景下的点击、下载特征;这种组合特征的方式可以是内积、外积和笛卡尔积,它们都可以帮助我们构造非线性的特征,当然这样做也会大大增加特征维度,特别是笛卡尔积。当然这种人肉组合的方式在对业务有深刻的理解下是可以构造出出色的特征,但时间这种方式时间周期长,也需要进行线上线下测试来检验特征效果。
惰性是推动科技发展的动力,很多算法工程也在思考,能不能通过模型的方式来自动的学习和构成特征呢?"所有的想法都会有实现的一天",现在市面上有效的特征构造模型有 FM(Factorization Machine 因子分解机)、深度学习(提取训练好的模型中隐层作为特征)可以自己学习出一些特征以及特征之间的组合关系。笔者使用过主题模型 LDA、word2vec、FM 来作为特征生成的模型,将模型训练的中间结果,比如 LDA 的主题分布、word2vec 生成的词向量用于 LR 这样的线性模型,线上测试效果都非常好。
通过上面的例子我们可以知道特征构造大致思路,也就是从场景目标出发,去找出与之有关的因素。但是在实际场景除了天马行空想特征之外,还需要对于想出来的特征做一可行性评估:获取难度、覆盖度、准确度等,比如笛卡尔积会使得特征维度增加的非常快,会出现大量覆盖度低的特征,如果把这些覆盖度低的特征加入到模型中训练,模型会非常不稳定;然而这一系列的工作就是传说中的特征工程。
在实际生产环境中,业务数据并非如我们想象那样完美,可能存在各种问题,比如上报异常、恶意作弊行为、爬虫抓取等。为了让模型能够学到真实的行为规律,我们需要对已经构造的原始特征进行清洗,排除掉脏数据。主要包括一下两个方面:
1.结合业务情况进行数据的过滤,例如去除 crawler 抓取,spam,作弊等数据。
2.异常点检测,采用异常点检测算法对样本进行分析,常用的异常点检测算法包括
例如极差,四分位数间距,均差,标准差等,这种方法适合于挖掘单变量的数值型数据。全距(Range),又称极差,是用来表示统计资料中的变异量数(measures of variation) ,其最大值与最小值之间的差距;四分位距通常是用来构建箱形图,以及对概率分布的简要图表概述。
主要通过距离方法来检测异常点,将数据集中与大多数点之间距离大于某个阈值的点视为异常点,主要使用的距离度量方法有绝对距离 ( 曼哈顿距离 ) 、欧氏距离和马氏距离等方法。
考察当前点周围密度,可以发现局部异常点,例如 LOF 算法
很多特征开发出来之后,可能并不在同一个值域中,比如用户对某个游戏的活跃时长特征,可以是 1000s 或者 10000S 这样,而用户的性别的取值是 0 或者 1,那么这两个特征如果不做处理,直接放入模型中进行训练,会严重影响模型效果。下面介绍一些单特征预处理的以一些方法:
归一化有很多好处,比如可以加快梯度下降寻找最优解的速度,可以提升模型的精度,同时也使得特征之间具有可比性,当然所有的事情都是双面的,经过归一化处理之后,会损失掉源特征的一些信息,但这个损失相对应带来的好处我们还是可以接受的。
归一化可以分成以下类型:
这种归一化方法比较适用在数值比较集中的情况。这种方法有个缺陷,如果 max 和 min 不稳定,很容易使得归一化结果不稳定,使得后续使用效果也不稳定。实际使用中可以用经验常量值来替代 max 和 min。
在完全随机的情况下,我们可以假设我们的数据是符合标准正态分布的,也就是均值为 0,标准差为 1;那么其归一化函数如下:
在数据分化比较大的场景中,有些数值很大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。需要根据数据分布的情况,决定非线性函数的曲线,比如 log(V, 2) 还是 log(V, 10) 等。
实际业务中我们可以根据自己对数据的理解进行不同的归一化方法,下面是手游推荐业务使用到的归一化函数:
正向特征,特征越大打分越大,例如付费金额
其中
反向特征,特征越大打分越小,例如首次付费距离当前天数
其中
汇总特征,取均值,例如活跃天
=score/天数
可能很多同学会问,这样的归一化为啥会比其他归一化更好呢!或许数学家们可以从公式上进行推到证明,而我们的理解是,其实每个业务的数据都会有特定的分布,比如完全随机的时候数据满足正态分布,那么所选择的方法必须要符合这种数据分布的特点,一般情况下会根据自己对业务数据的了解,对公式进行调整,但是归一化的思路还是跟上面提到的一样的。
离散化也可以理解成特征的二值化,即是把原来连续的特征值分段,转化成一个元素取值要么是 0 要么是 1 的向量。原始值落在某个段里,向量中此段对应的元素就是为 1,否则为 0。其中对原始值进行分段,具体如何分、分成几分,这里面又很多学问;离散化对于线性模型来说是非常有帮助的,原因是它可以将目标值 Y 与特征值的线性转为目标值与离散化之后转化的向量里的每个元素之间的线性关系,这样向量的每个分量都有一个权重,引入了非线性,提升了模型拟合能力。之前做过实验,使用同样的特征,有经过离散化处理的特征训练出来的模型,会比没有经过离散化训练出来的模型效果好 20%以上;现在使用比较多的特征离散化的方法有,等频离散、等距离散、树模型离散。
等频意思是说我们在对特征值进行离散的时候,根据样本点量来选取分割点,举个例子假设就是我们有 1000 个样本,每个样本对应于需要进行离散化的特征都会有一个值,把这个值做一个排序,假设将特征离散成 10 段,等频就是说 10 个分段里面的样本数是相同的(0,100)一段,排在 100 这个样本对应的特征值就是一个分割点,依次类推。这种分割方式可以保证每个离散分量有相同的样本数,但也会出现特征值差异非常大的样本被放在一个分段的情况。
等距离散顾名思义就是我们根据特征值来进行离散化,比如特征取值是 0~10,将特征离散成 5 段,那么【0~2)第一个分段,【2,4)一个分段,以此类推;使用这种离散化的方式需要样本分布均匀,不然会出现一个分段占据了大部分的样本,这样不同时间训练出来的模型会偏差很大,也就是说模型不鲁棒。
树模型是在机器学习中使用非常广泛的非线性模型,其因简单、直观、解释性强而被广泛用于工业界。说到树模型,可能大家第一印象肯定是决策树,决策树的直观理解就是一堆 if else,所以这种模型天生具有对连续型特征切分的能力,用于特征离散化也是合情合理的。实际操作中,我们可以单独连续特征和目标值 y 训练一个决策树模型,然后把训练获得的模型内的特征分割点作为离散化的离散点。
在实际业务中,可能会因为各种原因会造成数据的缺失,比如某些用户年龄、性别、设备这类型的特征无法获取到,同时线上模型又有使用这些类型的特征,那么缺失了这些特征的用户在线上打分的时候会出现比较大的偏差;通常会有几种方式来进行处理:数值型特征可以使用均值或者中位数进行简单的替换,年龄这类型的特征可以通过关系链进行加权打分,当然也可以通过把缺失的全部都归为一类,用户默认值来替代。
当然对于新用户或者新 item 来说其实也是属于一种缺失值情况,对于这种情况已经属于领一个非常大的领域,那就是推荐系统的启动问题。对于冷启动我问题,现在的做法会从两个方面着手,一种是通过集体智慧来解决,另外一种是通过网络模型;第一种方法就是使用协同过滤的思想,与这个新用户类似的用户表现来知道新用户的推荐。第二种利用网络把 item 周围信息考虑进去,比如下面会提到的层次平滑,热传导模型也可以通过引入基础属性到二部图中,达到解决冷启动问题。
在推荐场景中会有大量的点击率类型的特征,这类型的特征通常都是使用行为操作量/曝光量得到,这类统计类特征会受到行为操作与曝光量之间的关系的影响;比如同一个游戏的 banner 的随着曝光量的增长,点击量的增长率是会不断下降的,也就是说如果不做任何处理行为操作量/曝光量产生的特征对曝光量大的游戏是不公平的。对于曝光量小 item 是有利的,极端的例子是曝光一次,点击一次,那么点击率就是 100%,这明显是不可能的;那么如何做呢?一种常用的方式是训练一个 beta(a,b)分布,使用(行为操作量 a)/(曝光量 a b);原理是我们可以把每次点击与不点击看成是一个伯努利分布,那么所有用户与所有游戏这种点击与不点击对可以看成是一个 beta 分布,从全局的角度学习到平滑因子;
还有一种方法是,既然不能对不同量级的曝光量进行比较,那我们可以把曝光量进行分段,同一个曝光量级的点击率进行比较。当然还有一种叫做层次平滑的算法,把游戏进行分类,如果单个游戏的曝光量很少,可以使用所述类的平均值进行平滑处理。
特征选择的目的是选择模型最优特征子集。特征与特征之间多多少少会有一些相互作用,比如有些特征是包含其他特征,有些特征与另一些特征存在相关性的,也有一些特征需要与其他特征组合起来才能起作用,还有一些特征是会存在负相关的;正是因为特征之间的这些关系,合理的选择适合的特征集合对于模型效果有非常大的作用。现有的特征选择方法可以大体分成三种类型:
1、Filter
这种方法是衡量单个特征值与目标变量也就是样本 label 值之间的关联,常用的方法有:
2、Wrapper
Wrapper 这一类特征选择方法,应该来说是比较科学的,但是也是非常耗时,工业界在生产环境中很少使用,非常耗时,也是一个 NP 复杂的问题,一般通过不断迭代,然后每次加入一个特征,来训练模型,使用模型评估比如 AUC 或者 MSE 等函数评估是否将特征加入到特征子集中。
3、Embedded
Embedded 方法我觉得是一个比较可行的一种方法,它的思想是使用模型自身自动的选择特征,比如正则化——L1 Lasso 具有特征选择能力,决策树,每次选择分类节点时,都会选择最佳的分类特征来进行切分,高级一点的如深度学习,很多项目组也在开始使用比如 CNN 或者 RNN 进行特征选择。
前面写了很多特征构造和处理的方法,可能更多时间我们更想知道一个特征是否真的靠谱,在时间有限的情况下,用贪心的思想,每次选择表现最好的特征加入到模型训练中,这个时候就会特征评估这个东西了,特征评估可能会从几个维度进行衡量:
1、特征自身的质量
2、特征与目标值的相关性
特征工程主要功能模块划分,主要是从特征类型上进行划分,单特征主要包括特征分析、特征组合、特征评估;多特征包括特征选择;衍生特征:特征构造,主要是用过现有特征,通过模型学习的方式生成新特征。
1、单特征(特征报告)
2、多特征(特征选择)
3、衍生特征(特征生成)
斯坦福机器学习视频 特征选择常用算法综述 Weka 3: Data Mining Software in Java Stanford机器学习---第十讲. 数据降维 机器学习中的数学(4)-线性判别分析(LDA), 主成分分析(PCA) 维基百科:Supervised learning 维基百科:维数灾难 《Click-Through Rate Estimation for Rare Events in Online Advertising》 《elements of statistical learning》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。