从零开始入门kaggle,以Titanic为例
引言
这篇教程为零基础的入门者准备,不推导复杂的数学公式,也不搞繁琐的本地环境配置,而是在kaggle的云端notebook中,通过一个新手级别的机器学习项目:Titanic,让想入门kaggle竞赛以及机器学习的初学者熟悉机器学习的基本流程
一:Python语言基础
需要说明的是,初学者只需了解python的语法,能够看懂代码即可,如果碰到难以理解的语言问题再回去学习。
无python语言基础者可通过该教程python基础教程进行学习,学习范围为python基础语法到常用数据结构的(list set tuple dict)以及库的import,对面向对象有一定的了解
二:kaggle注册以及使用指南
通过https://www.kaggle.com/# 进入kaggle主页

右上角register注册账号(略)

从左侧competitions进入竞赛页面,找到Titanic

kaggle的云端notebook附带了一些python的重要库,因此可以直接import,同时带有该项目的训练集和测试集(也可以自己导入),在右侧即可复制训练集和测试集的文件地址
解读一下左侧代码的含义,这是 Kaggle 新建 Notebook 时自带的默认模板代码。
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: ...
# For example, here's several helpful packages to load
意思是:这个 Notebook 运行在 Kaggle 配置好的 Python 3 环境(Docker 容器)里,已经预装了很多常用数据分析库,不需要你自己 pip 安装。
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
导入两个最常用的库(也可以自己导入)
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
列出所有输入数据文件(无需在意)
import kagglehub
# kagglehub.dataset_download('<owner>/<dataset-slug>')
kagglehub 是 Kaggle 官方客户端库,可以在代码里下载数据集 / 模型。最后一行被注释掉,只是演示用法。你现在用不到它,因为竞赛数据已经直接挂载在 /kaggle/input 下了。
kaggle的提交需要将测试结果转换为csv文件提交,这个我们在后续再提
首先我们介绍一下Titanic这个问题

要利用机器学习创建一个模型,预测哪些乘客在泰坦尼克号沉船中幸存(其实是个二分类问题)

提交文件的格式要求
三:调用库的介绍
首先要声明的是,在这个教学中我们主要使用pandas(核心),sklearn(一种机器学习库)
注:许多机器学习会使用到numpy,matplotlib库,但是在这个教学代码中不会涉及
接下来会介绍pandas和sklearn的一些函数,如果看不懂可以直接跳过,我在后续会在拆解代码的同时逐个解释
Pandas:
Pandas 是 Python 语言的一个扩展程序库,用于数据分析,名字衍生自术语 "panel data"(面板数据)和 "Python data analysis"(Python 数据分析)。
在这里我们会使用到
pd.read_csv(): 读取 CSV 文件,并将其加载为 Pandas 的 DataFrame 数据框(用于读取 train.csv 和 test.csv)。
pd.DataFrame(): 创建一个新的 DataFrame 对象(用于最后构建包含 PassengerId 和预测结果 Survived 的提交文件)。
.info(): 打印 DataFrame 的简要摘要信息,包括列名、非空值数量和数据类型。
.isna(): 检测数据中的缺失值,返回一个与原数据形状相同的布尔型 DataFrame/Series。
.sum(): 对数据进行求和,在这里与 .isna() 连用(train.isna().sum()),用于统计每一列的缺失值总数。
.describe(): 生成数值型列的描述性统计信息(如计数、均值、标准差、最小/最大值、分位数等)。
.value_counts(): 统计某一列中各个唯一值出现的频次,代码中使用了参数 normalize=True,使其返回的是比例(频率)而非绝对数量。
.groupby(): 根据指定列(如 Sex)的值对数据进行分组操作。
.mean(): 计算平均值,在这里与 .groupby() 连用,用于计算不同性别下的平均存活率。
.to_csv(): 将 DataFrame 导出/保存为 CSV 文件(用于保存最终的 Kaggle 提交文件 submission.csv)。
sklearn:
Scikit-learn 主要用于机器学习的数据预处理、模型构建和评估。
代码中使用了以下类、函数以及它们的方法:
数据预处理与流水线模块
Pipeline() (来自 sklearn.pipeline): 将多个数据处理步骤(如缺失值填充、标准化)和最终的模型串联成一个流水线,防止数据泄露并简化代码。
ColumnTransformer() (来自 sklearn.compose): 允许对 DataFrame 的不同列(如数值列和类别列)分别应用不同的预处理流水线。
SimpleImputer() (来自 sklearn.impute): 用于填补缺失值。
StandardScaler() (来自 sklearn.preprocessing): 对数值型特征进行标准化处理(使数据均值为 0,标准差为 1),以加速逻辑回归等模型的收敛。
OneHotEncoder() (来自 sklearn.preprocessing): 对类别型特征(如 Sex, Embarked)进行独热编码(One-Hot Encoding),将其转换为模型可理解的数值型矩阵。
模型选择与划分模块
train_test_split() (来自 sklearn.model_selection): 将数据集随机划分为训练集和验证集。
模型构建模块
LogisticRegression() (来自 sklearn.linear_model): 实例化逻辑回归分类模型。
.fit(X, y): 模型和预处理器的核心方法,用于在训练集上训练/拟合模型。
.predict(X): 使用训练好的模型对验证集或测试集进行预测,输出预测标签。
模型评估模块
accuracy_score() (来自 sklearn.metrics): 计算模型预测的准确率(Accuracy)。
confusion_matrix() (来自 sklearn.metrics): 计算并返回混淆矩阵,用于直观展示预测
正确和错误的分类数量(如 TP, TN, FP, FN)。
classification_report() (来自 sklearn.metrics): 生成一份详细的文本分类评估报告,包含精确率(Precision)、召回率(Recall)、F1 分数(F1-Score)等指标。
四:具体流程以及代码拆解
在这次教程中我们会构建一个baseline,以熟悉机器学习的流程
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
##读取文件(训练集和测试集)
train=pd.read_csv('/kaggle/input/competitions/titanic/train.csv')
test=pd.read_csv('/kaggle/input/competitions/titanic/test.csv')
##熟悉及分析数据
print(train.shape)
print(test.shape)
train.columns
train.info()
train.isna().sum()
train.describe()
train['Survived'].value_counts(normalize=True)
train.groupby('Sex')['Survived'].mean()
##特征及标签选取
features=['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
x=train[features]
y=train['Survived']
x_test=test[features]
num_features=['Pclass','Age','SibSp','Parch','Fare']
cate_features=['Sex','Embarked']
##数据预处理
num_features_pipeline=Pipeline([('imputer',SimpleImputer(strategy='median')),('scaler',StandardScaler())])
cate_features_pipeline = Pipeline([
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
preprocessor=ColumnTransformer([('num',num_features_pipeline,num_features),('cate',cate_features_pipeline,cate_features)]) ##预处理
##建模
model=Pipeline([('preprocessor',preprocessor),('logimod',LogisticRegression(max_iter=1000, random_state=42))])##逻辑回归模型,最多迭代1000次,随机种子42
x_train,x_valid,y_train,y_valid=train_test_split(x,y,test_size=0.2,random_state=42,stratify=y)##构造验证集,为训练集的0.2,要求存活率(y)一致
##预先训练和验证
model.fit(x_train,y_train)
y_valid_pred=model.predict(x_valid)
print(accuracy_score(y_valid, y_valid_pred))
print(confusion_matrix(y_valid, y_valid_pred))
print(classification_report(y_valid, y_valid_pred))
##正式训练
model.fit(x,y)
test_pred=model.predict(x_test)
##生成提交文件
submission=pd.DataFrame({'passengerId':test['PassengerId'],'Survived':test_pred})
submission.to_csv('submission.csv', index=False)
从这个代码中我们可以看出,机器学习的基本流程即
# 1. 读数据
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
# 2. 准备特征和标签
X = train[features]
y = train['Survived']
X_test = test[features]
# 3. 预处理(包括数据处理过程)
preprocessor = ColumnTransformer([...])
# 4. 建模型
model = Pipeline([
('preprocessor', preprocessor),
('classifier', LogisticRegression(max_iter=1000))
])
# 5. 训练
model.fit(X, y)
# 6. 预测
pred = model.predict(X_test)
# 7. 提交
submission = pd.DataFrame({
'PassengerId': test['PassengerId'],
'Survived': pred
})
submission.to_csv('submission.csv', index=False)
接下来我们逐步拆解代码并且进行解释
1库的导入
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
这是导入本次项目所需要的库sklearn和pandas
2文件读取
train=pd.read_csv('/kaggle/input/competitions/titanic/train.csv')
test=pd.read_csv('/kaggle/input/competitions/titanic/test.csv')
pd.read_csv会读取一个 CSV 文件,并返回一个 DataFrame(可以理解为一张有行有列的表)
在这里我们将训练集(即train.csv)存入train中,对测试集同理
3观察数据
train.head(10)
print(train.shape)
print(test.shape)
train.columns
train.info()
train.isna().sum()
train.describe()
train['Survived'].value_counts(normalize=True)
train.groupby('Sex')['Survived'].mean()
这些都是用来观察图表以及一些数据的统计的函数,接下来逐个分析
train.head(10)
表示查看前十行

print(train.shape)
print(test.shape)
.shape会返回图表的(行数,列数)

train.columns
返回所有列名。

train.info()
可以查看:
每列的名字
非空数量
数据类型
缺失值情况

在这里我们可以看到,Age,Embarked有少量缺失,Cabin缺失很多
train.isna().sum()
.isna() 返回一个布尔表:
True:该位置缺失
False:该位置不缺失
.isna().sum() 就可以返回缺失的总数

train.describe()
.describe()可以查看数值列的统计信息:
count:非空数量
mean:均值
std:标准差
min:最小值
max:最大值
25%、50%、75%:分位数

train['Survived'].value_counts(normalize=True)
返回train图表中Survived中的数据
其中0表示死亡,1表示存活
normalize=True表示返回比例
若不写这个参数则会返回个数

train.groupby('Sex')['Survived'].mean()
.groupby('Sex')是将数据分组Sex的数据分组,然后再统计分组后Survived的均值(这一步可以忽略)

4特征选取
这是数据分析中比较重要的一步,哪些特征是重要的,哪些特征是干扰项,需要进行区分
features=['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
x=train[features]
y=train['Survived']
x_test=test[features]
num_features=['Pclass','Age','SibSp','Parch','Fare']
cate_features=['Sex','Embarked']
在Titanic这个问题里,name和ticket是无法量化的,因此我们不选取这两个特征
features=['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
在这里我们选取可量化并且可能对训练有帮助的特征(你也可以根据数据新造特征,比如将同一姓氏列为一个特征,在此不做要求)
x=train[features]
x_test=test[features]
x=train[features]和x_test=test[features]都是从train和test里面将我们所选取的列给提出来,我们也可以随意设定features然后从train中提出,先定义features这个列表纯粹是为了方便
x = train[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']]
x_test = test[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']]
这样子写也是完全可行,本质一致的
y=train['Survived']
y是训练标签,即是模型要学着预测的"答案"
num_features=['Pclass','Age','SibSp','Parch','Fare']
cate_features=['Sex','Embarked']
我们观察数据可以发现,有一些列的数据是单纯的数值特征(如Age fare),而另外一些则是类别特征(如Sex Embarked),我们将其分开,以更好地进行处理
5数据处理
首先介绍一下Pipeline,Pipeline就是将一些步骤封装为一个整体,并且逐个执行
num_features_pipeline=Pipeline([
('imputer',SimpleImputer(strategy='median')),
('scaler',StandardScaler())
])
在这里我们创建了一个pipeline对象-并且命名为num_features_pipelines,Pipeline 里面每一项是一个元组:
('名字', 处理器)
名字可以随便填,这样一来当执行num_features_pipeline时,就会先执行SimpleImputer再执行StandardScaler,就把两个步骤封装在一起了。接下来我们详解这一步代码
('imputer',SimpleImputer(strategy='median')
SimpleImputer用来填充缺失值,sklearn SimpleImputer只是处理缺失值的其中一种方法,其余方法可自行学习
strategy='median'
这里指用中位数进行填充
strategy
mean 用均值填充
median 用中位数填充
most_frequent 用众数填充
constant 用固定值填充
'scaler',StandardScaler()
StandardScaler()用于标准化数值。
标准化后,每列大致变成:
均值为 0
标准差为 1
使得据测结果不会被某些维度过大的特征值而主导。
cate_features_pipeline = Pipeline([
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
对于类别特征,我们同样使用SimpleImputer处理缺失值并且用出现最多的值进行填充
('onehot', OneHotEncoder(handle_unknown='ignore'))
OneHotEncoder用于把类别变量变成数字。比如说sex有male和female两种,但是模型只能识别数字,它能够将类别特征的每个元素转化为一个可以用来计算的数值,这个过程通常称为特征值数字化
handle_unknown='ignore'
意思是: 如果测试集出现了训练集没见过的类别,不要报错,直接忽略。
假如训练集有S C Q,而测试集有X,这时候就不会报错
综上所述
我们知道了对于数据我们必须做
缺失值的填充
而对于数值特征需要进行归一化,
对于类别特征需要进行特征值数字化
preprocessor=ColumnTransformer([('num',num_features_pipeline,num_features),('cate',cate_features_pipeline,cate_features)])
ColumnTransformer是列转换器,能偶对不同列应用不同的预处理方法,并将结果合并成一个新的特征矩阵
格式:
('名字', 处理方式, 作用在哪些列)
('num',num_features_pipeline,num_features)
这里意思是对数值特征即num_features这些列(比如age fare)应用num_features_pipeline(即缺失值处理和归一化)
('cate',cate_features_pipeline,cate_features)
同理,对类别特征cate_feaures这些列(比如sex embarked)应用cate_features_pipeline(即缺失值处理和特征值数字化)
6建立模型
model = Pipeline([
('preprocessor', preprocessor),
('classifier', LogisticRegression(max_iter=1000, random_state=42))
])
这个pipeline包括
原始数据
↓
预处理(前面写好的preprocessor)
↓
逻辑回归模型
('classifier', LogisticRegression(max_iter=1000, random_state=42)
这里我们采用LogisticRegression,逻辑回归模型,是一个二分类模型(你也可以采用其他的模型)
其中max_iter是最大迭代数
random_state是随机数种子,这里填的和后面填的一样,保持固定即可
7验证集构造和模型验证
这一步是选取训练集的一部分作为测试,来测试模型的能力,以方便进行模型的调整
x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size=0.2, stratify=y)
做的一件事是:把 (x, y) 这对数据按行随机打乱,然后 8:2 切成两组,一组用来训练,一组用来"模考"。下面拆开讲。
前面我们提到x=train[features],y=train['survived']
而这里我们创建四个新的变量
其中x_train,y_train分别为用来训练的特征和标签,而x_valid和y_valid则为用来验证的特征和标签
那为什么要按照这个顺序写呢
train_test_split(x, y)
因为train_test_split(x, y) 的返回顺序固定为:
x 的训练部分、x 的"测试"部分、y 的训练部分、y 的"测试"部分。
test_size=0.2
总样本(x)的 20% 分给验证集(x_valid),剩下 80% 做训练集(x_train)
也可以传整数,如 test_size=200 表示固定切 200 行。
random_state=42
保持和模型构建时的随机数种子一致即可
stratify=y
切分时保持 y 的类别比例不变
Titanic 整体存活率 ≈ 342/891 ≈ 38%,加了 stratify=y 后,y_train 和 y_valid 里的存活率也都 ≈ 38%
纯随机切分可能碰巧让验证集存活率变成 50% 或 25%,那么算出来的准确率就忽高忽低、不可信;训练集分布也可能偏离整体。分层切分消除了这种随机性
model.fit(x_train,y_train)
fit 是 scikit-learn 里最重要的方法之一
model.fit(X, y)
就是让模型从 X 和 y 中学习规律。
y_valid_pred=model.predict(x_valid)
predict() 在这里就是用模型对验证集(x_valid)做预测,并且返回结果给y_valid_pred这个变量
输出结果类似
[0, 1, 0, 1, 1, 0, ...]
print(accuracy_score(y_valid, y_valid_pred))
print(confusion_matrix(y_valid, y_valid_pred))
print(classification_report(y_valid, y_valid_pred))
这三串代码都是用来评估模型能力的
sklearn.metrics 里所有函数(也包括这三段代码)都是真实值在前、预测值在后
print(accuracy_score(y_valid, y_valid_pred))
返回一个数:即预测准确率
准确率 = 预测对的样本数 / 总样本数

print(confusion_matrix(y_valid, y_valid_pred))
查看混淆矩阵
[[TN, FP],
[FN, TP]]
这是混淆矩阵的格式
TP(True Positive)真正类:真实为正类且预测为正类
FN(False Negative)假负类:真实为正类但预测为负类
FP(False Positive)假正类:真实为负类但预测为正类
TN(True Negative)真负类:真实为负类且预测为负类

该模型的混淆矩阵

print(classification_report(y_valid, y_valid_pred))
查看分类报告,这个API会给出:
precision:精确率
recall:召回率
f1-score:综合指标
support:样本数量

8正式预测
model.fit(x,y)
test_pred=model.predict(x_test)
我们利用正式的训练集(x)去训练模型,最后对kaggle提供的测试集(x_test)进行预测,返回的预测结果我们储存在test_pred中
9生成提交文件
submission=pd.DataFrame({'passengerId':test['PassengerId'],'Survived':test_pred})
submission.to_csv('submission.csv', index=False)
pd.DataFrame会返回一张图表,而这里kaggle对Titanic的要求是有passengerid和survived(存活情况)两个信息
.to_csv是生成csv文件,to_csv 默认会把 index 写进文件,所以index我们要写False,不然不符合kaggle的格式要求
执行后文件会出现在kaggle的output处
10提交到kaggle

右上角save version,之后可以在左侧Edited找到这个notebook

选择output,点击submit to competition,就能提交到kaggle并且获得打分

这份baseline的打分为0.76555,即准确率

五:后续改进
读者可根据这个baseline,通过为某个特征分桶,新增特征,更换模型等处理尝试提高模型能力。
结语
这份baseline对大部分操作都是简略处理,在真正的机器学习中会涉及更多特征工程相关的内容,通常会对每个特征进行绘图观察分布以及趋势来分析数据或者是精进模型来获得更好的效果
不过读到这里你已经初步了解了机器学习的基本流程并且能够熟悉kaggle的操作,加油完成第一份机器学习项目吧!
"If you repeat your code 3 times, write a function. If you give in-person advice to the same question 3 times, write a blog."

浙公网安备 33010602011771号