Datawhal AI 夏令营第三期-- Task01

本次的赛题背景与第二期相比有了很大变化。第二期是三特征输入的时序预测,这次是多特征输入的回归拟合预测。数据集的量减少了,但是本质是一样的,主要是回归拟合。本次的比赛更偏向于对特征的分析和提取。对特征做好分类和排列是至关重要的。

对于此次的baseline,我在未发布Task01之前就在本地做了部署。在本地部署的时候也是花了很大功夫,在基本的训练模型生成之后,接着去预测测试集这一部分对代码的调试是一个难点。下面是我自己添加的测试集预测的输出代码,比Datawhale给的要简略一点,但是功能是相同的。

# Load data
    train_data = pd.read_csv('train_data.csv')
    # 缩小训练集,用于debug
    # train_data = train_data.iloc[:32, :]
    test_data = pd.read_csv('sample_submission.csv')
    # 删除 concentration_unit 特征
    train_data.drop('concentration_unit', axis=1)
    test_data.drop('concentration_unit', axis=1)
    # 自加行
    columns = ['siRNA_antisense_seq', 'modified_siRNA_antisense_seq_list']
    train_data.dropna(subset=columns + ['mRNA_remaining_pct'], inplace=True)
    test_data.dropna(subset=columns, inplace=True)
    # 删除训练数据集和测试数据集中特定列(siRNA_antisense_seq、modified_siRNA_antisense_seq_list)包含空值的行,以及训练数据集中
    # mRNA_remaining_pct列包含空值的行。
    # 自加行
    train_data, val_data = train_test_split(train_data, test_size=0.1, random_state=42)

    # Create vocabulary
    tokenizer = GenomicTokenizer(ngram=3, stride=3)

    all_tokens = []
    for col in columns:
        for seq in train_data[col]:
            if ' ' in seq:  # Modified sequence
                all_tokens.extend(seq.split())
            else:
                all_tokens.extend(tokenizer.tokenize(seq))
    vocab = GenomicVocab.create(all_tokens, max_vocab=10000, min_freq=1)

    # Find max sequence length
    max_len = max(max(len(seq.split()) if ' ' in seq else len(tokenizer.tokenize(seq))
                      for seq in train_data[col]) for col in columns)
    # Create datasets
    train_dataset = SiRNADataset(train_data, columns, vocab, tokenizer, max_len)
    val_dataset = SiRNADataset(val_data, columns, vocab, tokenizer, max_len)

    # Create data loaders
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    val_loader = DataLoader(val_dataset, batch_size=32)

    # Initialize model
    model = SiRNAModel(len(vocab.itos))
    criterion = nn.MSELoss()

    optimizer = optim.Adam(model.parameters())

    train_model(model, train_loader, val_loader, criterion, optimizer, 100, device)

    # # 假设测试数据集最后一列为空,我们需要预测并填入预测值
    # X_test = test_data # 假设测试集最后一列为空,不包含目标变量
    # 保存训练好的模型
    torch.save(model, 'D:/pythonProject5/model3.pth')

    # 在测试集上进行预测
    test_dataset = SiRNADataset(test_data, columns, vocab, tokenizer, max_len)
    test_loader = DataLoader(test_dataset, batch_size=32)

# 加载模型
model = torch.load('D:/pythonProject5/model3.pth', map_location=device)
print(model)  # 打印模型结构

# 确保模型在评估模式下
model.eval()

predictions = []

# 使用 no_grad 来确保不计算梯度
with torch.no_grad():
    for inputs, targets in test_loader:
        # 确保输入移动到设备上
        inputs = [x.to(device) for x in inputs]
        # print("inputs:", inputs)
        # 进行预测
        outputs = model(inputs)

        # 打印输出以进行调试
        # print("Outputs:", outputs)
        # 将预测结果移动到 CPU 并转换为 numpy 数组
        predictions.extend(outputs.cpu().numpy())

# 确认 predictions 不为空
print("checking predictions:")
print(predictions, len(predictions), len(test_data))

# 检查预测结果的长度是否与测试数据匹配
if len(predictions) == len(test_data):
    test_data['mRNA_remaining_pct'] = predictions
else:
    print("预警:预测与测试数据的行数不匹配。")

# 将完整的测试集(包括预测结果)保存为CSV文件
test_data.to_csv('predicted_test_data2100.csv', index=False)

# 输出预测完成的信息
print("预测完成,并将结果保存为 predicted_test_data2100.csv 文件。")

从加载数据开始,开始添加代码。train model往下全是自己添加的。这个程序在本地跑50代的时间为两个多小时,不建议大家在本地跑。和大家在云端的服务器跑的结果差不多,0.5-0.6的样子。调参之后分数还是上不去。后续选择别的方法和程序再去预测,比如说SVR,Lightgbm,catboost,xgboost等等。

我利用SVR预测后的结果要好于运行200epochs的baseline,为0.69左右,以下是我用的SVR的一种代码,和大家一起交流学习。

import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

# 读取数据
train_data = pd.read_csv('train_data.csv')
test_data = pd.read_csv('sample_submission.csv')

# 确保训练集和测试集中的列名和顺序一致
print("训练集列名:", train_data.columns)
print("测试集列名:", test_data.columns)

# 分离训练集的特征和目标变量
features_to_drop = ['mRNA_remaining_pct', 'concentration_unit']
X_train = train_data.drop(features_to_drop, axis=1)
y_train = train_data['mRNA_remaining_pct']
X_test = test_data.drop(features_to_drop, axis=1)

# 确认修改后的数据集
print("训练集特征:", X_train.columns)
print("测试集特征:", X_test.columns)

# 定义数值型和类别型特征列
numerical_features = X_train.select_dtypes(include=[np.number]).columns
categorical_features = X_train.select_dtypes(exclude=[np.number]).columns

# 数据预处理管道
numeric_transformer = Pipeline(steps=[
    ('scaler', StandardScaler()),
    ('imputer', SimpleImputer(strategy='mean'))  # 添加缺失值填充
])

categorical_transformer = Pipeline(steps=[
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numerical_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# 数据预处理和转换
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR
# 定义SVR模型
svr = SVR()
# # 定义SVR--linear模型参数
# svr = SVR(kernel='linear', C=1.0, epsilon=0.01)
# # 定义SVR模型参数--poly
# svr = SVR(kernel='poly', C=1.0, epsilon=0.1, degree=2, gamma='scale', coef0=1)
# # 定义SVR模型参数--rbf
# # 定义SVR模型参数,使用RBF核
# svr = SVR(kernel='rbf', C=1.0, epsilon=0.1, gamma='scale')
# # 定义参数网格,仅使用多项式核
param_grid = {
    'C': [0.1,1,10],  # 尝试不同的C值
    'epsilon': [0.01],  # 尝试不同的epsilon值
    'kernel': ['poly'],  # 只使用多项式核
    'degree': [2,3,4],  # 多项式的度数
    'gamma': ['auto','scale'],  # 定义gamma的值
    'coef0': [0,1,10],  # 独立项
}
# # 定义参数网格
# param_grid = {
#     'C': [0.1, 1, 10, 100],  # 尝试不同的C值
#     'epsilon': [0.01, 0.1, 0.5, 1],  # 尝试不同的epsilon值
#     'kernel': ['linear', 'rbf', 'poly']  # 尝试不同的核函数
#     # 'gamma': ['scale', 'auto', 0.1, 1, 10],  # 仅用于非线性核
#     # 'degree': [2, 3, 4],  # 仅用于多项式核
#     # 'coef0': [0, 1, 10],  # 仅用于非线性核
# }
# 创建GridSearchCV对象
grid_search = GridSearchCV(estimator=svr, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error')

# 训练模型并进行参数调优
grid_search.fit(X_train_processed, y_train)

# 打印最佳参数
print("最佳参数:", grid_search.best_params_)

# 使用最佳参数的模型进行预测
best_svr = grid_search.best_estimator_
y_pred = best_svr.predict(X_test_processed)

# 保存预测结果
test_data['mRNA_remaining_pct'] = y_pred
test_data.to_csv('predicted_test_data_poly_kernel.csv', index=False)
print("使用最佳参数的预测结果已保存到 predicted_test_data_poly_kernel.csv 文件中。")

这段代码是可以运行通的,大家可以试一试。虽然分数提高不多,但是可以多一中预测方式。

通过直播学习,后续会针对其特征进一步进行学习和调整,继续提分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值