计算广告常用指标
ROI (Return On Investment): 投资回报率 =订单额/消费量(即广告费用)=(单均额转化量)/(CPA转化量)=单均额/CPA
CPC (Cost Per Click): 按点击计费(平均点击价格)=消费量/点击量
CPA (Cost Per Action): 按成果数计费 =消费量/转化量=(CPC点击量)/(CVR点击量)=CPC/CVR
CPM (Cost Per Mille): 按千次展现计费(千次展现价格)=(消费量/展现量)×1000
CVR (Click Value Rate): 转化率,衡量CPA广告效果的指标 =转化量/点击量
CTR (Click Through Rate): 点击率 =点击量/展现量
PV (Page View): 流量(即页面浏览量,不管是否相同IP,只要对目标页面进行一次有效访问即为1pv)
UV (Unique Visitor):独立访客,一台电脑24小时以内访问N次计为1次(同一天内,uv只记录第一次进入网站的具有独立IP的访问者,在同一天内再次访问该网站则不计数.)
ADPV (Advertisement Page View): 载有广告的pageview流量
ADimp (ADimpression): 单个广告的展示次数
PV单价: 每PV的收入,衡量页面流量变现能力的指标
RPS (Revenue Per Search): 每搜索产生的收入,衡量搜索结果变现能力指标
GSP——广义二阶竞价规则
常见对的一阶竞价规则是:每个竞价者不公布自己的出价,把它密封在信封里交给卖主,拍卖主让最高出价者赢得竞拍,并且支付最高出价者的出价。
**有人说,这种方式看起来很完美啊,符合广告主不公开报价的需求,而且也被很多实践证明过,然而这种竞价方式广告主的出价策略取决于别人怎么出,反而和自己的真实估值关系不大,而这应用到在线广告拍卖就会存在问题。
在线广告一个特征就是重复博弈,什么意思呢?比如线下的工程招标是一次性的,竞拍者会更加倾向于谨慎对待自己的出价,因为他只有一次机会。然而在线广告是多次的,即广告主有多次机会不断试探别人的出价,从而实现自己的最优策略。
在最简单的GSP拍卖中,对于一个特定的关键词,广告主给出他对一次点击的最高出价。 当用户 输入一个关键词,用户会得到搜索结果和赞助链接,赞助链接是以广告的出价降序展示的。 出价最高 的广告展示在最顶部,出价次高的展示在第二个广告位,以此类推。 如果一个用户点击了位置i上的广 告,广告主需要付下一个广告的出价,就是位置i + 1上的广告出价。 如果一个搜索引擎只展示一个 广告,那GSP机制就与标准的Second-Price或是Vickrey-Clarke-Groves(VCG)没有区别。 当有多个广告 位时,在GSP机制下,每个广告主对每次点击付费为下一名的出价。我们将会解释, 这种多个广告位 的GSP拍卖与VCG不等价,并缺乏一些VCG的一些好的特性。 特别是,不同于VCG机制,GSP一般在 占优策略中没有一个均衡点。
GSP中每个广告主对每个关键词只能给出一个出价――尽管可能是不同的商品出售(在不同的广告 位)。 GSP的不寻常出价要求在下面的场景中是合理的:每个广告位的价值区别在于每个广告位所能带 来的点击量不同, 一个广告在较高的位置的好处在于这个广告得到的点击更多,但是在不同的广告位 上广告的一次点击对广告主的价值是相同的 (比如,相同的购买机率)。结果就是,尽管GSP是一个多元素的环境中,购买者的估价却可以用单无素充分表达。 对一些广告主来讲,每个关键词一个出价,可 能无法充分表达他们的意向。 比如,单一出价忽略了点击第5个广告位与点击第2个广告位用户的不同 性,等等。 不管怎么讲,这些限制显然不足以成为让竞价变复杂的理由。 Nico Brooks(2004)发现在不 同的广告位展示的广告对影响用户购买机率只有很小的差别。
我们还忽略了一个重要的因素,就是点击率,比如,在同一个广告位,两个不同的广告有着不 同的点击率。 (这个在业界被称为”click-though-rates”, 或CTR)。不同的引擎对点击率的态度不同。 Yahoo!直接忽略点击率,仅按用户的出价的降序对广告进行排序,并按下一名广告主的出价扣费。 Google将用户的出价乘上广告的质量得分(”Quality Score”),质量得分的计算基于CTR和其它因素, 质量得分被用于广告排序,每次点击付费为下一名的出价加上一个很小的值。
广义二阶拍卖,在广义一价定价拍卖中,能快速改变广告出价的广告主有着巨大的竞争优势。 这种 拍卖机制实质上鼓励了广告主们在这个系统中博弈,博弈的结果就是导致出价和配置低效,影响了引擎 的引入。 Google在2002年它提出自己的pay-per-click系统Adwords Select时指出了这个问题, Google还 指出了在广告位i的广告主只愿意比i + 1广告位的广告主多出一点, Google将这个现象融合进了它新 设计的GSP拍卖机制中,在最简单的GSP拍卖中, 在第i个广告位的广告每次点击所付的费用,等于 第i + 1个广告位的广告出价加上一个很小的值(一般是$0.01)。 这种二价定价方式使用广告主之间更友好,并更少地受到博弈的影响。
Pandas处理大数据的一些技巧
Pandas分批读取大数据集
电脑内存小在本地读取数据的时候会跑不动.
这里考虑分批读取.1
2
3
4
5import pandas as pd
df=pd.read_csv(r'E:\Click-Through Rate Prediction\test.csv',chunksize=1000000)
for chunk in df:
print chunk.shape
这里通过设置了一个chunksize来实现分批读入.
一行代码,Pandas秒变分布式,快速处理TB级数据
加州大学伯克利分校RiseLab最近在研究的Pandas on Ray,就是为了让Pandas运行得更快,能搞定TB级数据而生的。这个DataFrame库想要满足现有Pandas用户不换API,就提升性能、速度、可扩展性的需求。
研究团队说,只需要替换一行代码,8核机器上的Pandas查询速度就可以提高4倍。
其实也就是用一个API替换了Pandas中的部分函数,这个API基于Ray运行。Ray是伯克利年初推出的分布式AI框架,能用几行代码,将家用电脑上的原型算法转换成适合大规模部署的分布式计算应用。
Pandas on Ray的性能虽说比不上另一个分布式DataFrame库Dask,但更容易上手,用起来和Pandas几乎没有差别。用户不需要懂分布式计算,也不用学一个新的API。
与Dask不同的是,Ray使用了Apache Arrow里的共享内存对象存储,不需要对数据进行序列化和复制,就能跨进程通讯。
它将Pandas包裹起来并透明地把数据和计算分布出去。用户不需要知道他们的系统或者集群有多少核,也不用指定如何分配数据,可以继续用之前的Pandas notebook。
前面说过,使用Pandas on Ray需要替换一行代码,其实就是换掉导入语句。
1 | import ray.dataframe as pd |
这时候你应该看到:
初始化完成,Ray自动识别了你机器上可用的核心,接下来的用法,就和Pandas一样了。
Pandas on Ray目前还处于早期,实现了Pandas的一部分功能。以一个股票波动的数据集为例,它所支持的Pandas功能包括检查数据、查询上涨的天数、按日期索引、按日期查询、查询股票上涨的所有日期等等。
这个项目的最终目标是在Ray上完整实现Pandas API的功能,让用户可以在云上用Pandas。
目前,伯克利RiseLab的研究员们已经用45天时间,实现了Pandas DataFrame API的25%。
to_csv,to_excel的选择
在输出结果时统称会遇到输出格式的选择,平时大家用的最多的.csv, .xls, .xlsx,后两者一个是excel2003,一个是excel2007,我的经验是csv>xls>xlsx,大文件输出csv比输出excel要快的多,xls只支持60000+条记录,xlsx虽然支持记录变多了,但是,如果内容有中文常常会出现诡异的内容丢失。因此,如果数量较小可以选择xls,而数量较大则建议输出到csv,xlsx还是有数量限制,而且大数据量的话,会让你觉得python都死掉了
读入时处理日期列
我之前都是在数据读入后通过to_datetime函数再去处理日期列,如果数据量较大这又是一个浪费时间的过程,其实在读入数据时,可以通过parse_dates参数来直接指定解析为日期的列。它有几种参数,TRUE的时候会将index解析为日期格式,将列名作为list传入则将每一个列都解析为日期格式
关于to_datetime函数再多说几句,我们拿到的时期格式常常出现一些乱七八糟的怪数据,遇到这些数据to_datimetime函数默认会报错,其实,这些数据是可以忽略的,只需要在函数中将errors参数设置为’ignore’就可以了。
另外,to_datetime就像函数名字显示的,返回的是一个时间戳,有时我们只需要日期部分,我们可以在日期列上做这个修改,datetime_col = datetime_col.apply(lambda x: x.date()),用map函数也是一样的datetime_col = datetime_col.map(lambda x: x.date())
把一些数值编码转化为文字
前面提到了map方法,我就又想到了一个小技巧,我们拿到的一些数据往往是通过数字编码的,比如我们有gender这一列,其中0代表男,1代表女。当然我们可以用索引的方式来完成1
2
3
4
5data['gender'].ix[data['gender']==0] = u'女'
data['gender'].ix[data['gender']==1] = u'男'
#这里要注意一下,上面的写法是给索引找到的列修改值,而下面的方法则不会对原有值进行修改
data.ix[data['gender']==0]['gender'] = u'女'
data.ix[data['gender']==1]['gender'] = u'男
其实我们有更简单的方法,对要修改的列传入一个dict,就会达到同样的效果。
1 | data['gender'] = data['gender'].map({0:'男', 1:'女'}) |