BlackCat

Predicting Student Health Risk

Kaggle 3 min read

student health — GPT-generated monochrome cover

Kaggle Competition (URL) : https://www.kaggle.com/competitions/playground-series-s6e7

题目背景

每一行是一个学生健康状况的记录,然后我们的target 是预测 health_condition (qualitative, ordinal ):

health_condition要预测的状态:

  • at-risk
  • fit
  • unhealthy

训练集有 690,088 行,测试集有 295,753 行。输入有 13 个feature:

类型 特征
数值 睡眠时长、心率、BMI、卡路里消耗、步数、运动时长、饮水量
类别 饮食类型、压力水平、睡眠质量、活动水平、烟酒情况、性别

首先我们可以先看训练集的 target 分布(这个与titanic类似)

类别 训练占比
at-risk 85.87%
fit 5.77%
unhealthy 8.36%

对所有数据预测 at-risk,普通 accuracy 可以达到 85.87%

但比赛使用:
BA(Balancing Accuracy [sklearn url: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.balanced_accuracy_score.html ]):

$$ BA = \frac{\text{Recall}_{at-risk} + \text{Recall}_{fit} + \text{Recall}_{unhealthy}}{3} $$

这里的 $ \text{Recall}_{at-risk} , \text{Recall}_{fit} ,\text{Recall}_{unhealthy} $ 也就是每个类别真正识别出了多少
例如 100个 at-risk 模型识别了 80 那就是 $ \text{Recall}_{at-risk} = 80/100 $ 然后对于这些类别的总数相加 然后取mean

就按我们上面那个如果按普通accuracy 很高的baseline 来说 在 BA下 $ \text{Recall}_{at-risk} $ 是 100% 其他是 0 的话 (1+0+0)/3 也只有 1/3 而已 。

然后我们首先要研究target 和 feature 的相关性, 看看target 是由哪个feature 决定的。使用决策树从 全部13个特征中寻找规则。

决策树本质上是一种自动寻找条件分支规则的方法,寻找类似如下的条件嵌套逻辑:

if 条件1:
if 条件2:
...
else:
...

其实也就是不断通过特征条件(condition)做分类。举例:

睡眠 < 6 小时?
├── Yes
│   └── 压力 high?
│       ├── Yes → unhealthy
│       └── No  → at-risk
│
└── No
    └── 压力 low?
        ├── No  → at-risk
        └── Yes
            └── activity = active?
                ├── Yes → fit
                └── No  → at-risk

那么这个条件是怎么出来的 就是蛮力试出来的

例如测试
sleep < 5.5?
sleep < 6.0?
sleep < 6.5?

age < 30?
age < 40?

stress = high?
activity = active?

然后这个Decision tree (Sklearn Decision tree classifier) 的loss function:

$$ Gini = 1 - \sum^{K}_{k=1} p_k^2 $$

其中k为第几类

例如

1/3 fit
1/3 at-risk
1/3 unhealthy

$$ Gini = 1- \left[ \left(\frac{1}{3}\right)^2 + \left(\frac{1}{3}\right)^2 + \left(\frac{1}{3}\right)^2 \right] $$
$$ = 1-\frac{1}{3} $$
$$ = \frac{2}{3} \approx 0.667 $$

decision tree 就会不停对 Gini 做优化 直到 maximum Gini 出现。

原代码:

tree = DecisionTreeClassifier(max_depth=4, random_state=0)
# 这里限制了tree的深度为4(判断简单结构),random_state=0 确保结果可复现
tree.fit(X_original, y_original)

实际的结果就是:

睡眠少于 6 小时?
├─ 是:压力高?
│      ├─ 是 → unhealthy
│      └─ 否 → at-risk
└─ 否:压力低?
       ├─ 否 → at-risk
       └─ 是:活动水平为 active?
              ├─ 否 → at-risk
              └─ 是:睡眠至少 7 小时?
                     ├─ 否 → at-risk
                     └─ 是 → fit

为了防止 DecisionTree Overfit 做一下测试 我们做一下 5 fold cross validation
把5w个数据平均分五等份 然后就可以分出 training set 和 validation set 然后就做测试

将获得的规则 看看对比一下比赛的数据

规则字段完整的比赛训练行:511,675
规则预测正确:            507,574
规则预测错误:              4,101
Accuracy:                 99.1985% (并非BA)

自己的思路

他人的思路

反思

Keep reading

View all