快手、孩子王、华为等专家分享大模型在电商运营、母婴消费、翻译等行业场景的实际应用 了解详情
写点什么

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

  • 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:072120

评论

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

新一代云原生日志架构 - Loggie的设计与实践

网易数帆

开源 云原生 日志 Loggie 企业号 1 月 PK 榜

这可能是Feign调用可重试的最佳方案了

JAVA旭阳

Java spring

房价危机:疫情后时代席卷全球的新变局|数据报告

前嗅大数据

数据分析 数据采集 爬虫案例 爬虫工具 房价

深圳大数据程序员培训多长时间可以找工作

小谷哥

Python对txt进行读写操作

Geek_7ubdnf

Python

PyTorch中 nn.Conv2d与nn.ConvTranspose2d函数的用法

Geek_7ubdnf

Python PyTorch

稳扎稳打,坚定前行 | 一文带你回顾 StoneDB 的 2022 年

StoneDB

MySQL 数据库 HTAP StoneDB 企业号 1 月 PK 榜

为什么 APISIX Ingress 是比 Ingress NGINX 更好的选择?

API7.ai 技术团队

APISIX Ingress Controller Kubernetes Serverless NGINX Ingress Controller

软件测试/测试开发丨如何从 0 开始学 Python 自动化测试开发(一)

测试人

Python 软件测试 自动化测试 测试开发

PyTorch的简单实现

Geek_7ubdnf

Python PyTorch

无需服务器开发,实现设备状态缓存方案——实践类

阿里云AIoT

sql 缓存 运维 物联网 存储

TiDB 底层存储结构 LSM 树原理介绍

C++后台开发

数据结构 后端开发 LSM树 TiDB

Python将二维数组输出为图片

Geek_7ubdnf

Python

小令观点 | 个人信息泄露——当代数字身份之殇

令牌云数字身份

数字身份 信息泄露 身份

尚硅谷Filebeat视频教程发布

小谷哥

软件开发入门教程网之Git 基本操作

雪奈椰子

git clone git push

啥玩意儿?一个计时模块要做2天?

为自己带盐

dotnetcore

平安健康 Dubbo 3 升级、迁移和验证之路

阿里巴巴中间件

阿里云 云原生 dubbo

pip安装更换镜像

Geek_7ubdnf

Python.

未来软件开发主流模式——低代码开发

力软低代码开发平台

如何通过Java应用程序添加或删除 PDF 中的附件

在下毛毛雨

PDF Java’ 添加注释

极光笔记 | 如何为 iOS 16 创建一个实时活动

极光JIGUANG

ios 开发者 运营 API

RPN:Region Proposal Networks (区域候选网络)

Geek_7ubdnf

图像处理

上海前端培训课程哪家的好

小谷哥

创建Root权限虚拟环境

Geek_7ubdnf

Linux

I see you!「2022 龙蜥社区优秀贡献者」正式启动

OpenAnolis小助手

开源 龙蜥社区 2022 奖项 优秀贡献者

Python将图片输出为二维数组并保存到txt中

Geek_7ubdnf

Python

高性能网络SIG月度动态:virtio新设备进入virtio规范、smc新特性IPC性能比tcp提升88% | 龙蜥SIG

OpenAnolis小助手

操作系统 高性能网络 龙蜥社区 sig virtio

Python中LSTM回归神经网络的时间序列预测

Geek_7ubdnf

Python

软件测试/测试开发丨从 0 开始学 Python 自动化测试开发(二):环境搭建

测试人

Python 软件测试 自动化测试 测试开发

PyTorch中 torch.nn与torch.nn.functional的区别

Geek_7ubdnf

Python PyTorch

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