企业级大数据项目之新闻推荐系统Word文档格式.docx
《企业级大数据项目之新闻推荐系统Word文档格式.docx》由会员分享,可在线阅读,更多相关《企业级大数据项目之新闻推荐系统Word文档格式.docx(48页珍藏版)》请在冰豆网上搜索。
基于这两个需求,我们参考了google在2010年KDD上公布的分层实验模型,结合自己的业务场景将实验空间横向和纵向进行划分。
纵向上流量可以进入独占实验区域或者是并行实验区域。
在独占实验区域,只有一层,实验可以独享流量且不受其他实验的干扰。
在分层区域,不同的应用属于不同layer,每个应用内部,又可以划分为多层,层与层之间相互不影响。
流量可以横向经过多层,每一层可有多个实验。
流量在每一层都会被重新打散。
图2-1分层分域模型图
在工程实现上,我们将google的实验模型做了一定的简化
1.横向上分为多层,每一层含一个bucket集合(默认为100),流量按照其guid和layerid被哈希到某一个bucket中,并绑定该实验的参数取值。
这个策略的本质所在就是在hash的时候考虑了两个变量:
guid和layerid,从而在不同层之间实现了流量的重新打散,保证层与层之间实验的正交性。
2.纵向上,按照流量的属性:
如地域,用户特征等把空间划分为segment,这些segment被某个实验独占,从而可以实现多个实验在不同流量域进行且占有该域下面的所有流量。
2.2评测方法
2.2.1用户调查
用户调查通常用来衡量定性的指标,成本也是比较高的,收益上不稳定。
这个工作通常我们是这么完成的,有了一个新的idea,比如"
基于星座的召回推荐"
,后续在召回里会介绍。
上线把产品,运营都拉一个大群里,让他们使用反馈。
通常如果一个决策对用户的满意度影响程度不确定且有可能波动很大的时候,我们会开启用户调查
2.2.2离线实验
获取用户行为日志,按照一定格式生成标准数据集
通常,在训练有监督的机器学习模型的时候,会将数据划分为训练集、验证集合测试集,划分比例一般为6:
2:
2。
对原始数据进行三个集合的划分,是为了能够选出效果(可以理解为准确率)最好的、泛化能力最佳的模型
训练集的作用是用来拟合模型,通过设置分类器的参数,训练分类模型。
后续结合验证集作用时,会选出同一参数的不同取值,拟合出多个分类器。
验证集的作用是当通过训练集训练出多个模型后,为了能找出效果最佳的模型,使用各个模型对验证集数据进行预测,并记录模型准确率。
选出效果最佳的模型所对应的参数,即用来调整模型参数。
如svm中的参数c和核函数等。
测试集的作用是作用是当通过训练集训练出多个模型后,为了能找出效果最佳的模型,使用各个模型对验证集数据进行预测,并记录模型准确率。
对原始数据进行三个数据集的划分,也是为了防止模型过拟合。
当使用了所有的原始数据去训练模型,得到的结果很可能是该模型最大程度地拟合了原始数据,亦即该模型是为了拟合所有原始数据而存在。
当新的样本出现,再使用该模型进行预测,效果可能还不如只使用一部分数据训练的模型。
好处是不需要一个实际的系统来供他实验,只要从日志系统提取数据集就行,可以方便快速的测试大量不同的算法。
当然商业上关心的指标诸如点击率访购率等无法获得
2.2.3在线实验
在线实验的核心就是AB测试,通过一定的规则将用户随机分成几组,不同组采用不同的策略,算法,通过统计不同组用户的各种评测指标评估策略收益,算法性能。
缺点是评测周期较长,一般的一个ab实验后评估时间大约在7-14天。
在实际工作中,往往是一个新的推荐算法或者推荐策略上线,首先经过离线评测,证明它在很多离线指标上优于现有的算法,在小流量进行ab实验,确定我们实际关心指标上的表现情况。
2.3评估指标
如何评价一个产品系统好坏
定量类如准确率,覆盖率,点击转化率,分享率,收藏率,阅读时长等等
定性类如新颖度,惊喜度等等
具体场景指标
如果你是家电商平台,除了用户端,你还要有供应链端也即商家端,那你的平台是要给用户和商家都能带来盈利的,他们都满意才能让你的平台发展壮大。
所以在这种场景下对于一个好的推荐系统,不仅能够准确地预测用户的行为,也能扩展用户的视野,帮助用户发现他们可能会感兴趣,但不那么容易发现的东西,同时推荐系统能够帮助商家将那些埋没在长尾中的好东西介绍给会对他们感兴趣的用户
回头看我们的业务场景,也是考虑了这一部分。
之前我们的资讯来源主要依靠抓取,那我们只要迎合好用户的喜好就完事大吉,但随着发展我们要扩大我们的资讯来源,我们希望这个来源能够丰富,领先,高质,后来我们加入了自媒体创作平台,问答平台等10余种来源,这时候参与推荐系统的角色就不只有用户了。
为了满足新的需求,推荐系统也做出了相应的变化,自媒体参与人数,投放率等等。
2.3.1AUC
在统计和机器学习中,常常用AUC来评估二分类模型的性能。
AUC的全称是areaunderthecurve,即曲线下的面积。
在推荐场景中则用来预测用户喜欢/不喜欢某物品
预测模型会对每一个样本预测一个得分s或者一个概率p。
然后,可以选取一个阈值t,让得分s>
t的样本预测为正,而得分s<
t的样本预测为负。
这样一来,根据预测的结果和实际的标签可以把样本分为4类:
一个二分类问题,总会有正例,负例。
那我们预测也会有正例,负例
如果本来是正的,我们预测也是正的,就是TP
如果我们预测是负例的,但其实是正的,我们预测错了,就是FN
所以每一次预测的结果,我们都可以数数,每个区域内有多少个
最理想的结果就是F开头的,都是0
TPR的意思,在所有的正例中,我们预测是正例的,也就是正确率是多少
FPR的意思是,在所有的负例中,我们预测时正例的,也就是错误率是多少
二分类的结果比方说0或者1,那么阈值是多少,一定是0.5吗?
预测的样例中大于0.5的都归于"
1"
这个分类
小于0.5的都归于"
0"
这个分类。
这样正确吗?
常规考试的阈值是60分,驾校考试的是90分。
还有的阈值比如高考本科批次线,是先有了考试结果,根据人数划线。
属于事后得出的阈值。
随着阈值t的变化,TPR和FPR在坐标图上形成一条曲线,这条曲线就是ROC曲线
图2-2AUC概念图
先看坐标系,横坐标fpr,错误率。
纵坐标tpr,正确率
再看曲线两个端点,(0,0),(1,1)。
(0,0)表示错误率是0,正确率也是0,看公式,也就是我们预测全部的数据都是负例,带有正例P的都为0。
同样的,(1,1)表示错误率是100%,正确率也是100%,表示我们预测全部的数据都是正例,当然在正样本上都是正确的,在负样本上都是错误的。
这时候回过头再看曲线,就可以理解为我们以0.1的错误率,换取了0.8的正确率
实操举例:
y=[0,0,1,1],y_pred=[0.1,0.6,0.4,0.9]
从0到1之前取阈值,比方说0,2
y_pred=[0,1,1,1]
计算tpr=1,fpr=0.5
依次画出曲线
所以AUC常常被用来作为推荐排序好坏的指标,原因在于AUC可以看做随机从正负样本中选取一对正负样本,其中正样本的得分大于负样本的概率,也就是说一个模型把正样本排在负样本前面的概率
2.3.2覆盖率
coverage=Uniq(Ru)/I
描述一个推荐系统对物品长尾的发掘能力,一个简单的定义就是推荐的物品占总物品集合的比例。
我们每天入库文章几千万,要确保这些文章都可以被曝光,特别是自媒体的文章。
随着物品集合增大,物品冷启动问题,不知道物品的质量到底受众如何,往往会由投放系统成单物品冷启动的破冰,在统计的时候再把这部分去掉。
2.3.3多样性
diversity=2sigma(1-cos(a,b))/(n*n-n)
用户的兴趣在较长时间跨度是一样的,不唯一的,一个喜欢足球的用户可能也喜欢科技,如果推荐列表只能覆盖用户的一个兴趣点,这个兴趣点在当前时刻不是用户感兴趣的,推荐列表就不会让用户感到满意,此外持久的曝光单一兴趣也会让用户感到疲劳。
我们在多样性的定义上有两种,一种是排版多样性,大家能直观看到到的大小图,多图等UI样式,以及兴趣多样性
这个指标不是越接近于两端越好,因为推荐列表过于多样,但没有考虑到用户的主要兴趣,或者考虑到了用户的主要兴趣,但缺少多样性,都是比较差的结果
0.5-0.75之间,都是得分较高的
2.3.4时效性
推荐今天的新闻显然比推荐昨天的新闻更合理,如果一个用户买了大疆无人机,如果推荐系统能够立即给他推荐相关配件,那么肯定比第二天再推荐相关配件更有价值。
很多推荐系统都会在离线状态每天计算一次用户推荐列表,然后用户在线的时候推荐给用户,显然这种设计是无法满足实时性的。
除此还有很多文章内容具有极强的时效性,比如一场比赛,在比赛结束已经出分数的情况下,推荐系统告诉用户这比赛谁谁踢进了一个球,胜利势在必得。
这种效果显然非常差的。
惊喜度,新颖度等其他定性指标可以据此进行启发式产品策略设计,但是落地到指标上我们还是用上述我们提到的指标
2.3.5商业目标
我们提到的评测指标其实都是对商业目标的一种拆解,商业目标是我们的最终目的,无论是单位用户价值还是成交量销售额。
2.4用户画像与内容画像
简单说一下用户画像和内容画像
推荐模型的特征抽取依赖用户画像和内容画像的各种标签
用户标签挖掘和内容分析是搭建推荐系统的基石
内容画像:
没有内容及文本标签,无法得到用户的兴趣标签,比如只有知道文章标签是互联网,用户看了互联网的文章,才能知道用户有互联网标签。
其他标签也一样。
内容分析在推荐系统中的作用很广泛
除了给喜欢阅读互联网文章的用户打上互联网标签之外,还可以帮助内容推荐,和生成频道内容
比如把绝地求生的内容推荐给有绝地求生标签的用户,把绝地求生的文章投进游戏频道
内容画像的一个实际case:
文章内容:
ID:
46679982,标题:
43杀,世界绝地求生击杀记录诞生
一级标签:
游戏0.8
二级标签:
手游0.9
三级标签:
绝地求生0.9三级头盔0.2世界纪录0.1
用户画像:
图2-3用户画像简介图
过滤噪声:
通过停留时间短的点击,过滤标题党。
热点惩罚:
对用户在一些热门文章(如前段时间龙哥被反杀的新闻)上的动作做降权处理。
理论上,传播范围较大的内容,置信度会下降。
时间衰减:
用户兴趣会发生偏移,因此策略更偏向新的用户行为。
因此,随着用户动作的增加,老的特征权重会随时间衰减,新动作贡献的特征权重会更大。
惩罚展现:
如果一篇推荐给用户的文章没有被点击,相关特征(类别,关键词,来源)权重会被惩罚
2.5Pandas
pandas是python中用于数据处理和数据分析的一个神器
在推荐系统中,用来做一些数据清洗,特征转换之类的工作
安装很简单
pipinstallpandas
加载
*pd.read_table('
x.csv'
sep='
:
'
header=None,names=mnames)
采样:
*随机sample(n)
*重排序df.take(np.random.permutation(5))
缺失值
*去空dropna(how='
all'
axis=1)
*填充fillna/replace([-999,-1000],np.nan)
去重
*drop_duplicates(['
k1'
'
k2'
],keep='
last'
)
*索引去重df_pe_pb[~df_pe_pb.index.duplicated()]
转换
*map/.str.toLower
重命名
*data.rename(index={'
OHIO'
'
INDIANA'
},inplace=True)
重建索引
*obj.reindex(['
a'
'
b'
c'
d'
e'
...],fill_value=0]
*#按给出的索引顺序重新排序,而不是替换索引。
如果索引没有值,就用0填充
*data.index=data.index.map(str.upper)#就地修改索引
重排序DataFrame.reindex[index=['
...],columns=['
col1'
col2'
col3'
...])
重命名data.rename(index={'
old_index'
new_index'
},columns={'
old_col'
new_col'
})
删除行列.drop(['
index1'
index2'
...])|.drop(['
...],axis=1)|delDataFrame['
]
类型转换(category)
*df['
]=df['
].astype('
category'
)|<
df['
].categories,df['
].codes>
int'
归一化
*哑变量df[['
data1'
]].join(pd.get_dummies(df['
key'
],prefix='
))|
数据合并
*join->
pd.merge(df1,df2,how='
inner'
left_on='
l_key'
right_on='
r_key'
suffixes=('
_left'
_right'
))
*append->
pd.concat([df1,df2],ignore_index=True)
描述分析
单特征描述。
*类别形:
value_counts,数值型:
describe/更多统计量
排序
*df.sort_index(by=['
col'
])
*df.sort_values(['
total_bill'
tip'
],ascending=[False,True])
*df['
].rank(axis=,ascending=False)
桶分析。
cut
相关分析。
*by_year.apply(lambdag:
g['
].corr(g['
]))
交叉表。
pivot_table
分组排序
*topdf.groupby('
).value.transform(lambdax:
x.rank(ascending=False))
聚合
*group组装列表groupby('
).apply(list)
*group多列操作df2.groupby(['
uid'
sid'
]).agg({'
num'
{'
num_sum'
:
sum'
num_count'
count'
}})
性能优化
内存使用col.memory_usage()
大文件分块读取
*data=pd.read_csv(file,chunksize=1000000)
*forsub_dfindata:
*print('
dosomethinginsub_dfhere'
2.6逻辑回归
一句话总结逻辑回归就是
假设数据服从伯努利分布,通过极大化似然估计的方法,运用梯度下降法来求解参数,来达到将数据二分类的目的
伯努利分布,任何的模型都是有自己的假设,在这个假设下模型才是适用的。
逻辑回归的基本假设是假设数据服从伯努利分布。
伯努利分布有一个简单的例子是抛硬币,只有正面反面,用户点击文章,只有点击或者不点击
极大化似然估计,利用已知的样本的结果,在使用某个模型的基础上,反推最有可能导致这样结果的模型参数值
梯度下降法,一种最优化算法,找到给定点的梯度,然后朝着梯度相反的方向,就能让函数值下降的最快
达到将数据二分类的目的,二分类(0or1)就是用于估计某种事物的可能性。
比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,用户点击文章的可能性
逻辑回归形式
图2-4sigmoid函数图
损失函数
通俗讲,就是衡量真实值和预测值之间差距的函数。
所以,我们希望这个函数越小越好。
在这里,最小损失是0。
以二分类(0,1)为例:
当真值为1,模型的预测输出为1时,损失最好为0,预测为0是,损失尽量大。
同样的,当真值为0,模型的预测输出为0时,损失最好为0,预测为1是,损失尽量大。
所以,我们尽量使损失函数尽量小,越小说明预测的越准确。
这个损失函数为:
我们压缩之后,预测y在0-1之间。
我们利用这个损失函数,尽量使这个损失小,就能达到很好的效果。
我们把这两个损失综合起来:
也称交叉熵损失函数
y就是标签,分别取0,1,对于m个样本,总的损失:
这个式子中,m是样本数,y是标签,取值0或1,i表示第i个样本,f(x)表示预测的输出。
不过,当损失过于小时,也就是模型能拟合全部/绝大部分的数据,就有可能出现过拟合。
这种损失最小是经验风险最小,为了不让模型过拟合,我们又引入了其他的东西,来尽量减小过拟合
使用
lr=LogisticRegression()
lr.fit(X_train,y_train)
lr.predict_proba(X_test)
优缺点总结:
工业界当中一些优点:
形式简单,模型的可解释性非常好。
从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大。
模型效果不错。
在工程上是可以接受的(作为baseline),如果特征工程做的好,效果不会太差,并且特征工程可以大家并行开发,大大加快开发的速度。
训练速度较快。
分类的时候,计算量仅仅只和特征的数目相关。
并且逻辑回归的分布式优化sgd发展比较成熟,训练的速度可以通过堆机器进一步提高,这样我们可以在短时间内迭代好几个版本的模型。
资源占用小,尤其是内存。
因为只需要存储各个维度的特征值,。
方便输出结果调整。
逻辑回归可以很方便的得到最后的分类结果,因为输出的是每个样本的概率分数,我们可以很容易的对这些概率分数进行cutoff,也就是划分阈值(大于某个阈值的是一类,小于某个阈值的是一类)。
但是逻辑回归本身也有许多的缺点:
准确率并不是很高。
因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布。
很难处理数据不平衡的问题。
举个例子:
如果我们对于一个正负样本非常不平衡的问题比如正负样本比10000:
1.我们把所有样本都预测为正也能使损失函数的值比较小。
但是作为一个分类器,它对正负样本的区分能力不会很好。
处理非线性数据较麻烦。
逻辑回归在不引入其他方法的情况下,只能处理线性可分的数据,或者进一步说,处理二分类的问题。
逻辑回归本身无法筛选特征。
有时候,我们会用gbdt来筛选特征,然后再上逻辑回归。
2.7决策树
信息熵
1948年由香农提出,用来对信息进行量化度量。
过去我们常常说信息很多,信息太少,但是很难说清楚信息到底有多少,比如一本百科词典的信息量有多少
信息熵是借自与热力学中的热熵,描述分子混乱程度的物理量,香农用来描述信息的不确定度。
也即信息熵越大,信息量越多,信息越不稳定。
举一个例子
混乱的男生宿舍和整洁的女生宿舍
前者的熵很大,键盘,烟头,袜子等等,后者的熵很小
推荐业务场景中
我们拿到用户的行为日志,有发生点击的行为,也有只曝光未点击的行为,信息混乱,信息熵很大,我们希望通过找到一个凭据,能让熵变小,能让点击或者不点击的分类明确,给用户推荐用户能点击的。
这就是信息熵在推荐场景中的作用
信息熵的计算公式:
决策树:
这就是一棵树,根据这棵树做决策,就是决策树
决策树可以用来做分类,也可以用来做回归的。
在推荐中你可以说是一种分类,一个物品用户喜欢还是不喜欢,点击还是不点击,购买还是不购买,也可以说是一种回归,预测在现有特征下用户喜欢的概率值,概率值越大的说明喜欢的可能性越大。
如何构建一棵决策树
1.构建root
2.遍历特征,找到一个特征的一个阈值,使树分成两个分支
3.递归,重复步骤2
构建