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))
相关推荐
九章云极AladdinEdu2 分钟前
超参数自动化调优指南:Optuna vs. Ray Tune 对比评测
运维·人工智能·深度学习·ai·自动化·gpu算力
人工智能训练师1 小时前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js
cxr8282 小时前
SPARC方法论在Claude Code基于规则驱动开发中的应用
人工智能·驱动开发·claude·智能体
研梦非凡3 小时前
ICCV 2025|从粗到细:用于高效3D高斯溅射的可学习离散小波变换
人工智能·深度学习·学习·3d
幂简集成3 小时前
Realtime API 语音代理端到端接入全流程教程(含 Demo,延迟 280ms)
人工智能·个人开发
龙腾-虎跃3 小时前
FreeSWITCH FunASR语音识别模块
人工智能·语音识别·xcode
智慧地球(AI·Earth)3 小时前
给AI配一台手机+电脑?智谱AutoGLM上线!
人工智能·智能手机·电脑
Godspeed Zhao3 小时前
自动驾驶中的传感器技术46——Radar(7)
人工智能·机器学习·自动驾驶
limengshi1383924 小时前
机器学习面试:请介绍几种常用的学习率衰减方式
人工智能·学习·机器学习
AKAMAI4 小时前
Sport Network 凭借 Akamai 实现卓越成就
人工智能·云原生·云计算