赞
踩
该笔记分为六个part:
一、赛题介绍
二、评估结果
三、比赛解题思路
四、Baseline介绍及其代码
五、我的打榜过程
六、注意事项及答疑学习
比赛链接:
https://challenge.xfyun.cn/topic/info?type=molecular-properties
在当今科技日新月异的时代,人工智能(AI)技术正以前所未有的深度和广度渗透到科研领域,特别是在化学及药物研发中展现出了巨大潜力。精准预测分子性质有助于高效筛选出具有优异性能的候选药物。以PROTACs为例,它是一种三元复合物由目标蛋白配体、linker、E3连接酶配体组成,靶向降解目标蛋白质。本次大赛聚焦于运用先进的人工智能算法预测其降解效能,旨在激发参赛者创新思维,推动AI技术与化学生物学的深度融合,进一步提升药物研发效率与成功率,为人类健康事业贡献智慧力量。通过此次大赛,我们期待见证并孵化出更多精准、高效的分子性质预测模型,共同开启药物发现的新纪元。
选手根据提供的demo数据集,可以基于demo数据集进行数据增强、自行搜集数据等方式扩充数据集,并自行划分数据。运用深度学习、强化学习或更加优秀人工智能的方法预测PROTACs的降解能力,若DC50>100nM且Dmax<80% ,则视为降解能力较差(demo数据集中Label=0);若DC50<=100nM或Dmax>=80%,则视为降解能力好(demo数据集中Label=1)。
大白话解释:
【训练分子性质分类预测模型】
运用深度学习、强化学习或更加优秀人工智能的方法预测PROTACs的降解能力,
分类为 降解能力较差/降解能力好 两种结论
本次竞赛的评价标准采用f1_score,分数越高,效果越好
参赛选手的任务是基于训练集的样本数据,构建一个模型来预测测试集中分子的性质情况。
这是一个二分类任务,其中目标是根据分析相关信息以及结构信息等特征,预测该分子的性质标签。
具体来说,选手需要利用给定的数据集进行特征工程、模型选择和训练,然后使用训练好的模型对测试集中的用户进行预测,并生成相应的预测结果。
我们 Baseline 选择使用机器学习方法,在解决机器学习问题时,一般会遵循以下流程:
思考:这里为什么选择机器学习算法?为什么不考虑深度学习?
在许多机器学习问题中,特征工程的重要性不容忽视。如果特征工程能够充分捕捉数据的关键特征,那么机器学习算法也能够表现很好。深度学习在某种程度上可以自动学习特征,但对于特定问题,手动设计特征可能会更有效。
思考:这里从逻辑回归和决策树中选择,哪一个模型更加合适?
Datawhale提供了2个Baseline,其中第一个Baseline为线上Baseline,部署在飞桨的Aistudio里面,可以一键运行,第二个Baseline为基于catboost。(Baseline直达链接:AI夏令营 - ML实践教程 )
该Baseline运行后的A榜分数为:0.7064
#Step1:下载相关库 !pip install lightgbm openpyxl #Step2:训练模型并预测结果 # 1. 导入需要用到的相关库 # 导入 pandas 库,用于数据处理和分析 import pandas as pd # 导入 numpy 库,用于科学计算和多维数组操作 import numpy as np # 从 lightgbm 模块中导入 LGBMClassifier 类 from lightgbm import LGBMClassifier # 2. 读取训练集和测试集 # 使用 read_excel() 函数从文件中读取训练集数据,文件名为 'traindata-new.xlsx' train = pd.read_excel('./data/data280993/traindata-new.xlsx') # 使用 read_excel() 函数从文件中读取测试集数据,文件名为 'testdata-new.xlsx' test = pd.read_excel('./data/data280993/testdata-new.xlsx') # 3 特征工程 # 3.1 test数据不包含 DC50 (nM) 和 Dmax (%),将train数据中的DC50 (nM) 和 Dmax (%)删除 train = train.drop(['DC50 (nM)', 'Dmax (%)'], axis=1) # 3.2 将object类型的数据进行目标编码处理 for col in train.columns[2:]: if train[col].dtype == object or test[col].dtype == object: train[col] = train[col].isnull() test[col] = test[col].isnull() # 4. 加载决策树模型进行训练 model = LGBMClassifier(verbosity=-1) model.fit(train.iloc[:, 2:].values, train['Label']) pred = model.predict(test.iloc[:, 1:].values, ) # 5. 保存结果文件到本地 pd.DataFrame( { 'uuid': test['uuid'], 'Label': pred } ).to_csv('submit.csv', index=None) #Step3:下载 submit.csv 文件
该Baseline运行后的A榜分数为:0.74359
导入Python中用于数据分析、机器学习建模和化学信息学所需的库。以下是每个库的简要说明:
numpy
: 提供强大的多维数组对象和相应的操作。pandas
: 提供高性能、易用的数据结构和数据分析工具。catboost
: 一个用于机器学习的库,特别是分类和回归任务。sklearn.model_selection
: 包含模型选择的多种方法,如交叉验证。sklearn.metrics
: 包含评估模型性能的多种指标。rdkit
: 一个化学信息学和机器学习软件,用于处理化学结构。sklearn.feature_extraction.text
: 提供将文本转换为特征向量的Tf-idf向量化器。tqdm
: 用于在长循环中添加进度条的库。sys
: 与Python解释器密切相关的模块,提供访问由解释器使用或维护的变量和函数。os
: 提供与操作系统交互的功能。gc
: 垃圾收集器接口,用于手动标记对象为可删除。re
: 正则表达式库,用于字符串搜索和替换。argparse
: 用于编写用户友好的命令行接口。warnings
: 用于发出警告的库,这里用来忽略警告信息。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)
代码执行了以下步骤:
TfidfVectorizer
从处理后的SMILES字符串创建TF-IDF特征矩阵。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
的函数,用于使用交叉验证训练分类模型,并对测试集进行预测。以下是代码的详细步骤和说明:
cv_model
函数接受分类器对象 clf
,训练特征集 train_x
和标签集 train_y
,测试特征集 test_x
,分类器名称 clf_name
,以及可选的随机种子 seed
。KFold
进行5折交叉验证,shuffle=True
表示在分折前打乱数据。train
和 test
来存储交叉验证过程中的训练集预测和测试集预测。train_index
和验证索引 valid_index
分割训练集和验证集。params
。iterations=20000
表示最大迭代次数,eval_metric='AUC'
表示使用 AUC 作为评估指标。val_x
和 val_y
对模型进行评估,获取预测概率 val_pred
。test_x
获取测试集预测概率 test_pred
。train
数组中,将测试集的预测结果累加到 test
数组中,并计算当前折的 F1 分数。train
和测试集预测结果 test
。cv_model
函数训练 CatBoost 分类器,并将返回的测试集预测结果 cat_test
用于生成提交文件。cat_test
生成二元标签,概率大于0.5的预测为1,否则为0。uuid
和预测标签 Label
的 DataFrame,并将其保存为 CSV 文件。6.28 按照datawhale提供的一站式baseline教程完成了第一次比赛提交
目前排名:546
score:0.7064
7.3 改用catboost进行提交
目前排名:274
score:0.74359
至此、
_test用于生成提交文件。 2. 根据预测概率
cat_test生成二元标签,概率大于0.5的预测为1,否则为0。 11. **生成提交文件**:创建一个包含
uuid和预测标签
Label` 的 DataFrame,并将其保存为 CSV 文件。
6.28 按照datawhale提供的一站式baseline教程完成了第一次比赛提交
目前排名:546
score:0.7064
7.3 改用catboost进行提交
目前排名:274
score:0.74359
至此、
谢谢你能阅读到它的结尾。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。