Kaggle入门Titanic生存预测 v1.0.0

2023-11-10 03:11

本文主要是介绍Kaggle入门Titanic生存预测 v1.0.0,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录标题

    • 前言
    • 问题定义
    • 数据查看分析
    • 数据处理
    • 数据替换
    • 将数据导入模型中进行训练
    • 数据预处理
    • 模型训练
    • 测试集预测
    • 总结
    • 源码地址

前言

一直在学机器学习的理论知识,但是没有实践,还是感觉心里不踏实,Kaggle的入门比赛Titanic号生存预测是一个getting started competition,很适合入门,掌握机器学习的各种常见套路.这里刚开始也是参考其他代码做的,得分是0.78947,不是很高,由此可见,虽然是入门级的比赛,想要拿到好的成绩也是要下一番功夫的.

问题定义

生存预测,这是一个二分类问题,根据训练数据集上得到的模型(其实就是一组权重),去测试集上对其中的乘客,将其归类为活着(1)还是死亡(0).

数据查看分析

利用Pandas进行数据分析,用seaborn和matplotlib进行数据可视化,这样我们第一步对数据就有一个直观的认识,可以为后续的特征工程做好准备

  1. 使用dataframe的info()方法查看csv文件各列的情况 ,相比于直接去查看csv文件的内容,pandas的这个方法可以更直观的对文件各个特征有一个宏观的认识,打印出训练数据集文件的特征如下:
    train.info()
    
    <class ‘pandas.core.frame.DataFrame’>
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
    PassengerId 891 non-null int64
    Survived 891 non-null int64
    Pclass 891 non-null int64
    Name 891 non-null object
    Sex 891 non-null object
    Age 714 non-null float64
    SibSp 891 non-null int64
    Parch 891 non-null int64
    Ticket 891 non-null object
    Fare 891 non-null float64
    Cabin 204 non-null object
    Embarked 889 non-null object
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.6+ KB
    由上可见,train.csv中共有891个乘客的信息,每个乘客有12个特征(属性),下面逐个对这些特征进行分析处理:
    • PassengerId:用户id,每个乘客都有,对于最后的实际分析并没有帮助,后续要drop掉这一列.
    • Survived:是否活下来,每个乘客都有,用以标记乘客是否最终存活.
    • Pclass: 类似与头等舱,二等舱的这样一个概念
    • Name: 乘客姓名,每个乘客都有,原先我以为Name没有什么用,可是有的针对这个进行了一下特征提取,抽取出来了Mr, Mrs, Miss, Master和Others5类,确实是有道理的,毕竟身份越高贵的活下来的几率越大
    • Sex: 乘客性别,kaggle的示例提交文件中,认定所有女性乘客都活了下来,最后也有0.76555的准确率
    • Age: 乘客年龄,注意只有714项,是存在缺失的,这里使用了对应类别均值填充的方法来补足.
    • Sibsp:在船上的兄弟姐妹和配偶的数量
    • Parch:在船上的父母和孩子的数量
    • Ticket:票号
    • Fare:船票的价格
    • Cabin:乘客所在的船舱号,只有204项,缺失了很多
    • Embarked:在那个地方上的船,注意缺了两项
  2. 在知晓数据情况后,使用dataframe.describe()方法查看各类的数学统计情况.
    在这里插入图片描述

数据处理

  1. 针对"Name"特征的数据处理
    使用seaborn的计数图,可视化Name和Survived之间的关系图: 在这里插入图片描述
    可以看到Name的分布主要集中在"Mr", “Mrs”, "Miss"和"Master"这5类上,剩下的我们统一用"Others"来代替,可以写一个方法,再结合pandas的apply方法,对一列的数据进行直接应用.
# 对姓名的数据进行特征处理
def arrangename(name):if name == "Mr" or name == "Mrs" or name == "Miss" or name == "Master":return nameelse:return "Others"# pandas的apply方法对dataframe的某一列进行操作,不必使用低效的循环
train["Name"] = train["Name"].apply(arrangename)
test["Name"] = test["Name"].apply(arrangename)
  1. 针对Age的数据进行处理
    之前数据分析的时候已经看到了,Age列存在很多的缺失数据,往往我们对于缺失数据使用平均值进行填充,但这里由于已经根据Name将人群划分成了5类,所以可以进一步细化,在每个具体类别中用其平均值进行填充,先对Name和Age进行可视化,查看条状图:
    在这里插入图片描述
    下面对各个类别的缺失值进行平均值填充,对训练集和测试集都要进行同样的操作:
# pandas的loc方法的使用,填充缺失的Age值,数据预处理
#  这里采取的填充方式是平均值填充!这里的年龄填充不是所有人的年龄平均值,而是细化到对应类别后的一个平均值,这样更精细,效果更好
train.loc[(train["Name"]=="Mr")&(train["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Mr","Age"].mean()
train.loc[(train["Name"]=="Mrs")&(train["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Mrs","Age"].mean()
train.loc[(train["Name"]=="Miss")&(train["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Miss","Age"].mean()
train.loc[(train["Name"]=="Master")&(train["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Master","Age"].mean()
train.loc[(train["Name"]=="Others")&(train["Age"].isnull()), "Age"] = train["Age"].mean()# 对测试数据集做同样的处理
test.loc[(test["Name"]=="Mr")&(test["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Mr","Age"].mean()
test.loc[(test["Name"]=="Mrs")&(test["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Mrs","Age"].mean()
test.loc[(test["Name"]=="Miss")&(test["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Miss","Age"].mean()
test.loc[(test["Name"]=="Master")&(test["Age"].isnull()), "Age"] = train.loc[train["Name"]=="Master","Age"].mean()
test.loc[(test["Name"]=="Others")&(test["Age"].isnull()), "Age"] = train["Age"].mean()
  1. 针对Fare数据
    注意:train中的Fare数据是没有缺失的,但是test中确实有缺失的,这里使用fillna方法直接将train中的Fare平均值填充到test的缺失项中.
# using the fillna method to replace the nan with specific value
test['Fare'].fillna(train['Fare'].mean(), inplace=True)
  1. 针对Cabin数据进行处理
    查看都有那些船舱:
    在这里插入图片描述
    可以看到,我们只需要提取首字母就行,代码如下:
# 当一个字符串使用了正则表达式后,最好在前面加上r
# str.extract(),可用正则从字符数据中抽取匹配的数据,只返回第一个匹配的数据。
# 先查看数据是什么样子的,然后用正则表达式进行筛选,只需要知道船舱等级(A~Z)的值就够了, 不需要知道具体位置
train['Cabin'] = train['Cabin'].str.extract(r"([A-Z])")
test['Cabin'] = test['Cabin'].str.extract(r"([A-Z])")

下面可视化"Cabin"与"Survived"之间的计数图:
在这里插入图片描述
由图可见,在以"B", “C”, “D”, "E"开头的船舱中乘客存活率较高,具体用0, 1数字表示,代码如下:

def cabin2int(cabin):if cabin == 'B' or cabin == 'C' or cabin == 'D' or cabin == 'E':return 1else:return 0
train['Cabin'] = train['Cabin'].apply(cabin2int)
test['Cabin'] = test['Cabin'].apply(cabin2int)
  1. 针对"Embarked"进行处理
    注意:Embarked是有缺失值的,但因为其不是数字型数据,不能使用平均值填充,这里使用出现最频繁的值进行填充
    在这里插入图片描述
  2. 针对PassengerId进行的操作:
    PassengerId没有实际意义,因此可以就地删除掉
#  原始数据中的passengerId没有什么用,删除掉
train.drop('PassengerId', axis=1, inplace=True)

数据替换

  1. 因为Name已经用"Mr", “Mrs”, “Miss”, "Master"和"Others"替换了,所以使用one-hot进行编码:
# 使用get_dummies可以进行one-hot编码,独热编码之后相当与将之前的name列换成了Mr, MISS, MRS, Master, Others5列
tmp = pd.get_dummies(train["Name"])
train.drop("Name", axis=1, inplace=True)
train = pd.concat((train, tmp), axis=1)
train.drop(['Others'], axis=1, inplace=True)tmp = pd.get_dummies(test['Name'])
test.drop("Name", axis=1, inplace=True)
test = pd.concat((test, tmp), axis=1)
test.drop(['Others'], axis=1, inplace=True)
  1. 针对sex的数据替换,用0表示男性,1表示女性:
# 针对Series用replace进行单值替换
train['Sex'].replace({'male':0, 'female':1}, inplace=True)
test['Sex'].replace({'male':0, 'female':1}, inplace=True)
  1. 针对Embarked进行数据替换
    在这里插入图片描述
    因为可视化效果中S对应的Embarked值比较高,所以将"C"和"Q"看做一类,"S"看做另一类进行0,1替换:
train.replace({"S":0, "C":1, "Q":1}, inplace=True)
test.replace({"S":0, "C":1, "Q":1}, inplace=True)

将数据导入模型中进行训练

构造出训练数据集(X_train, y_train),构造测试集test

# 训练数据将数据和对应标签分开存放,掌握这个技巧
X_train = train.drop("Survived", axis=1)
columns = X_train.columns
y_train = train["Survived"]
# 测试集
Id = test["PassengerId"]
test = test.drop("PassengerId", axis=1)

数据预处理

from sklearn.preprocessing import StandardScaler# StandardScaler的作用:去均值和方差归一化。且是针对每一个特征维度来做的,而不是针对样本。 
std = StandardScaler()
X_train = std.fit_transform(X_train)
test = std.transform(test)

模型训练

  1. 进行数据切分,按照1:4的比例将训练数据集,切分为训练集和验证集
from sklearn.model_selection import  train_test_split# 进行数据集切分, 验证集的数据量占五分之一
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=0)
  1. 定义一个统一的方法来进行模型的训练
def modeling(params, estimator):"""利用Python的语法特性,传过来的是分类器和对应的参数,这样一个函数就可以用来对多个模型进行测试了!!!GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合于小数据集"""grid = GridSearchCV(estimator, params, scoring="accuracy", n_jobs=-1)grid.fit(X_train, y_train)clf = grid.best_estimator_clf.fit(X_train, y_train)predict = clf.predict(X_valid)accuracy = accuracy_score(y_valid, predict)print("paramater:", grid.best_params_)print("accuracy:", accuracy)return accuracy, grid.best_estimator_
  1. 选用合适的模型去训练
    1 . 使用随机森林去训练
params = {"n_estimators": [5, 10, 20, 25],"max_depth": [3, 5, 7, 9, None],"max_features": ['auto', 'sqrt', 'log2', None]
}
rfc_accuracy, rfc_clf = modeling(params, RandomForestClassifier())
importance = pd.DataFrame({"feature": columns, "importance": rfc_clf.feature_importances_})
importance.sort_values(by="importance", ascending=False)
2. 使用SVM分类器去训练
params = {"C": [0.5, 1.0, 1.5],"gamma": [0.01, 0.05, 0.1],"probability": [True]
}svc_accuracy, svc_clf = modeling(params, SVC())
3. 使用逻辑回归
# 使用logistic regression
params = {"C": [0.1, 1, 10],"max_iter": [50, 100, 200]
}
# 使用逻辑回归
lr_accuracy, lr_clf = modeling(params, LogisticRegression())
4. 使用knn分类器
# 使用knn分类器
params = {"n_neighbors": [2, 3, 4, 5, 10, 15],"leaf_size": [20, 30, 50],"weights": ["uniform", "distance"],"algorithm": ["auto", "ball_tree", "kd_tree"]
}
# 传入的param是一个字典
knc_accuracy, knc_clf = modeling(params, KNeighborsClassifier())
5. 使用高斯分布
# 使用高斯分布
params = {}gnb_accuracy, gnb_clf = modeling(params, GaussianNB())
6. 使用lsvc分类器
# 使用lsvc分类器
params = {"C": [0.005, 0.01, 0.5, 1.0]}
lsvc_accuracy, lsvc_clf = modeling(params, LinearSVC())
  1. 针对上述的模型进行实际效果测试,选出准确率最高的分类器
accuracy = pd.DataFrame({"model":["RandomForestClassifer", "SVC", "LogisticRegression", "KNeighborsClassifier", "GaussianNB", "LinearSVC"],"accuracy": [rfc_accuracy, svc_accuracy, lr_accuracy, knc_accuracy, gnb_accuracy, lsvc_accuracy]})
# 对于多个模型的性能进行比较
# 掌握这种dataframe的排序方法
accuracy.sort_values(by="accuracy", ascending=False)

在这里插入图片描述

测试集预测

从上面各个模型的效果来看,在验证集上,knn的效果最好,所以用knn在训练数据集上进行训练并在测试数据集上进行预测,得到knc_submission.csv后,提交得到0.78947的分数.不过,我又用其他几个模型试了一些,发现SVC的效果更好,分数达到了0.79

# 因为KNeighboursClassifier的效果最好,使用这个模型来做
knc_clf.fit(X_train, y_train)
submission_predictions = knc_clf.predict(test)
submission = pd.DataFrame({"PassengerId":Id, "Survived": submission_predictions})
# 使用to_csv方法直接写回到csv文件中!!
# index=False是为了不保留行索引,默认index值为True,是保留行索引的,但是提交的数据不需要!
submission.to_csv("knc_submission.csv", index=False)

总结

这一系列分析做下来,虽然最终得分一般,但还是学到了一些套路的,现总结如下:

  1. pandas不愧是数据分析神器,要好好的加以利用,善用info(), describe(), values_count()等方法来对数据有一个宏观的认识.
  2. 对于缺失的数据,要进行数据填充,如平均值填充, 最大值填充,最好是用细化到最小单位的类别去填充,这样效果更好.
  3. seaborn, matplotlib等可视化工具对于刻画特征列与目标列(如这里的"survived")之间的关系很有帮助,可以直观的进行分析,从而对数据进行归类
  4. 掌握其中使用多个模型的预测方法

源码地址

源码和提交csv文件已放到github上,点此访问

这篇关于Kaggle入门Titanic生存预测 v1.0.0的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/380090

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

MySQL入门到精通

一、创建数据库 CREATE DATABASE 数据库名称; 如果数据库存在,则会提示报错。 二、选择数据库 USE 数据库名称; 三、创建数据表 CREATE TABLE 数据表名称; 四、MySQL数据类型 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串类型 4.1 数值类型 数值类型 类型大小用途INT4Bytes整数值FLOAT4By

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是