通过用户安装app列表判定性别

Sep 11, 2017


  通过用户安装的app列表来判断用户性别似乎不是一件十分困难的事情,因为在日常生活中,我们接触到大量的app在男女用户中的安装比例存在明显的差异。比如,‘汽车之家’app明显男性用户的安装量大于女性,而‘购物类’app和母婴类app女性用户的安装量大于男性。这种app在男女人群安装量的差异,是我们通过app判定用户性别的基础。
  我来公司的第一份工作就是爬取各应用市场的app数据,包括app的包名,中文名,类别信息,描述信息,安装量和公司等。这些信息中,app包名相当于标识一个app的唯一id,而app中文名,类别信息,描述信息等都可以经过处理作为特征,参与模型的训练和预测。(google上可以搜到一些paper同样把app的价格作为一个重要特征,但这与国情不服,因为国内大部分的应用类app都是免费的,本文不考虑这个特征)在正式进行实验之前,还需要弄清几个基本问题:

  • 模型baseline:掷硬币的概率50%
  • 目前有哪些可用数据:
    • 搜狗输入法语音标注过的数据:这份数据量只有一万左右,准确率96%,格式为:用户imei 性别(1男2女)。
    • 腾讯人口属性数据:格式可以解析为:用户imei 性别 年龄 学历。
    • 今日头条的人口属性数据:格式可以解析为:用户imei 性别 年龄。
    • 输入法回传app数据:格式可以解析为:用户imei app列表。
  • 实验预期效果:
    • 在工作开始前,我们预计模型的准确率会达到90%以上。因为除了一些明显有区分度的app,还存在大量的app是没有任何区分度的,例如:微信,淘宝。
  • 前期工作积累:
    • 在正式开始试验之前,我们已经有了一些前期的工作积累,主要是对app数据的理解和处理上,后面会进行简单的解释。

  下面,本文会从以下几个方面对本文涉及到的工作进行介绍:

  • app预处理
  • 训练数据制作
  • 模型选择
  • 思考和总结

一、app预处理

1、包名去尾缀规则

  在进行实验之前,首先需要对app数据有一个基本的理解。目前国内手机市场很乱,手机厂商众多,而同一个app在不同的手机上或者不同的应用市场上可能存在包名不一致的现象。前文提到过,app的包名是用于标识一个app的唯一id,如果同一个app在不同的场景下包名变化,必然会对app特征的提取产生不利影响,所以我们需要通过规则消除这种影响。好在app包名的变化一般体现在尾部,我们把这个提取到的规则叫做‘app包名去尾缀规则’。举个简单的例子:com.hexikd.bikes.wdj、com.hexikd.bikes.huawei、com.hexikd.bikes实际上就是同一个app,只不过第一个包是在wdj应用市场下载的,第二个是预装在华为手机上的,所以形式发生了变化。

2、系统级app判定规则

  系统级app是指一些和系统后台服务直接相关的app,用户日常使用的app大多是非系统级app,这部分app才能真正反映用户的兴趣偏好,为了得到更好的分类效果,需要将非系统级app去除。一般用户安装一个app,系统会提示app所需要的权限,但是每个app都默认会有扫描用户安装app列表的权限,app通过扫描列表,判断是否已经安装过这个app,如果安装的是低版本,会自动进行替换更新。(这里简单提一下,刚才提到过,包名是app的唯一id,而不同的应用市场或者手机上,同一个app的包名可能会变化,那此时在一台机器上安装两个包名不同的apk包会发生什么呢?答案是同时装两个一样的app。所以一般的较大的app无论在什么环境下包名都不会改变,但是一些小app可能为了标识推广渠道或者其他一些商业考虑,会改变包名,游戏类尤其居多。)判定系统级app一般可以通过一些关键的字段进行判定,比如有一些厂商就是专门做系统优化的或操作系统层的工作,那么包名这有标识这个公司的字段,就可以进行率除。还有一些通用的规则,比如以’com.sec.’开头或者以’com.android.’开头的大部分很多app都是系统级app。

3、分类标注

  在爬取的app信息中,app的类别信息是最重要的信息,因为其直接反映了app的主要功能。遗憾的是,虽然我想了很多办法,但是最终的效果并不理想。原因是目前各应用市场的app分类体系不够新,而且存在多分类的情况。我们系统一个app能够唯一对应一个一级类和一个二级类。虽然现在安卓市场app的规模量级达到百万,但是我们根据数据统计,大概安装量top3万的app就能够覆盖97%的pv了(top3万app的总安装量占全部app总安装量的97%)。所以我们重点对这top3万的app按照自己从新设计的分类体系进行的人工标注。我们的分类体系参考了应用宝,百度,360和豌豆荚等,又在其基础上进行了改进,新增的共享单车,信息流等新类别,同时,在进行标注时,我们保证一个app唯一对应一个一级类和二级类,有时一个app的确可以分到多个类别,但是经过仔细分析,其一定会有一个最主要的属性,对应唯一一个类别。
  在对top3万app进行标注的过程中,可以同时对“系统级app判定规则”和“包名去尾缀规则”进行完善。同时,又可以提取出“游戏类app判定规则”和“书名判定规则”,这个属于太细节的东西,就不细讲了。经过对top三万的app进行标注,最终我们得到了有完成标注信息的1.6万app,其余1.4万还是属于系统级或者明显是某个类型的游戏或电子书,可以通过规则进行判定,为节省成本,就没有一一对游戏名字进行确认。

二、数据预处理制作

  如上文所述,我们有的四份数据如下:

  • 语音标注数据
  • 腾讯人口属性数据
  • 头条人口属性数据
  • 输入法app数据

  这四份数据的key都为imei,首先我们需要根据imei,将语音标注数据,腾讯人口属性数据和头条人口属性数据都与输入法回传的app数据进行匹配。得到三份数据,格式如下:
   imei 性别 app列表 其他信息等
  这三份数据中,语音数据的性别准确率为96%,而腾讯人口属性数据和头条人口数据数据的准确率只有80%左右。所以第一阶段的实验,我们只使用语音标注的数据,这部分数据经过匹配后只有2888条,我们随机从中抽取了2000条做训练,888条做测试,迅速迭代,探索模型的性能。
  在实验的第二个阶段,我们为了扩大训练数据量,提高模型的泛化能力,对腾讯人口属性数据和头条数据进行了匹配。匹配规则时,对于同一个imei,两份数据的性别字段和年龄字段必须一致,这部分数据匹配后剩余的量大概有400万,准确率用语音数据评估后为91.1%。我们对这400万中的男女进行按1.1:1的比例进行采样后剩余200万。这200万数据我们随机取出160万数据进行训练,40万数据作为测试数据1,语音数据作为测试数据2。

三、特征和模型选择

  在最初实验的时候,我们使用app是否安装作为one-hot特征,因为app种类过多,我们只考虑有标注信息的16000个app,这部分app通常是非系统级app且有一定的覆盖率。因为xgboost在数据竞赛中的良好表现,我们选择使用xgboost模型进行实验。第一版实验效果并不理性,只有不到70%的准确率。分析原因如下:

  1. 数据规模较小(2000)而特征维度较高(16000),数据不足以对特征进行充分的表达。
  2. xgboost更适合与特征是连续值的分类模型,使其树结构可以在某个特征上进行连续分裂,而不是one-hot特征。   经过第一次尝试失败,我们对app数据进行了整理,利用了app的分类信息进行统计计算,得到一些新的特征。计算新的特征,需要每个app都对应一个得分数据,具体计算如下:
      app_score = log(male_install_num + 1) - log(female_install_num + 1)
      计算公式非常的简单,就是男性安装量与女性安装量比值取log,+1是为了平滑。通过这个公式,我们可以计算出每个app对应的唯一得分,然后使用如下的特征进行模型训练和预测:
    • 用户app安装量
    • 用户app总分
    • 用户app平均分
    • 用户在每个一级类下的安装量
    • 用户在每个二级类下的安装量
    • 用户在每个一级类下的app总得分
    • 用户在每个二级类下的app总得分

  使用以上的特征对模型进行训练和测试,准确率可以达到85%左右。经过多次特征选择实验,我们发现使用如下特征可以得到最好的判别效果(准确率略高于以上参数):

  • 用户app平均分
  • 用户在每个一级类下的安装量
  • 用户在每个二级类下的安装量
  • 用户在每个一级类下的app总得分(app得分泛化,乘以1000后四舍五入取整)
  • 用户在每个二级类下的app总得分(app得分泛化,乘以1000后四舍五入取整)
  • 机型(imei前8位)得分(计算方式与每个app类似,同样进行泛化处理)

四、总结与思考

  这是我入职以来,第一次独立进行策略方面的工作,还是有很多的收获的。我不仅对以前在书本上学习到的知识有了更深刻的认识,而且犯了很多低级的错误,这些错误我早就知道实际上是不应该犯的,但是仅仅通过书本学习并不能是我对错误有直观的认识,该犯的错误还是要再犯一遍,才能认识深刻。纸上得来终觉浅,绝知此事要躬行啊。下面对收获和思考进行一下简单的总结。

1、训练数据是第一位的!

  在进行策略工作之前,我觉得首先要思考的是工作的合理性。人的直觉有时不如数据来的精确,但是在开始工作之前,凭借经验对工作可能达到的效果有一个大概的估计,还是非常有必要的。对于本文的工作,我们通过经验的确可以判断出app安装列表可以在一定程度上反映用户的性别。在确定可行性之后,我们就要考虑训练数据了。策略工作中,训练数据可以说是最重要的一环,不同于读研时在实验室的工作,企业中使用的数据规模比实验室高出好几个量级,数据中噪音较多,质量较差,通过适当的手段进行数据提纯和去燥十分的重要。我知道训练数据的重要性,却没有在实验开始前,首先对训练数据进行完整有效的评估。

2、训练数据提纯时一定要小心!

  当对训练数据进行评估后,发现其质量非常差,那么就需要通过规则对其进行提纯。但是这个过程一定要十分谨慎,因为一不小心训练数据就会变为有偏的。而且本文的几份训练数据本身就代表了不同的人群,进行merge时更是会带来各种问题。首先,输入法语音数据虽然较为准确,但是其代表的人群却一般素质偏低(年龄较大,学历较低,语言粗俗),腾讯人口属性数据相对比较正常,但是准确率只有80%,今日头条的数据在男女比上比较偏,男性比女性三倍还多,而网民的数量男性大概为女性的1.1倍。因为数据本身有各种问题,在进行提纯时,就需要考虑实际的应用场景,比如实际应用场景下的男女比是什么样子的,大概是什么样的人群等问题。

3、充分考虑时间成本,选择模型和特征!

  因为xgboost模型在各种数据竞赛中的优异表现,我们觉得选用xgboost模型。在开始进行实验时,我们只使用的语音数据进行快速迭代实验寻找特征。xgboost是一种生成树模型,比较适合于连续特征,有利于训练过程中的分裂,开始使用的one-hot特征效果很差并不意外(而且16000的特征空间也太大了,有限的树难以对其进行拟合,使用深度网络则训练成本较高)。使用经度较高的小样本进行训练和测试,虽然可能得到过拟合的结果,但是只要会对模型的能力有个直观的感受。在大规模数据集训练过程中,会进行多次的迭代实验,切记每次只能改变一个变量,首先调整特征,然后在调整模型参数。在进行实验结果记录时,至少要记录三组数据:

  1. 训练集上的准确率。(模型的拟合程度)
  2. 同分布的测试集上的准确率。(通过与1对比,判断是否过拟合,判断模型效果)
  3. 精度较高的小样本集准确率。(这里主要指语音数据,分布于训练数据是不一致的,主要看模型的泛化能力)

4、特征统计只使用训练数据

  在对数据提取特征时,必须只考虑训练数据,这是个最起码的常识,而我居然也犯了这个错误!在计算app得分时,开始的实验我分别对不同的数据集进行了统计,当时没考虑太多,从数据到特征只用了一个脚本,这个错误的确很2,好在及时修正了。

5、不要设计复杂的规则

  在计算app得分的时候,我最开始通过自己的理解设计了一个相对比较复杂的规则,而这个规则实际的区分度是较差的。所以对于我这种经验不足的菜鸟,有时候简单的规则往往是更有效的。后来使用的这个规则就十分的直观且有区分度,效果很好。至于最后得分的泛化处理,确实对模型整体的泛化能力有一定的提升。

6、多请教和沟通

  对于一些困境,还是要多向有经验的前辈请教,这样能节约非常多的时间。做策略工作的人,在日常工作中,时间真的是最宝贵的资源,要时时刻刻感受到时间的压力。