跳至主要内容

Kaggle 竞赛教程:从泰坦尼克号学机器学习

通过此循序渐进的教程,为您的第一个 Kaggle 竞赛做好准备。
· 9分钟 阅读

使用 AI 探索

在本教程中,我们将走读泰坦尼克号数据集,对其进行分析,并将结果提交到实际竞赛中。您已经在本教程中学习了如何获取数据并将其导入 Kaggle Notebook。现在我们将使用 DataLab 作为数据科学笔记本。您将学会在不同平台上使用这两种工具,从而选择您更喜欢的一种。

首先,前往 Kaggle 的“Competitions”板块并搜索 Titanic(图 5.4)。在直接进入 notebook 之前,您应当先理解“Description”和“Rules”部分中的所有信息。同时也很重要的一点是查看其他用户的 notebooks,因为这可能为您的解法带来更多思路。

图 5.4:Titanic - Machine Learning from Disaster

本次竞赛旨在使用机器学习创建一个模型,预测哪些乘客在泰坦尼克号沉船事故中幸存。我们将使用一个包含乘客信息的数据集,例如姓名、性别、年龄等。我们会用到两个不同的数据集。第一个名为“train.csv”。在该数据集中,除了乘客信息外,还包含“survived”(幸存)和“not survived”(未幸存)等真实标签。第二个数据集名为“test.csv”,其中不会包含任何ground truth 值,因为我们需要对其进行预测并提交结果。

提交文件只应包含两列:PassengerId 和 Survived。如果您尝试上传包含超过两列的文件,提交流程将报错。请注意,您每天最多可以提交 10 次。

在阅读完“Competition Description”部分提供的信息后,下一步就是将数据抓取到我们的 DataLab 并进行分析。

首先,您需要在 Data Explorer 的 Data 选项卡中下载数据集(图 5.5)。您应当下载“train.csv”和“test.csv”两个文件。

下载完文件后,您应当前往DataLab。请注意,您需要先创建一个账户。创建账户并使用 DataLab 是免费的。

您可以将文件直接拖放到笔记本左侧(图 5.6)。

图 5.5:下载数据集
图 5.6:将数据集添加到 DataLab

下一步是在数据集描述部分查看数据字典。这将帮助我们决定要可视化哪些列。

  • survival:是否幸存
  • pclass:船票等级
  • sex:性别
  • Age:年龄(岁)
  • sibsp:在泰坦尼克号上的兄弟姐妹/配偶人数
  • parch:在泰坦尼克号上的父母/子女人数
  • ticket:船票号
  • fare:票价
  • cabin:舱位号
  • embarked:登船港口

导入数据

您可以在 Jupyter 笔记本中通过在单元格前加感叹号来使用 bash 命令。我们将使用 pwd 和 ls 命令检查已上传数据集文件的位置。

!pwd; ls

/work/files/workspace

notebook.ipynb test.csv train.csv

Pandas 是一个 Python 库,用于数据处理和数据分析。我们现在已经移除了 Ticket、Name 和 PassengerId 列,因为它们不包含任何有意义的数值或类别数据。现在您将能看到剩余可用的特征。

接下来几行代码中,分别使用 Pandas 的 read_csv 方法读取训练集和测试集文件。请注意,Survived 和 PassengerId 列分别被添加到训练和测试数据框中。我们将分别使用 columns_to_be_added_as_features 中的特征和 Survived 列中的标签来喂给模型。但为了简化预处理,我们可以先将它们合并。变量 test_df_matcher 也包含 PassengerId。我们将用它把 PassengerId 与测试集预测结果匹配,生成将作为结果上传到 Kaggle 的 CSV 文件。

import pandas as pd
columns_to_be_added_as_features = ['Sex','Age','SibSp','Parch','Pclass','Fare','Embarked']
train_df = pd.read_csv('train.csv', usecols=columns_to_be_added_as_features + ['Survived'])
test_df_matcher = pd.read_csv('test.csv', usecols=columns_to_be_added_as_features + ['PassengerId'])
test_df = test_df[columns_to_be_added_as_features]

通过 head() 方法,我们可以查看前 5 行及其列名。您可以在 head() 方法中传入参数来指定显示的起始行数。下一单元分别打印了训练集和测试集的行数。

print(train_df.head())
图 5.7:数据框
print("Number of rows in training set: {}".format(len(train_df)))
print("Number of rows in test set: {}".format(len(test_df)))

Number of rows in training set: 891 Number of rows in test set: 418

预处理

我们应当将将用作模型特征的值类型转换为 float。此转换将允许我们在归一化数据时执行一些数值运算。

for column_title in columns_to_be_added_as_features:
    if column_title in ['Embarked', "Sex"]:
        continue
    train_df[column_title] = pd.to_numeric(train_df[column_title], downcast="float")
    test_df[column_title] = pd.to_numeric(test_df[column_title], downcast="float")

train_df["Survived"] = pd.to_numeric(train_df["Survived"], downcast="float")

我们需要使用数值来喂给模型。下面的代码将字符串转换为数值。

train_df['Embarked'].replace('Q', 0,inplace=True)
train_df['Embarked'].replace('S', 1,inplace=True)
train_df['Embarked'].replace('C', 2,inplace=True)

test_df['Embarked'].replace('Q', 0,inplace=True)
test_df['Embarked'].replace('S', 1,inplace=True)
test_df['Embarked'].replace('C', 2,inplace=True)

train_df['Sex'].replace('male', 0,inplace=True)
train_df['Sex'].replace('female', 1,inplace=True)

test_df['Sex'].replace('male', 0,inplace=True)
test_df['Sex'].replace('female', 1,inplace=True)

print(train_df.head())
图 5.8:数值化数据框

下面对所有特征进行归一化,在此例中表示缩放到 0 到 1 之间。

#Credit: Michael Aquilina,
#https://stackoverflow.com/questions/26414913/normalize-columns-of-pandas-data-frame
def normalize(df):
    result = df.copy()
    for feature_name in df.columns:
        max_value = df[feature_name].max()
        min_value = df[feature_name].min()
        result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
    return result

train_df = normalize(train_df)
test_df = normalize(test_df)

print(train_df.head())
图 5.9:归一化数据框

由于将把数据集划分为训练集和验证集,我们会先对数据集进行打乱,以避免某一组内出现集中分布。

#Credit: Kris, https://stackoverflow.com/questions/29576430/shuffle-dataframe-rows
train_df = train_df.sample(frac=1).reset_index(drop=True)

所有空值将被替换为 0;此选择是出于节省时间的考虑。不过,您可以阅读这篇教程,了解在机器学习中如何处理缺失值。

train_df = train_df.fillna(0)
test_df = test_df.fillna(0)

下面将验证集比例设为 0.2,即 20% 的数据将用于验证。为了将数据集划分为训练集和验证集,我们将使用 Sklearn 的 train_test_split 方法。随后我们将按如下代码最后四行所示拆分特征和标签。

validation_set_ratio = 0.2
validation_set_size = int(len(train_df)*validation_set_ratio)
training_set_size = len(train_df) - validation_set_size

print("Total set size: {}".format(len(train_df)))
print("Training set size: {}".format(training_set_size))
print("Validation set size: {}".format(validation_set_size))

from sklearn.model_selection import train_test_split

train, val = train_test_split(train_df, test_size=validation_set_ratio)

train_X = train[columns_to_be_added_as_features]
train_Label = train[['Survived']]

val_X = val[columns_to_be_added_as_features]
val_Label = val[['Survived']]

训练

支持向量机是一类用于分类和回归分析的监督学习模型。本例选择了如下参数的模型。您应当尝试其他模型及不同的参数组合。每次想修改参数或尝试其他模型时无需频繁启动/停止代码,您可以将此过程自动化。如果您对支持向量机感兴趣,可以查看 DataCamp 上的使用 Scikit-learn 的支持向量机教程。

from sklearn.svm import SVC

SVM_KERNEL = "linear"
SVM_C = 10
SVM_GAMMA = 0.00001

svm_model = SVC(kernel = SVM_KERNEL, C = SVM_C, gamma = SVM_GAMMA)
svm_model.fit(train_X, train_Label)

获取验证集预测

在这一部分,我们将把验证集特征喂给模型以获得预测。然后将其与真实标签进行比较。我们使用了 Sklearn 的 metrics.accuracy_score 方法来简化准确率计算。验证集准确率为 0.799,这是一个不错的开始。

from sklearn import metrics

y_pred = svm_model.predict(val_X)
print("Accuracy:",metrics.accuracy_score(val_Label, y_pred))

Accuracy: 0.7988826815642458

获取测试集预测

现在我们继续获取实际测试集的预测。由于测试集没有真实标签,只有在将预测文件上传到 Kaggle 后,我们才能知道准确率。

test_pred = svm_model.predict(test_df)

生成输出数据框

test_df_matcher 数据框中的 PassengerId 列被取出。直接取出时返回值类型为 Series。因此,我们会将其转换为 Pandas DataFrame 类型。随后我们会将测试集预测作为第二列插入到数据框中。

result = pd.DataFrame(test_df_matcher['PassengerId'])
print(result.head(10))
图 5.10:PassengerId 数据框
result.insert(1, "Survived", test_pred, True)
result["Survived"] = pd.to_numeric(result["Survived"], downcast="integer")
print(result.head(10))
图 5.11:最终数据框

生成输出文件

至此,输出格式已准备就绪。最后一步,通过将 index 参数设为 False 来移除索引值。现在您可以下载生成的文件并上传到 Kaggle。这样您将获得测试集准确率,并出现在排行榜上。

result.to_csv("out.csv", index=False)

我们现在返回竞赛页面,点击“Submit Predictions”,然后上传预测文件。几秒钟后,您将获得测试集准确率(图 5.12)。

图 5.12:测试集准确率

结语

在本教程中,您学习了如何分析数据集并将结果提交至 Kaggle 竞赛。如果您喜欢参与数据科学竞赛,您可以在这里了解更多关于 DataCamp Competitions 的信息。

主题