kaggle新赛:ICR疾病预测 EDA&Baseline

1. 项目简介

ICR - Identifying Age-Related Conditions是Kaggle中的一个Featured竞赛,2023.8.10截止。

在这里插入图片描述

  • 赛题链接:https://www.kaggle.com/competitions/icr-identify-age-related-conditions/overview
  • 背景:通过对个人病史的综合评估、体检和特定测试,评估其整体健康状况并确定任何与年龄相关的疾病,从而尽早发现潜在问题,以便及时干预和管理与年龄相关的健康问题。以往已经使用XGBoost和随机森林,想要探索更多可能。
  • 目的:预测一个人是否患有三种疾病中的任何一种或多种(1),或不患有三种疾病中的任何一种(0)。——二分类问题
  • 提交:0/1类的概率
  • 评价指标:balanced logarithmic loss
    在这里插入图片描述
  • Score:0.14
  • 本文内容:EDA & Baseline

2. 读取数据

  • train.csv:训练集
    • 617×58,有少量缺失值
    • AB~GL:56个匿名健康特征;除了EJ为类别外,其余均为浮点数
    • Class:0/1
  • greeks.csv:补充元数据,仅适用于训练集。
    • Alpha:A-0,B、D、G-1
    • Beta, Gamma, Delta:三个实验特征
    • Epsilon:数据收集日期,有Unknown
  • test.csv:测试集。目标是预测该集合中的受试者属于两个类别中的每个类别的概率。5条
train = pd.read_csv('/kaggle/input/icr-identify-age-related-conditions/train.csv')
greeks = pd.read_csv('/kaggle/input/icr-identify-age-related-conditions/greeks.csv')
test = pd.read_csv('/kaggle/input/icr-identify-age-related-conditions/test.csv')

train的缺失值:

missing_count_by_column = (train.isnull().sum())
print(missing_count_by_column[missing_count_by_column > 0])

在这里插入图片描述

将EJ转换为onehot:

# EJ onehot
train['EJ'] = train['EJ'].replace({'A': 0, 'B': 1})
test['EJ']  = test['EJ'].replace({'A': 0, 'B': 1})

合并train和greeks:

# 合并train和greeks
train_all = pd.merge(train, greeks, on='Id', how='left')
train_all.set_index('Id', inplace=True)

3. EDA

  1. 各种特征与Class的分布密度图(KDE):
fig, axes = plt.subplots(nrows=14, ncols=4, figsize=(16, 50))
for i, col_name in enumerate(train.columns.tolist()[1:-1]):
    ax = axes[i//4, i%4]
    sns.kdeplot(data=train, x=col_name, hue='Class', shade=True, ax=ax, alpha=0.5, linewidth=2)
    ax.set_xlabel(col_name, fontsize=14)
    ax.set_ylabel('Class', fontsize=14)
    ax.legend([1, 0], title='Class', fontsize=12)
plt.tight_layout()

在这里插入图片描述
在这里插入图片描述

分布差异较大的特征有
BQ、BZ、CC、CF、CR、DA、FI、GI等

  1. 特征之间相关性的热力图:
corr_mat = train.iloc[:, 1:-1].corr()
# 为上三角矩阵生成掩码
mask = np.zeros_like(corr_mat, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# 热力图
fig, ax = plt.subplots(figsize=(20, 20))
sns.set_style("ticks")
ax=sns.heatmap(corr_mat, square=True, mask=mask, annot=True, 
            annot_kws={'size':5}, cmap=plt.cm.RdBu_r)
ax.set_xticklabels(labels=train.columns.tolist()[1:-1], fontsize=14)
ax.set_yticklabels(labels=train.columns.tolist()[1:-1], fontsize=14);

在这里插入图片描述

相关性高的:GL-EJ(-0.98),EH-FD(0.97),CL-DV(0.95),BC-BZ(0.91),DU-EH(0.85),AR-DV(0.82),DU-FD(0.81),CS-EP(0.79)

  1. 特征的层次聚类树:
fig, ax = plt.subplots(figsize=(15, 10))
corr_all = train.iloc[:, 1:-1].corr()
# squareform:用于距离方阵与距离向量相互转换的函数,要求方阵对角线为0
# 所以需要做1 - np.abs的转换
corr_all_convert = 1 - np.abs(corr_all)
Z = hierarchy.linkage(squareform(corr_all_convert), 'complete')
dn = hierarchy.dendrogram(Z, labels=train.columns.tolist()[1:-1], ax=ax, 
                above_threshold_color='#ff0000', orientation='right')

在这里插入图片描述

热力图与层次聚类树相互印证。

  1. greeks数据集中的各类数量的条形图:
fig, ax = plt.subplots(2,2,figsize=(12, 10), constrained_layout=True)
sns.countplot(x='Alpha', hue='Alpha', data=data, ax=ax[0,0])
sns.countplot(x='Beta', hue='Beta', data=data, ax=ax[0,1])
sns.countplot(x='Gamma', hue='Gamma', data=data, ax=ax[1,0])
sns.countplot(x='Delta', hue='Delta', data=data, ax=ax[1,1])

在这里插入图片描述

可见,各类别数量差距较大

  1. greeks各特征与train中特征的关系:

① Alpha:

fig, axes = plt.subplots(nrows=8, ncols=7, figsize=(20, 20))
for i, col_name in enumerate(train.columns.tolist()[1:-1]):
    ax = axes[i//7, i%7]
    sns.boxplot(data=train_all, x='Alpha', y=col_name, ax=ax)
    ax.set_xlabel(col_name, fontsize=14)
fig.suptitle('Alpha',fontsize=16, y=1.00)
plt.tight_layout()

在这里插入图片描述

对于Alpha

  • 一些特征的离群点较多,如AB、AM、BP等
  • 大多数特征的数据分布比较集中且区分度不高,如AY、BR等
  • 一些特征的数据分布较为离散且区分度高,如BQ、CW等

② Beta:

fig, axes = plt.subplots(nrows=8, ncols=7, figsize=(20, 20))
for i, col_name in enumerate(train.columns.tolist()[1:-1]):
    ax = axes[i//7, i%7]
    sns.boxplot(data=train_all, x='Beta', y=col_name, ax=ax)
    ax.set_xlabel(col_name, fontsize=14)
fig.suptitle('Beta',fontsize=16, y=1.00)
plt.tight_layout()

在这里插入图片描述

对于Beta

  • 一些特征的离群点较多,如FE、FL、GF等
  • 大多数特征的数据分布比较集中且区分度不高,如AY、BR、FR、FS、EJ、GL等
  • 一些特征的数据分布较为离散且区分度高,如AF、BQ

③ Delta:

在这里插入图片描述

对于Delta

  • 一些特征的离群点较多,如AB、DE等
  • 大多数特征的数据分布比较集中且区分度不高,如AY、BR、FR
  • 一些特征的数据分布较为离散且区分度高,如CW等

④ Gamma:

在这里插入图片描述

对于Gamma

  • 一些特征的离群点较多,如AB、AM、BP等
  • 大多数特征的数据分布比较集中且区分度不高,如AY、BR、FD、FR
  • 一些特征的数据分布较为离散且区分度高,如EL等

3. Baseline¶

3.1 数据集划分

从EDA可以发现各类别分布不均衡,按照原信息划分验证集:

kf = StratifiedKFold(n_splits=5, random_state=42, shuffle=True)
train['fold'] = -1

for fold, (train_idx, valid_idx) in enumerate(kf.split(train, greeks['Alpha'])):
    train.loc[valid_idx, 'fold'] = fold
train.groupby('fold')["Class"].value_counts()

在这里插入图片描述

3.2 自定义评价函数

def balanced_log_loss(y_true, y_pred):
    N_0 = np.sum(1 - y_true)
    N_1 = np.sum(y_true)
    # np.clip(a, a_min, a_max, out=None):
    # 将一个array的值限定在给定的上下界,在界限外的值修改为边界值
    p_1 = np.clip(y_pred, 1e-15, 1 - 1e-15)
    p_0 = 1 - p_1
#     print(p_1.shape, y_true.shape): (124, 2) c
#     (124,)表示只有1维,是个向量,需要从列的维度扩维成矩阵
    y_true = y_true[:, np.newaxis]
    log_loss_0 = -np.sum((1 - y_true) * np.log(p_0))
    log_loss_1 = -np.sum(y_true * np.log(p_1))
    w_0 = 1 / N_0
    w_1 = 1 / N_1
    logloss = (w_0 * log_loss_0 + w_1 * log_loss_1) / 2
    return logloss

3.3 Baseline

# 记录每个fold的权重
weights = []
test_preds = []

for fold in range(5):
    train_df = train[train['fold'] != fold]
    valid_df = train[train['fold'] == fold]
    valid_ids = valid_df.Id.values.tolist()
    train_X, train_y = train_df.drop(['Id', 'Class', 'fold'], axis=1), train_df['Class']
    val_X, val_y = valid_df.drop(['Id', 'Class', 'fold'], axis=1), valid_df['Class']
    
    # lightgbm
    model = LGBMClassifier(boosting_type='gbdt', 
                           learning_rate=0.05, 
                           n_estimators = 50000, 
                           early_stopping_round = 100, 
                           random_state=42,
                           subsample=0.7,
                           colsample_bytree=0.6,
                           class_weight='balanced',
                           is_unbalance=True, 
                           max_depth=9,
                           num_leaves=31)
    model.fit(train_X,train_y,eval_set=[(val_X,val_y)], verbose=1000)
    pred = model.predict_proba(val_X)
    
    weights.append(1/balanced_log_loss(val_y,pred))
    
    test_pred = model.predict_proba(test.drop('Id', axis=1))
    test_preds.append(test_pred)
test_preds_weight = np.average(test_preds, weights=weights, axis=0)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提交:

test_dict = {}
test_dict.update(dict(zip(test.Id.values.tolist(), test_preds_weight)))
submission = pd.DataFrame.from_dict(test_dict, orient="index").reset_index()
submission.columns = ['Id', 'class_0', 'class_1']  
submission.to_csv("submission.csv", index=False)   
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ICR比赛是一个机器学习竞赛,旨在预测一个人是否患有三种医疗状况中的任何一种。参赛者需要根据健康特征的测量数据训练一个模型,来预测一个人是否患有这三种医疗状况中的一种或多种(类别1),或者没有患有这三种医疗状况之一(类别0)的概率。这个比赛由InVitro Cell Research公司主办,他们是一家专注于再生和个性化预防医学的公司,旨在帮助指导和定义快速修复老龄化人群的研究方向。目前,像XGBoost和随机森林这样的机器学习模型已经被用于预测医疗情况,但是在处理涉及生命安全的关键问题时,需要能够可靠地、一致性地做出正确的预测。参赛者需要利用健康特征的测量数据来创建一个模型,并通过该模型进行预测123 #### 引用[.reference_title] - *1* *2* [Kaggle 数据竞赛 | ICR - 鉴定与年龄相关的疾病](https://blog.csdn.net/fyfugoyfa/article/details/130668398)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [ICR - Identifying Age-Related Conditions解读](https://blog.csdn.net/dragon_T1985/article/details/130963486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值