进阶baseline详解

import numpy as np
import pandas as pd
from catboost import CatBoostClassifier
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
from sklearn.metrics import f1_score
from rdkit import Chem
from rdkit.Chem import Descriptors
from sklearn.feature_extraction.text import TfidfVectorizer
import tqdm, sys, os, gc, re, argparse, warnings

 numpy (np): 一个用于科学计算的库,提供多维数组对象、派生对象(如掩码数组和矩阵)以及用于快速操作数组的各种例程,如数学、逻辑、形状操作、排序、选择等。

pandas (pd): 提供高性能、易用的数据结构和数据分析工具,适用于处理表格数据(例如CSV文件、SQL查询结果等)。

catboost: 由Yandex开发的一个机器学习库,提供对称树算法的实现,用于分类、回归和其他机器学习任务。

sklearn: 即scikit-learn,是Python中一个广泛使用的机器学习库,提供简单有效的工具用于数据挖掘和数据分析,包括模型选择、数据分割、预处理、元学习等。

StratifiedKFold, KFold, GroupKFold: 这些是sklearn中的交叉验证类,用于模型评估时的数据分割,以确保训练集和测试集的分布一致性。

f1_score: F1分数是sklearn.metrics模块中的一个指标,用于评估二分类模型的性能,它是精确率和召回率的调和平均值。

rdkit: 一个开源化学信息学软件库,用于处理化学分子、反应和相关数据。

Descriptors: rdkit中的一个模块,用于计算化学分子的各种描述符。

TfidfVectorizer: 来自sklearn.feature_extraction.text,用于将文本数据转换为TF-IDF特征。

tqdm: 一个快速、可扩展的Python进度条库,可以在长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator)

sys: 提供了与Python解释器密切相关的函数和变量。

os: 一个Python标准库,用于使用操作系统依赖的功能。

gc: 控制垃圾收集器的接口,用于管理内存。

re: 一个提供正则表达式匹配操作的库。

argparse: 编写用户友好的命令行接口的库。

warnings: 一个用于发出警告信息的库。

warnings.filterwarnings('ignore')
train = pd.read_excel("C:/Users/姜荣国/Downloads/traindata-new.xlsx")
test = pd.read_excel("C:/Users/姜荣国/Downloads/testdata-new.xlsx")
# test数据不包含 DC50 (nM) 和 Dmax (%)
train = train.drop(['DC50 (nM)', 'Dmax (%)'], axis=1)
# 定义了一个空列表drop_cols,用于存储在测试数据集中非空值小于10个的列名。
drop_cols = []
for f in test.columns:
    if test[f].notnull().sum() < 10:
        drop_cols.append(f)
# 使用drop方法从训练集和测试集中删除了这些列,以避免在后续的分析或建模中使用这些包含大量缺失值的列
train = train.drop(drop_cols, axis=1)
test = test.drop(drop_cols, axis=1)
# 使用pd.concat将清洗后的训练集和测试集合并成一个名为data的DataFrame,便于进行统一的特征工程处理
data = pd.concat([train, test], axis=0, ignore_index=True)
cols = data.columns[2:]
# 将SMILES转换为分子对象列表,并转换为SMILES字符串列表
data['smiles_list'] = data['Smiles'].apply(
    lambda x: [Chem.MolToSmiles(mol, isomericSmiles=True) for mol in [Chem.MolFromSmiles(x)]])
data['smiles_list'] = data['smiles_list'].map(lambda x: ' '.join(x))
# 使用TfidfVectorizer计算TF-IDF
tfidf = TfidfVectorizer(max_df=0.9, min_df=1, sublinear_tf=True)
res = tfidf.fit_transform(data['smiles_list'])
# 将结果转为dataframe格式
tfidf_df = pd.DataFrame(res.toarray())
tfidf_df.columns = [f'smiles_tfidf_{i}' for i in range(tfidf_df.shape[1])]
# 按列合并到data数据
data = pd.concat([data, tfidf_df], axis=1)
  1. 忽略警告:使用 warnings.filterwarnings('ignore') 来忽略可能产生的警告信息,以避免控制台输出不必要的警告。

  2. 读取数据:使用 pandasread_excel 函数从指定的路径读取训练集和测试集数据。

  3. 数据清洗

    • 从训练集中删除了两列 'DC50 (nM)' 和 'Dmax (%)',因为测试数据不包含这两列。
    • 遍历测试集的列,找出非空值少于10个的列,并存储在 drop_cols 列表中。
    • 从训练集和测试集中删除这些含有大量缺失值的列。
  4. 合并数据集:使用 pd.concat 将清洗后的训练集和测试集合并成一个 DataFrame data,便于进行统一的特征工程处理。

  5. 特征工程

    • 对 'Smiles' 列中的每个 SMILES 字符串进行处理,转换为分子对象,然后再次转换回 SMILES 字符串格式,并存储在新的 'smiles_list' 列中。
    • 使用 TfidfVectorizer 计算 'smiles_list' 列的 TF-IDF 特征。
  6. TF-IDF 特征向量化

    • 使用 fit_transform 方法计算 TF-IDF 特征矩阵。
    • 将 TF-IDF 矩阵转换为 DataFrame tfidf_df
    • 将 TF-IDF 特征按列合并回原始的 DataFrame data。
# 自然数编码
def label_encode(series):
    unique = list(series.unique())
    return series.map(dict(zip(
        unique, range(series.nunique())
    )))

for col in cols:
    if data[col].dtype == 'object':
        data[col] = label_encode(data[col])
train = data[data.Label.notnull()].reset_index(drop=True)
test = data[data.Label.isnull()].reset_index(drop=True)
# 特征筛选
features = [f for f in train.columns if f not in ['uuid', 'Label', 'smiles_list']]
# 构建训练集和测试集
x_train = train[features]
x_test = test[features]
# 训练集标签
y_train = train['Label'].astype(int)

 

  1. 自然数编码函数:定义了一个名为 label_encode 的函数,它接受一个 pandas Series 作为输入,并返回一个将分类值映射到自然数的 Series。这是处理分类特征的一种方法,特别是当这些特征需要用作模型输入时。

  2. 应用自然数编码:遍历 DataFrame data 中的列,对于数据类型为 'object'(通常指字符串)的列,使用 label_encode 函数进行编码。

  3. 分割训练集和测试集:基于 'Label' 列的存在与否,将合并后的 DataFrame 分割为训练集和测试集。data.Label.notnull() 创建一个布尔索引,用于选择非空标签的行作为训练集,而 data.Label.isnull() 用于选择空标签的行作为测试集。

  4. 重置索引:使用 reset_index(drop=True) 重置训练集和测试集的索引,以便它们从0开始,并且原来的索引不再保留。

  5. 特征筛选:创建一个列表 features,包含训练集中除了 'uuid''Label''smile_list' 之外的所有列名。这些被排除的列可能是ID列或标签列,不应该作为特征输入到模型中。

  6. 构建特征矩阵:从训练集和测试集中选取 features 列表中的特征列,构建特征矩阵 x_trainx_test

  7. 提取标签:从训练集中提取标签列 'Label',将其转换为整数类型 int,以便用于模型训练。

def cv_model(clf, train_x, train_y, test_x, clf_name, seed=2022):
    kf = KFold(n_splits=5, shuffle=True, random_state=seed)
    train = np.zeros(train_x.shape[0])
    test = np.zeros(test_x.shape[0])
    cv_scores = []
    # 100, 1 2 3 4 5
    # 1 2 3 4    5
    # 1 2 3 5。  4
    # 1
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} {}************************************'.format(str(i + 1),                                                                                             str(seed)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], \
        train_y[valid_index]
        params = {'learning_rate': 0.1, 'depth': 6, 'l2_leaf_reg': 10, 'bootstrap_type': 'Bernoulli',
                  'random_seed': seed,
                  'od_type': 'Iter', 'od_wait': 100, 'allow_writing_files': False, 'task_type': 'CPU'}
        model = clf(iterations=20000, **params, eval_metric='AUC')
        model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                  metric_period=100,
                  cat_features=[],
                  use_best_model=True,
                  verbose=1)
        val_pred = model.predict_proba(val_x)[:, 1]
        test_pred = model.predict_proba(test_x)[:, 1]
        train[valid_index] = val_pred
        test += test_pred / kf.n_splits
        cv_scores.append(f1_score(val_y, np.where(val_pred > 0.5, 1, 0)))
        print(cv_scores)
    print("%s_score_list:" % clf_name, cv_scores)
    print("%s_score_mean:" % clf_name, np.mean(cv_scores))
    print("%s_score_std:" % clf_name, np.std(cv_scores))
    return train, test
cat_train, cat_test = cv_model(CatBoostClassifier, x_train, y_train, x_test, "cat")
pd.DataFrame(
    {
        'uuid': test['uuid'],
        'Label': np.where(cat_test > 0.5, 1, 0)
    }
).to_csv('submit.csv', index=None)
  1. 交叉验证模型函数 cv_model

    • 接受分类器 clf、训练集特征和标签 train_xtrain_y、测试集特征 test_x、分类器名称 clf_name 和随机种子 seed 作为参数。
    • 使用 KFold 进行5折交叉验证,shuffle=True 表示在分折前打乱数据。
  2. 初始化:

    • train 和 test 数组用于存储交叉验证中每个折的训练预测和测试集的预测。
    • cv_scores 列表用于存储每一折的F1分数。
  3. 交叉验证循环

    • 遍历由 kf.split 生成的训练集索引和验证集索引。
    • 打印当前折数和随机种子。
    • 根据索引分割训练集和验证集数据。
    • 设置CatBoost分类器的参数 params
    • 训练CatBoost模型,并使用验证集评估模型性能。
    • 使用验证集预测结果更新 train 数组,使用测试集的预测结果更新 test 数组。
    • 计算并存储当前折的F1分数。
  4. 输出结果

    • 打印所有折的F1分数、平均值和标准差。
  5. 返回值

    • 返回交叉验证中的训练集预测结果 train 和测试集的预测结果 test
  6. 调用 cv_model 函数

    • 使用 CatBoostClassifier、训练集特征和标签 x_trainy_train、测试集特征 x_test 调用 cv_model 函数。
    • 将分类器名称设置为 "cat"
  7. 生成提交文件

    • 使用测试集的 uuid 和 cat_test 中的预测结果创建一个DataFrame。
    • 将预测结果(通过阈值0.5判定)设置为 'Label' 列。
    • 将这个DataFrame保存为CSV文件 submit.csv,不包含索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值