【Pytorch】kaggle 泰坦尼克生存预测

数据集介绍

1912年4月15日,泰坦尼克号在首次航行期间撞上冰山后沉没,船上共有2224名乘客和乘务人员,最终有1502人遇难。沉船导致大量伤亡的重要原因之一是,没有足够的救生艇给乘客和船员。虽然从这样的悲剧性事故中幸存下来有一定的运气因素,但还是有一定规律可循的,一些人,比如妇女、儿童和上层人士,比其他人有更高的存活可能性。泰坦尼克号事件留下了“弥足珍贵”的数据记录。如前所述,乘客的幸存率存在一定的规律,因此这些数据记录集成了Kaggle上流行的入门机器学习的数据集。同时,又由于该数据集中的记录不完整,存在缺失值、异常值等,因此也成了很典型的练习数据分析的数据集。

数据集共有891行、12列。每条数据有12个特征,含义如下:

  • PassengerId 乘客ID
  • Survived 获救情况(1为获救,0为未获救)
  • Pclass 乘客等级(1/2/3等舱位)
  • Name 乘客姓名
  • Sex 性别
  • Age 年龄
  • SibSp 堂兄弟/妹个数
  • Parch 父母与小孩个数
  • Ticket 船票信息
  • Fare 票价
  • Cabin 客舱
  • Embarked 登船港口

数据处理

加载数据集

import torch  
import torch.nn as nn  
import pandas as pd  
import matplotlib.pyplot as plt  
from torch.utils.data import Dataset, DataLoader
# 加载CSV文件  
train_df = pd.read_csv(r"D:\kaggle\Titanic\train.csv") 
test_df = pd.read_csv(r"D:\kaggle\Titanic\test.csv")  
PassengerId = test_df['PassengerId']

查看数据信息

通过查看数据集信息,分析如何对数据集进行处理。

train_df.info()

info

从信息中我们可以看出哪些特征有缺失值,哪些特征是非数值型特征,这样我们就能对相应的特征进行处理。

数据集合并

将训练集和测试集合并,方便后面的数据处理。

full_df = pd.concat([train_df, test_df], ignore_index=True, sort=False)

缺失值处理

full_df['Embarked'] = full_df['Embarked'].fillna(full_df['Embarked'].mode()[0])  
full_df['Age'] = full_df['Age'].fillna(full_df['Age'].mean())

因为 Embarked 是非数值型特征,而 Age 是数值型特征,我们用 Embarked 的众数,Age 的平均值来填充缺失值。

特征工程

我们可以将SibSp(船上直系兄弟姐妹和配偶的数量)和 Parch(船上父母和子女的数量)相加,并加上1(代表乘客本人),以得到每个乘客的家庭规模,作为一个新的特征。

full_df['Family'] = full_df['SibSp'] + full_df['Parch'] + 1

删除多余数据列

full_df.drop(['PassengerId', 'Name', 'Ticket', 'Cabin','SibSp','Parch'], axis=1, inplace=True)

数据标准化

为了确保所有特征都在相同的尺度上,我们需要对数据进行标准化

full_df['Age'] = (full_df['Age'] - full_df['Age'].mean()) / full_df['Age'].std()  
full_df['Fare'] = (full_df['Fare'] - full_df['Fare'].mean()) / full_df['Fare'].std()

特征转换

我们需要对非数值型特征进行编码,将其转换为数值型特征

full_df['Sex'] = full_df['Sex'].map({'male': 1, 'female': 0})  
full_data = pd.get_dummies(full_df).astype(float)

分离数据集

train_data = full_data[full_data['Survived'].notnull()]  
test_data = full_data[full_data['Survived'].isnull()]

经过数据处理后的数据集是这样的。

train_data

构建数据集

定义超参数

batch_size = 32  
learning_rate = 0.05  
epochs = range(1,1001)

构建数据集

class TitanicDataset(Dataset):  
    def __init__(self, data):  
        self.data = data  
        self.len = len(data)  
        # 将数据转换为张量  
        self.x_data = torch.tensor(data.iloc[:, 1:].values, dtype=torch.float32)  
        self.y_data = torch.tensor(data['Survived'].values, dtype=torch.float32).view(-1, 1)  
  
    def __getitem__(self, index):  
        return self.x_data[index], self.y_data[index]  
  
    def __len__(self):  
        return self.len

创建数据加载器

train_dataset = TitanicDataset(train_data)  
dataloader = DataLoader(dataset=train_dataset, shuffle=True, batch_size=batch_size)

模型训练

定义模型

class Model(nn.Module):  
    def __init__(self):  
        super(Model, self).__init__()  
        self.model = nn.Sequential(  
            nn.Linear(train_dataset.x_data.shape[1], 16),  
            nn.Sigmoid(),   
            nn.Linear(16, 4),  
            nn.Sigmoid(),    
            nn.Linear(4, 1),  
            nn.Sigmoid(),  
        )  
  
    def forward(self, x):  
        return self.model(x)  
  
# 实例化模型  
model = Model()

定义损失函数和优化器

criterion = nn.BCELoss(reduction='mean')    
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

其中 BCELoss 主要用于二分类问题

模型训练

losses = []  # 用于保存损失值  
for epoch in epochs:  
    total_loss = 0  
    for inputs, labels in dataloader:  
        optimizer.zero_grad()  # 清除梯度  
        outputs = model(inputs)  
        loss = criterion(outputs, labels)  # 计算损失  
        total_loss += loss.item()  
        loss.backward()  
        optimizer.step()  # 更新模型参数  
    if epoch % 10 == 0:  
        print(f'Epoch: 【{epoch}/{max(epochs)}】, Loss: {total_loss}')  
    losses.append(total_loss)  
  
# 可视化损失  
plt.plot(epochs, losses)  
plt.xlabel('Epoch')  
plt.ylabel('Loss')  
plt.title('Training Loss Over Epochs')  
plt.show()  
  
# 计算训练集准确率  
with torch.no_grad():  
    outputs = (model(train_dataset.x_data) > 0.5).float()  
    accuracy = (outputs == train_dataset.y_data.float()).float().mean().item()  
    print(f'Training Accuracy: {accuracy:.4f}')

训练的可视化结果如下 :

accuracy

loss

结果预测

# 预测测试集  
test_dataset = TitanicDataset(test_data)  
predictions = (model(test_dataset.x_data).detach().numpy() > 0.5).astype(int)  
  
# 输出预测结果  
output_df = pd.DataFrame({'PassengerId': PassengerId, 'Survived': predictions.flatten()})  
output_df.to_csv("D:\kaggle\Titanic\predict.csv", index=False)

将结果在kaggle上提交后的score是0.78468

test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值