用AI预测新增用户-机器学习**
概要
这次的学习将以科大讯飞的比赛:用AI预测新增用户,来深入学习机器学习的一些知识和任务。赛题背景:本次 用户新增预测的目标,是通过分析 讯飞开放平台 的用户行为数据, 预测用户是否为新增用户。
整体架构流程
对于整个Baseline方案项目分为三个模块:
特征设计
基于用户行为分析理论,重点捕捉行为模式特征,提取时间相关特征(如时段分 布、停留时长等),增强模型对用户行为的表征能力。
模型选择
采用LightGBM模型,其优势包括训练效率高、对数据预处理依赖低、且模型稳定性强;结合Scikit-learn的五折交叉验证方法,确保模型评估的鲁棒性。
阈值优化
通过动态调整分类阈值优化F1-score,采用精确率-召回率平衡策略,确保模型在业务场景中的分类性能最优。
技术名词解释
数据处理与特征工程: 如处理缺失值、异常值,解析JSON字段,从时间戳中提取特征(年、月、日、小时等),以及构造新的特征以提升模型表现。
分类模型与集成学习: 了解常用的分类算法(如逻辑回归、决策树、随机森林等),特别是梯度提升树(如LightGBM)的原理和使用。LightGBM是微软开发的*高效梯度提升框架,具有训练速度快、内存占用低和精度高等优点。
模型评估与指标: 掌握二分类问题的评估指标,如精确率(Precision)、召回率(Recall)和F1分数的定义及计算方法。F1分数是精确率和召回率的调和均值,在正负样本不均衡时比准确率更有参考意义。
交叉验证: 理解交叉验证的作用,能够使用分层K折交叉验证来评估模型性能,避免因随机划分导致的偏差。
超参数调优: 熟悉如何调整模型的超参数(如学习率、树的深度等)以提高模型效果,常用方法包括网格搜索、随机搜索和贝叶斯优化等。
数据建模与特征工程
TF-IDF 特征提取
用途:将文本数据转化为数值特征,捕捉关键词频率分布。
关键点:
文本预处理(分词、去停用词、标准化)。
TfidfVectorizer 的参数调优(如 max_features 、 token_pattern )。
高维稀疏特征的降维(PCA、TruncatedSVD)。
集成学习
用途:提升模型泛化能力,适用于标签不唯一或稀疏场景。
关键点:
LightGBM/XGBoost 的超参数调优(学习率、树深度)。
动态集成策略(加权平均、Stacking)。
半监督学习(伪标签生成与联合训练)。
时间序列分析
用途:捕捉用户行为的时间动态性(如活跃周期性)。
关键点:
时间戳处理( hour , dayofweek 等特征提取)。
动态权重(近期行为的重要性)
技术细节
1、要解这道题,需要解决以下要点和难点:
用户行为事件数据 → 用户级别预测
高维稀疏特征(设备/地域/行为ID)
正负样本不均衡(新增用户占比较少)
用户行为聚合:如何将事件级数据转化为用户特征
时间敏感特征:用户行为模式随时间变化
2、解题思考过程
关键决策点:
选择树模型而非神经网络(训练速度/特征处理)
优先构造简单的时间特征而非复杂特征工程
参考资料:
LightGBM官方文档(分类任务参数配置)
时序特征工程最佳实践(FeatureTools库)
3、Baseline核心函数
核心函数1:交叉验证建模
n_folds = 5
kf = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=42)
for fold, (train_idx, val_idx) in enumerate(kf.split(X_train, y_train)):
print(f"\n======= Fold {fold+1}/{n_folds} =======")
X_tr, X_val = X_train.iloc[train_idx], X_train.iloc[val_idx]
y_tr, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx]
# 创建数据集(指定类别特征)
train_set = lgb.Dataset(X_tr, label=y_tr)
val_set = lgb.Dataset(X_val, label=y_val)
# 模型训练
model = lgb.train(
params,train_set,
num_boost_round=5000,
valid_sets=[train_set, val_set],
callbacks=[
lgb.early_stopping(stopping_rounds=200, verbose=False),
lgb.log_evaluation(period=200)
]
)
核心函数2:目标优化函数
def find_optimal_threshold(y_true, y_pred_proba):
"""寻找最大化F1分数的阈值"""
best_threshold = 0.5
best_f1 = 0
for threshold in [0.1,0.15,0.2,0.25,0.3,0.35,0.4]:
y_pred = (y_pred_proba >= threshold).astype(int)
f1 = f1_score(y_true, y_pred)
if f1 > best_f1:
best_f1 = f1
best_threshold = threshold
return best_threshold, best_f1
4、优化方案:这里我采用的是TFIDF挖掘用户更多信息
示例:
def create_tfidf_features(df, tfidf_cols, max_features=200):
"""为指定列创建TF-IDF特征(按did聚合)"""
# 按did聚合文本
agg_text = df.groupby('did')[tfidf_cols].agg(
lambda x: ' '.join([str(val) for val in x if pd.notna(val)])
)
# 为每列创建TF-IDF特征
tfidf_features = pd.DataFrame(index=agg_text.index)
for col in tfidf_cols:
print(f"处理字段: {col}")
# 创建TF-IDF向量器
vectorizer = TfidfVectorizer(max_features=max_features,token_pattern=r'\b\w+\b')
try:
# 尝试拟合和转换
tfidf_matrix = vectorizer.fit_transform(agg_text[col])
# 获取特征名称
feature_names = vectorizer.get_feature_names_out()
# 创建特征列
for i, feature_name in enumerate(feature_names):
tfidf_features[f'tfidf_{col}_{i}'] = tfidf_matrix[:, i].toarray().ravel()
print(f" 创建了 {len(feature_names)} 个特征")
except ValueError as e:
print(f" 处理失败: {e}")
# 如果处理失败,创建默认特征列
for i in range(max_features):
tfidf_features[f'tfidf_{col}_{i}'] = 0.0
return tfidf_features.reset_index()
该函数的核心目标是:为指定的文本列( tfidf_cols )生成 TF-IDF 特征,并按用户唯一标识 did 进行聚合。适用场景:当某些字段(如用户行为序列、设备信息组合等)需要转化为数值化特征时,通过 TF-IDF 捕捉关键词频率分布,为模型提供更丰富的输入。
参数说明
df : 原始数据框,包含 did 和待处理的文本列。
tfidf_cols : 需要生成 TF-IDF 特征的列名列表(如 [‘device_brand’, ‘os_type’] )。
max_features : 每个 TF-IDF 向量的最大特征数(默认 200,控制维度)。
核心逻辑:
TF-IDF 向量化:
使用 TfidfVectorizer 将文本转换为 TF-IDF 矩阵。
max_features 控制保留的关键词数量。
token_pattern=r’\b\w+\b’ 用于匹配英文单词(如 hello ),对中文需替换为分词工具(如 jieba )。
特征存储:
将 TF-IDF 矩阵的每一列(对应一个关键词)提取为新特征列,命名格式为 tfidf_{列名}_{序号} 。
例如:若 col=‘device_brand’ ,生成 tfidf_device_brand_0 , tfidf_device_brand_1 等。
异常处理:
若 TF-IDF 转换失败(如所有文本为空),则生成全 0 列,避免程序中断。
小结
这里的处理只是众多方法的其中一个,这道题的后续将继续优化,我也会继续学习机器学习。