python 泰坦尼克号存活率分析

本文分析了泰坦尼克号乘客数据,探究了存活率与乘客等级、性别、亲朋人数、船票费用等因素的关系,并通过数据清理、特征工程处理缺失值,如用众数填充类别特征,用年龄平均值填充年龄。创建新特征如'IsAlong',将分类特征转化为数值,离散化连续特征如年龄和票价。应用多种机器学习模型如逻辑回归、SVM、决策树、随机森林和KNN进行预测,最后选择了决策树模型进行预测并输出预测结果。
摘要由CSDN通过智能技术生成

对泰坦尼克号的数据 进行特征分析、数据清理、数据填充、处理分类特征、将连续特征转化为离散特征、合并特征、制作模型、模型预测

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#将警告不显示
import warnings
warnings.filterwarnings('ignore')

#导入测试集和训练集
train_df=pd.read_csv('train.csv')
# train_df.head()
test_df=pd.read_csv('test.csv')
combine=[train_df,test_df]

PassengerId=test_df['PassengerId']#因为后续会将该列删除 所以先对这一列数据进行备份

特征分析
分析存活率与几个因素之间的关系

#pclass与survived的关系
train_df[['Pclass','Survived']].groupby(['Pclass'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#Sex与survived的关系
train_df[['Sex','Survived']].groupby(['Sex'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#SibSp与Survived的关系
train_df[['SibSp','Survived']].groupby(['SibSp'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#Parch与Survived的关系
train_df[['Parch','Survived']].groupby(['Parch'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#Embarked与Survived的关系
train_df[['Embarked','Survived']].groupby(['Embarked'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#绘制年龄与死亡率、存活率的条形图
fig=plt.figure(figsize=(12,8))

ax1=fig.add_subplot(1,2,1)
ax2=fig.add_subplot(1,2,2)

age1=train_df.Age[train_df['Survived']==0]
age2=train_df.Age[train_df['Survived']==1]

ax1.set_title('Survived=0')
ax1.hist(age1,bins=20)
ax1.set_xlabel('age')
ax1.set_yticks([10,20,30,40,50,60])

ax2.set_title('Survived=1')
ax2.hist(age2,bins=20)
ax2.set_xlabel('age')
ax2.set_yticks([10,20,30,40,50,60])
#定义同一规格的y轴 方便查看死亡与存货的区别

plt.show()

在这里插入图片描述

#fare和Survived 绘制图像
fare=train_df.Fare[train_df['Survived']==1]
plt.hist(fare)
plt.show()

在这里插入图片描述
数据清理

#删除无用特征
train_df=train_df.drop(['Ticket','Cabin'],axis=1)
test_df=test_df.drop(['Ticket','Cabin'],axis=1)
combine=[train_df,test_df]
train_df.head()
#创建新特征

train_df.Name.str.extract(' ([a-zA-Z]+)\.',expand=False)
#通过正则表达式 将姓名中与性别有关的称呼截取出来 创建为新的特征

for database in combine:
    database['Title']=database.Name.str.extract(' ([a-zA-Z]+)\.',expand=False)
    
pd.crosstab(train_df['Title'],train_df['Sex'])
#crosstab 交叉提取列 两个参数(列,行)

在这里插入图片描述

#分类title 归为几个大类
for database in combine:
    database['Title']=database['Title'].replace(['Lady','Countess','Capt','Col','Don','Dr','Major','Rev','Sir','Jonkheer','Dona'],'Rare')
    #将出现次数少的归类为Rare一类
    database['Title']=database['Title'].replace('Mlle','Miss')
    #将表达为同一意思的称呼归为一类
    database['Title']=database['Title'].replace('Ms','Miss')
    database['Title']=database['Title'].replace('Mme','Mrs')
#replace函数 两个参数(被替换内容,替换后内容)    

train_df[['Title','Survived']].groupby(['Title'],as_index=False).mean().sort_values(by='Survived',ascending=False)

在这里插入图片描述

#删除无用两列数据
train_df.drop(['PassengerId','Name'],axis=1,inplace=True)
test_df.drop(['PassengerId','Name'],axis=1,inplace=True)
combine=[train_df,test_df]
train_df

数据填充

#快速查找缺失值
train_df.info()

在这里插入图片描述
从图中会发现 Age 和 Embarked 都有缺失值

#填充Embarked特征(缺失值较少 利用众数进行填充)
freq=train_df.Embarked.dropna().mode()[0]  
#mode 显示数量最多的数

for database in combine:
    database.Embarked=database.Embarked.fillna(freq)
#填充Age(缺失值较多 不可以用众数填充 需通过其他特征填充值)
grp = train_df.groupby(['Pclass','Sex','Title'])['Age'].mean().reset_index()

#定义一个新函数 填充缺失值
def fill_age(x):
    return grp[(grp['Pclass']==x['Pclass']) & (grp['Sex']==x['Sex']) & (grp['Title']==x['Title'])].Age.values[0]
    #如果缺失值的三个条件满足平均的三个条件,即填充对应的Age值

#用lambda 定义另一个简单的新的函数 判断Age值是否缺失
train_df['Age'] = train_df.apply(lambda x: fill_age(x) if np.isnan(x['Age']) else x['Age'] ,axis=1)
test_df['Age'] = test_df.apply(lambda x: fill_age(x) if np.isnan(x['Age']) else x['Age'] ,axis=1)
combine = [train_df,test_df]

处理分类特征
将数据根据分类转化为数字 0.1.2.3…

#处理sex 将数据转化为1和0
for database in combine:
    database['Sex'] = database['Sex'].map({'female':1,'male':0}).astype(int)
#处理Title
title_mapping = {'Mr':1 ,'Miss':2 ,'Mrs':3 ,'Master':4 ,'Rare':5}
for database in combine:
    database['Title'] = database['Title'].map(title_mapping).astype(int)

在这里插入图片描述
将连续特征转化为离散特征
将连续的数据 分为几组\几类

#处理Age离散化

#将age分为五组 准确分组
train_df['AgeBand'] =pd.cut(train_df['Age'],5)
train_df['AgeBand']

在这里插入图片描述
通过切割数据 可以将Age准确的分为五个组 并将不同组用1.2.3.4.5代替

for database in combine:
    database.loc[ database['Age'] <16,'Age']=0
    database.loc[(database['Age'] >=16)&(database['Age'] <32),'Age']=1
    database.loc[(database['Age'] >=32)&(database['Age'] <48),'Age']=2
    database.loc[(database['Age'] >=48)&(database['Age'] <64),'Age']=3
    database.loc[ database['Age'] >=64,'Age']=4
    
train_df.drop(['AgeBand'],axis=1,inplace=True)
combine=[train_df,test_df]
train_df

利用qcut处理Fare的数据

#处理Fare (不可用cut均分的方法 使用qcut 根据数量均等分)
train_df['FareBand']=pd.qcut(train_df['Fare'],4,duplicates='drop')

#处理test_df中的缺失值(因为缺失1个,所以选择平均值填充)
test_df['Fare'] = test_df['Fare'].fillna(test_df['Fare'].mean())

for dataset in combine:
    dataset.loc[ dataset['Fare'] <=7.91,'Fare']=0
    dataset.loc[(dataset['Fare'] >7.91)&(dataset['Fare'] <=14.454),'Fare']=1
    dataset.loc[(dataset['Fare'] >14.454)&(dataset['Fare'] <=31),'Fare']=2
    dataset.loc[dataset['Fare'] >31,'Fare']=3
    dataset['Fare'] = dataset['Fare'].astype(int)

train_df.drop(['FareBand'],axis=1,inplace=True)
combine=[train_df,test_df]
train_df

在这里插入图片描述

合并特征

将SibSp(兄弟姐妹配偶)和Parch(父母)两组数据合并为一组Family
后借助family判断是否为一个人出行IsAlong

for database in combine:
    database['Family']=database['SibSp'] + database['Parch'] + 1
    
# train_df.head()

for database in combine:
    database['IsAlong']=1
    database.loc[database['Family']>1,'IsAlong']=0
    
train_df.drop(['SibSp','Parch','Family'],inplace=True,axis=1)
test_df.drop(['SibSp','Parch','Family'],inplace=True,axis=1)

train_df

在这里插入图片描述
制作模型

#选择变量
X_train = train_df.drop('Survived',axis=1)
Y_train = train_df['Survived']
#逻辑回归模型
from sklearn.linear_model import LogisticRegression

logreg = LogisticRegression()#实例化 调用
logreg.fit(X_train,Y_train)#fit拟合模型
Y_pred = logreg.predict(test_df)#利用predict进行预测
acc_log = round(logreg.score(X_train,Y_train)*100)#round函数--四舍五入 保留两位小数

#支持向量机 SVC
from sklearn.svm import SVC

svc = SVC()
svc.fit(X_train,Y_train)
Y_prd = svc.predict(test_df)
acc_svc = round(svc.score(X_train,Y_train)*100,2)

#决策树
from sklearn.tree import DecisionTreeClassifier

decision_tree = DecisionTreeClassifier()
decision_tree.fit(X_train,Y_train)
Y_pred = decision_tree.predict(test_df)
acc_decision_tree = round(decision_tree.score(X_train,Y_train)*100,2)

#随机森林
from sklearn.ensemble import RandomForestClassifier

random_forest = RandomForestClassifier()
random_forest.fit(X_train,Y_train)
Y_pred = random_forest.predict(test_df)
acc_random_forest = round(random_forest.score(X_train,Y_train)*100,2)

#K阶近邻
from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier()
knn.fit(X_train,Y_train)
Y_pred = knn.predict(test_df)
acc_knn = round(knn.score(X_train,Y_train)*100,2)

#朴素贝叶斯
from sklearn.naive_bayes import GaussianNB

gaussian = GaussianNB()
gaussian.fit(X_train,Y_train)
Y_pred = gaussian.predict(test_df)
acc_gaussian = round(gaussian.score(X_train,Y_train)*100,2)

将模型根据评分进行排名

models = pd.DataFrame({  #采用字典
    'Modle':['Logistic Regression','Support Vector Machines','KNN','Naive Bayes','Decision Tree','Random Forest'],
    'Score':[acc_log,acc_svc,acc_knn,acc_gaussian,acc_decision_tree,acc_random_forest]
})
models.sort_values(by='Score',ascending=False)

在这里插入图片描述
模型预测
有以上模型的排名情况 可选择决策树对数据进行预测

#决策树
from sklearn.tree import DecisionTreeClassifier

decision_tree = DecisionTreeClassifier()
decision_tree.fit(X_train,Y_train)
Y_pred = decision_tree.predict(test_df)
acc_decision_tree = round(decision_tree.score(X_train,Y_train)*100,2)

#定义一个新的变量 为预测后的值
submission = pd.DataFrame({
    'PassengerId':PassengerId,
    'Survived':Y_pred
})

#将结果输出为文件
submission.to_csv('submission.csv',index=False)
submission

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值