泰坦尼克号幸存者预测

目录

数据集

1、分析需求

 2、探索性数据分析(EDA)

性别:是离散型变量

 Age:连续型变量

Fare:票价,连续型变量,可以使用箱线图或者小提琴图看分布

Pclass

Embarked:离散型变量

3、特征工程

特征抽取

 抽取 Title 特征

 抽取家庭规模

缺失值填充

Age:根据 Sex、Pclass 和 Title 分组,如果落在相同的组别里,就用这个组别的中位数填充

Fare:缺失值较多,使用平均值填充。(本人水平不够,先略过)

​编辑

​编辑

​编辑

离散型变量处理成独热编码

​编辑

​编辑

​编辑

4、模型训练与评估

 数据集

测试数据集

https://download.csdn.net/download/llf000000/86732641

训练数据集

https://download.csdn.net/download/llf000000/86732643

1、分析需求

1.os.listdir()

描述

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
只支持在 Unix, Windows 下使用

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns
import os
print(os.listdir(r"C:\Users\10596\课程作业\泰坦尼克号"))

 

没加“r”之前,出现这样的报错

SyntaxError: (unicode error) ‘unicodeescape‘ codec can‘t decode bytes in position 2-3: truncated \UX

问题点:python中\是转义的也是,必须去掉转义
方法一:加r强制不转义可写为:
fd = os.open(r"C:\Users\eric\Desktop\python\foot.txt", os.O_RDWR|os.O_CREAT )
方法二:加
fd = os.open(“C:\Users\eric\Desktop\python\foot.txt”, os.O_RDWR|os.O_CREAT )
方法三:正斜杠法/
fd = os.open(“C:/Users/eric/Desktop/python/foot.txt”, os.O_RDWR|os.O_CREAT )

data_train = pd.read_csv("train.csv")
data_test = pd.read_csv("test.csv")
data_train.head()

data_test.head()

data_train.shape, data_test.shape

data_train.info()

data_test.info()

data_train.describe()

data_test.describe()

 2、探索性数据分析(EDA)

性别:是离散型变量

 参数说明:
x: x轴上的条形图,以x标签划分统计个数

y:y轴上的条形图,以y标签划分统计个数

hue:在x或y标签划分的同时,再以hue标签划分统计个数

data:df或array或array列表,用于绘图的数据集,x或y缺失时,data参数为数据集,同时x或y不可缺少,必须要有其中一个

palette:使用不同的调色板

 

 

color = {0: 'r', 1: 'g'}
sns.countplot(data=data_train,x='Sex', hue='Survived', palette=color)
plt.show()

 下面这一步是创建列联表,然后进行卡方检验,以检测“性别是否幸存是否有影响

scipy.stats

scipy.stats 是 scipy 专门用于统计的函数库,所有的统计函数都位于子包 scipy.stats 中,可以使用 scipy.info(scipy.stats) 函数获得这些函数的完整列表。

 

 

sex_survived_pivot_table = pd.pivot_table(
 data_train,
 index='Sex',
 columns='Survived',
 values='PassengerId',
 aggfunc='count')
sex_survived_pivot_table

from scipy.stats import chi2_contingency
chi2_contingency(sex_survived_pivot_table.values)[1]

 

 

可以看到p值为1.1973570627755645e − 58,远小于0.05,因此“性别 幸存 的确不是独立的, 性别” 是一项预测 是否幸存 的重要特征。

 Age:连续型变量

fig, axes = plt.subplots(nrows=1, ncols=2)
fig.set_size_inches(18, 6)
data_train[data_train['Survived'] == 1]['Age'].hist(color='g', ax=axes[0])
axes[0].set_title('Survived Age hist', size=18)
data_train[data_train['Survived'] == 0]['Age'].hist(color='r', ax=axes[1])
axes[1].set_title('Died Age hist', size=18)
plt.show()

set_size_inches设置

plt.figure().set_size_inches(6,8)#6,8分别对应宽和高

 可以看出,年轻人幸存较多

Fare:票价,连续型变量,可以使用箱线图或者小提琴图看分布

sns.boxplot( data=data_train,x="Survived", y="Fare", palette={0: 'r', 1: 'g'})
plt.show()

 fig,ax = plt.subplots()等价于:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
fig, ax = plt.subplots(1,3),其中参数1和3分别代表子图的行数和列数,一共有 1x3 个子图像。函数返回一个figure图像和子图ax的array列表。
fig, ax = plt.subplots(1,3,1),最后一个参数1代表第一个子图。
如果想要设置子图的宽度和高度可以在函数内加入figsize值
fig, ax = plt.subplots(1,3,figsize=(15,7)),这样就会有1行3个15x7大小的子图。

我们准备区间化两组数据:第一组是被救上来的人的船票价格,第二组是没被救上来的船票价格。都需要DataFrame格式。这就用到之前对DateFrame的选择了,还用到了布尔下标:

s1=train[train['Survived']==1]['Fare']
s2=train[train['Survived']==0]['Fare']
注意,布尔下标不能直接是'Survived'==1,要把train加上。

这样我们就分别得到了两组数据。

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(18, 8))
sns.distplot(data_train[data_train['Survived'] == 1]['Fare'], color='g', ax=axes[0])
sns.distplot(data_train[data_train['Survived'] == 0]['Fare'], color='r', ax=axes[1])
plt.show()

plt.figure(figsize=(18, 8))
sns.distplot(data_train[data_train['Survived'] == 1]['Fare'], color='g')
sns.distplot(data_train[data_train['Survived'] == 0]['Fare'], color='r')
plt.show()

 可以看出,票价比较低的,遇难的人数比较多,因此票价是一个重要的特征。

Pclass

color = {0: 'r', 1: 'g'}
sns.countplot(x='Pclass', hue='Survived', palette=color, data=data_train)
plt.show()

可以看到, 号乘客等级幸存者较多, 号乘客等级死亡比幸存多很多,因此乘客等级是一个预测是否幸存的重要变量。下面使用卡方检验,验证我们的想法。
pclass_survived_pivot_table = pd.pivot_table(
 data_train,
 index='Pclass',
 columns='Survived',
 values=['PassengerId'],
 aggfunc='count')
pclass_survived_pivot_table

chi2_contingency(pclass_survived_pivot_table.values)[1]

plt.figure(figsize=(18, 6))
sns.boxplot(x='Pclass', y='Fare', data=data_train, hue='Survived', palette=color)
plt.show()

 乘客等级为 1 的,票价相对较高。

Embarked:离散型变量

data_train['Embarked'].unique()

     在处理数据中,如果希望查看列中的去重之后的不同值或者唯一值,这可以使用 Pandasunique()函数来完成。Python的Pandas库Series.unique方法会返回Series中的唯一值。这些值是按照出现顺序排序的,它返回一个 NumPy 数组。

sns.countplot(x='Embarked', hue='Survived', palette=color, data=data_train)
plt.show()

 S 登船港口罹难者多,C 登船港口幸存者多。

plt.figure(figsize=(18, 6))
sns.boxplot(
 x='Embarked', y='Fare', data=data_train, hue='Survived', palette=color)
plt.show()

embarked_survived_pivot_table = pd.pivot_table(
 data=data_train,
 index='Embarked',
 columns='Survived',
 values='PassengerId',
 aggfunc='count')
embarked_survived_pivot_table

chi2_contingency(embarked_survived_pivot_table.values)[1]

 

3、特征工程

data_train.head()

data_test.head()

把目标变量(target)和 ID 拿出来。
        目标变量用于训练数据;
        ID 用于提交结果时使用。

pandas 中 inplace 参数在很多函数中都会有,它的作用是:是否在原对象基础上进行修改

​ inplace = True:不创建新的对象,直接对原始对象进行修改;

​ inplace = False:对数据进行修改,创建并返回新的对象承载其修改结果。

默认是False,即创建新的对象进行修改,原对象不变,和深复制和浅复制有些类似。

 

y = data_train.Survived
PassengerId = data_test.PassengerId
data_train.drop(['Survived'], axis=1, inplace=True)
合在一起,一般不这么做,因为测试数据集很可能是随时来的
combined = pd.concat([data_train, data_test], sort=False, axis=0)
combined.shape

combined.drop(['PassengerId'], inplace=True, axis=1)
combined.shape

特征抽取

 抽取 Title 特征

combined['title'] = combined['Name'].map(
 lambda x: x.split(',')[1].split('.')[0].strip())
  • map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如map(lambda x: x+1, [1, 2,3])将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。

1、strip()方法
strip() 方法用于移除字符串头尾指定的字符(默认为空格)。
strip()方法语法:

str.strip([c])
c指的是字符串头尾指定的字符

str = "FFF I am a zhulang FFF";
print str.strip( 'FFF' );
输出:I am a student

2、split()方法
split()方法通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串
split()方法语法:

str.split(str="", num=string.count(str)).

参数:
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。

str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );
输出:
[‘Line1-abcdef’, ‘Line2-abc’, ‘Line4-abcd’]
[‘Line1-abcdef’, ‘\nLine2-abc \nLine4-abcd’]

combined['title'].value_counts()

# 再根据这些 title 细分,是官员,还是皇室,还是女士、先生、小姐
combined['title'].unique()

Title_Dictionary = {
 "Mr": "Mr",
 "Mrs": "Mrs",
 "Miss": "Miss",
 "Master": "Master",
 "Don": "Royalty",
 "Rev": "Officer",
 "Dr": "Officer",
 "Mme": "Mrs",
 "Ms": "Mrs",
 "Major": "Officer",
 "Lady": "Royalty",
 "Sir": "Royalty",
 "Mlle": "Miss",
 "Col": "Officer",
 "Capt": "Officer",
 "the Countess": "Royalty",
 "Jonkheer": "Royalty",
 "Dona": 'Mrs'
}
combined['Title'] = combined['title'].map(Title_Dictionary)
combined['Title'].value_counts()

del combined['Name']
del combined['title']
combined.head()

 抽取家庭规模

 

combined['FamilySize'] = combined['SibSp'] + combined['Parch'] + 1
print(combined['FamilySize'].head())

def deal_with_family_size(num):
     if num == 1:
         return 'Singleton'
     elif num <= 4:
         return 'SmallFamily'
     elif num >= 5:
         return 'LargeFamily'
     return num
combined['FamilySize'] = combined['FamilySize'].map(deal_with_family_size)

缺失值填充

Age:根据 SexPclass Title 分组,如果落在相同的组别里,就用这个组别的中位数填充

combined.isnull().sum()

 根据 SexPclass Title 分组,如果落在相同的组别里,就用这个组别的平均数填充。

combined.groupby(['Sex', 'Pclass', 'Title'])['Age'].mean()

age_group_mean = combined.groupby(['Sex', 'Pclass', 'Title'])['Age'].mean().reset_index()
age_group_mean

def select_group_age_median(row):
     condition = ((row['Sex'] == age_group_mean['Sex']) &
                 (row['Pclass'] == age_group_mean['Pclass']) &
                 (row['Title'] == age_group_mean['Title']))
     return age_group_mean[condition]['Age'].values[0]
# 针对每一行做映射,所以要加上 `axis=1`
combined['Age'] = combined.apply(
 lambda x: select_group_age_median(x) if np.isnan(x['Age']) else x['Age'],
 axis=1)
combined['age_bin'].head()

Fare:缺失值较多,使用平均值填充。(本人水平不够,先略过)

combined.isnull().sum()

combined['Fare'].fillna(combined['Fare'].mean(), inplace=True)
combined['Embarked'].fillna(combined['Embarked'].mode(), inplace=True)
combined.head()

combined.loc[combined['Cabin'].notnull(), 'Cabin'] = 'yes'
combined.loc[combined['Cabin'].isnull(), 'Cabin'] = 'no'
combined['Cabin'].value_counts()

离散型变量处理成独热编码

处理成独热编码以后,要把原始变量删掉。
combined.head()

combined = pd.get_dummies(
     combined,
     columns=[
     'Sex', 'Cabin', 'Pclass', 'Embarked', 'Title', 'FamilySize', 'age_bin'
     ],
     drop_first=True)
combined.drop(['Ticket'], axis=1, inplace=True)
X_train = combined.iloc[:891]
X_test = combined.iloc[891:]
X_train.head()

X_test.head()

4、模型训练与评估

from sklearn.ensemble import RandomForestClassifier#随机森林分类
rfc = RandomForestClassifier(n_estimators=100, max_features='sqrt')
from sklearn.model_selection import cross_val_score
scores = cross_val_score(rfc, X_train, y, cv=10)
scores

scores.mean()

 

rfc.fit(X_train, y)

 

rfc.feature_importances_

X_train.columns

feature_importances = pd.Series(rfc.feature_importances_, X_train.columns)
feature_importances.sort_values(ascending=False, inplace=True)
feature_importances

feature_importances.plot(kind='barh')#kind='barch'(水平柱状图)即可生成柱状图
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值