写点什么

如何用机器学习模型,为十几亿数据预测性别

  • 2020-05-31
  • 本文字数:4672 字

    阅读完需:约 15 分钟

如何用机器学习模型,为十几亿数据预测性别

基于用户画像进行广告投放,是优化投放效果、实现精准营销的基础;而人口属性中的性别、年龄等标签,又是用户画像中的基础信息。那该如何尽量准确的为数据打上这些标签?


这时候机器学习就派上用场了。 本文将以性别标签为例,介绍人口属性标签预测的机器学习模型构建与优化。

性别标签预测流程

通常情况下,无监督学习不仅很难学习到有用信息,而且对于学习到的效果较难评估。所以,如果可以,我们会尽可能地把问题转化成有监督学习。


对于性别标签也是如此,我们可以使用可信的性别样本数据,加上从 TalkingData 收集的原始数据中提取出来的有用信息,将性别标签的生产任务转化成有监督机器学习任务。更具体来说,男/女分别作为 1/0 标签(Label,也就是常说的 Y 值,为了方便表达,我们标记男/女分别为 1/0 标签),这样性别标签的任务就转化成了二分类任务。


性别标签的生产流程图如下:



  • 简单来说,输入为具有可信性别信息的样本数据,以及从近期活跃的原始数据中提取出有用特征;

  • 将两者 join 之后,得到可以直接用于建模的数据集;

  • 基于该数据集进行建模,学习出性别预测模型;

  • 再用该模型对全部样本进行预测,从而得到所有样本的性别打分。至此,模型部分的工作基本完成;

  • 最后一步是确定阈值,输出男/女标签。这里我们不依赖模型确定阈值,而是借助比较可信的第三方工具,保证在期望准确度(precision)下,召回尽可能多的样本。


另外,面对 TalkingData 十几亿的数据体量,在标签生产的过程中,为了加速运算,除了必须用单机的情况下,我们都会优先采用 Spark 分布式来加速运算。

特征与模型方法的版本迭代

为了优化模型的效果,我们又对该性别标签预测模型进行了多次迭代。

01 性别预测模型 V1

模型最初使用的特征包括 4 个维度: 设备应用信息、嵌入 SDK 的应用包名、嵌入 SDK 的应用内自定义事件日志以及设备机型信息。


模型采用 Xgboost (版本为 0.5),基于每个维度的特征分别训练模型,得到 4 个子模型。每个子模型会输出基于该特征维度的设备男/女倾向的打分,分值区间从 0 到 1,分值高代表设备为男性倾向,反之则为女性倾向。模型代码示例如下:


   import com.talkingdata.utils.LibSVM   import ml.dmlc.xgboost4j.scala.DMatrix   import ml.dmlc.xgboost4j.scala.spark.XGBoost//version 0.5
//train stage val trainRDD = LibSVM.loadLibSVMFile(sc, trainPath)// sc为SparkContext val model = XGBoost.train(trainRDD, paramMap, numRound, nWorkers = workers)

//predict stage val testSet = LibSVM.loadLibSVMFilePred(sc,testPath,-1,sc.defaultMinPartitions) val pred = testSet.map(_._2).mapPartitions{ iter => model.value.predict(new DMatrix(iter)).map(_.head).toIterator }.zip(testSet).map{case(pred, (tdid, feauture)) => s"$tdid\t$pred" }
复制代码


缺点及优化方向


  • 模型为四个子模型的融合,结构较复杂,运行效率较低,考虑改为使用单一模型;

  • 嵌入 SDK 的应用内自定义事件日志特征覆盖率低,且 ETL 处理资源消耗大,需重新评估该字段对模型的贡献程度;

  • 发现设备名称字段看上去有男/女区分度——部分用户群体会以名字或者昵称命名设备名(例如带有“哥”“军”等字段的倾向为男性,带有“妹”“兰” 等字段的倾向为女性),验证效果并考虑是否加入该字段。

02 性别预测模型 V2

对模型使用特征的 4 个维度进行了调整 ,改为:嵌入 SDK 的应用包名、嵌入 SDK 的应用 AppKey、设备机型信息以及设备名称。


其中,对嵌入 SDK 的应用包名和设备名称做分词处理。再使用 CountVectorizer 将以上 4 类特征处理成稀疏向量(Vector),同时用 ChiSqSelector 进行特征筛选。


模型采用 LR (Logistic Regression),代码示例如下:


   import org.apache.spark.ml.feature.VectorAssembler   import org.apache.spark.ml.PipelineModel   import org.apache.spark.ml.classification.LogisticRegression
val transformedDF = spark.read.parquet("/traindata/path")//分词、CountVectorizer、ChiSqSelector操作之后的特征,为vector列
val featureCols = Array("packageName","appKey", "model", "deviceName") val vectorizer = new VectorAssembler(). setInputCols(featureCols). setOutputCol("features") val lr = new LogisticRegression() val pipeline = new Pipeline().setStages(Array(vectorizer, lr)) val model = pipeline.fit(transformedDF)
//predict stage val transformedPredictionDF = spark.read.parquet("/predictData/path")//同train一致,为分词、CountVectorizer、ChiSqSelector处理之后的特征,为vector列 val predictions = model.transform(transformedPredictionDF)
复制代码


优点及提升效果


  • 采用单一的模型,能够用常见的模型评估指标(比如 ROC-AUC, Precision-Recall 等)衡量模型,并在后续的版本迭代中作为 baseline,方便从模型角度进行版本提升的比较。


缺点及优化方向


  • LR 模型较简单,学习能力有限,后续还是替换成更强大的模型,比如 Xgboost 模型。

03 性别预测模型 V3

模型所使用的特征,除了上个版本包括的 4 个维度:嵌入 SDK 的应用包名、嵌入 SDK 的应用 AppKey、设备机型信息以及设备名称, 又增加了近期的聚合后的设备应用信息 ,处理方式与上个版本类似,不再赘述。


模型从 LR 更换成 Xgboost (版本为 0.82),代码示例如下:


   import org.apache.spark.ml.feature.VectorAssembler   import ml.dmlc.xgboost4j.scala.spark.XGBoostClassifier//version 为0.82
val transformedDF = spark.read.parquet("/trainData/path")//分词、CountVectorizer操作之后的特征,为vector列
val featureCols = Array("packageName","appKey", "model", "deviceName") val vectorizer = new VectorAssembler(). setInputCols(featureCols). setOutputCol("features") val assembledDF = vectorizer.transform(transformedDF)
//traiin stage //xgboost parameters setting val xgbParam = Map("eta" -> xxx, "max_depth" -> xxx, "objective" -> "binary:logistic", "num_round" -> xxx, "num_workers" -> xxx) val xgbClassifier = new XGBoostClassifier(xgbParam). setFeaturesCol("features"). setLabelCol("labelColname")
model = xgbClassifier.fit(assembledDF)
//predict stage val transformedPredictionDF = spark.read.parquet("/predictData/path")//同train一致,为分词、CountVectorizer操作之后的特征,为vector列 val assembledpredicDF = vectorizer.transform(transformedPredictionDF) val predictions = model.transform(assembledpredicDF)
复制代码


优点及提升效果


  • 相比上个版本, AUC 提升了 6.5%,在最终的性别标签生产中召回率提升了 26% 。考虑到 TalkingData 的十几亿的数据体量,这个数值还是很可观的。

04 性别预测模型 V4

除了上个版本包括的 5 个特征维度,还 添加了 TalkingData 自有的三个广告类别维度的特征 ,虽然广告类别特征覆盖率仅占 20%,但对最终标签的召回率的提升也有着很大的影响。


模型由 Xgboost 替换成 DNN ,设置最大训练轮数(Epoch)为 40,同时设置了 early stopping 参数。考虑到神经网络能工作是基于大数据的,因此我们将用于训练的样本量扩充了一倍,保证神经网络的学习。


DNN 的结构如下:


python   GenderNet_VLen(     (embeddings_appKey): Embedding(xxx, 64, padding_idx=0)     (embeddings_packageName): Embedding(xxx, 32, padding_idx=0)     (embeddings_model): Embedding(xxx, 32, padding_idx=0)     (embeddings_app): Embedding(xxx, 512, padding_idx=0)     (embeddings_deviceName): Embedding(xxx, 32, padding_idx=0)     (embeddings_adt1): Embedding(xxx, 16, padding_idx=0)     (embeddings_adt2): Embedding(xxx, 16, padding_idx=0)     (embeddings_adt3): Embedding(xxx, 16, padding_idx=0)     (fc): Sequential(       (0): Linear(in_features=720, out_features=64, bias=True)       (1): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)       (2): ReLU()       (3): Dropout(p=0.6)       (4): Linear(in_features=64, out_features=32, bias=True)       (5): BatchNorm1d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)       (6): ReLU()       (7): Dropout(p=0.6)       (8): Linear(in_features=32, out_features=16, bias=True)       (9): BatchNorm1d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)       (10): ReLU()       (11): Dropout(p=0.6)       (12): Linear(in_features=16, out_features=2, bias=True)     )   )
复制代码


优点及提升效果


  • 与上个版本对比, AUC 仅提升了 1.5%,但在最终性别标签生产中的召回率提升了 13% ,考虑数据体量以及现有的标签体量,这个提升还是不错的。

  • 由此可以看出,在验证版本迭代效果的时候,我们 不应该仅仅从模型的 AUC 这单一指标来衡量 ,因为这对版本迭代的效果提升程度衡量不够准确。我们应该验证最终的、真正的指标提升情况——在性别标签预测中, 是期望准确度(precision)下召回的样本数量 。但我们仍然可以在版本优化时使用 AUC 等模型相关指标,来快速验证控制变量的实验效果,毕竟这些指标容易计算。

模型探索小建议

从原始日志当中抽取字段聚合成信息,需要经过很多步 ETL,也会涉及很多优化方式,这部分有专门的 ETL 团队负责,在这里不做过多介绍。


模型团队可以直接使用按时间聚合之后的字段进行建模任务,尽管如此,ETL 和特征生成所花费的时间,也占据了模型优化和迭代的大部分时间。


下面总结两个优化方面的坑和解决经验,希望能给大家一些参考。

01

对于性别标签预测,输入的特征大部分为 Array 类型,比如近期采集到的设备应用信息。对于这种类型的字段,在训练模型之前,我们一般会调用 CountVectorizer 将 Array 转成 Vector,然后再作为模型的输入,但是 CountVectorizer 这一步非常耗时,这导致我们在版本迭代时不能快速实验。


针对该问题,我们 可以事先完成这一步转换,然后将生成的 Vector 列也存储下来 ,这样在每次实验时,就可以节省 CountVectorizer 消耗的时间。


在实际生产中,因为有很多标签的生产都会用到同样的字段,事先将 Array 转成 Vector 存储下来,后续不同任务即可直接调用 Vector 列,节省了很多时间。

02

虽然第一条能够节省不少时间,但 Spark 还是更多用于生产。其实在模型前期的探索当中,我们也 可以先用 Spark 生成训练集 ——因为真实样本通常不会很多,生成的训练集往往不是很大,这时我们就可以用单机来进行快速实验了。


在单机上,我们可以使用 Python 更方便的画图来更直观的认识数据,更快的进行特征筛选,更快的验证想法。在对数据、对模型有了深入的了解之后,我们就可以把实验所得的结论快速应用到生产当中。


作者介绍


张小艳,TalkingData 数据科学家,目前负责企业级用户画像平台的搭建以及高效营销投放算法的研发,长期关注互联网广告、用户画像、欺诈检测等领域。


本文转载自公众号 TalkingData(ID:Talkingdata)。


原文链接


https://mp.weixin.qq.com/s/-6FEBPsVyAhnPThbQsSK2g


2020-05-31 14:072548

评论

发布
暂无评论
发现更多内容

Java架构师必备技能,java程序设计实用教程第五版答案,掌握这个提升路径

Java 程序员 后端

Java程序员如何有效提升学习效率,如何化身BAT面试收割机

Java 程序员 后端

Java百度云资源,java基础案例教程黑马程序员在线阅读,美团Java面试流程

Java 程序员 后端

Java的Io模型你了解多少?尚硅谷大厂学院课,Java开发面试笔试题大汇总

Java 程序员 后端

Java日常开发的12个坑,你踩过几个,一招让你拿下seata分布式事务框架

Java 程序员 后端

Java知识体系!极客学院黑马程序员,BIO和NIO有啥区别

Java 程序员 后端

Java程序员全套,百度三面牛客网猿生活,疯狂膜拜

Java 程序员 后端

Java程序员最新职业规划,尚学堂高琪300集,初级Java工程师面试题

Java 程序员 后端

Java笔试编程题大全带答案,mysql入门视频教程,Java多态实现原理

Java 程序员 后端

Java框架,黑马java视频教程,面试资料分享

Java 程序员 后端

Java程序员面试笔记,极客时间vue开发实战,Java进阶教程视频

Java 程序员 后端

Java笔试题及答案详解,nginx入门到精通百度云,全网最全原理讲解

Java 程序员 后端

Java知识体系!java黑马视频和达内,链表反转的两种实现方法

Java 程序员 后端

Java春招实习面试经验汇总,图灵学院诸葛,Java微服务架构视频下载

Java 程序员 后端

云栖发布|企业级互联网架构全新升级 ,助力数字创新

阿里巴巴云原生

阿里云 云原生 产品升级 云栖大会

Java研发岗必问30+道高级面试题,腾讯,字节等大厂面试真题汇总

Java 程序员 后端

Java程序员必会!开课吧java高级架构师课程,Java开发大厂面试经验

Java 程序员 后端

Java经典入门教程,vue尚学堂,Java面试问项目

Java 程序员 后端

Java编程入门经典,linux使用教程课后答案,mysql常见笔试题

Java 程序员 后端

Java百度云教程,深入java虚拟机百度云,附详细答案

Java 程序员 后端

Java程序员面试中最容易答错的8道面试题,tomcat面试题及答案

Java 程序员 后端

Java程序员面试笔试真题,java零基础入门视频百度云,阿里P7大牛亲自讲解

Java 程序员 后端

Java算法基础面试题,java教程张孝祥百度云,Java初级程序员面试题目

Java 程序员 后端

Java编程入门经典,慕课网java架构师百度网盘,字节跳动Java高级工程师

Java 程序员 后端

Java编程入门自学,牛客网在线编程,Java基础入门视频教程

Java 程序员 后端

Java月薪过万要掌握的技能,javajdk下载教程,高级Java工程师面试问题

Java 程序员 后端

Java架构师进阶之路,马士兵的java教程,大厂Java面试总结+详细解答

Java 程序员 后端

Java爬虫爬取视频,尚硅谷笔试答案,最全面试考点与面试技巧

Java 程序员 后端

Java百度云,springboot实例教程,面试大厂应该注意哪些问题

Java 程序员 后端

Java研发岗面试复盘总,4面技术5面HR附加笔试面

Java 程序员 后端

Java编程书籍推荐,尚硅谷springboot,遇到的面试官都是架构师级别

Java 程序员 后端

如何用机器学习模型,为十几亿数据预测性别_AI&大模型_张小艳_InfoQ精选文章