【kaggle深度学习实战
【kaggle深度学习实战
本文使用深度学习来预测表格数据
使用的模型为tabnet,因此需要安装相应的模块 !pip install pytorch-tabnet
Tabet 简介
Tabet 是由 Google Research 提出的一个深度学习模型,旨在高效处理表格数据(Tabular Data)。Tabet 的设计目标是为表格数据提供一种新的、更高效、更易解释的处理方法。与传统的机器学习模型(如决策树、随机森林、XGBoost 等)和神经网络(如 MLP)相比,Tabet 在处理表格数据时具有显著优势,尤其是在复杂性和可解释性方面。
- Tabet 的核心特点和优势 自注意力机制 (Attention Mechanism): Tabet 的核心创新之一是引入了 注意力机制,这种机制通常用于自然语言处理(LP)和计算机视觉(CV)领域,在 Tabet 中,注意力机制帮助模型选择性地关注输入数据的不同特征。 Tabet 的注意力机制帮助模型决定哪些特征对于当前的任务是最重要的,从而能更好地对表格数据进行建模。这使得模型能够学习到特征之间的复杂依赖关系。
- 解释性 (Interpretability): Tabet 提供了较好的模型可解释性,尤其在需要理解模型做出预测原因的场景中。这主要得益于其注意力机制,用户可以通过分析模型的 “解释” 部分,了解模型是如何从输入特征中选择相关信息的。 在实际应用中,解释性对很多行业来说是一个重要需求,尤其在金融、医疗等领域,Tabet 在此方面的表现十分突出。
- 高效的稀疏性学习 (Sparse Learning): Tabet 通过稀疏注意力机制提高了计算效率,减少了不必要的计算。具体来说,它通过学习哪些特征组合是最重要的,减少了对无关特征的依赖,从而提高了模型的学习速度和泛化能力。 稀疏性能够有效降低模型的复杂度,提高训练和推理速度,特别适用于大规模数据集。
- 优秀的性能: 在多个标准数据集上,Tabet 在准确性和效率上都表现优异,尤其在一些复杂的表格数据任务上,Tabet 经常优于传统的模型,如梯度提升树(GBDT)等。 它特别适合于处理高维、复杂的表格数据,并且比传统模型更能充分利用数据中的深层特征。
- 模型训练和推理速度: Tabet 在训练时使用了动态特征选择和逐步决策机制,这使得其在训练时速度较快。 推理时,Tabet 通过稀疏的计算过程显著提高了计算效率,使得在大数据场景下仍能保持良好的速度。
Tabet 的工作原理
Tabet 的架构基于深度神经网络(D)和增强的自注意力机制,主要包括以下几个部分:
- 特征选择模块:
Tabet 的核心机制是通过 注意力机制 来选择重要的特征。这种注意力机制允许模型动态选择每个决策步骤中最重要的特征,从而进行有效的信息提取。
- 决策树模块:
Tabet 在决策时引入了类似决策树的概念,它通过多个阶段的选择和调整来做出最终的预测。每个决策阶段都会依据当前阶段的目标选择不同的特征子集进行处理。
- 稀疏激活 (Sparsity) 机制:
Tabet 通过稀疏激活机制提高了模型效率。稀疏激活是指只有少部分特征在每次计算中被激活,这样减少了计算量并提高了效率。
- 掩码与路由机制:
Tabet 采用掩码与路由机制(Masking and Routing),它通过学习如何将输入数据映射到一个更小的子集,以便进行后续的预测。 通过这种方式,Tabet 能够更高效地处理复杂数据并减少计算资源的消耗。
Tabet 的优势
适用于表格数据:Tabet 特别适用于处理表格数据,而不像一些深度学习模型(如 C 或 R)那样主要面向图像或文本数据。 可解释性:通过其自注意力机制,Tabet 提供了比传统深度学习模型(如标准的多层感知机)更高的可解释性。 高效性:Tabet 在计算上相对较为高效,尤其在处理稀疏数据时能有效提升速度。 性能:在多个表格数据集上,Tabet 在准确性上经常超过传统的模型,如 XGBoost 和 LightGBM,尤其在特征选择和高维数据的处理上具有优势。
项目简介
此挑战的目标是根据各种因素预测保险费。
数据集描述
本次比赛的数据集(训练和测试)是根据保险费预测数据集训练的深度学习模型生成的。特征分布与原始分布接近,但不完全相同。请随意使用原始数据集作为本次比赛的一部分,既可以探索差异,也可以看看将原始数据集纳入训练是否可以提高模型性能。 - 训练数据集;Premium Amount是目标变量 - 测试数据集;
源码
数据的探索
代码语言:javascript代码运行次数:0运行复制import numpy as np
import pandas as pd
train_data = pd.read_csv('/kaggle/input/playground-series-s4e12/')
test_data = pd.read_csv('/kaggle/input/playground-series-s4e12/')
train_data.shape, test_data.shape
这里需要对数据集的数量,缺失值情况等进行查看,不多赘述这块的知识。
代码语言:javascript代码运行次数:0运行复制numeric_columns = ['Age', 'Annual Income', 'umber of Dependents', 'Health Score', 'Previous Claims', 'Vehicle Age', 'Credit Score', 'Insurance Duration']
train_data[numeric_columns] = train_data[numeric_columns].fillna(train_data[numeric_columns].mean())
categorical_columns = ['Marital Status', 'Occupation', 'Customer Feedback']
train_data[categorical_columns] = train_data[categorical_columns].fillna('unknown')
numeric_columns = ['Age', 'Annual Income', 'umber of Dependents', 'Health Score', 'Previous Claims', 'Vehicle Age', 'Credit Score', 'Insurance Duration']
test_data[numeric_columns] = test_data[numeric_columns].fillna(test_data[numeric_columns].mean())
categorical_columns = ['Marital Status', 'Occupation', 'Customer Feedback']
test_data[categorical_columns] = test_data[categorical_columns].fillna('unknown')
以上是对缺失值进行的数据,test_data和train_data都是要进行同样操作的处理,要保证test_data和train_data的数据维度一致,这样构建的模型在预测test_data时能够正常预测。
代码语言:javascript代码运行次数:0运行复制# 将 'Policy Start Date' 列转换为 datetime 类型
train_data['Policy Start Date'] = _datetime(train_data['Policy Start Date'])
# 提取年、月、日、时、分、秒
train_data['Year'] = train_data['Policy Start Date'].dt.year
train_data['Month'] = train_data['Policy Start Date'].
train_data['Day'] = train_data['Policy Start Date'].dt.day
train_data['Hour'] = train_data['Policy Start Date'].dt.hour
train_data['Minute'] = train_data['Policy Start Date'].
train_data['Second'] = train_data['Policy Start Date'].dt.second
== 这里是对时间字段进行的操作,要转换为数值类型。test_data也要进行同样的操作。==
代码语言:javascript代码运行次数:0运行复制# 遍历所有object类型的字段,查看这些字段的unique()值
for column in train_data.select_dtypes(include=['object']).columns:
unique_values = train_data[column].unique()
print(f"Unique values in '{column}': {unique_values}")
查看object类型字段的值,以确定后面的编码方式。
代码语言:javascript代码运行次数:0运行复制# 创建教育水平的映射字典
education_mapping = {
'High School': 1,
"Bachelor's": 2,
"Master's": ,
'PhD': 4
}
policy_type = {
'Basic':1,
'Comprehensive':2,
'Premium':
}
customer = {
'unknown':0,
'Poor':1,
'Average':2,
'Good':
}
exercise = {
'Rarely':1,
'Monthly':2,
'Weekly':,
'Daily':4
}
# 使用映射字典进行序列编码
train_data['Education Level'] = train_data['Education Level'].map(education_mapping)
train_data['Policy Type'] = train_data['Policy Type'].map(policy_type)
train_data['Customer Feedback'] = train_data['Customer Feedback'].map(customer)
train_data['Exercise Frequency'] = train_data['Exercise Frequency'].map(exercise)
test_data['Education Level'] = test_data['Education Level'].map(education_mapping)
test_data['Policy Type'] = test_data['Policy Type'].map(policy_type)
test_data['Customer Feedback'] = test_data['Customer Feedback'].map(customer)
test_data['Exercise Frequency'] = test_data['Exercise Frequency'].map(exercise)
代码语言:javascript代码运行次数:0运行复制from sklearn.preprocessing import OneHotEncoder
import pandas as pd
# 需要处理的列
columns_to_encode = [
'Gender',
'Marital Status',
'Occupation',
'Location',
'Smoking Status',
'Property Type'
]
# 初始化one-hot编码器
encoder = OneHotEncoder(drop='first', sparse_output=False)
# 拆分编码器拟合和转换的步奏
train_encoded = encoder.fit_transform(train_data[columns_to_encode])
test_encoded = (test_data[columns_to_encode])
# 将编码后的数据转换为DataFrame,并与原始数据拼接
train_encoded_df = pd.DataFrame(train_encoded, columns=encoder.get_feature_names_out(columns_to_encode))
test_encoded_df = pd.DataFrame(test_encoded, columns=encoder.get_feature_names_out(columns_to_encode))
# 删除原始编码列,并在数据集中合并新编码的列
train_data_encoded = train_data.drop(columns=columns_to_encode).reset_index(drop=True)
test_data_encoded = test_data.drop(columns=columns_to_encode).reset_index(drop=True)
train_data_encoded = ([train_data_encoded, train_encoded_df], axis=1)
test_data_encoded = ([test_data_encoded, test_encoded_df], axis=1)
# 查看结果
train_data_encoded.shape, test_data_encoded.shape
以上就是编码的操作,对于有顺序的分类变量进行了映射,也可以使用序列编码,对于没有顺序的分类变量采用独热编码。
代码语言:javascript代码运行次数:0运行复制# 划分好目标变量和特征
x = train_data_encoded.drop(['id', 'Premium Amount','Policy Start Date'], axis=1)
x_test_encoded = test_data_encoded.drop(['id', 'Policy Start Date'], axis=1).values
y = train_data_encoded['Premium Amount']
代码语言:javascript代码运行次数:0运行复制from _selection import train_test_split
from import mean_squared_error
import torch
from pytorch__model import TabetRegressor
# 检查 GPU 的数量
device = 'cuda' if is_available() else 'cpu'
num_gpus = device_count()
print(f"Using {num_gpus} GPUs on device: {device}")
# 数据准备:确保 X 和 y 是 umPy 数组
X = train_data_encoded.drop(['id', 'Premium Amount', 'Policy Start Date'], axis=1).values
y = train_data_encoded['Premium Amount'].values
# 将 y 转换为二维数组
y = y.reshape(-1, 1)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据归一化(标准化)
from sklearn.preprocessing import StandardScaler
scaler_X = StandardScaler()
scaler_y = StandardScaler()
X_train = scaler_X.fit_transform(X_train)
X_test = scaler_(X_test)
y_train = scaler_y.fit_transform(y_train)
y_test = scaler_(y_test)
# 初始化 Tabet 模型
model = TabetRegressor(device_name=device)
# 混合精度训练支持
scaler = amp.GradScaler() if device == 'cuda' else one
# 多 GPU 分片数据
if num_gpus > 1:
print(f"Using {num_gpus} GPUs with manual data partitioning...")
# 将数据分成 num_gpus 份
split_size = len(X_train) // num_gpus
X_train_splits = [X_train[i * split_size:(i + 1) * split_size] for i in range(num_gpus)]
y_train_splits = [y_train[i * split_size:(i + 1) * split_size] for i in range(num_gpus)]
# 逐 GPU 分片训练
for i, (X_split, y_split) in enumerate(zip(X_train_splits, y_train_splits)):
print(f"Training on GPU {i}...")
current_device = f'cuda:{i}'
model = TabetRegressor(device_name=current_device)
model.fit(
X_split, y_split,
eval_set=[(X_test, y_test)],
patience=20, # 提高 early stopping 容忍度
max_epochs=200, # 增加最大训练轮数
batch_size=8192, # 增大 batch size
virtual_batch_size=1024, # 降低虚拟 batch size,减少显存占用
num_workers=8, # 增加 worker 数
drop_last=True
)
else:
print("Training on a single GPU...")
# 单 GPU 训练
model.fit(
X_train, y_train,
eval_set=[(X_test, y_test)],
patience=20, # 提高 early stopping 容忍度
max_epochs=200, # 增加最大训练轮数
batch_size=8192, # 增大 batch size
virtual_batch_size=1024, # 降低虚拟 batch size,减少显存占用
num_workers=8, # 增加 worker 数
drop_last=True
)
# 在测试集上预测
print("Model evaluation...")
y_pred = model.predict(X_test)
# 反归一化预测结果
y_pred = scaler_y.inverse_transform(y_pred)
y_test = scaler_y.inverse_transform(y_test)
# 评估模型性能
mse = mean_squared_error(y_test, y_pred)
print(f"Test MSE: {mse}")
# 准备真实数据的特征
print("Preparing prediction on real data...")
real_X = x_test_encoded.values
real_X = scaler_(real_X) # 归一化特征数据
# 预测真实数据
real_y_pred = model.predict(real_X)
# 反归一化真实预测
real_y_pred = scaler_y.inverse_transform(real_y_pred)
# 获取真实数据的 id
id = test_data['id'].values
# 确保形状匹配
real_y_pred = real_y_pred.flatten()
if len(id) != len(real_y_pred):
raise ValueError(f"Length mismatch: id ({len(id)}) and predicti ({len(real_y_pred)})")
# 创建结果 DataFrame
result_df = pd.DataFrame({
'id': id,
'Premium Amount': real_y_pred
})
# 保存结果为 CSV 文件
result__csv('predicted_', index=False)
print("Prediction results saved to 'predicted_'")
# 显示结果
print(result_df.head())
本次竞赛的数据集训练数据有120w,因此考虑要使用Gpu进行训练,其运行速度更快。
以上就是损失图像,可以看到效果还行。 batch_size和virtual_batch_size的含义
- batch_size(批量大小) batch_size 是指每次模型训练时使用的样本数量。每次更新模型参数时,使用这个数量的数据来计算梯度。 较小的 batch_size 更频繁地更新参数,但训练慢;较大的 batch_size 更新参数较少,但训练更快。
- virtual_batch_size(虚拟批量大小) virtual_batch_size 是在显存有限时,用来模拟一个更大 batch_size 的方法。 它通过 梯度累积 实现,即分多次处理小批量数据,累积它们的梯度,再更新一次模型参数。这样可以有效增加批量大小,而不增加显存占用。
batch_size 是每次处理的数据量。 virtual_batch_size 通过分批次累积梯度来模拟更大的 batch_size,帮助节省显存。
处理表格数据的神经网络比较少,除了上述这个,其实卷积神经网络也是可以处理时间序列数据,只需将卷积核进行改变即可。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-12-0,如有侵权请联系 cloudcommunity@tencent 删除pytorchdatasetkaggle数据深度学习#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 15 条评论) |
本站网友 史博利 | 18分钟前 发表 |
1 | |
本站网友 艾古理论 | 11分钟前 发表 |
{unique_values}")查看object类型字段的值 | |
本站网友 云端软件 | 6分钟前 发表 |
减少显存占用 num_workers=8 | |
本站网友 报喜 | 2分钟前 发表 |
Tabet 的核心特点和优势 自注意力机制 (Attention Mechanism): Tabet 的核心创新之一是引入了 注意力机制 | |
本站网友 川沙永安公墓 | 27分钟前 发表 |
它通过学习哪些特征组合是最重要的 | |
本站网友 横栏镇租房 | 15分钟前 发表 |
其运行速度更快 | |
本站网友 公交车性骚扰 | 17分钟前 发表 |
Tabet 能够更高效地处理复杂数据并减少计算资源的消耗 | |
本站网友 长沙艾特婚纱 | 1分钟前 发表 |
2 | |
本站网友 治狐臭 | 18分钟前 发表 |
'Good' | |
本站网友 厦门租房信息网 | 25分钟前 发表 |
y_test)] | |
本站网友 菊花茶的功效 | 21分钟前 发表 |
本站网友 corollary | 20分钟前 发表 |
它特别适合于处理高维 | |
本站网友 网吧迅雷 | 11分钟前 发表 |
并在数据集中合并新编码的列 train_data_encoded = train_data.drop(columns=columns_to_encode).reset_index(drop=True) test_data_encoded = test_data.drop(columns=columns_to_encode).reset_index(drop=True) train_data_encoded = ([train_data_encoded | |
本站网友 横店电影院 | 30分钟前 发表 |
对于没有顺序的分类变量采用独热编码 |