Kaggle竞赛系列_SpaceshipTitanic金牌方案分析_数据分析

文章目录

    • 【文章系列】
    • 【前言】
    • 【比赛简介】
    • 【正文】
      • (一)数据获取
      • (二)数据分析
        • 1. 缺失值
        • 2. 重复值
        • 3. 属性类型分析
        • 4. 类别分析
        • 5. 分析目标数值占比
      • (三)属性分析
        • 1. 对年龄Age分析
          • (1)直方图分析
          • (2)创建新属性
        • 2. 对支出属性进行分析
          • (1)直方图分析
          • (2)创建新属性
        • 3. 对离散属性进行分析
          • (1)直方图分析
        • 4. 对定性属性进行分析
          • (1)属性分析
          • (2)根据PassengerId划分group
          • (3)对Cabin属性进一步划分
          • (4)根据Name的姓氏划分出家庭组
      • (四)归纳总结
      • (五)写在最后

【文章系列】

第一章 初探Kaggle竞赛————Kaggle竞赛系列_Titanic比赛

第二章 知识补充_随机森林————数学建模系列_随机森林

第三章 知识补充_LightGBM————集成学习之Boosting方法系列_LightGBM

第四章 再战Kaggle竞赛————Kaggle竞赛系列_SpaceshipTitanic比赛

第五章 重温回顾_学习金牌方法_数据分析————Kaggle竞赛系列_SpaceshipTitanic金牌方案分析_数据分析

第六章 重温回顾_学习金牌方法_数据处理————Kaggle竞赛系列_SpaceshipTitanic金牌方案分析_数据处理

【前言】

Spaceship Titanic比赛,类似Titanic比赛,只是增加了更多的属性以及更大的数据量,仍是一个二分类问题。

今天要分析的是一篇大神的解决方案,看完后觉得干货满满,由衷地敬佩他们对数据分析的细致程度,对比之下只觉得之前自己的分析仅仅是表面功夫,单纯靠着模型的强大能力去完成任务。看来以后还是得不断地向各位前辈大佬学习,完善自己的解决方案!!!

image-20240127131649713

项目代码 : 🚀 Spaceship Titanic: A complete guide 🏆 | Kaggle

我的解决方案:Kaggle竞赛系列_SpaceshipTitanic比赛

【比赛简介】

Spaceship Titanic比赛是一个在Kaggle上举办的机器学习挑战,参赛者的任务是预测Spaceship Titanic在与时空异常碰撞时,哪些乘客被传送到了另一个维度。这个比赛提供了从飞船损坏的计算机系统中恢复的一组个人记录,参赛者需要使用这些数据来进行预测。

【正文】

(一)数据获取

参考之前的Titanic比赛的数据获取操作 Kaggle_Titanic比赛

(二)数据分析

image-20240125094535642

  • train.csv - 用于训练数据的大约三分之二(约8700名)乘客的个人记录。
  • PassengerId - 每位乘客的唯一标识。每个标识的格式为gggg_pp,其中gggg表示乘客所在的团体,pp是他们在团体中的编号。一个团体中的人通常是家庭成员,但并不总是如此。
  • HomePlanet - 乘客出发的星球,通常是他们的永久居住星球。
  • CryoSleep - 表示乘客是否选择在航程期间被置于悬浮动状态。处于冷冻睡眠状态的乘客被限制在他们的舱房内。
  • Cabin - 乘客所住的舱房号码。格式为deck/num/side,其中side可以是P(港口)或S(舷侧)。
  • Destination - 乘客将要下船的星球。
  • Age - 乘客的年龄。
  • VIP - 乘客是否支付额外费用获得特殊的VIP服务。
  • RoomService, FoodCourt, ShoppingMall, Spa, VRDeck - 乘客在太空巨轮泰坦尼克号的许多豪华设施上的费用金额。
  • Name - 乘客的名字和姓氏。
  • Transported - 乘客是否被传送到另一个维度。这是目标,也就是您要预测的列。
  • test.csv - 剩余三分之一(约4300名)乘客的个人记录,用作测试数据。您的任务是预测这一集合中乘客的Transported值。
  • sample_submission.csv - 一个以正确格式的提交文件。
  • PassengerId - 测试集中每位乘客的标识。
  • Transported - 目标。对于每位乘客,预测True或False。
1. 缺失值
print('TRAIN SET MISSING VALUES:')
print(train.isna().sum())
print('')
print('TEST SET MISSING VALUES:')
print(test.isna().sum())

image-20240127133241505

2. 重复值
print(f'Duplicates in train set: {train.duplicated().sum()}, ({np.round(100*train.duplicated().sum()/len(train),1)}%)')
print('')
print(f'Duplicates in test set: {test.duplicated().sum()}, ({np.round(100*test.duplicated().sum()/len(test),1)}%)')

image-20240127133252458

3. 属性类型分析
train.nunique()

image-20240126180311252

4. 类别分析
train.dtypes

image-20240127133310358

一般而言,连续型属性被存储为floatdouble类型,离散型属性被存储为objectint类型。

  • 6个连续性属性(RoomService,FoodCourt,ShoppingMall,Spa,VRDeck,Age)
  • 4个离散属性(HomePlanet,CryoSleep,Destination,VIP)
  • 剩余3个描述性/定性属性(PassengerId,Name,Cabin)
5. 分析目标数值占比
# 特征尺寸
plt.figure(figsize=(6,6))# 饼状图
train['Transported'].value_counts().plot.pie(explode=[0.1,0.1], autopct='%1.1f%%', shadow=True, textprops={'fontsize':16}).set_title("Target distribution")

image-20240126180500759

分布平衡,因此不需要采用过采样、欠采样方法。

(三)属性分析

1. 对年龄Age分析
(1)直方图分析

直方图关键参数:hue=Target属性

# 特征尺寸
plt.figure(figsize=(10,4))# 直方图
sns.histplot(data=train, x='Age', hue='Transported', binwidth=1, kde=True)plt.title('Age distribution')
plt.xlabel('Age (years)')

image-20240126180645751

注意到:

  • 0-18岁的青少年更容易被转移。
  • 18-25岁的人被转移的可能性比不被转移的可能性要小。
  • 25岁以上的人被转移的可能性和没有被转移的可能性差不多。
(2)创建新属性

根据直方图False与True的高度关系,对年龄划分为多层,并依次建立一个新特征。

# 新特征-训练集
train['Age_group']=np.nan
train.loc[train['Age']<=12,'Age_group']='Age_0-12'
train.loc[(train['Age']>12) & (train['Age']<18),'Age_group']='Age_13-17'
train.loc[(train['Age']>=18) & (train['Age']<=25),'Age_group']='Age_18-25'
train.loc[(train['Age']>25) & (train['Age']<=30),'Age_group']='Age_26-30'
train.loc[(train['Age']>30) & (train['Age']<=50),'Age_group']='Age_31-50'
train.loc[train['Age']>50,'Age_group']='Age_51+'# 新特征-测试集
test['Age_group']=np.nan
test.loc[test['Age']<=12,'Age_group']='Age_0-12'
test.loc[(test['Age']>12) & (test['Age']<18),'Age_group']='Age_13-17'
test.loc[(test['Age']>=18) & (test['Age']<=25),'Age_group']='Age_18-25'
test.loc[(test['Age']>25) & (test['Age']<=30),'Age_group']='Age_26-30'
test.loc[(test['Age']>30) & (test['Age']<=50),'Age_group']='Age_31-50'
test.loc[test['Age']>50,'Age_group']='Age_51+'# 新特征的分布图
plt.figure(figsize=(10,4))
g=sns.countplot(data=train, x='Age_group', hue='Transported', order=['Age_0-12','Age_13-17','Age_18-25','Age_26-30','Age_31-50','Age_51+'])
plt.title('Age group distribution')

image-20240126182059818

2. 对支出属性进行分析
(1)直方图分析
# 支出特征
exp_feats=['RoomService', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']# 绘图
fig=plt.figure(figsize=(10,20))
for i, var_name in enumerate(exp_feats):# 左图ax=fig.add_subplot(5,2,2*i+1)sns.histplot(data=train, x=var_name, axes=ax, bins=30, kde=False, hue='Transported')ax.set_title(var_name)# 右图(核密度估计)ax=fig.add_subplot(5,2,2*i+2)sns.histplot(data=train, x=var_name, axes=ax, bins=30, kde=True, hue='Transported')plt.ylim([0,100])ax.set_title(var_name)
fig.tight_layout()  # 改善外观
plt.show()

image-20240127134808931

注意到:

  • 大多数人都没有花钱,因此可以创建一个二元属性对是否有支出进行划分。
  • 有少数的异常值。
  • 被运输的人往往花费更少。
  • RoomService、Spa和VRDeck与FoodCourt和ShoppingMall有着不同的分布
(2)创建新属性

创建一个新属性记录5个支出属性的总开支。再创建一个二元属性对是否有支出进行划分。

# 新特征-训练集
train['Expenditure']=train[exp_feats].sum(axis=1)
train['No_spending']=(train['Expenditure']==0).astype(int)# 新特征-测试集
test['Expenditure']=test[exp_feats].sum(axis=1)
test['No_spending']=(test['Expenditure']==0).astype(int)# 新特征的分布图
fig=plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
sns.histplot(data=train, x='Expenditure', hue='Transported', bins=200)
plt.title('Total expenditure (truncated)')
plt.ylim([0,200])
plt.xlim([0,20000])plt.subplot(1,2,2)
sns.countplot(data=train, x='No_spending', hue='Transported')
plt.title('No spending indicator')
fig.tight_layout()

image-20240126182217365

3. 对离散属性进行分析
(1)直方图分析

离散属性——>countplot

# 离散特征
cat_feats=['HomePlanet', 'CryoSleep', 'Destination', 'VIP']# 绘图
fig=plt.figure(figsize=(10,16))
for i, var_name in enumerate(cat_feats):ax=fig.add_subplot(4,1,i+1)sns.countplot(data=train, x=var_name, axes=ax, hue='Transported')ax.set_title(var_name)
fig.tight_layout()  # 改善外观
plt.show()

image-20240126181442663

注意到:

  • VIP似乎不是一个有用的功能,对目标分割差不多相等。相比之下,CryoSleep似乎是一个非常有用的功能。因此我们可以考虑去掉VIP列以防止过拟合。
4. 对定性属性进行分析
(1)属性分析
# 定性特征
qual_feats=['PassengerId', 'Cabin' ,'Name']# 预览定性特征
train[qual_feats].head()

image-20240126181717264

注意到:

  • Passengerld采用gggg_pp的形式,其中gggg表示乘客所在的旅行团,pp表示他们在旅行团中的编号。
  • Cabin的形式为deck/num/side,其中side可以是P代表左舷,也可以是S代表右舷。

因此我们可以从Passengerld特征中提取群组和群组大小。从Cabin特征中提取甲板、数量和侧面。从Name特征中提取姓氏来识别家庭。

(2)根据PassengerId划分group
# 新特征-分组
train['Group'] = train['PassengerId'].apply(lambda x: x.split('_')[0]).astype(int)
test['Group'] = test['PassengerId'].apply(lambda x: x.split('_')[0]).astype(int)# 绘图
plt.figure(figsize=(20,4))
plt.subplot(1,2,1)
sns.histplot(data=train, x='Group', hue='Transported', binwidth=1)
plt.title('Group')

image-20240126182514714

发现分组过多,不好进行独热编码,因此新建一个属性根据分组的人数记录每个分组的数量。

# 新特征-分组大小
train['Group_size']=train['Group'].map(lambda x: pd.concat([train['Group'], test['Group']]).value_counts()[x])
test['Group_size']=test['Group'].map(lambda x: pd.concat([train['Group'], test['Group']]).value_counts()[x])plt.subplot(1,2,2)
sns.countplot(data=train, x='Group_size', hue='Transported')
plt.title('Group size')
fig.tight_layout()

image-20240126182629213

发现除了1人组更不容易被传输,其他人数的分组基本上都是更容易被传输,因此可以将其他人数的分组划分在一起。为此我们可以再新建一个属性来判断该数据是否是1人组(是否独自出行)。

# 新特征
train['Solo']=(train['Group_size']==1).astype(int)
test['Solo']=(test['Group_size']==1).astype(int)# 新特质分布图
plt.figure(figsize=(10,4))
sns.countplot(data=train, x='Solo', hue='Transported')
plt.title('Passenger travelling solo or not')
plt.ylim([0,3000])

image-20240126182857568

(3)对Cabin属性进一步划分
# 现在用离群值替换NaN(这样我们就可以拆分特征)
train['Cabin'].fillna('Z/9999/Z', inplace=True)
test['Cabin'].fillna('Z/9999/Z', inplace=True)#  新特征-训练集
train['Cabin_deck'] = train['Cabin'].apply(lambda x: x.split('/')[0])
train['Cabin_number'] = train['Cabin'].apply(lambda x: x.split('/')[1]).astype(int)
train['Cabin_side'] = train['Cabin'].apply(lambda x: x.split('/')[2])#  新特征-测试集
test['Cabin_deck'] = test['Cabin'].apply(lambda x: x.split('/')[0])
test['Cabin_number'] = test['Cabin'].apply(lambda x: x.split('/')[1]).astype(int)
test['Cabin_side'] = test['Cabin'].apply(lambda x: x.split('/')[2])# 把Nan的放回去(我们稍后会填充这些)
train.loc[train['Cabin_deck']=='Z', 'Cabin_deck']=np.nan
train.loc[train['Cabin_number']==9999, 'Cabin_number']=np.nan
train.loc[train['Cabin_side']=='Z', 'Cabin_side']=np.nan
test.loc[test['Cabin_deck']=='Z', 'Cabin_deck']=np.nan
test.loc[test['Cabin_number']==9999, 'Cabin_number']=np.nan
test.loc[test['Cabin_side']=='Z', 'Cabin_side']=np.nan# 丢弃Cabin属性(我们不再需要它了)
train.drop('Cabin', axis=1, inplace=True)
test.drop('Cabin', axis=1, inplace=True)# 新特征的分布图
fig=plt.figure(figsize=(10,12))
plt.subplot(3,1,1)
sns.countplot(data=train, x='Cabin_deck', hue='Transported', order=['A','B','C','D','E','F','G','T'])
plt.title('Cabin deck')plt.subplot(3,1,2)
sns.histplot(data=train, x='Cabin_number', hue='Transported',binwidth=20)
plt.vlines(300, ymin=0, ymax=200, color='black')
plt.vlines(600, ymin=0, ymax=200, color='black')
plt.vlines(900, ymin=0, ymax=200, color='black')
plt.vlines(1200, ymin=0, ymax=200, color='black')
plt.vlines(1500, ymin=0, ymax=200, color='black')
plt.vlines(1800, ymin=0, ymax=200, color='black')
plt.title('Cabin number')
plt.xlim([0,2000])plt.subplot(3,1,3)
sns.countplot(data=train, x='Cabin_side', hue='Transported')
plt.title('Cabin side')
fig.tight_layout()

image-20240126183134741

注意到Cabin_number被按照300的数量进行划分,每个划分的False与True的高度都不一样。这意味着我们可以压缩这个特征被压缩成一个分类特征,其他注意事项:客舱甲板的“T”似乎是一个异常值(只有5个样本)。

# 新特征-训练集
train['Cabin_region1']=(train['Cabin_number']<300).astype(int)   # 独热编码
train['Cabin_region2']=((train['Cabin_number']>=300) & (train['Cabin_number']<600)).astype(int)
train['Cabin_region3']=((train['Cabin_number']>=600) & (train['Cabin_number']<900)).astype(int)
train['Cabin_region4']=((train['Cabin_number']>=900) & (train['Cabin_number']<1200)).astype(int)
train['Cabin_region5']=((train['Cabin_number']>=1200) & (train['Cabin_number']<1500)).astype(int)
train['Cabin_region6']=((train['Cabin_number']>=1500) & (train['Cabin_number']<1800)).astype(int)
train['Cabin_region7']=(train['Cabin_number']>=1800).astype(int)# 新特征-测试集
test['Cabin_region1']=(test['Cabin_number']<300).astype(int)   # 独热编码
test['Cabin_region2']=((test['Cabin_number']>=300) & (test['Cabin_number']<600)).astype(int)
test['Cabin_region3']=((test['Cabin_number']>=600) & (test['Cabin_number']<900)).astype(int)
test['Cabin_region4']=((test['Cabin_number']>=900) & (test['Cabin_number']<1200)).astype(int)
test['Cabin_region5']=((test['Cabin_number']>=1200) & (test['Cabin_number']<1500)).astype(int)
test['Cabin_region6']=((test['Cabin_number']>=1500) & (test['Cabin_number']<1800)).astype(int)
test['Cabin_region7']=(test['Cabin_number']>=1800).astype(int)# 新特征的分布图
plt.figure(figsize=(10,4))
train['Cabin_regions_plot']=(train['Cabin_region1']+2*train['Cabin_region2']+3*train['Cabin_region3']+4*train['Cabin_region4']+5*train['Cabin_region5']+6*train['Cabin_region6']+7*train['Cabin_region7']).astype(int)
sns.countplot(data=train, x='Cabin_regions_plot', hue='Transported')
plt.title('Cabin regions')
train.drop('Cabin_regions_plot', axis=1, inplace=True)

image-20240126183439865

(4)根据Name的姓氏划分出家庭组

根据形式划分出家庭组,再根据家庭组的大小划分出一个新的二元属性。

# 现在用离群值替换NaN(这样我们就可以拆分特征)
train['Name'].fillna('Unknown Unknown', inplace=True)
test['Name'].fillna('Unknown Unknown', inplace=True)# 新特征-姓氏
train['Surname']=train['Name'].str.split().str[-1]
test['Surname']=test['Name'].str.split().str[-1]# 新特征-家庭大小
train['Family_size']=train['Surname'].map(lambda x: pd.concat([train['Surname'],test['Surname']]).value_counts()[x])
test['Family_size']=test['Surname'].map(lambda x: pd.concat([train['Surname'],test['Surname']]).value_counts()[x])# 把Nan的放回去(我们稍后会填充这些)
train.loc[train['Surname']=='Unknown','Surname']=np.nan
train.loc[train['Family_size']>100,'Family_size']=np.nan
test.loc[test['Surname']=='Unknown','Surname']=np.nan
test.loc[test['Family_size']>100,'Family_size']=np.nan# 删除Name(我们不再需要它了)
train.drop('Name', axis=1, inplace=True)
test.drop('Name', axis=1, inplace=True)# 新特征分布图
plt.figure(figsize=(12,4))
sns.countplot(data=train, x='Family_size', hue='Transported')
plt.title('Family size')

image-20240126183656161

(四)归纳总结

数据分析流程总结

思维导图 (1)

(五)写在最后

至此,我们已经完成了对数据集的初步分析,下一篇我们会对该数据集进行预处理。

Kaggle竞赛系列_SpaceshipTitanic金牌方案分析_数据处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/442566.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图片不能超过200kb怎么修改?30秒学会图片压缩

图片不能超过200kb怎么修改&#xff1f;图片压缩想必大家都经常操作&#xff0c;但是想要把图片压缩指定大小就需要用的一些比较专业的图片处理工具了&#xff0c;市面大多的压缩图片的软件都只有普通的照片缩小kb功能&#xff0c;本文推荐的压缩图网站&#xff0c;不仅支持压缩…

设计模式——职责链模式(Chain of Responsibility Pattern)

概述 职责链模式(Chain of Responsibility Pattern)&#xff1a;避免请求发送者与接收者耦合在一起&#xff0c;让多个对象都有可能接收请求&#xff0c;将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理它为止。职责链模式是一种对象行为…

CSAPP shell lab

CSAPP shell lab shell lab 的目标 实现shell 功能&#xff0c;包括解析命令&#xff0c;调用可执行文件和内置命令&#xff0c;(quit, jobs,fg, 和bg)。实现job控制和signal handler。 shell 介绍 Shell中的作业&#xff08;job&#xff09;管理是一种用于跟踪和控制正在运…

幻兽帕鲁服务器多少钱?服务器租借价格一览表

2024年幻兽帕鲁服务器价格表更新&#xff0c;阿里云、腾讯云和华为云Palworld服务器报价大全&#xff0c;4核16G幻兽帕鲁专用服务器阿里云26元、腾讯云32元、华为云26元&#xff0c;阿腾云atengyun.com分享幻兽帕鲁服务器优惠价格表&#xff0c;多配置报价&#xff1a; 幻兽帕鲁…

blender关于几何接近(geometry proximity)节点的理解

如图&#xff0c;可以见到&#xff0c;我输入了一个立方体&#xff0c;一个圆锥体&#xff0c;为了便于区分 &#xff0c;将原生的立方体与圆锥转为了曲线&#xff0c;而进行了几何接近处理的网格不进行此转换。 几何接近的输入端&#xff0c;分为target&#xff08;目标&…

字符串转换const char* , char*,QByteArray,QString,string相互转换,支持中文

文章目录 1.char * 与 const char * 的转换2.QByteArray 与 char* 的转换3.QString 与 QByteArray 的转换4.QString 与 string 的转换5.QString与const string 的转换6.QString 与 char* 的转换 在开发中&#xff0c;经常会遇到需要将数据类型进行转换的情况&#xff0c;下面依…

渲染案例|《江豚·风时舞》,以动画传递公益价值

1月20日&#xff0c;全国首部围绕濒危物种长江江豚形象打造的地域文化IP动画电影《江豚风时舞》在全国院线正式上映&#xff0c;蓝海创意云作为《江豚风时舞》的渲染服务商之一&#xff0c;为该片提供了大量的离线渲染服务&#xff0c;帮助制片方完成了高质量的视觉效果制作。 …

vs2008配置mysql

1.在官网下载C库&#xff1a;MySQL Connector C 1.0.5 2.在官网下载C库&#xff1a;mysql-connector-c-noinstall-6.0.2-win32 3.vs2008中工程配置 4.拷贝dll到程序运行目录

Unity中使用Ultraleap的Slider组件

Unity中使用Ultraleap的Slider组件&#xff0c;实现物体在指定范围内滑动&#xff1a; 本节在上一节基础上进行&#xff0c;上一小结参考如下&#xff1a; Unity中使用Ultraleap的InteractionButton组件 本节工程文件如下&#xff1a; Unity中使用Ultraleap的Slider组件 1、在…

4个国产AI大模型备案获批,众多科技巨头进入AIGC赛道

北京商报官网消息&#xff0c;第四范式、什么值得买、新壹科技、衔远科技、小米、智联招聘、Boss直聘、脉脉等13家企业的&#xff0c;14个国产AI大模型通过《生成式人工智能服务管理暂行办法》备案&#xff0c;可实现商业化应用。 自2023年8月&#xff0c;文心一言、讯飞星火、…

Linux进程间通信(IPC)机制之一:共享内存

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Nonsense—Sabrina Carpenter 0:50━━━━━━️&#x1f49f;──────── 2:43 &#x1f504; ◀️ ⏸ ▶️ …