ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于行为数据的用户性别年龄预测:特征工程与模型实战

基于行为数据的用户性别年龄预测:特征工程与模型实战 简介行为数据是移动互联网产品中记录用户操作轨迹的核心资源其背后隐藏着丰富的人群属性信息。通过统计用户在应用品类、使用时段、活跃节奏等方面的差异机器学习模型能够从行为模式中推断出性别、年龄段等人口属性特征为广告定向、内容推荐和风控反欺诈提供基础标签支撑。然而这类任务并非简单堆叠算法即可完成标签来源的可靠性、行为特征的聚合粒度、验证集的时间切分方式都会显著影响模型效果。以LightGBM为代表的梯度提升树模型在中等规模表格数据上表现稳定配合SHAP特征归因能够有效提升可解释性。同时设备信息泄露、随机切分导致的虚高评估等问题也需警惕。本文结合实际项目完整呈现了从zip数据解析到特征工程、模型训练与效果评估的全流程并总结了行为预测任务中值得注意的工程细节。 拿到 zip 包的第一反应我以为又是一个常规的“用户画像补全”任务无非是把移动端采集到的行为日志清洗一遍再堆几个树模型上去输出性别和年龄段概率就完事。真正动手之后才发现这个任务的坑全都埋在最不起眼的地方——标签怎么来、行为特征怎么聚合、验证集怎么切每一步都能让模型效果腰斩。这篇文章记录的就是我从解压 zip 到上线第一版完整模型的全部过程包括我在特征工程和模型选型上的取舍、最终效果评估以及三个差点让整个项目报废的大坑。如果你正准备做类似的任务行为数据预测用户属性、风险识别、内容偏好建模都算或者只是对“机器到底是怎么从使用行为里看出一个人大概多大、是男是女”这件事感兴趣这篇内容应该能给你一些可落地的参考。1. 为什么行为数据能“猜”出性别和年龄数据可行性拆解先说一个常见疑问不碰通讯录、不读短信、不做实名认证仅凭行为数据推断性别年龄这真的靠谱吗答案是非常靠谱前提是你得理解“行为偏好”和“人口属性”之间的相关关系强度。这种关系不是玄学它来自移动互联网产品运营这几年沉淀下来的统计规律。1.1 行为数据里的“人群指纹”不同性别和年龄的人群在移动设备上的使用习惯差异大到什么程度我拿我们手头的数据跑过一轮简单的分布对比几个维度的区分度特别明显应用品类分布工具类应用清理加速、文件管理、手电筒等在中年及以上用户里的使用时长占比显著偏高社交和短视频类应用在 18-35 岁段的渗透率和使用频率一骑绝尘游戏类则存在明显的性别差异MOBA 和策略类以男性为主休闲消除和模拟经营类女性占比更高。使用时段节奏年轻用户在工作日晚上 22 点到凌晨 2 点之间仍保有较高的活跃度而 45 岁以上用户通常在 22 点前就结束当日活跃女性用户在白天时段尤其是午休和下班后 18-20 点的电商类应用活跃峰值明显男性用户在工作日上午和深夜的资讯、游戏类活跃占比更高。使用时长与频率按周维度看男性用户单日平均使用时长波动更大容易在周末出现明显峰值女性用户的每日活跃时长分布更平稳。次数上女性用户对单一应用尤其是社交和购物的日均打开次数通常高于男性。行为多样性与切换频率年轻用户的应用切换频率和品类多样性明显高于年长用户年长用户更倾向于“固定几个应用、来回使用”的习惯模式。这些差异综合在一起相当于每个用户身上都带着一个“行为指纹”如果我们能把指纹里的关键纹路提取成特征机器就能找到人群之间的决策边界。1.2 业务价值决定了它值不值得做这类模型在很多场景里都是基础设施级别的组件广告投放没有实名性别年龄信息时用行为预测结果做投放定向能显著提升 CTR 和转化率内容推荐新用户冷启动阶段先打一个预测年龄性别的标签再决定首页内容流的物料配比风控反欺诈性别年龄与设备行为模式的一致性校验是识别仿冒设备和账号异常的辅助信号。需要注意的是这类模型的准确率天花板通常达不到“实名验证”级别的 99%。在我的实践中一个好的模型在性别二分类上 AUC 可以做到 0.85-0.90年龄分段比如按 18-24、25-34、35-44、45 分成四段的准确率在 60%-70% 之间这已经是行为推断任务里相当可观的结果了。它解决的问题不是“确认你是谁”而是“在无法确认时用概率把一群人的优先序排出来”。2. 解压与探查拿到的 zip 里到底有什么无论是数据集还是交付代码zip 这种打包格式在移动设备数据项目里实在太常见了。但是解压这一步就有一堆人栽过跟头。2.1 解压环节最容易出现的问题这次拿到的 zip 大概 4.7 GB解压后接近 20 GB。解压过程本身不复杂但有几个高频报错值得提前说file is not a zip file大概率是下载过程中文件损坏或者把文件名后缀改了但实际不是 zip。用file命令检查一下真实格式确认无误再用unzip解压。invalid zip archive: could not find EOCDEOCDEnd of Central Directory Record是 zip 包末尾的目录记录区如果它丢了说明压缩包结构不完整。这种情况优先检查磁盘空间和文件是否上传/下载完整不要急着用修复工具。解压到一半报错“CRC failed”压缩文件块损坏多数情况下是源文件本身的问题可以先尝试用unzip -t测试完整度再决定是否重新获取。基本的解压命令# 检查文件类型 file 移动设备行为数据.zip # 测试压缩包完整性 unzip -t 移动设备行为数据.zip # 常规解压保留目录结构 unzip 移动设备行为数据.zip -d ./behavior_data/ # 如果是拆卷压缩包比如 z01/z02 zip zip -s 0 移动设备行为数据.z01 --out 合并.zip unzip 合并.zip -d ./behavior_data/数据完整解开之后这份压缩包里包含两个目录raw_logs/是行为日志序列labels/是带有性别年龄标注的样本子集。2.2 行为日志的数据结构不是每个字段都值得信真实业务里的行为日志和教科书上的干净数据差异很大。这次拿到的原始日志核心字段包括字段名含义说明需要注意的问题user_id匿名用户标识同一用户可能有多台设备只能按 user_id 聚合device_id匿名设备标识要注意同一设备被多用户共用的情况比如家庭平板ts行为发生时间戳存在时区混用全部按 UTC 转化后再聚合app_id应用包名/标识需要映射到应用名称和品类app_category应用品类编号不同来源的品类体系不一致必须统一映射network网络状态wifi/4g/5g存在大量空值is_active_open是否主动打开区分前台打开和后台心跳duration本次使用时长有的端上报为 0需要做异常值过滤值得警惕的是日志里可能存在同一用户的行为被拆到多条记录、时间戳出现重复或倒序、app_category在部分早期版本的产品里是未知值比如值为-1或null。这些脏数据如果不处理后面特征计算出来的均值、占比会集体跑偏。我处理策略是先按user_id 日期去重保留时间戳最早的那条过滤掉duration 0或duration 12小时的异常记录单次使用超过 12 小时显然是挂机或上报异常对app_category做统一的映射表把未知、未知品类归到统一的other类目直接用 pytz 把所有时间戳换算成东八区本地时间再提取小时、星期、是否节假日等字段。2.3 标签是怎么来的训练数据的构建方式原始行为日志本身是没有性别年龄标签的——现实中不可能从行为里直接读到性别。这次项目里的标签来自两个渠道一部分是已实名认证用户回传的画像信息另一部分来自合作方 SDK 上报的自填画像。也就是说只有一部分样本拥有可靠的标签这部分样本才进入训练其余大量行为日志只能作为无标注数据用于特征分布校验和伪标签扩展。用有标签样本构图时还有一个细节标签是“人”的属性不是“设备”的属性。同一user_id下如果有多个device_id那这些设备日志都归到这个人但如果一台设备被多个user_id使用过家庭平板那这台设备的行为就不应该整段进训练集否则会造成标签噪声。清理后的标签分布大概是男性样本占比 46%女性 54%年龄分段方面18-24 岁约 2 成25-34 岁约 3 成35-44 岁约 2 成45 岁以上约 3 成。整体分布还算健康但后面我会讲到这种“整体健康”不代表“每个细分都健康”建模时仍然要留意样本不平衡问题。3. 特征工程三层次从使用时长到行为节奏特征工程决定这个项目的上限。我在这个项目里把特征分成三个层次基础统计特征、品类偏好特征、时序节奏特征。三个层次各自解决不同的问题叠加起来才有完整的用户行为画像。3.1 第一层基础统计特征怎么用、用多久最基础但也最稳定的特征全部从“用户在观察窗口内用了什么应用、用了多久、什么时间用”里聚合出来。我按 30 天观察窗口来统计因为窗口太短比如 7 天会让活跃低的用户特征稀疏窗口太长比如 90 天又会引入太多旧行为掩盖近期模式变化。常用的统计特征包括总活跃天数、总使用次数、总使用时长日均使用次数、日均使用时长、人均单次使用时长工作日使用时长占比、周末使用时长占比夜间23:00 - 05:00使用次数占比、夜间使用时长占比最活跃时段的起始小时和结束小时每日首次使用和末次使用的平均时刻。这些特征的判别力虽然基础但信息量足够稳定。一个典型的例子夜猫子特征夜间使用次数占比在年龄推断里几乎是 Top 级别的重要特征因为 45 岁以上用户凌晨活跃的比例显著偏低。3.2 第二层品类偏好特征用什么、偏好什么只看总使用时长会抹掉所有偏好差异所以品类维度是关键。我把应用归到十几个一级品类包括短视频、综合资讯、即时通讯、综合电商、手机游戏、在线视频、音乐音频、电子阅读、旅游出行、生活服务、金融理财、学习教育、效率办公、系统工具、其他。每个品类下聚合以下特征该类目使用次数占比、使用时长占比该类目使用天数覆盖了多少天该类目平均每次使用时长该类目在周末与工作日的时长比值。这些特征的价值在于刻画“一个用户把时间花在了哪里”。比如30 岁以上用户在教育学习、金融理财等品类上的使用时长占比通常明显高于 18-24 岁群体而 18-24 岁群体在短视频和游戏上的时长占比则显著偏高。单看一个特征的区分度都是有限的但如果十几个品类的特征联合起来模型就能找到一个高维空间去分离开不同人群。品类特征还有一个特别有价值的衍生方向偏好强度排序。我把每个用户使用时长占比最高的前 3 个品类作为单独的离散特征喂进去同时计算一个品类熵值用户使用品类的多样性品类熵 - Σ(p_i * log(p_i)) 其中 p_i 第 i 个品类的使用时长占比熵值低说明用户高度聚焦在少数品类上熵值高说明兴趣分散。实测中品类熵与年龄呈负相关年长用户更聚焦、更“恋旧”年轻用户则更多元、更爱尝鲜。3.3 第三层时序节奏特征什么时间活跃、是否规律基础统计特征把时间维度压扁了但用户的行为节奏本身是强信号。这一层特征我主要做了三件事第一构造典型日活跃曲线。把一天切分成 24 个时段计算每个用户的活跃分布凌晨、上午、中午、下午、晚间、深夜六个时段的使用次数和时长占比。不要小看这种粗粒度曲线它能捕捉“这个人是不是典型的上班族作息”等强信号。第二计算作息规律性指标。比如用户每天首次使用时间的标准差、末次使用时间的标准差。标准差小说明这个人作息高度规律多为中年上班族或年长者标准差大说明作息紊乱或频繁熬夜年轻人常客。第三跨日规律特征。比如工作日和周末行为差异比、用户在一周内的活跃天数分布、相邻两天活跃时间长度的相关系数。这类特征能反映学生群体和工作群体的差异——学生周末行为与工作日相差不大部分工作人群则恰好相反。整套特征做完每人最终得到 150 维左右的特征矩阵。这些特征并不需要每一维都强区分但它们组合在一起就足够让下游模型捕获复杂的交互关系。4. 模型选型与训练GBDT 在此类任务中的回归模型选型上我最初也纠结过要不要上深度学习——毕竟手头有行为序列数据LSTM 或者 Transformer 处理时序似乎是更“高级”的选择。但做完对照实验之后我还是把主力模型放回了 LightGBM。4.1 为什么最终选择了 LightGBM 而非深度模型当时我同时跑了 LSTM 和 LightGBM 两组基线结论很现实数据形态不匹配我们最终构造出来的是表格型特征统计量、占比、熵值而不是原始序列。LSTM 确实可以吃原始行为序列但要写出高效的序列预处理流程工程复杂度明显增加样本量和维度我们有几十万有标注样本、150 维特征这正好是 GBDT 的优势区间。深度学习在这种中等规模表格数据上并没有天然优势想超过调优后的 GBDT需要额外做大量序列特征工程和超参搜索可解释性业务方需要知道“为什么把这个人判断成 25-34 岁”LightGBM 配合 SHAP 能给出清晰的归因深度学习模型在这方面的成本要高得多。LightGBM 在这一类任务里的定位其实类似“表格数据的默认最优解”。它有足够强的非线性拟合能力对缺省值有原生处理训练速度也快非常适合快速迭代。4.2 性别与年龄的不同建模方式性别和年龄虽然是两个目标但建模方式上我采用了不同的设计性别直接做二分类。输出 P(男)阈值默认 0.5但在实际应用时会把阈值调整到能让精确率和召回率平衡的位置比如 0.42 或 0.55而不是固定在 0.5。年龄我没有直接做四分类而是先用回归建模“连续年龄”再按 18-24、25-34、35-44、45 的边界切分。这么做有几个好处一是年龄段边界本来就有一定主观性回归输出连续值后期可以随时调整二是回归任务的样本利用效率更高不会把 24 岁和 25 岁因为人为切分而变成完全不同的两类。为了对比我也跑了直接做年龄四分类的版本。实测结果是回归后切分的版本在边界样本上的错分率更低整体准确率高了大概 3 个百分点。模型层面我用了两个独立的 LightGBM 模型一个管性别一个管年龄而不是用一个多任务模型。原因很简单两个任务的损失函数和样本权重不同强行共享特征表示反而可能互相干扰。4.3 训练配置与参数调优实践我用的是 LightGBM 的标准配置配合 Optuna 做了 50 次贝叶斯搜索最终一组比较稳定的参数是params { objective: binary, # 性别模型 # objective: regression, # 年龄模型 metric: auc, # 性别模型用 AUC年龄模型用 MAE learning_rate: 0.03, num_leaves: 63, max_depth: 7, min_child_samples: 40, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 1, lambda_l1: 1.0, lambda_l2: 5.0, n_estimators: 2000, early_stopping_rounds: 100, }训练时要注意几个细节类别样本权重性别模型里男女接近 1:1不用额外加权。年龄模型里 18-24 岁样本相对少回归任务本身对不平衡不那么敏感所以也不用特意过采样。早停要用验证集验证集必须是时序上靠后的数据不能用随机抽样这点后面会细讲。特征重要性监控训练完成后第一时间打印 feature importance如果发现某些强泄漏特征排在前面要返回特征工程阶段修复而不是直接上线。模型推理时我是把年龄回归结果先离散化成年龄段然后把“年龄段概率分布”用 Softmax 近似输出——具体是用一个校准后的回归残差分布换算成各个年龄段概率。这套方案在业务接口里更实用因为下游系统可以同时拿到点估计和不确定性。5. 效果评估与特征解读哪些行为信号最值钱模型训练完不是看个准确率就算完还要回答“它学到了什么、哪里学得好、哪里学得不好”。这一节把我在这个项目里的评估方式和特征解读一并列出供大家参考。5.1 评价指标准确率之外还要看什么性别二分类模型的主要指标AUC0.872验证集最优阈值下的准确率80.4%男性召回率76.8%精确率83.1%女性召回率83.7%精确率77.6%年龄模型分段的评估结果年龄段精确率召回率样本数18-2456.2%50.8%接近 2 万25-3461.5%63.2%接近 3 万35-4458.7%59.3%接近 2 万4570.2%73.5%接近 3 万总体加权62.3%62.3%-从这个表能看到一个规律年龄越大分段效果越好。45 的精确率和召回率最高18-24 最低。原因也直观——年轻人的行为模式分化更大有人像 35 岁一样只用工具类应用有人像 16 岁一样天天打游戏、看短视频把 18-24 岁的“代表性行为”刻画清楚本身就比中年群体更难。5.2 混淆矩阵里的典型错分模式年龄段的混淆矩阵值得仔细看。虽然四个年龄段都能大致分开但错分主要集中在相邻年龄段25-34 的人最容易错分到 35-44反之亦然18-24 的人一部分会错分到 25-34但很少会错分到 45错分距离通常不超过一个年龄段跨两个年龄段的情况很少。这说明模型学到的是“渐变的年龄信号”而不是“离散的标签跳跃”。这也是我坚持用回归而不是直接用四分类的原因——回归模型天然更适合这种有序目标。5.3 SHAP 分析哪些特征对预测的“贡献最大”我用 SHAP 分析了全局特征重要性排在前列的特征非常有业务洞察价值睡眠深度相关特征夜间使用次数占比、末次使用时间均值。这两个特征对年龄预测的贡献极大。深夜活跃是年轻人的强信号45 群体的夜间活跃占比几乎只有 18-24 岁群体的一半。应用品类结构特征各类目的使用时长占比尤其是游戏类、系统工具类、教育学习类、资讯类。这个信号可以同时解释性别和年龄。行为多样性指标品类熵值、活跃应用数、日均使用品类数。年轻用户在品类个数和切换频率上都明显高于年长用户。使用总时长注意这里的贡献不是线性增加而是非线性——非常短和非常长的使用时长都会导向特定人群方向。这些特征本身就是一份“人群行为趋势说明书”。即使不做模型直接把分布差异最大的特征画出来也能给产品和运营提供人群洞察的参考。6. 必须绕开的三个大坑数据泄露、时间切分与样本失衡这个项目里最值得记录的不是怎么把模型调好而是三个差点让我拿到错误结论的坑。我一个个来说。6.1 数据泄露设备型号和性别“意外联动”第一个版本的特征里我把设备品牌、机型、屏幕分辨率、设备价格档位都放进去了。逻辑很简单年轻人可能用性价比机型中年群体可能用商务机型这看起来是合理信号。结果训练时性别模型 AUC 直接飙到了 0.95 以上验证集准确率超过 88%。乍一看很兴奋但冷静下来检查 SHAP发现排在特征重要性第一的是“设备价格档位”和“屏幕分辨率”。问题出在哪里这批数据里有大量低端设备机型是公司测试机、渠道刷量机或者特定活动的奖励机这些机器的“使用者”在标注样本里大部分是男性测试账号而高端机型的一部分用户标签来自特定渠道的实名认证群体偏商务男性。模型学到的是“用这台设备的人大概率是男性”而不是“该用户的行为模式更像男性”。这是典型的数据泄露特征包含的信息不是用户自身属性而是设备环境的代理变量。排查方法是交叉验证特征与标签的相关性或者直接检查单一特征单独训练时的表现如果某个特征的 AUC 异常高就要小心了。我把设备相关的特征全部剔除后模型 AUC 从 0.95 回到 0.87但这个 0.87 才是真实可信的水平。剔除特征后模型的可解释性和稳定性反而更好了。6.2 时间切分随机切分带来的虚高第二个坑是验证集切分方式。一开始我用train_test_split(random_state42)随机切分模型验证集 AUC 在 0.89 左右。后来我意识到行为数据的观察窗口是 30 天同一用户的行为在不同时间段可能会出现在训练集和验证集两侧导致“记忆”而不是“泛化”。正确的做法是按时序切分用 T 到 T30 天的数据做训练用 T31 到 T60 天的数据做验证中间还要保证训练集和验证集的时间范围不重叠。改用严格时间切分之后验证集 AUC 从 0.89 掉到了 0.87准确率也从 82% 掉到了 80.4%。这个差距本质上就是模型“偷看”未来数据获得的信息增益。真实线上场景里我们永远只能用过去预测未来所以验证也必须这样做。这块我印象特别深同样是 AUC 从 0.89 掉到 0.87如果是随机扰动导致的我可能完全忽略但如果是切分方式导致的它说明泛化能力没有我们最初以为的那么高。做行为序列类项目时画一条时间轴再决定训练集和验证集的范围是最基本但也最容易忽略的一步。6.3 样本不平衡与“看起来很好”的假象第三个坑是年龄段的样本不平衡。我刚才给的标签分布看起来每个年龄段都占 20%-30%挺健康。但在用户活跃度和应用品类偏好上低年龄段和高年龄段用户产生的日志量差异巨大。18-24 岁用户一天打开应用 80 次45 用户可能只有 25 次。如果按日志条数而非用户人数构建特征低年龄段用户的特征会更稠密、置信度更高。这种差异不会直接导致预测偏差但会让模型更倾向于给低活跃用户打“保守”标签导致 45 用户的特征预测方差高。更隐蔽的问题出现在评估时由于各个品牌或渠道的设备样本分布不均模型可能在某个渠道的男性预测上表现很好在另一渠道上却差得离谱。我的做法是评估时按渠道、活跃度两个维度分别计算正确率。如果发现某个细分人群的准确率显著低于整体就需要返回特征工程看是不是信息不足而不是模型问题。除了这三个坑上线后还得监控“概念漂移”。行为偏好的可能随季节、假期、产品版本变化而漂移。模型上线后不能只看整体指标还要定期重算特征分布一旦发现某些高权重特征的分布偏移过大就要启动重训或特征修正。写在项目之后的一些心得整个项目做下来我对行为数据预测人口属性这件事的理解又深了一层。模型本身不难难的是每一步都要反复问自己这个特征真的在捕捉人的行为还是在捕捉设备和环境这个验证集真的模拟了线上场景吗这个指标在某个细分人群上的下降是被整体平均值掩盖掉了吗最后再分享一个小技巧。做这类任务时我会额外保留一份“评估专用特征”也就是只用线上实时能拿到的特征禁止一切需要离线全量重算才能拿到未来信息的特征参与评估。比如“该用户下个月的活跃总时长”这种特征显然在训练时可以用、上线时不可用但它在模型里会带来巨大的前视偏差。把这类特征提早列出来、标记出来并排除掉能帮你省掉很多不必要的返工。如果你手头也有一批移动设备行为数据想试一下预测用户画像我的建议很直接先花一半时间在特征工程和标签清洗上再花半小时跑一个 LightGBM 基线最后再花一小时用 SHAP 审视结果。这个流程走完你对“行为推断人口属性”这件事的信心会比单纯堆模型高得多。本文还有配套的精品资源点击获取
返回列表