Contents
  1. 1. 1. 要解决的问题
  2. 2. 2. 整体思路
  3. 3. 3. 特征选取
    1. 3.1. 3.1 特征举例
    2. 3.2. 3.2 获取数据
    3. 3.3. 3.3 特征工程
      1. 3.3.1. 3.3.1 删除无用特征
      2. 3.3.2. 3.3.2 特征的空值处理
      3. 3.3.3. 3.3.3 处理重要特征
      4. 3.3.4. 3.3.4 特征标签化
      5. 3.3.5. 3.3.5 可用数据量
  4. 4. 4. 模型调优
    1. 4.1. 4.1 Decision Tree 调优
      1. 4.1.1. 4.1.1 树的深度调优
      2. 4.1.2. 4.1.2 其他参数调优
      3. 4.1.3. 4.1.3 DT 输出
    2. 4.2. 4.2 Random Forest 调优
    3. 4.3. 4.3 Adaboost 调优
  5. 5. 5. 踩过的坑
    1. 5.1. 5.1 信息熵
    2. 5.2. 5.2 PCA 降维
    3. 5.3. 5.3 用了未来特征
  6. 6. 6. 模型对比
  7. 7. 7. 总结
  8. 8. 参考文档

1. 要解决的问题

一句话概述:
预测进入 App 首页的用户是否会点击「XLJH推荐模块」,该模块是 App 的一个功能,用户点击按钮则会进入一个XLJH的页面。

目前每天进入 App 首页的用户中,有 2.1234% 的用户会点击「XLJH推荐模块」,转化率非常低,而首页每日的曝光量是最大的,所以优化这个模块的转化率就变得尤为重要,也是本次作业要解决的问题。

2. 整体思路

获取某一段时间的相关埋点事件、用户业务数据、用户画像等数据,将数据合并、清洗、整理为可用的数据集,然后跑决策树,随机森林和 Adaboost 三个模型。
要获取的数据是:

  • 用户被展示到该模块的埋点事件
  • 用户点击该模块的埋点事件
  • 用户使用过 XLJH 的统计数据
  • 用户画像
  • 用户的业务画像

3. 特征选取

3.1 特征举例

特征的总数非常多,总共有 280 个,抽取一些特征描述如下:

  • 年龄
  • 性别
  • 身高
  • 体重
  • 业务特征 1
  • 业务特征 2
  • 业务特征 3
  • … …
  • 业务特征 n-1
  • 业务特征 n
  • 进入首页时距离上一次使用模块的时间
  • 设备机型

3.2 获取数据

通过在 hive 里跑 sql(具体的 sql 语句略) 获取到的数据量为:54w。(单位为数据行数,下同)

3.3 特征工程

3.3.1 删除无用特征

  1. 无用特征的删除:例如 userId 等。这些特征明显与结果无关。
  2. 删除由预测结果导致的特征:例如使用过该模块的时间。这些特征是在预测值为 True 时才会有值,而且这特征的赋值在要预测的事件发生之后。

3.3.2 特征的空值处理

  1. 删除特征为空的数据,例如年龄,性别等必须会有的特征。
  2. int 类型的特征将空值填充为 0,例如某业务的 累计分钟数,某实体数量,粉丝数量,过去7天的XX业务使用统计等
  3. string 类型的特征将空值填充为 0,例如 citycode,tags 等。

3.3.3 处理重要特征

跑完 Random Forest 模型,可以输出 Feature importances 列表, Top 10 的图略。

其中需要特别处理的特征是 c.bmi 和 c.age。
分析数据后发现年龄为空值的情况非常少,所以把 c.age 为空的数据删掉。
c.bmi 需要用户填入身高和体重,这部分数据缺失一些,所以填为 c.bmi 这一列的平均值,数据集中的 dataset[c.bmi].mean = 23.3174390247965,符合常识。

3.3.4 特征标签化

数据标准化的处理方式如下:

1
2
3
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
dataset = dataset.apply(le.fit_transform)

3.3.5 可用数据量

按如上方式处理完后,最终可用的数据量为:30w

4. 模型调优

4.1 Decision Tree 调优

4.1.1 树的深度调优

使用的特征数量为 275 个,使用的训练集数量为 54801。

不同树深度对应的模型评估如下:

tree_depth_3_to_5.jpg

tree_depth_10_to_50.jpg

可以发现树的深度越高,召回率越高,准确率却越低。总体评价是树的深度为 5 最好。

4.1.2 其他参数调优

max_features=’sqrt’ 加了这个反而变差了很多。
min_samples_split=5, min_samples_leaf=5,加了这个反而变差了一些。

4.1.3 DT 输出

深度为 5 的 DT 截取部分放大后的图如下:
tree_depth_5_img.jpg

4.2 Random Forest 调优

n_estimators:100, 300, 500 都试过,差别不大。弱学习器的最大迭代次数太小会不准确,太大模型训练地就很慢。
oob_score: True,即采用袋外样本来评估模型的好坏,提高模型拟合后的泛化能力。
基本上,RF 不怎么需要调参。

比较有价值的是能产生特征的重要性,Top 30 Feature importances 的图片略。
Feature importances Top 10 的可视化略。

使用 GridSearchCV 搜索最优参数,参数搜索结果如下:
GridSearchCV_result.jpg

但是使用参数后,RF 的 AUC 降到了 0.82,应该是 max_features 和 min_samples_leaf 这两个参数调的不对。

4.3 Adaboost 调优

AdaBoostClassifier 的 base_estimator 选择已经之前训练好的 DT,效果更好,如下:

1
2
3
4
adb_clf = AdaBoostClassifier(n_estimators=100, random_state=100, learning_rate=0.02).fit(X_train, y_train)
AUC Score (Train): 0.629162
adb_clf_2 = AdaBoostClassifier(clf, n_estimators=100, random_state=100, learning_rate=0.02).fit(X_train, y_train)
AUC Score (Train): 0.659129

learning_rate 设置为 0.02 能兼顾速度和效果。

5. 踩过的坑

5.1 信息熵

基尼指数和信息熵的几乎无差别,不怎么影响结果。

5.2 PCA 降维

PCA 降维,使用 mle 和 5 个特征,都不好使,准确度反而更低,AUC 得分降至 0.51。

5.3 用了未来特征

决策树 AUC: 0.52 -> 0.77
随机森林 AUC: 0.82->0.93

随机森林的模型评价如下:
RF_auc.jpg

会发现准确度太高了,仔细分析后,发现用了一个「创建体测时间」的特征,而这个特征是在用户点击了 「智能计划推荐模块」后会更新值的,所以相当于用了事件发生后的特征来预测事件发生的概率,这样肯定会导致模型的准确率很高。后来去掉了这个特征。

6. 模型对比

数据集:30w,其中正样本的比例为 22%。

dt_model_compare.jpg

对比发现,DT 和 Adaboost 的效果都不好,AUC Score 都在 0.65 左右。RF 的效果最好,AUC Score 能到 0.90。
可能是因为数据集符合 low bias, high variance 的规律,所以 RF 要比 Adaboost 好。

RF 的准确率和召回率都还不错,感觉可以后续上线用于 App 首页了。

7. 总结

整个过程可以抽象为:
获取数据 -> 调整模型参数 -> 引入更多特征 -> 调整模型参数 -> PCA -> 减少特征 -> 处理重要特征 -> gridSearchCV -> 调整模型参数

一些总结:

  1. 特征工程很重要,特征处理好后 AUC 有明显的提升
  2. 调参也有用,但相比起来,好的特征更有用
  3. 基尼系数和熵的区别不大
  4. 树的层数越多,准确率越低,召回越高
  5. AdaBoostClassifier base_estimators 用训练好的决策树来做,效果更好
  6. gridSearchCV 搜索最有用的参数太慢了,而且最终效果还不好
  7. 小心引入未来特征!

参考文档

决策树分类器在Scikit-learn的使用小结 - qq_29003925的博客 - CSDN博客
sklearn中的回归决策树 - FontTian的专栏 - CSDN博客
1.10. 决策树 — scikit-learn 0.19.0 中文文档 - ApacheCN
pandas的汇总和计算描述统计 - 修炼之路 - CSDN博客
数据分析-pandas数据处理清洗常用总结 - 简书
https://www.zhihu.com/question/29316149/answer/252391239
集成学习概述(Bagging,RF,GBDT,Adaboost) - U R MINE - CSDN博客
数据预处理与特征选择 - Joe的博客 - CSDN博客
谈谈评价指标中的宏平均和微平均 - robert_ai - 博客园
https://blog.csdn.net/sinat_26917383/article/details/75199996
DecisionTreeClassifier和DecisionTreeClassifier 重要参数调参注意点 - akon_wang_hkbu的博客 - CSDN博客
机器学习-分类器-Adaboost原理 - 宋兴柱 - 博客园

Contents
  1. 1. 1. 要解决的问题
  2. 2. 2. 整体思路
  3. 3. 3. 特征选取
    1. 3.1. 3.1 特征举例
    2. 3.2. 3.2 获取数据
    3. 3.3. 3.3 特征工程
      1. 3.3.1. 3.3.1 删除无用特征
      2. 3.3.2. 3.3.2 特征的空值处理
      3. 3.3.3. 3.3.3 处理重要特征
      4. 3.3.4. 3.3.4 特征标签化
      5. 3.3.5. 3.3.5 可用数据量
  4. 4. 4. 模型调优
    1. 4.1. 4.1 Decision Tree 调优
      1. 4.1.1. 4.1.1 树的深度调优
      2. 4.1.2. 4.1.2 其他参数调优
      3. 4.1.3. 4.1.3 DT 输出
    2. 4.2. 4.2 Random Forest 调优
    3. 4.3. 4.3 Adaboost 调优
  5. 5. 5. 踩过的坑
    1. 5.1. 5.1 信息熵
    2. 5.2. 5.2 PCA 降维
    3. 5.3. 5.3 用了未来特征
  6. 6. 6. 模型对比
  7. 7. 7. 总结
  8. 8. 参考文档