DataWhale AI夏令营-催化反应速率预测(机器学习方向思路)

@[TOC](DataWhale AI夏令营-催化反应速率预测(机器学习方向思路))

(无特征工程)

个人的机器学习竞赛上分之路分享

因为自己也是机器学习竞赛方面的小白嘛,所以就总结了一下自己一步一步调优的思路吧。

首先是baseline的调优,刚接触催化反应速率预测这个任务的时候没什么思路,就是简单的调参,跟着网上的一些教程,还有AI,接触了网格搜索调参、贝叶斯调参。然后调到一定位置的时候基本想长分就开始困难了。

就开始接触换模型,这部分试了一些感觉更高级的模型,比如之前写到的梯度提升回归模型、XGBoost模型等等,相较于baseline也有不小的提升。

试过很多模型,但上分空间还是有限,看了一些大佬的笔记,了解到了stacking,基本的概念就是通过堆叠一些一级模型的结果,交给一个二级模型学习,能得到更好的效果,刚好自己之前试过很多模型参数调的也都比较好,很适合拿来做一级模型,就用了一个简单的线性回归作为二级模型没想到效果出奇的好。查阅了一些资料,如果增加一级模型也能够使结果得到提升,或者使用更复杂的二级模型学习更多的非线性的知识也能取得更好的效果,就又在不断的尝试。

Stacking

纯分享没干货怎么行。下面是一份我使用随机森林、梯度提升回归模型和XGBoost模型作为一级模型,二级模型选择最简单的线性回归的一份代码,现在我只简单的跑了一次是拿到了0.37+的分数。大家也可以去尝试一下。

在阿里云CPU就可以运行,但是如果你换了更复杂的二级模型,就需要用GPU来跑了,不然带不动

python 复制代码
# 导入库
import pickle
import pandas as pd
from tqdm import tqdm
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, StackingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from rdkit.Chem import rdMolDescriptors
from rdkit import RDLogger, Chem
import numpy as np
from xgboost import XGBRegressor
RDLogger.DisableLog('rdApp.*')

def mfgen(mol, nBits=2048, radius=2):
    # 返回分子的位向量形式的Morgan fingerprint
    fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(mol, radius=radius, nBits=nBits)
    return np.array(list(map(int, list(fp.ToBitString()))))

# 加载数据
def vec_cpd_lst(smi_lst):
    smi_set = list(set(smi_lst))
    smi_vec_map = {}
    for smi in tqdm(smi_set):  # tqdm:显示进度条
        mol = Chem.MolFromSmiles(smi)
        smi_vec_map[smi] = mfgen(mol)
    smi_vec_map[''] = np.zeros(2048)

    vec_lst = [smi_vec_map[smi] for smi in smi_lst]
    return np.array(vec_lst)

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)}')

# 从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, 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)

# 划分训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(train_x, train_y, test_size=0.2, random_state=42)

# 定义一级模型
rf_model = RandomForestRegressor(n_estimators=200, max_depth=None, max_features='sqrt', min_samples_leaf=1, min_samples_split=5, n_jobs=-1)
gb_model = GradientBoostingRegressor(n_estimators=200, learning_rate=0.05, max_depth=20, max_features='sqrt', min_samples_leaf=1, min_samples_split=6)
xgb_model = XGBRegressor(n_estimators=300, learning_rate=0.05, max_depth=20, min_child_weight=3, subsample=0.8, colsample_bytree=0.4, n_jobs=-1)

# 定义堆叠模型
stacking_model = StackingRegressor(
    estimators=[('rf', rf_model), ('gb', gb_model), ('xgb', xgb_model)],
    final_estimator=LinearRegression()
)

# 训练堆叠模型
stacking_model.fit(X_train, y_train)

# 在验证集上进行预测并评估模型
y_val_pred = stacking_model.predict(X_val)
print(f'Validation MSE: {mean_squared_error(y_val, y_val_pred):.4f}')

# 使用整个训练集训练堆叠模型
stacking_model.fit(train_x, train_y)

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

# 加载模型
with open('stacking_model.pkl', 'rb') as file:
    loaded_model = pickle.load(file)

# 预测\推理
test_pred = loaded_model.predict(test_x)

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))
相关推荐
一个处女座的程序猿2 小时前
LLMs之SLMs:《Small Language Models are the Future of Agentic AI》的翻译与解读
人工智能·自然语言处理·小语言模型·slms
档案宝档案管理5 小时前
档案宝:企业合同档案管理的“安全保险箱”与“效率加速器”
大数据·数据库·人工智能·安全·档案·档案管理
IT_Beijing_BIT6 小时前
TensorFlow Keras
人工智能·tensorflow·keras
mit6.8246 小时前
[手机AI开发sdk] 安卓上的Linux环境
人工智能·智能手机
张较瘦_6 小时前
[论文阅读] AI + 教育 | AI赋能“三个课堂”的破局之道——具身认知与技术路径深度解读
论文阅读·人工智能
望十五江洋7 小时前
泊松分布的参数可加性
线性代数·机器学习·概率论
小雨青年7 小时前
Cursor 项目实战:AI播客策划助手(二)—— 多轮交互打磨播客文案的技术实现与实践
前端·人工智能·状态模式·交互
西西弗Sisyphus7 小时前
线性代数 - 初等矩阵
人工智能·线性代数·机器学习
weixin_429630267 小时前
第6章 支持向量机
算法·机器学习·支持向量机
王哈哈^_^7 小时前
【数据集】【YOLO】【目标检测】共享单车数据集,共享单车识别数据集 3596 张,YOLO自行车识别算法实战训推教程。
人工智能·算法·yolo·目标检测·计算机视觉·视觉检测·毕业设计