【机器学习实战】Baseline精读笔记

news/2024/7/8 2:35:19 标签: 机器学习, 笔记, 人工智能

比赛用到的库

  1. numpy:提供(多维)数组操作

  2. pandas:提供数据结构、数据分析

  3. catboost:用于机器学习的库,特别是分类和回归任务

  4. sklearn.model_selection:包含模型选择的多种方法,如交叉验证

  5. sklearn.metrics:包含评估模型性能的多种指标,提供如accuracy_score这样的方法

  6. sklearn.feature_extraction.text:提供将文本转换为特征向量的TF-idf向量化器

  7. rdkit:化学信息学和机器学习软件,处理化学结构

  8. tqdm:用于在长循环中添加进度条的库

  9. sys:与Python解释器密切相关的模块和由解释器使用或维护的变量和函数

  10. os:提供与操作系统交互的功能

  11. gc:垃圾收集器接口:用于手动标记对象为可删除

  12. re:正则表达式库,用于字符串搜索和替换

  13. argparse:用于编写用户友好的命令行接口

  14. warnings:用于发出警告,或忽略警告。

使用到的关键的库文档链接:

numpy:NumPy 参考 — NumPy v2.0 手册

pandas:API reference — pandas 2.2.2 documentation (pydata.org)

catboost:CatBoost | CatBoost

sklearn:API Reference — scikit-learn 1.5.1 documentation

rdkit:RDKit中文教程 — RDKit 中文教程 2020.09 文档 (chenzhaoqiang.com)

sys:sys — System-specific parameters and functions — Python 3.12.4 documentation

库的导入

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
warnings.filterwarnings('ignore') # 忽略警告

数据预处理

train = pd.read_excel('./dataset-new/traindata-new.xlsx')
test = pd.read_excel('./dataset-new/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)

# 自然数编码
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)

特征工程是构建一个良好的机器学习模型的关键步骤。有用的特征使得模型表现更好。

在这个特征工程中,使用了具有关键特征的简单模型,要想用最佳方式完成特征工程,必须对问题的领域有一定的了解,并且很大程度上取决于相关数据。

特征方程不仅仅是创建新特征,还包括不同类型的归一化和转换。

在这一段代码里,没有归一化流程,只有转换。

常见的归一化手段:

  • Min-Max缩放
  • Z-score标准化
  • Robust缩放

而在这段代码里:

  • SMILES转换:使用RDKit库将数据集中的SMILES字符串转换回字符串的列表。这是特征工程的一部分:这是为了便于下一步特征的提取,SMILES可以使用TF-IDF计算方法。这是一种数据预处理的手段。

  • 字符串处理:将SMILES字符串列表转换为单个字符串,每个SMILES之间用空格分隔。

  • TF-IDF计算:使用TfidfVectorizer从处理后的SMILES字符串创建TF-IDF特征矩阵,TF-IDF是一种词文本的统计学方法,用于统计词文本在文件中出现的频率,衡量该词条的重要程度。这是一种特征提取手段。

  • 自然数编码:定义了一个函数label_encode,将分类特征(对象类型)转换为整数编码。首先,它接受一个pandas Series作为输入,获取Series中的唯一值列表,然后创建一个字典,将每个唯一值映射到一个整数,最后使用这个字典将原始Series中的每个值映射到相应的整数。检测到object类型,就应用label_encode进行编码。这样的编码方式比较直观,同时符合需要顺序的特点。

  • 特征和标签准备:对于所有的特征列(cols),如果它们的数据类型是对象(通常表示为字符串),则应用自然数编码;从合并后的数据集中分离出训练集和测试集,其中训练集包含标签(Label),测试集不包含。

  • 特征和标签的筛选:由于不需要uuid、Label和smiles_list,剔除并提取标签列。

  • 数据类型转换:将Label转换为整数类型,便于训练。

模型训练与预测

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)

代码定义了一个名为cv_model的函数,用于交叉验证和预测。这段代码的核心是交叉验证和CatBoost训练模型。

K折交叉验证

交叉检验是评估模型性能的常用方法。交叉检验是使用训练数据集来训练模型,然后使用测试数据集来评估模型性能。*一轮交叉验证包括将数据样本划分为互补子集,对一个子集(称为训练集)执行分析,并在另一个子集(称为验证集或测试集)上验证分析结果。为了减少可变性,在大多数方法中,使用不同的分区执行多轮交叉验证,并且在这些回合中验证结果被组合(例如,平均)以估计最终的预测模型。(引自:维基百科)*作者使用了暂留集(hold-out set)这种方法:在一部分上训练模型,然后在另一部分上检查其性能。这也是交叉检验的一种。

选择正确的交叉检验取决于所处理的数据集。在一个数据集上适用的交叉检验并不一定就适合别的数据集。

有几种交叉检验技术最为流行和广泛使用:

  • k折交叉检验

  • 分层k折交叉检验

  • 留一交叉检验

  • 分组k折交叉检验

交叉检验是将训练数据分层几个部分,在一部分上训练模型,在其余部分上测试。

得到一个数据集来构建机器学习模型时,可以把他们分为两个不同的集:训练集和验证集。训练集用来训练模型,验证集用来评估模型。实际上很多人会用第三个集:测试集,在下述代码中只使用两个集。

我们可以将数据分为k个互不关联的不同集合,即所谓的k折交叉验证。这样每一个不同的集合称为一个“褶皱”。

注意,交叉验证非常强大,几乎所有类型的数据集都可以使用此流程。

在本例Baseline里,Kfold进行了5折交叉验证。

CatBoost分类器训练模型

最大迭代次数是iterations=20000,eval_metric=‘AUC’,表示使用AUC作为评估指标。

AUC(Area Under the ROC Curve)是一种评价二分类模型性能的指标之一,ROC(Receiver Operating Characteristic)曲线是基于不同的分类阈值计算得出的,展示了在各种阈值下真阳性率(True Positive Rate,即召回率)和假阳性率(False Positive Rate)之间的权衡。

具体来说:

  • ROC 曲线:ROC 曲线是以假阳性率(FPR)为横轴,真阳性率(TPR)为纵轴绘制的曲线。在理想情况下,ROC 曲线应该尽量靠近左上角,表示在保持高真阳性率的同时,尽量低假阳性率。

  • AUC 值:AUC 值是 ROC 曲线下的面积,即 Area Under the ROC Curve。AUC 的取值范围在 0 到 1 之间,通常用来表示分类器的性能。AUC 值越大,说明模型在不同阈值下的性能越好。

接着,使用验证集val_xval_y对模型进行评估,获取预测概率val_pred。

使用测试集test_x获取测试集预测概率test_pred

F1_score(F1分数): F 1 = 2 ∗ T F 2 ∗ T F + F P + F N F1=\frac{2*TF}{2*TF+FP+FN} F1=2TF+FP+FN2TF,它是精确度和召回率的调和平均值,是衡量测试准确度的标准。可能的最高值为1,表示完美的精确度和召回率。

精准率(P,Precision):它用于衡量模型的查准性能,正确预测的样本中,预测为正的样本的比例。

召回率(R,Recall):它用于衡量模型的查全性能,预测为正的样本中,实际为正的样本的比例。

CatBoost 是一种高效的梯度提升算法(Gradient Boosting),专为处理分类特征和提高机器学习模型性能而设计。以下是 CatBoost 的主要特点和使用说明:

1. 梯度提升算法

CatBoost 属于梯度提升算法家族,通过迭代训练一组弱学习器(通常是决策树)来提高预测准确性。每一步都会根据前一步模型的错误来改进当前模型。

2. 处理分类特征

CatBoost 的一个显著优势是能够直接处理分类特征,无需将它们转换为数值形式(如独热编码)。CatBoost 采用了专门的技术来编码分类特征,简化了数据预处理过程,并且往往能提升模型性能。

3. 高性能
  • 优化的计算效率:CatBoost 进行了许多优化,能够高效地进行梯度提升训练。
  • 支持并行计算和 GPU 加速:CatBoost 支持多线程计算和 GPU 加速,能显著缩短训练时间。
4. 正则化

CatBoost 默认包含 L2 正则化等技术来防止模型过拟合,提高模型的泛化能力。

5. 兼容性

CatBoost 支持分类(如二分类、多分类)和回归任务。你可以在 CPU 或 GPU 上训练模型,适用于各种硬件配置。

CatBoost接收的主要的参数有最大迭代次数iterations,最大深度depth,学习率learning_rate(梯度学习算法中控制每棵树贡献的步长大小的参数,通常小于1),分类特征cat_features,它是一个用于指定哪些特征是分类变量的列表。CatBoost可以直接处理这些分类特征,而不依赖于数值转换。


http://www.niftyadmin.cn/n/5536130.html

相关文章

【第六节】C/C++静态查找算法

目录 前言 一、搜索查找 二、查找算法 1. 线性查找&#xff08;Linear Search&#xff09; 2. 二分查找&#xff08;Binary Search&#xff09; 3. 插值查找&#xff08;Interpolation Search&#xff09; 4. 哈希查找&#xff08;Hash Search&#xff09; 5. Fibonacc…

【Git】忘记切换分支! 如何将一个分支上的修改转移到另一个分支上去?

【Git】忘记切换分支! 如何将一个分支上的修改转移到另一个分支上去? step1: 使用git stash暂存修改step2: 切换回要提交的分支step3: 应用特定的stash step1: 使用git stash暂存修改 git stash 命令可以添加一些描述性的信息, 方便识别自己的暂存内容. 以下是具体的使用方法…

基于Hadoop平台的电信客服数据的处理与分析④项目实现:任务15:数据生产

任务描述 电信数据生产是一个完整且严密的体系&#xff0c;这样可以保证数据的鲁棒性。在本项目的数据生产模块中&#xff0c;我们来模拟生产一些电信数据。同时&#xff0c;我们必须清楚电信数据的格式和数据结构&#xff0c;这样才能在后续的数据产生、存储、分析和展示环节…

【观察】三合实业X华为:十载风雨同舟路,奋楫逐浪向未来

十年前&#xff0c;广东三合电子实业有限公司&#xff08;以下简称&#xff1a;三合实业&#xff09;正式成立&#xff0c;同年成为华为金牌伙伴&#xff0c;由此也开启了与华为深度“结缘”的十年。 十年来&#xff0c;作为华为“铁杆”的合作伙伴&#xff0c;三合实业始终与华…

力扣(2024.07.01)

1. 84——柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 标签&#xff1a;栈&#xff0c;数组&#xff0c;单调栈&#xff08;目…

Arduino - Keypad 键盘

Arduino - Keypad Arduino - Keypad The keypad is widely used in many devices such as door lock, ATM, calculator… 键盘广泛应用于门锁、ATM、计算器等多种设备中。 In this tutorial, we will learn: 在本教程中&#xff0c;我们将学习&#xff1a; How to use key…

【Qt知识】qrc机制

在Qt中&#xff0c;qrc机制是一种资源管理系统&#xff0c;它允许你将应用程序所需的静态资源&#xff0c;如图像、样式表、字体和音频文件&#xff0c;嵌入到可执行文件中而不是作为外部文件存在。这样做的好处是资源管理更加安全&#xff0c;因为它们不会丢失或被意外修改&am…

IP地址設置的全面指南-okeyproxy

IP地址是每個連接到互聯網的設備的唯一識別字&#xff0c;無論是家庭網路還是企業網路&#xff0c;正確設置IP地址是確保網路穩定和安全的關鍵。IP地址由一系列數字組成&#xff0c;通常分為IPv4和IPv6兩種格式。IPv4是最常見的形式&#xff0c;由四組0到255之間的數字組成&…