简介在机器学习与大数据风控领域用户画像是精细化运营的核心基础。通过分析移动设备产生的行为数据如App使用记录、传感器信号与交互习惯可有效推测用户的性别与年龄等基础属性。这一过程依托于完整的特征工程体系包括统计特征、时序特征与序列行为特征并借助LightGBM、LSTM等模型进行训练与融合从而在冷启动场景下快速构建初始画像。该技术广泛应用于精准营销、内容推荐、风险控制等业务能够显著提升用户洞察效率。本文基于“通过移动设备行为数据预测使用者性别和年龄”的真实项目系统梳理了从数据解析、特征设计到模型调优的完整链路并分享常见问题与工程落地经验。 最近在做一个用户画像相关的分析项目拿到一份名为“通过移动设备行为数据预测使用者的性别和年龄.zip”的数据集。这个标题看起来就是一个标准的机器学习任务根据用户在手机上的操作行为去推断ta的性别和年龄段。听起来不算复杂但真正做起来从数据清洗到特征工程再到模型调优坑一点都不少。这篇文章我就把整个流程从头到尾拆开讲一遍包括我是怎么理解这个任务的、用了什么特征、踩了哪些坑、最终的模型效果如何以及一些可以直接拿去用的代码和参数配置。无论你是刚接触用户画像的新手还是已经在做行为序列建模的老手这篇内容应该都能给你一些参考。这个项目本质上属于移动端用户画像Mobile User Profiling领域。它的核心逻辑是每个人的手机使用习惯是独特的——有人喜欢半夜刷短视频有人每天打开购物App的次数是别人的五倍有人习惯用左手打字导致传感器数据分布不同——这些看似零散的日志数据其实暗含了非常强的个人属性信息。性别和年龄预测只是其中最常见的两个维度但把这条链路跑通之后扩展到兴趣偏好、职业、消费能力等维度逻辑是完全一样的。1. 项目定位与核心思路拆解1.1 这个任务到底在预测什么先把这个任务定义清楚。性别是一个典型的二分类问题男/女。年龄则比较灵活可以做成回归问题也可以做成多分类问题——比如分为18岁以下、18-24岁、25-34岁、35-44岁、45岁以上这几个区间。从实际落地效果来看我更推荐用分箱的方式做多分类。原因有两个第一用户自报年龄本来就有模糊性很多人填的生日是假的精确到个位数的回归本身就没有意义。第二分箱之后类别之间的边界更清晰模型的学习难度更低评估指标也更直观。比如你预测一个人的年龄是28岁但真实值是32岁回归模型会扣分但如果分箱是25-34这个区间两个人都落同一个箱子这单就不算错。从数据层面看移动设备行为数据通常包括以下几类App使用记录启用了什么App、启动时间、使用时长、使用频率传感器数据加速度计、陀螺仪、GPS定位、光线传感器等设备交互数据解锁次数、滑动速度、键盘输入速度、点击间隔通信数据通话时长、短信频率有些数据集会包含脱敏后的通信统计网络数据Wi-Fi连接记录、流量使用量、网络类型切换频率不同的数据源对性别和年龄的敏感程度不一样。比如传感器数据里加速度计记录的步态信息对人的性别有相当强的区分度——因为男女的步行姿态、步频和振幅存在统计学差异。而App使用数据则对年龄更敏感——60后和00后安装的应用列表、使用时段几乎完全不在一个频道上。1.2 为什么用“行为数据”而不是“静态属性”这里有一个值得琢磨的问题既然要预测性别和年龄为什么不直接用注册信息、头像、昵称这些静态属性原因在于绝大多数真实业务场景里静态属性是不可得的。你拿到的数据集往往是一个匿名化的行为日志表里面只有一串设备ID、一堆行为事件、对应的时间戳什么都没有。没有头像没有昵称没有身份证号。你要做的就是从这些行为痕迹里把用户的性别和年龄“猜”出来然后基于这个推断结果去做后续的精准运营、内容推荐、风险控制等业务动作。所以这个任务本质上是在解决“数据冷启动”问题——对一个新识别到的设备在没有任何显性画像信息的情况下快速建立初始画像。1.3 项目的大致技术路线这类项目到最后的落地流程基本是固定的我按自己的经验整理成如下几步数据探索与清洗先搞清楚zip包里有什么、字段结构长什么样、有没有缺失值和异常值特征工程从原始行为日志中提取统计特征、时序特征、序列特征模型构建以LightGBM或XGBoost为主力模型配合逻辑回归做baseline必要时用LSTM做序列建模对比评估与调优用准确率、F1、AUC多维度评估重点看分层效果结果解释与落地输出特征重要性验证模型是否学到了有业务含义的模式下面我按这个路线把每个环节展开来讲。2. 数据准备与特征工程实战2.1 数据集的解压与初步检查拿到手的是一个zip压缩包。如果你是在Linux或者macOS上操作一条命令就解压了unzip user_profile.zip -d user_profile_dataWindows用户直接用解压软件或者PowerShell里的Expand-Archive命令都行。解压之后我习惯先用tree命令或者文件管理器看一眼目录结构find user_profile_data -type f | head -50一般这种数据集里至少会有两张表一张是行为日志表一张是用户信息表。行为日志表通常非常庞大——如果它是个CSV文件动辄几个GB是非常正常的。这里我要提一个很多人会踩的坑不要直接用Excel打开大CSV也不要直接read_csv一把梭。我建议先用命令行的方式瞄一眼数据长什么样head -20 user_behavior.csv或者用Python快速读取前几行import pandas as pd # 只读前1000行快速了解字段结构 df_sample pd.read_csv(user_behavior.csv, nrows1000) print(df_sample.columns.tolist()) print(df_sample.head())如果要更精确地控制读取类型可以在read_csv里指定dtype参数避免Pandas把数字列自动推断成float64导致内存翻倍。比如设备ID如果是字符串就显式指定为str时间戳如果不是要参与运算也可以先用字符串存着。批量读取大文件时我还习惯用chunksize参数分块处理或者用dask.dataframe做分布式的懒加载。这些技巧能帮你避免“内存不足”直接崩掉的情况。2.2 字段级的数据理解与预处理我自己拿到的这份数据集行为日志表大概是这样的结构真实字段名我做了脱敏处理字段名类型说明device_idstring设备唯一标识已匿名化event_typestring事件类型如app_launch、screen_unlock、gps_updateevent_timedatetime事件发生时间app_categorystringApp所属分类如游戏、社交、购物durationint事件持续时间秒extra_infostring附加信息可能是来源页、网络类型等标签表则很简单字段名类型说明device_idstring设备唯一标识genderstringmale/femaleage_groupstring18-24、25-34等做预处理的时候我建议重点关注三个问题第一个是缺失值。行为日志一般不太缺但标签表里偶尔会出现有的设备没有标签的情况。这类样本如果当无监督数据用还好但如果是做监督学习直接丢掉就好不用勉强。第二个是异常设备。有的设备一天的行为事件有十几万条明显不是正常人类使用大概率是测试机或者刷量机。我的经验是设定一个每日事件量的合理范围超出上限的设备直接剔除否则它会成为模型里的噪声源。第三个是时间窗口的归一化。同一个用户在不同时间段的数据量可能差异巨大——比如前两个月每天都有行为日志后一个月突然就消失了。这种情况要统一截取时间窗口保证每个样本的观测期长度一致否则模型会学到“数据量多年轻用户”这种表面规律。2.3 三类核心特征的设计与实现特征工程是这个项目里最花时间、也最决定上限的环节。我从三个维度来设计特征。第一类统计类特征这类特征最简单但往往是最有效的。统计维度的核心是“使用强度”。比如每天平均App启动次数每天平均使用时长常用App类别的数量和占比每日解锁次数、解锁时间间隔的均值和方差夜间23点到5点活跃天数占比代码实现起来不复杂以“计算每个用户每天的App启动次数”为例# 假设df已经筛选过event_type为app_launch的记录 df[date] pd.to_datetime(df[event_time]).dt.date launch_count df.groupby([device_id, date]).size().reset_index(namelaunch_count) # 统计每个用户的日均启动次数和方差 user_launch_stat launch_count.groupby(device_id)[launch_count].agg([mean, std, max, min]).reset_index() user_launch_stat.columns [device_id, launch_mean, launch_std, launch_max, launch_min]第二类时序类特征统计特征是“一坨数据压成一个数”丢掉了时间维度上的信息。时序特征则是把时间维度显式建模进来。最有代表性的几个特征包括一天中活跃时段的分布是Morning Person还是Night Owl用每个小时段0-23点的活跃占比来表示一共24个特征一周内各天的活跃度差异工作日和周末的使用模式可以区分学生党和上班族活跃时间段的规律性计算用户每天首次使用设备的时间的方差方差小说明作息极其规律App使用时的转移规律比如从社交类跳到视频类的概率这个可以构建一个App类别转移矩阵再从中提取特征时序特征里我特别推荐一个每小时活跃占比的熵。熵值高说明这个用户全天活跃均匀分布熵值低说明活跃高度集中在某些时段。这个特征在区分年龄上表现很好——年轻用户的活跃时段熵通常比中老年用户低因为年轻人有明显的“熬夜峰值”。hour_counts df.groupby([device_id, hour]).size().reset_index(namecnt) user_total hour_counts.groupby(device_id)[cnt].transform(sum) hour_counts[ratio] hour_counts[cnt] / user_total # 熵特征 import numpy as np entropy hour_counts.groupby(device_id).apply( lambda x: -np.sum(x[ratio] * np.log(x[ratio] 1e-9)) ).reset_index(namehour_entropy)第三类序列行为特征统计和时序都是对“日志聚合成统计量”的建模但用户行为本质上是一个序列——App启动的顺序、白天到夜晚的转场模式都是序列信息。这里有两个常见做法一个是把每个用户的行为事件序列转成TF-IDF向量把“App类别”当成词把“一次会话中的操作序列”当成句子再降维作为特征。这个方法简单粗暴但效果很稳定。另一个是用LSTM或者Transformer直接对序列建模。这个后面在模型部分细说。如果只做特征工程可以先把行为序列转到Embedding空间再对Embedding做统计池化平均池化、最大池化喂给树模型。# 用session划分然后提取每个session内的事件序列 df df.sort_values([device_id, event_time]) df[session_id] (df[event_time].diff() pd.Timedelta(minutes30)).cumsum() session_sequences df.groupby([device_id, session_id])[app_category].apply(list).reset_index()注意session的划分是行为序列建模里一个非常关键的超参数。30分钟没动作就算新会话这是我常用的默认值但你可以通过看时间间隔的分布像来调整——有的业务场景5分钟就算新会话了。2.4 特征选择与去冗余特征做几百个之后就要考虑去冗余和筛选的问题。我的经验是树模型对特征之间的共线性不敏感但冗余特征会稀释特征重要性让模型变得不稳定。我常用的特征筛选方式有两种。第一种是看特征与标签之间的互信息低于某个阈值的直接删掉。第二种是训练一版LightGBM用feature_importance筛选出Top-N个特征再观察去掉后半部分特征后模型效果是否下降。这里教大家一个小技巧如果多个特征之间的相关系数超过0.95保留其中一个就够了不用全留。比如“日均App使用时长”和“日均解锁次数”有时候相关性极高留一个即可。3. 模型选型与训练调优3.1 四个候选模型的对比模型选择上我把候选方案分成四个梯队设计成对照实验最后直接比较效果。模型优点缺点适用场景逻辑回归训练快、可解释性强无法捕捉非线性关系作baselineLightGBM/XGBoost精度高、支持类别特征、对特征尺度不敏感需要调参容易过拟合主力模型LSTM天然建模行为序列训练慢、需要大量数据序列特征强时用Transformer效果上限高需要大量数据和算力数据量百万级时考虑按我的经验如果你只能选择一个模型默认选LightGBM。它对特征工程的要求更低、训练快、泛化能力在中小数据集上非常稳定。Transformer在这个数据规模下大概率打不过调好参的LightGBM除非你有几百万甚至上千万级别的行为序列样本。LSTM的价值可以体现在融合上——用LSTM输出一个隐向量拼到LightGBM的特征里往往能带来小幅提升。3.2 训练集与验证集的划分方式这里有一个非常容易犯错的点行为日志的样本不是独立的。同一个设备的多条行为日志关联同一个用户如果直接用事件级别划分训练集和验证集就会发生数据泄露——同一个用户的行为同时出现在训练集和验证集里模型相当于“见过”这个用户评估结果虚高。正确的做法是在设备ID维度做划分from sklearn.model_selection import train_test_split unique_devices df[device_id].unique() train_devices, val_devices train_test_split(unique_devices, test_size0.2, random_state42) train_df df[df[device_id].isin(train_devices)] val_df df[df[device_id].isin(val_devices)]如果数据有时间轴向更严格的做法是前80%的时间段做训练后20%的时间段做验证。这样能模拟真实上线时的状态——用历史数据训练预测未来新来的用户。3.3 LightGBM训练全流程代码我把从特征到训练的完整流程串成一个Pipeline的核心代码你可以直接参考import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, f1_score, roc_auc_score from sklearn.preprocessing import LabelEncoder # 假设features是特征DataFramelabels是标签Series X features.drop(device_id, axis1) y_gender labels[gender] y_age labels[age_group] # 性别二分类的标签编码 le_gender LabelEncoder() y_gender_encoded le_gender.fit_transform(y_gender) X_train, X_val, y_train, y_val train_test_split( X, y_gender_encoded, test_size0.2, random_state42, stratifyy_gender_encoded ) # LightGBM数据集 train_data lgb.Dataset(X_train, labely_train) val_data lgb.Dataset(X_val, labely_val, referencetrain_data) # 参数配置实测在多数用户画像数据集上表现不错的一组参数 params { objective: binary, metric: auc, boosting_type: gbdt, learning_rate: 0.05, num_leaves: 31, max_depth: -1, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 5, lambda_l1: 0.1, lambda_l2: 0.1, verbose: -1, seed: 42, } # 早停回调当验证集AUC连续50轮不提升就停止 callbacks [lgb.early_stopping(stopping_rounds50, verboseTrue)] model lgb.train( params, train_data, num_boost_round2000, valid_sets[val_data], callbackscallbacks, ) # 预测与评估 y_pred_proba model.predict(X_val, num_iterationmodel.best_iteration) y_pred (y_pred_proba 0.5).astype(int) auc roc_auc_score(y_val, y_pred_proba) acc accuracy_score(y_val, y_pred) f1 f1_score(y_val, y_pred) print(fGender model - AUC: {auc:.4f}, Accuracy: {acc:.4f}, F1: {f1:.4f})如果你的数据是类别不平衡的比如男女比例接近3:7那么需要在参数里加上is_unbalance: True或者在评估时以AUC和F1为主不要只看accuracy——否则模型全预测成多数类accuracy也会很高但毫无意义。3.4 LSTM做序列建模的完整流程如果你手里的数据是完整的用户操作序列可以试一下LSTM。它的建模思路是对每个用户把行为事件序列编码成定长的向量再接一个分类头。import torch import torch.nn as nn class BehaviorLSTM(nn.Module): def __init__(self, vocab_size, embed_dim64, hidden_dim128, num_layers2, num_classes2): super().__init__() self.embedding nn.Embedding(vocab_size, embed_dim, padding_idx0) self.lstm nn.LSTM(embed_dim, hidden_dim, num_layers, batch_firstTrue, dropout0.3) self.classifier nn.Sequential( nn.Linear(hidden_dim, 64), nn.ReLU(), nn.Dropout(0.3), nn.Linear(64, num_classes) ) def forward(self, x): embedded self.embedding(x) # [batch, seq_len, embed_dim] lstm_out, (h_n, c_n) self.lstm(embedded) # 取最后一层的最后一个时间步输出 last_hidden h_n[-1] # [batch, hidden_dim] logits self.classifier(last_hidden) return logits每个用户的行为序列要做定长处理。我的做法是取每个用户最近N条行为记录不足N条的用0填充超过N条的截断。N的选择需要看数据分布通常取50~200之间。LSTM训练这里有一个关键点行为序列的排序方式。同一个用户行为事件按时间正序排和倒序排模型学到的是完全不同的模式。一般来说正序更适合预测“接下来会干什么”而倒序离预测时刻最近的行为放最前面更适合做用户画像因为越近的行为携带的个人特征越强。3.5 模型的融合策略如果你把LightGBM和LSTM都训练出来了可以采用简单有效的融合方式把LSTM最后一层输出的概率作为新特征加入LightGBM的输入特征里重新训练一版LightGBM。# 假设lstm_proba是LSTM输出的概率值shape为[n_samples, 1] X_train_lstm[lstm_pred] lstm_proba这种Stacking的方式通常比直接对两个模型的结果取平均要好一点因为LightGBM知道何时该信任LSTM的输出而不是机械地取平均。4. 模型评估与业务落地解读4.1 评估指标的选型性别预测可以用AUC、Accuracy、F1年龄预测则要多关注分层准确率——尤其是相邻年龄段之间的错分情况。比如把25-34预测成了35-44这个错误的严重性远低于把25-34预测成18-24。所以年龄预测任务里我强烈建议加一个指标相邻准确率即预测结果与真实标签的年龄区间相邻或相同都算正确。这个指标更贴近真实的业务容忍度。4.2 特征重要性的解读LightGBM训练结束后一定要看特征重要性它不只是模型解释的工具更是你理解业务数据的窗口。import pandas as pd importance pd.DataFrame({ feature: model.feature_name(), importance: model.feature_importance(gain) }).sort_values(importance, ascendingFalse) print(importance.head(20))在我跑的这份数据里重要性靠前的特征大致有夜间活跃时长占比Sleep_Night_RatioApp类别多样性App_Category_Entropy每日平均解锁次数Unlock_Freq_Mean工作日与周末App使用差异Weekday_Weekend_Diff短视频类App使用时长比例Short_Video_Ratio这些特征的业务含义非常清晰年轻用户通常熬夜更多、装的App类型更杂、解锁手机更频繁而短视频类App的使用比例在不同年龄段的差异更是肉眼可见。4.3 分群效果验证模型整体AUC可能不错但你要去验证它在不同人群上的表现是否均匀。我习惯把用户按“高频使用”和“低频使用”分组单独看模型的评估指标。如果你发现低频用户的AUC明显低于高频用户那说明模型过度依赖“使用量”类特征。这时候就需要从序列特征里再挖掘一些对低频用户也有效的信号比如“低频用户使用的App类型是否更有年龄倾向性”。5. 常见问题与排查技巧实录5.1 ZIP相关的坑解压环节先有两个经典问题。第一个是“file is not a zip file”。拿到的压缩包明明后缀是.zip但解压就报错。这个问题的常见原因有两个一是文件下载不完整尤其通过网盘下载文件大小对不上二是这个文件被改过后缀其实可能是个RAR或者7z。排查方式很简单Linux下用file命令直接看文件真实类型file user_profile.zip如果是数据下载不完整老老实实重新下载。如果是伪装后缀改用unar这个解压工具它会自动识别真实格式并解压。第二个是“failed to copy spatial iop zip 与技术支持部门联系”——这个报错在专业软件加载数据时经常出现通常是解压后的某个文件被安全软件误删或者压缩包内部结构损坏。解决思路是先解压到纯英文路径不要有中文路径然后检查安全软件的隔离区看看是不是误隔离了某个文件。还有Z01和其他分卷压缩包的问题。如果压缩包是分卷的比如.zip、.z01、.z02必须把所有分卷文件放在同一个目录且命名一致然后从第一个.zip文件开始解压。用7-Zip或者WinRAR都能处理分卷压缩。解压后如果只是少了部分数据可以试试zip -FF来修复损坏的压缩包zip -FF damaged.zip --out repaired.zip这个命令会尽可能把能恢复的部分提取出来不保证100%恢复但对于“只坏了一个分卷”的情况很有用。5.2 “invalid zip archive: could not find EOCD”这个报错在Python的zipfile模块里很常见表示zip文件末尾找不到End of Central Directory记录。它本质上说明文件不完整或者已经被破坏。常见原因是文件在传输过程中被截断或者用迅雷这类下载工具下载时提前改了文件名。我一般直接放弃这个文件重新下载——因为zip作为一种结构化的归档格式尾部信息一旦丢失整个文件都很难修复。如果非要尝试修复用之前提到的zip -FF命令试一次但成功率不高不太建议花太多时间。5.3 内存爆掉怎么办处理几个GB甚至几十GB的行为日志时内存不足是最常见的崩溃原因。我的建议第一能用chunksize就分块读chunk_iter pd.read_csv(huge_behavior.csv, chunksize500000, dtype{device_id: str, event_time: str})第二尽早在管道里做聚合下推。比如你要算每个用户的日均启动次数不用把所有原始日志加载到内存里算可以先对device_id和date做groupby聚合聚合之后的数据量会缩到原来的几十分之一。第三如果特征数量过多考虑用feature_hashing或者PCA降维。特征数量到几千维的时候LightGBM训练速度会明显下降但降维后通常对效果影响不大。5.4 过拟合的典型信号与对策用户画像任务里过拟合的表现很典型训练集AUC高达0.99验证集只有0.75。这个差距如果超过0.1基本可以断定过拟合了。我推荐三个对策按优先级排序增加正则化把lambda_l1和lambda_l2调大feature_fraction从0.8降到0.6减少树的复杂度num_leaves从31降到15max_depth设为5或6降低learning_rate增大num_boost_round同时把早停轮数设置得更大——低学习率的模型更不容易过拟合如果你跑的是神经网络则可以考虑在LSTM层后面加Dropout把dropout从0.3调到0.5同时增加训练数据的batch size。5.5 类别不平衡的应对性别和年龄分布天然不平衡——比如某些平台女性用户占60%以上或者某个年龄段的用户是绝对多数。如果不做任何处理模型会倾向于把边界样本预测成多数类。我的做法包括在LightGBM参数里设置is_unbalance: True在训练集上做欠采样或过采样推荐用SMOTE但注意只能对数值特征做评估时以AUC和F1为主不要只盯accuracy如果业务上更关心少数类的预测准确率可以在预测时手动调整阈值5.6 数据的冷启动与时效性问题行为数据是有“保质期”的。三个月前的行为模式和现在的行为模式可能差别很大——比如疫情期间大家的App使用时长普遍上升节假日和开学季的使用模式也完全不同。所以模型上线后要定期用新数据重新训练同时监控模型预测分布的漂移。如果发现预测结果的分布随时间变化明显大概率是用户行为模式发生了结构性变化需要重新审视特征。6. 从模型到业务怎样走完最后一公里模型训出来AUC0.86看指标已经不错了但离业务落地还有一段路。首先是输出层的设计。真实业务里很少直接输出离散的类别标签更常用的是输出概率分数。比如性别模型输出male概率0.72、female概率0.28这种概率值比单纯的“男/女”标签提供的信息更多。年龄同理输出每个年龄段的概率分布业务方可以按需取期望值也可以取最大概率段的标签。其次是uncertainty的处理。如果模型对某个样本的预测概率在0.5附近徘徊比如性别概率0.51对0.49说明模型很犹豫这时候的预测结果基本不可信。我的做法是设置置信度阈值——低于阈值就标记为“不确定”不参与后续精准运营而是等积累更多行为数据后再重新预测。用户画像的置信度是一个很核心的业务概念。一个只用了两天的设备行为数据少预测出来的画像大概率不准一个用了半年的设备画像置信度通常就很高了。所以实际系统里要结合样本覆盖的行为时间跨度来动态调整置信度。最后是隐私合规的问题。预测性别和年龄虽然看起来不是什么敏感操作但涉及用户数据开发时就要做好脱敏处理行为日志里不要保留可关联到真实身份的信息。训练用的数据集如果是公开数据也要确认数据的使用条款。7. 一点实操经验分享项目做到最后我最大的体会是这类用户画像赛题模型之间的差距往往没有特征工程之间的差距大。同一份数据特征做得好的人可能AUC0.85特征粗糙的可能只有0.78。你的时间分配应该有至少70%花在数据清洗和特征设计上30%花在模型调参上。再说一个容易被忽视的细节做好Baseline。不要一开始就上LSTM、Transformer这些重型模型先用逻辑回归或者单棵决策树跑一个最简版本把整个Pipeline走通。这个Baseline不需要效果好它的意义在于验证你的特征拼接、标签对齐、验证集划分这些流程没有bug。等Baseline跑通再换LightGBM做主力心里会踏实很多。最后如果你在复现这个项目时发现性别模型和年龄模型的效果差异很大不用慌。性别在行为数据里的信号通常更强年龄则更依赖App使用习惯这类特征。两个任务各有各的难点分开建模、分别调优比用一个共享模型强行多任务学习更可控。但如果数据量足够大多任务学习也可以试试——性别和年龄之间确实存在相关性比如年轻女性在短视频类App上的行为模式和中年男性有明显的差异。这个方向值得深入探索。这个“通过移动设备行为数据预测使用者性别和年龄”的项目做到这里链路已经完整了。从zip解压、数据清洗、特征工程、模型训练到结果解读每一步都有很多可以优化的空间。如果你也在跑类似的数据建议先从LightGBM和一套扎实的统计特征开始把主干跑通再去探索序列模型和深度学习的空间。这套方法论你在构建任何用户画像系统时都可以直接迁移过去用。本文还有配套的精品资源点击获取