这几乎是特征工程里占大半时间的工作了:如何描述个性化并且用变量表示成特征。一般方法就是,想想你就是该商品的目标用户,你会想要什么样的个性化。比如说我们做一个女性衣服类的推荐引擎,这个网站卖各种牌子颜色尺寸等。我们列出可能相关的一些特征,然后在实际购买数据里面检查他们是否对购买结果产生影响和关联性。比如,从购买数据里可以看出,女性对衣服的品牌多数有固定偏好,比如我太太就很喜欢LOFT的衣服。这些能对购买产生影响的因素都可以成为特征。
这部分工作需要很多领域知识,一般需要一组的研究人员讨论,要认真的思考这个特定问题有些什么和别的问题不同的特征,也建议和市场部销售部等有领域知识的专家讨论。经验上来说,这些特征提取的越多越好,并不用担心特征过多,因为推荐系统的数据量都比较大,并且基于一些规则可以很好的筛选特征。
很多机器学习的方法也可以拿来提取一些比较不容易得到的直接特征,比如说原始数据里面没有人工标记过商品的颜色,这些颜色可以通过图像识别得到。统计规则也可以从销售数据里得到一些特征,比如该商品的流行程度。
注意,这些特征可能是固定不变的,比如颜色,品牌等。它也有可能随着时间变化,比如商品的销售排名。实际经验来说,时间变化采样的颗粒度要按照实际推荐效果来决定,很可能过去三个月的销售排名对推荐效果来说可以很稳定,也或许昨天的排名对今天的推荐效果比三个月平均更好。
什么样的特征适合用来预估ctr?这个问题是很多广告算法工程师的需要考虑的。
机器学习算法最多会大谈模型,对于特征的讨论很少涉及。真正的应用中,多数数据挖掘工程师的工作都是在想特征,验证特征。
想特征是一个脑力加体力的活,需要不少的领域的知识,更让人郁闷的是,工业界并没有一整套想特征的办法,工业界有的只是验证特征的办法。对于互联网广告业,就简单说说通用特征怎么来的吧。
首先说年龄这个特征,怎么知道它跟点击率有关系?现在直观的解释是,年轻人普遍喜欢运动类的广告,30岁左右的男人喜欢车,房子之类的广告,50岁以上的人喜欢保健品的广告。可以看到,选择年龄作为特征的理由是基于对各个年龄段的人喜欢的不同类型的东西的一个粗略的划分,是一个很主观的东西。
再说性别这个特征,直观的感觉是,男性普遍喜欢体育类的,车类的,旅游类广告,女性普遍喜欢化妆品,服装类的广告。这也可以看到,选择性别作为特征也是基于相似的理由,就是认为男性和女性大体会喜欢不同的东西。
对于地域这个特征,这下就学问多了,华南的人在比较喜欢动漫和游戏,华北的人喜欢酒品和烟?
在广告方面的特征,广告的图片大小,广告前景色背景色真的能影响人的点击吗?这其实都是一种猜测。图片里面是一个明星还是一个动物之类的因素也可以考虑。
总之,想特征的这个事情基本没多大谱,只能天南地北地想象,还要多了解各行各业的知识,以便想到更多的特征,哪怕某个特征跟人关系并不大,也得好好验证一番。这基本上跟男人为回家晚想借口一样,得有借口要想着怎么解释得好听点,没借口就要想借口。
想到了特征,就要分析、验证和进行判断。
再说年龄这个特征,怎么知道它跟点击率有关系?
只好去看看每个年龄段的人在各个广告上面的表现,比如经过跑数据分析,发现20~30岁之间的男性用户对车、房子之类的广告点击率比较高,而50岁以上的用户对保健品的广告点击率比较高。这就有了区分性了,说明年龄这个特征是对点击率是有预测能力的。
再说性别这个特征,去把每个性别对各个广告的点击率跑出来。根据结果,发现男性用户体育类的,车类的广告点击率比较高;而女性用户则对化妆品,服装类的广告点击率比较高。这就说明了性别这个特征对点击率是有预测能力的,因为有区分性。
实际分析过程中发现,性别这个特征比较有效,手机平台这个特征也比较有效,地域和年龄这两个特征有一定效果,但没有前两个那么明显,跟他们的使用方式可能有关,还需要进一步挖掘。
实际使用中也发现,实时广告ctr这个特征也很有效,这个特征的意思就是当前的广告正在投放,已经投放了一部分了,这部分的点击率基本可以认为是这个广告的点击率了,也可以认为是这个广告的质量的一个体现,用来预估一个流量的ctr是很有效的。
本文假定通过前面的分析,确定模型中考虑实时广告ctr,用户年龄,性别三个特征。
解决两个特征的差没有意义的情况
假设暂定有实时广告ctr,用户年龄,性别三个特征想要使用。
实时广告ctr是一个浮点数,直接作为特征是可以的,假设1号特征就是反馈ctr。
对年龄来说就不是这样了,因为年龄不是浮点数,而且年龄的20岁跟30岁这两个数字20,30大小比较是没有意义的,相加相减都是没有意义的,在优化计算以及实际计算ctr是会涉及这两个数字的大小比较的。如w.x,在w已经确定的情况下,x的某个特征的值是20,或者30,w.x的值相差是很大的,哪怕用逻辑化公式再比较,得到的值也是比较大的,但是往往20岁的人跟30岁的人对同一个广告的兴趣差距不会那么大。解决这样的情况的方法就是,每个年龄一个特征,如总共只有20岁到29岁10种年龄,就把每个年龄做一个特征,编号是从2到11(1号是广告的反馈ctr),如果这个人是20岁,那么在编号为2的特征上的值就是1,3到11的编号上就是0。这样,年龄这一类特征就有了10个特征,而且这10个特征就是互斥的,这样的特征称为二值特征。
对于性别来说也是,两种性别,分别编号到12、13号特征上就完成了二值化了。
特征经过交叉之后,可以将二值化阶段拆分的特征重新合并成一个。
二值化看起来就能解决两个特征的差没有意义的问题了,但是够了吗?
比如一个人是20岁,那么在编号为2的特征上面,它一直都是1,对篮球的广告是1,对化妆品的广告也是1,这样训练的结果得到的编号为2的权重的意义是——20岁的人点击所有的广告的可能性的都是这个权重,这样其实是不合理的。
有意义的应该是,这个20岁的人,当广告是跟体育相关的时候,它是一个值;当广告跟保健品相关的时候,它又是另一个值这样看起来才合理。
因为特征需要根据人和广告的关系不断变化,才能使得一个人对不同的广告预估出不同的ctr来,如果特征不能跟着广告变化,那么一个用户对所有广告都预估出同一个值来,也是不行的。
基于跟上面同样的道理,性别这个特征也是一样的,假如也做了上面的离散化操作,编号是12和13,12是男性,13是女性。这样的话,对于一个男性/体育广告组合来说,编号12的特征值为1,男性/化妆品的组合的编号12的特征值也是1。这样也是不合理的,主观看过去都不合理。
示例:
怎么做到合理呢?以上面的性别的例子来说。编号12的特征值不取1,取值为该广告在男性用户上面的点击率,如对于男性/体育广告的组合,编号12的特征的值为男性在体育广告上面点击率,这样,编号为12的特征就变成了一个浮点数,这个浮点数的相加减是有意义的,这个浮点数的值越大,意味着这个性别的用户对该广告越感兴趣。这样过后,同一个用户,对不同的广告主,编号为12的位置的值都不一样了。而且这样可以不用编号为13的特征了,直接拿性别/广告的组合的点击率作为编号12的特征的值,两种性别都考虑到了。其实也就是说,经过组合后,年龄和性别各自又变回了一个特征,这个特征的值会随着不同的广告变化的,这个值跟广告有关。
这样的做法称为特征的交叉,现在就是性别跟广告的交叉得到的特征值。还有很多其他的方式可以进行交叉,目前应用起来效果比较好的就是广告跟性别的交叉特征,广告跟年龄的交叉特征,广告跟手机平台的交叉特征,广告跟地域的交叉特征。如果做得比较多,可能会有广告主(每个广告都是一个广告主提交的一个投放计划,一个广告主可能会提交多个投放计划)跟各个特征的交叉。
用途:对点击反馈ctr特征进行平滑处理,避免因数据稀疏性,对整体点击反馈ctr的影响。
广告点击率CTR是度量一个用户对于一个广告的行为的最好的度量方法,广告点击率可以定义为:对于一个广告的被点击(click)的次数于被展示(impression)的次数的比值。
CTR=#click#impression
在计算CTR时,由于数据的稀疏性,利用上述的计算方法得到的CTR通常具有较大的偏差,这样的偏差主要表现在如下的两种情况:
例如展示impression的次数很小,如1次,其中,点击的次数也很小(这里的很小是指数值很小),如1,按照上述的CTR的计算方法,其CTR为1,此时的点击率就被我们估计高了;
例如展示的次数很大,但是点击的次数很小,此时,利用上述的方法求得的CTR就会比实际的CTR要小得多。
出现上述两种现象的主要原因是我们对分子impression和分母click的估计不准确引起的,部分原因可能是曝光不足等等,对于这样的问题,我们可以通过相关的一些广告的展示和点击数据对CTR的公式进行平滑处理。
关于这个问题雅虎出了个paper,能很好地解决这个问题,是用贝叶斯学派的方法的。
首先两个假设。
假设一,所有的广告有一个自身的ctr,这些ctr服从一个Beta(α,β)分布。
假设二,对于某一广告,给定展示次数时和它自身的ctr,它的点击次数服从一个伯努利分布 Binomial(I, ctr)。
如果用r表示点击率,I表示展示,C表示点击。这两个假设可以用下面的数学表示。
根据这两个假设,假如已经有了很多个广告投放数据,I1,C1,I2,C2……In,Cn,就可以根据这些投放数据列出似然函数
求解这个极大似然问题,得到两个参数alpha(α)和beta(β),然后每个广告的点击率就可以利用这两个参数计算后验ctr(平滑ctr)了,公式如下:
r=(C + alpha) / (I + alpha + beta)
有了这个技术,上面说的那些交叉特征的特征值都用这个技术平滑了一下,就避免了出现1.0或者正无穷这种这么病态的特征值,因为一般都是很小的特征值。
事实证明,平滑技术很有效。
特征在不同区间的重要程度是不一样的,连续特征默认特征的重要程度和特征值之间是线性的关系,但往往是非线性的,即特征值在不同区间的重要程度是不一样的
假设还是实时广告ctr,用户年龄,性别三个特征,经过上一次交叉和平滑,现在得到了3个特征值,实时广告ctr编号为1,年龄与广告交叉特征编号为2,性别与广告交叉特征编号为3。现在就三个特征了了。
这三个特征直接训练logisticregression模型,可以吗?可以的,但是线上效果并不好。为啥?这倒是个问题。看看下面的解释。
如编号为1的那个特征,就是广告实时的ctr,假设互联网广告的点击率符合一个长尾分布,叫做对数正态分布,其概率密度是下图(注意这个是假设,不代表真实的数据,从真实的数据观察是符合这么样的一个形状的,好像还有雅虎的平滑的那个论文说它符合beta分布)。
对于不同档次的点击率来说,重要程度是不一样的,比如在接近对数正态分布的那个拱附近(0.2%左右)的点击率,由于这类型的情况比较多,重要程度并不高,特征的权重需要小一点;但是对于接近那个长尾的那些点击率来说,这种情况比较少,重要程度高,特征的权重也应该大一点。下面是重要程度分布图。
如果直接用ctr的那个浮点值作为特征,训练后,对这个特征,只有一个权重,没办法把重要程度区分开来,所以效果不好。
当然,点击率与重要程度不一定是完全的正相关性,有可能值越大特征越重要,也有可能值增长到了一定程度,重要性就下降了。这样的就是非线性的情况,利用一个线性的方式去拟合,效果自然打折扣。
解决的方法就是把ctr那个浮点值离散化。
百度有科学家提出了对连续特征进行离散化。他们认为,特征的连续值在不同的区间的重要性是不一样的,所以希望连续特征在不同的区间有不同的权重,实现的方法就是对特征进行划分区间,每个区间为一个新的特征。
具体实现是使用等频离散化方式:1)对于上面的编号为1的那个特征,先统计历史记录中每条展示记录中编号为1的特征的值的排序,假设有10000条展示记录,每个展示记录的这个特征值是一个不相同的浮点数,对所有的展示记录按照这个浮点数从低到高排序,取最低的1000个展示记录的特征值作为一个区间,排名1001到2000的展示记录的特征值作为一个区间,以此类推,总共划分了10个区间。2)对特征编号重新编排,对于排名从1到1000的1000个展示记录,他们的原来编号为1的特征转变为新的特征编号1,值为1;对于排名是从1001到2000的记录,他们的原来编号为1的特征转变为新的特征编号2,值为1,以此类推,新的特征编号就有了1到10总共10个。对于每个展示记录来说,如果是排名1到1000的,新的特征编号就只有编号1的值为1,2到10的为0,其他的展示记录类似,这样,广告本身的ctr就占用了10个特征编号,就成为离散化成了10个特征。
另外的两个交叉ctr也是用这样的方式离散化成了10个特征,那样总共就有了30个特征。训练的结果w就会是一个30维的向量,分别对应着30个特征的权重。
实际的应用表明,离散化的特征能拟合数据中的非线性关系,取得比原有的连续特征更好的效果,而且在线上应用时,无需做乘法运算,也加快了计算ctr的速度。
用户的特征我们往往无法拿到具体值,比如性别,通过用户的浏览行为并不能完全定义其性别,而且也很难直接用某个具体指进行表示,比如品牌特征,用户往往并不是只对某一品牌感兴趣,而是对多个品牌感兴趣,只是感兴趣的程度不一样,因此需要用向量来表示用户特征,具体示例如下。
品牌特征,拿女性服饰类举例。比如我太太很喜欢LOFT的衣服,但如果一个推荐引擎使劲给推荐LOFT牌的衣服,她也会很烦。所以品牌并不完全是一个直接特征,它可以有一些变化。比如从购买数据里面看到,购买了LOFT牌衣服的,有20%也购买了J Crew牌,15%也购买了Ann Taylor牌。所以 LOFT 这个特征应该变成一个向量 [LOFT:1, J_Crew:0.2, Ann_Taylor:0.15, … ]。实际效果上它提高了推荐的多样性,在多个测试函数中都有不错的提升。
间接特征另外一个高级一些的例子就是用户职业。绝大多数用户都不会填自己的职业等个人相关信息,主要是因为隐私或者就是因为麻烦。从用户的购买记录和浏览记录里面,我们可以定义几个预设的职业类型然后用户的职业预测到这几个类型里。比如用户买过一些转换插头和充电器还有旅行电脑包,所以他可能常外出旅行,所以以后推荐的商品可能是轻便携带;又比如用户买过母婴用品就知道该用户可能自己是妈妈或者家里有小孩。
其实性别特征也是,比起我们直接认定某用户是男性还是女性,将其特征向量化为[男性0.8,女性0.2]更合理,因为即使是男性也可能会和部分女性的兴趣一致。毕竟目前性别的界限越来越不明确,很多产品都是同时可以满足男性和女性的需求。
准确率:策略命中的所有相关订单/策略命中的所有订单 召回率:策略命中的所有相关订单/所有的相关订单(包括策略未被命中的) F1-score(F1-分数):2×准确率×召回率/(准确率+召回率),是模型准确率和召回率的一种加权平均,它的最大值是1,最小值是0。(详细介绍见下) ROC:ROC曲线的横坐标为false positive rate(FPR,假正率),纵坐标为true positive rate(TPR,真正率,召回率) AUC:被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。
1.recall 假定:从一个大规模数据集合中检索文档的时,可把文档分成四组:
系统检索到的相关文档(A)(TP)
系统检索到的不相关文档(B)(FP)
相关但是系统没有检索到的文档(C)(FN)
不相关且没有被系统检索到的文档(D)(TN) 则:
召回率R:用检索到相关文档数作为分子,所有相关文档总数作为分母,即R = A / ( A + C )
准确率P:用检索到相关文档数作为分子,所有检索到的文档总数作为分母.即P = A / ( A + B ).
2.举例来说: 一个数据库有500个文档,其中有50个文档符合定义的问题。系统检索到75个文档,但是只有45个符合定义的问题。 召回率R=45/50=90% 精度P=45/75=60% 本例中,系统检索是比较有效的,召回率为90%。但是结果有很大的噪音,有近一半的检索结果是不相关。研究表明:在不牺牲精度的情况下,获得一个高召回率是很困难的
正如我们在这个ROC曲线的示例图中看到的那样,ROC曲线的横坐标为false positive rate(FPR),纵坐标为true positive rate(TPR)。 接下来我们考虑ROC曲线图中的四个点和一条线。第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false positive)=0。Wow,这是一个完美的分类器,它将所有的样本都正确分类。第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true positive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。类似的,第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。
下面考虑ROC曲线图中的虚线y=x上的点。这条对角线上的点其实表示的是一个采用随机猜测策略的分类器的结果,例如(0.5,0.5),表示该分类器随机对于一半的样本猜测其为正样本,另外一半的样本为负样本。
对于一个特定的分类器和测试数据集,显然只能得到一个分类结果,即一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值,这又是如何得到的呢?我们先来看一下Wikipedia上对ROC曲线的定义:
In signal detection theory, a receiver operating characteristic (ROC), or simply ROC curve, is a graphical plot which illustrates the performance of a binary classifier system as its discrimination threshold is varied.
问题在于“as its discrimination threashold is varied”。如何理解这里的“discrimination threashold”呢?我们忽略了分类器的一个重要功能“概率输出”,即表示分类器认为某个样本具有多大的概率属于正样本(或负样本)。通过更深入地了解各个分类器的内部机理,我们总能想办法得到一种概率输出。通常来说,是将一个实数范围通过某个变换映射到(0,1)区间3。
假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变“discrimination threashold”?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率4。
接下来,我们从高到低,依次将“Score”值作为阈值threshold,当测试样本属于正样本的概率大于或等于这个threshold时,我们认为它为正样本,否则为负样本。举例来说,对于图中的第4个样本,其“Score”值为0.6,那么样本1,2,3,4都被认为是正样本,因为它们的“Score”值都大于等于0.6,而其他样本则都认为是负样本。每次选取一个不同的threshold,我们就可以得到一组FPR和TPR,即ROC曲线上的一点。这样一来,我们一共得到了20组FPR和TPR的值,将它们画在ROC曲线的结果如下图:
当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。
其实,我们并不一定要得到每个测试样本是正样本的概率值,只要得到这个分类器对该测试样本的“评分值”即可(评分值并不一定在(0,1)区间)。评分越高,表示分类器越肯定地认为这个测试样本是正样本,而且同时使用各个评分值作为threshold。我认为将评分值转化为概率更易于理解一些。
TP —— True Positive (真正, TP)被模型预测为正的正样本;可以称作判断为真的正确率 TN —— True Negative(真负 , TN)被模型预测为负的负样本 ;可以称作判断为假的正确率 FP ——False Positive (假正, FP)被模型预测为正的负样本;可以称作误报率 FN—— False Negative(假负 , FN)被模型预测为负的正样本;可以称作漏报率 True Positive Rate(真正率 , TPR)或灵敏度(sensitivity) TPR = TP /(TP + FN) 正样本预测结果数 / 正样本实际数 True Negative Rate(真负率 , TNR)或特指度(specificity) TNR = TN /(TN + FP) 负样本预测结果数 / 负样本实际数 False Positive Rate (假正率, FPR) FPR = FP /(FP + TN) 被预测为正的负样本结果数 /负样本实际数 False Negative Rate(假负率 , FNR) FNR = FN /(TP + FN) 被预测为负的正样本结果数 / 正样本实际数
一个相关订单并不一定,一定会被策略命中,只是一个概率值,不过通常相比一个不想关订单被命中的概率越大。 因此一批样本被输入进策略中,返回的TPR和FPR并不固定。 针对这个问题,我们将一批样本中的每个样本输入策略中,策略命中这个样本的概率座位一个score分值。这样每一个样本就对应一个SCORE值。
AUC代表什么意思这句话有些绕,我尝试解释一下:首先AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值。当然,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。 score值的阈值代表了对这个策略的认可度。只有当这个策略认为某样本在90%以上的概率是真时,我们才认为这个样本是真。
为什么使用ROC曲线既然已经这么多评价标准,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线5的对比:
在上图中,(a)和(c)为ROC曲线,(b)和(d)为Precision-Recall曲线。(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,(c)和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。
[1]计算广告——平滑CTR
[2]互联网广告系统综述七特征
[3关于推荐系统中的特征工程 - 文章 - 伯乐在线
转自:https://zhuanlan.zhihu.com/p/27033340