一、赛事报名
网页链接:http://competition.sais.com.cn/competitionDetail/532233/format
记得在赛题和数据处下载资料/或者教程手册的也可以
二、调试basline
登录魔搭官网:https://www.modelscope.cn/my/mynotebook/preset
在我的notebook处启动CPU环境
并在左上角找到上传按钮(中间那个),上传自己下载的文件
开启Terminal,在终端输入解压指令,name换成你自己文件的名字
unzip mame.zip
解压缩完成后,打开baseline文件
最上面两个三角点击无脑运行就可以
然后会多出来一个文件,右键下载下来,回到比赛官网提交就行(记得接龙)
三、 分析baseline
1.安装代码所需环境
!pip install pandas
!pip install -U scikit-learn
!pip install rdkit
2. 生成一个分子的Morgan指纹
def mfgen(mol, nBits=2048, radius=2):
'''
Parameters
----------
mol : mol
RDKit mol 对象。这是一个RDKit库中的分子对象。
nBits : int
指纹的位数。这是Morgan指纹的维度。
radius : int
Morgan指纹的半径。这决定了在计算指纹时考虑的邻居数。
Returns
-------
mf_desc_map : ndarray
分子指纹描述符的ndarray。这是一个位向量,表示分子的Morgan指纹。
'''
# 返回分子的位向量形式的Morgan fingerprint
fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(mol, radius=radius, nBits=nBits)
# 将指纹的位字符串转换为布尔值列表,然后转换为numpy数组
return np.array(list(map(eval, list(fp.ToBitString()))))
3.将一系列SMILES字符串转换为对应的Morgan指纹向量列表
def vec_cpd_lst(smi_lst):
smi_set = list(set(smi_lst)) # 去除SMILES列表中的重复项
smi_vec_map = {} # 创建一个空字典来存储SMILES字符串到指纹向量的映射
for smi in tqdm(smi_set): # 使用tqdm显示进度条,遍历去重后的SMILES列表
mol = Chem.MolFromSmiles(smi) # 将SMILES字符串转换为RDKit分子对象
smi_vec_map[smi] = mfgen(mol) # 计算并存储该分子的Morgan指纹
smi_vec_map[''] = np.zeros(2048) # 为空字符串(可能表示无效或缺失数据)添加一个全零的指纹向量
vec_lst = [smi_vec_map[smi] for smi in smi_lst] # 根据原始SMILES列表的顺序,从映射中获取指纹向量
return np.array(vec_lst) # 将指纹向量列表转换为numpy数组并返回
4.设置数据集目录
dataset_dir = '../dataset' # 如果是在AI Studio上,将这里改为'dataset'
5.加载训练集和测试集:
train_df = pd.read_csv(f'{dataset_dir}/round1_train_data.csv')
test_df = pd.read_csv(f'{dataset_dir}/round1_test_data.csv')
6.打印数据集大小:
print(f'Training set size: {len(train_df)}, test set size: {len(test_df)}')
7.从CSV文件中读取化学反应的相关数据,包括反应物(Reactant1, Reactant2)、添加剂(Additive)和溶剂(Solvent)的SMILES(Simplified Molecular Input Line Entry System,简化分子线性输入规范)字符串,然后将这些SMILES字符串转化为分子指纹(Molecular Fingerprints),并将这些指纹拼接成一个大的特征向量,用于机器学习模型的训练和测试。
# 从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()
# 将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)
train_y = train_df['Yield'].to_numpy()
# 测试集也进行同样的操作
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()
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)
8.使用随机森林解题(这里不懂没关系,后面会说参数含义)
# 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) # 训练模型
# 保存模型
with open('./random_forest_model.pkl', 'wb') as file:
pickle.dump(model, file)
# 加载模型
with open('random_forest_model.pkl', 'rb') as file:
loaded_model = pickle.load(file)
# 预测\推理
test_pred = loaded_model.predict(test_x)
9.生成提交文件
ans_str_lst = ['rxnid,Yield']
for idx,y in enumerate(test_pred):
ans_str_lst.append(f'test{idx+1},{y:.4f}')
with open('./submit.txt','w') as fw:
fw.writelines('\n'.join(ans_str_lst))
四、方法解析
主要使用了随机森林算法
随机森林回归模型的具体工作流程可以归纳为以下几个步骤:
一、数据解析
-
收集数据集:首先,需要准备用于训练和测试模型的数据集。数据集应包含特征和对应的目标变量。特征是用于预测目标变量的属性或特性,而目标变量是需要进行回归预测的值。
-
数据预处理:包括数据清洗(如处理缺失值、异常值等)、特征选择(选择对预测目标有用的特征)、数据标准化或归一化等步骤,以提高模型的表现和训练效率。
-
划分数据集:将数据集划分为训练集和测试集(有时还包括验证集)。训练集用于训练模型,测试集用于评估模型的性能。
二、构建随机森林
-
随机选择样本子集:从原始训练集中随机选择多个样本子集,每个样本子集的大小通常小于或等于原始训练集的大小,并且是有放回的抽样(bootstrap抽样)。这些样本子集将分别用于训练每棵决策树。
-
随机选择特征子集:在每个决策树的每个节点上,从所有特征中随机选择一个特征子集,然后从这个子集中选择一个最优特征进行节点划分。这样做的目的是增加每棵树的差异性,从而提高整个随机森林的泛化能力。
-
构建决策树:使用步骤1和步骤2中选择的样本子集和特征子集,训练多棵决策树。每棵决策树都基于基尼系数或信息增益等指标进行节点的划分,直到达到停止条件(如树的深度达到预定值、节点中的样本数少于某个阈值等)为止。
三、训练模型
-
并行训练:随机森林并行地训练多棵决策树,每棵树都是独立训练的,互不影响。
-
集成预测:对于回归问题,随机森林通过对每棵树的预测结果进行平均(或加权平均),得到最终的预测结果。这种方法可以降低预测的变化范围,提高预测的准确性和稳定性。
四、模型评估
-
性能评估:使用测试集对训练好的随机森林回归模型进行性能评估。常用的评估指标包括均方误差(MSE)、平均绝对误差(MAE)和决定系数(R^2)等。这些指标可以帮助我们了解模型在未见过的数据上的预测性能。
-
参数调优:根据模型评估的结果,可以对随机森林回归模型进行参数调优。通过调整决策树的数量、最大深度、节点分裂的最小样本数等参数,可以进一步提高模型的性能。
五、模型应用
在模型评估和调优后,可以使用训练好的随机森林回归模型进行实际的预测任务。将新的输入样本输入到模型中,即可得到对应的回归预测结果。
五、参数解析
在构建随机森林回归模型时,可以通过设置一些参数来调整模型的性能。以下是一些常见的参数及其解释:
-
n_estimators:决策树的数量。增加决策树的数量可以提高模型的性能,但也会增加计算复杂度。
-
max_depth:决策树的最大深度。控制决策树的生长深度,避免过拟合。
-
min_samples_split:节点分裂的最小样本数。控制决策树节点分裂的最小样本数,有助于防止过拟合。
-
min_samples_leaf:叶子节点的最小样本数。控制叶子节点的最小样本数,同样有助于防止过拟合。
-
max_features:节点分裂时考虑的特征数。可以设置为整数、浮点数或字符串,用于控制每个节点在分裂时考虑的特征数量。
-
random_state:随机种子。设置随机种子可以使模型的随机性可复现,便于调试和比较不同模型的性能。
六、总结
随机森林算法这么复杂,为啥代码就那么几行?因为使用了sklearn这个机器学习库,只需要自己输入参数调用实例就可以了,可以根据结果尝试修改参数来获取更好的分数。