第三期AI+物质科学 Task1 baseline学习记录 Datawhale AI 夏令营

#Datawhale AI 夏令营

一、环境依赖

1.安装所需库

        需要先分别安装任务所需的pandas、scikit-learn和rdkit,这三个库在数据科学和化学信息学领域中都有广泛的应用。其中,rdkit是一个用于化学信息学的开源python工具包,用来处理化学分子。

!pip install pandas
!pip install -U scikit-learn
!pip install rdkit

2.导入所需库

         然后导入包括刚刚安装的库在内的需要使用的库。

# 首先,导入库
import pickle
import pandas as pd
from tqdm import tqdm
from sklearn.ensemble import RandomForestRegressor
from rdkit.Chem import rdMolDescriptors
from rdkit import RDLogger,Chem
import numpy as np
RDLogger.DisableLog('rdApp.*')

       其中,RDLogger.DisableLog('rdApp.*')表示禁用 RDKit 生成的日志消息。在数据处理和建模过程中,RDKit 可能会生成大量的警告和信息消息,导致输出变得杂乱。

二、数据预处理

1.加载数据

         设置数据集路径,使用pd.read_csv函数读取训练集和测试集的csv文件,并打印它们的大小。

# 设置数据集目录路径
dataset_dir = '../dataset'   # # 注:如果是在AI Studio上,将这里改为'dataset'

# 加载训练集和测试集
train_df = pd.read_csv(f'{dataset_dir}/round1_train_data.csv')
test_df = pd.read_csv(f'{dataset_dir}/round1_test_data.csv')

# 打印训练集和测试集的大小
print(f'Training set size: {len(train_df)}, test set size: {len(test_df)}')

2.数据处理

1)定义了一个mfgen函数,生成分子指纹并返回NumPy 数组
def mfgen(mol,nBits=2048, radius=2):
    # 返回分子的位向量形式的Morgan fingerprint
    fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(mol,radius=radius,nBits=nBits)
    return np.array(list(map(eval,list(fp.ToBitString()))))

        该函数使用rdkit库的“GetMorganFingerprintAsBitVect函数生成 Morgan 指纹。其中,radius 参数指定了指纹计算中包含的原子邻域的半径。

        最后return中,np.array(list(map(eval,list(fp.ToBitString())))):

fp.ToBitString() ”将 Morgan 指纹转换为一个二进制字符串(如 '101000...010')。

list(fp.ToBitString()) ”将这个二进制字符串转换为字符列表(如 ['1', '0', '1', ...])。

map(eval,list(fp.ToBitString()) ”将每个字符从字符串 '0''1' 转换为整数 01 eval 在这里是用来将字符 '1' 转换为整数 1'0' 转换为 0

np.array(map(eval,list(fp.ToBitString())) ”将处理后的列表转换为 NumPy 数组。

2)定义了一个vec_cpd_lst函数,将一组 SMILES 字符串转换为对应的分子指纹,并返回这些指纹的一个 NumPy 数组。

          具体解释看注释。之所以返回NumPy 数组,是因为其可以将数据转换成向量的形式,方便机器运算。

def vec_cpd_lst(smi_lst):
    smi_set = list(set(smi_lst))  # 1. 去重SMILES字符串
    smi_vec_map = {}  # 2. 创建一个字典用于存储SMILES字符串与其对应的分子指纹
    for smi in tqdm(smi_set):  # 3. 对每个唯一的SMILES字符串进行处理
        mol = Chem.MolFromSmiles(smi)  # 4. 将SMILES字符串转换为RDKit分子对象
        smi_vec_map[smi] = mfgen(mol)  # 5. 生成分子指纹并存储在字典中
    smi_vec_map[''] = np.zeros(2048)  # 6. 处理无效的SMILES字符串,使用全零向量代替
    
    vec_lst = [smi_vec_map[smi] for smi in smi_lst]  # 7. 将原始SMILES列表中的
                                                     #每个SMILES转换为指纹
    return np.array(vec_lst)  # 8. 返回分子指纹的NumPy数组
3)处理训练集与测试集数据
1.读取训练和测试数据

       从 train_df test_df中提取 “Reactant1”、“Reactant2”、“Additive ”和 “Solvent ”列的 SMILES 字符串,并转换为列表。

# 从csv中读取数据
train_rct1_smi = train_df['Reactant1'].to_list()
train_rct2_smi = train_df['Reactant2'].to_list()
train_add_smi = train_df['Additive'].to_list()
train_sol_smi = train_df['Solvent'].to_list()

test_rct1_smi = test_df['Reactant1'].to_list()
test_rct2_smi = test_df['Reactant2'].to_list()
test_add_smi = test_df['Additive'].to_list()
test_sol_smi = test_df['Solvent'].to_list()
2.转换特征

       使用 “vec_cpd_lst ”函数将训练集和测试集 SMILES 字符串转换为分子指纹,并对这些指纹进行拼接,形成特征矩阵。

# 将SMILES转化为分子指纹
train_rct1_fp = vec_cpd_lst(train_rct1_smi)
train_rct2_fp = vec_cpd_lst(train_rct2_smi)
train_add_fp = vec_cpd_lst(train_add_smi)
train_sol_fp = vec_cpd_lst(train_sol_smi)
# 在dim=1维度进行拼接。即:将一条数据的Reactant1,Reactant2,Product,Additive,Solvent字段的morgan fingerprint拼接为一个向量。
train_x = np.concatenate([train_rct1_fp,train_rct2_fp,train_add_fp,train_sol_fp],axis=1)

# 测试集也进行同样的操作
test_rct1_fp = vec_cpd_lst(test_rct1_smi)
test_rct2_fp = vec_cpd_lst(test_rct2_smi)
test_add_fp = vec_cpd_lst(test_add_smi)
test_sol_fp = vec_cpd_lst(test_sol_smi)
test_x = np.concatenate([test_rct1_fp,test_rct2_fp,test_add_fp,test_sol_fp],axis=1)
3.提取目标变量

        获取训练集中的目标变量,以便进行模型训练。

train_y = train_df['Yield'].to_numpy()

3.训练模型

1)随机森林模型

      使用fit函数来训练模型。

# Model fitting
model = RandomForestRegressor(n_estimators=10,max_depth=10,min_samples_split=2,min_samples_leaf=1,n_jobs=-1) # 实例化模型,并指定重要参数
model.fit(train_x,train_y) # 训练模型

      本次训练模型使用随机森林模型,使用方法及参数可参考如下:RandomForestRegressor 参数_randomforestregressor参数-CSDN博客

参数如下:

 - n_estimators=10: 决策树的个数,越多越好;但是越多意味着计算开销越大;

 - max_depth: (default=None)设置树的最大深度,默认为None;

 - min_samples_split: 根据属性划分节点时,最少的样本数;

 - min_samples_leaf: 叶子节点最少的样本数;

 - n_jobs=1: 并行job个数,-1表示使用所有cpu进行并行计算。

2)保存模型

      将训练好的随机森林模型保存到目录下的一个文件中,以便将来加载和使用。

# 保存模型
with open('./random_forest_model.pkl', 'wb') as file:
    pickle.dump(model, file)

4.模型预测

1)从磁盘目录中加载之前训练好的模型。
# 加载模型
with open('random_forest_model.pkl', 'rb') as file:
    loaded_model = pickle.load(file)
2)  使用模型进行预测。
# 预测\推理
test_pred = loaded_model.predict(test_x)

5.生成提交的submit文件

1)创建列表
ans_str_lst = ['rxnid,Yield']
2)格式化预测结果
for idx,y in enumerate(test_pred):
    ans_str_lst.append(f'test{idx+1},{y:.4f}')

其中,f‘test{idx+1} ’是样本的 ID,{y:.4f} 是预测值,格式化为四位小数。f‘test{idx+1},{y:.4f}':使用格式化字符串生成每一行的结果。append()函数将每一行格式化后的字符串添加到“ ans_str_lst 列表中

3)写入并生成submit.txt文件
with open('./submit.txt','w') as fw:
    fw.writelines('\n'.join(ans_str_lst))

参考:Datawhale

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值