Kaggle Titanic 数据分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangrongrongwq/article/details/85848582

拿到数据第一步,查看每个字段的意思

PassengerId

乘客id

Pclass

乘客等级

Name

乘客姓名

Sex

乘客性别

Age

乘客年龄

扫描二维码关注公众号,回复: 4832644 查看本文章

SibSp

乘客堂兄弟/妹个数

Parch

乘客父母/子女个数

Ticket

船票信息

Fare

票价

Cabin

客舱

Embarked

登船港口

Survived

是否获救

从训练集和测试的字段中可以看到训练集中有Survived而测试集中没有该字段,而且该字段是类别字段,所以也可以从这里知道该问题是一个分类问题,而且是二分类。

1.从训练集入手,查看数据信息

print(train_data.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
None

可以看到Age、Cabin、Embarked存在缺失值。

2.简单看一下数值型数据的分布

train_data.describe()

可以看到平均获救比例为0.383838,乘客等级大多为2、3等级,平均年龄为29.699118,平均票价为32.204208

3.看一下单变量分布

train_data.Survived.value_counts()

0    549
1    342
Name: Survived, dtype: int64

有549人未获救,342人获救

train_data.Pclass.value_counts()

3    491
1    216
2    184
Name: Pclass, dtype: int64

等级1的乘客有216人,等级2的乘客有184人,等级3的乘客有491人

train_data.Embarked.value_counts()

S    644
C    168
Q     77
Name: Embarked, dtype: int64

总共有3个登船港口,S港口644个乘客,C港口168个乘客,Q港口77个乘客,其中S港口的乘客人数最多

train_data.Sex.value_counts()

male      577
female    314
Name: Sex, dtype: int64

 男性乘客577人,女性乘客314人

train_data.SibSp.value_counts()

0    608
1    209
2     28
4     18
3     16
8      7
5      5
Name: SibSp, dtype: int64

乘客堂兄弟/妹人数,可以看到有608人都是一个人,占了总人数一大半。单纯想想,如果有堂兄弟妹的话互帮互助hu获取获救的几率高一点。

train_data.Parch.value_counts()

0    678
1    118
2     80
5      5
3      5
4      4
6      1
Name: Parch, dtype: int64

乘客父母/子女人数,可以看到大多乘客是一个人。

对这些数据分布有了大概的认识之后,将每个字段与是否获救联立分析

1.分析乘客等级和是否获救的关系

Survived_0 = train_data.Pclass[train_data.Survived == 0].value_counts()
Survived_1 = train_data.Pclass[train_data.Survived == 1].value_counts()
df = pd.DataFrame({u'survived':Survived_1, u'non_survived':Survived_0})
df.plot(kind='bar', stacked=True,color=['lightcoral','lightgreen']) #为获救赋予绿色,未获救赋予红色
plt.title(u"survived-info")
plt.xlabel(u"passenger-grade")
plt.ylabel(u"sum")
plt.show()

可以看到等级为1的乘客获救的几率最大,这也符合常识,这个特征是有用的。

2.分析性别与是否获救的关系

Survived_sex_0 = train_data.Sex[train_data.Survived == 0].value_counts()
Survived_sex_1 = train_data.Sex[train_data.Survived == 1].value_counts()
df = pd.DataFrame({'survived_sex_0':Survived_sex_0,'survived_sex_1':Survived_sex_1})
df.plot(kind='bar', stacked=True, color=['lightcoral', 'lightgreen'])
plt.title('sex-survived')
plt.xlabel('sex')
plt.ylabel('sum')
plt.show()

可以看到女性乘客获救的几率更大,大概是女士优先这样的原则吧,看电影的时候在营救的过程中确实有这样的体现。性别特征是有用的特征。

3.分析登船港口与是否获救的关系

Survived_embarked_0 = train_data.Embarked[train_data.Survived == 0].value_counts()
Survived_embarked_1 = train_data.Embarked[train_data.Survived == 1].value_counts()
df = pd.DataFrame({'survived_0':Survived_embarked_0, 'survived_1':Survived_embarked_1})
df.plot(kind='bar', stacked=True, color=['lightcoral', 'lightgreen'])
plt.title('survived-embarked')
plt.xlabel('embarked')
plt.ylabel('sum')
plt.show()

可以看到C港口的获救几率最大,该特征是有用的特征。

4.分析乘客等级以及登船港口与是否获救的关系

y1 = train_data[train_data.Survived == 0].groupby(['Embarked', 'Pclass'])['Survived'].count().reset_index()['Survived'].values
y2 = train_data[train_data.Survived == 1].groupby(['Embarked', 'Pclass'])['Survived'].count().reset_index()['Survived'].values
pos = range(9)
ax = plt.figure(figsize=(8, 3)).add_subplot(111)
ax.bar(pos, y1, align='center', alpha=0.5, color='r', label='dead')
ax.bar(pos, y2, align='center', bottom=y1, color='g', label='alive')
ax.set_xticks(pos)
xticks_labels = []
for embarked_val in ['C', 'Q', 'S']:
    for pclass_val in range(1, 4):
        xticks_labels.append('%s/%d'%(embarked_val, pclass_val))
ax.set_xticklabels(xticks_labels, size=15)
ax.legend(fontsize=15, loc='best')
plt.show()

可以看到S港口的乘客等级分布符合常理,应该是属于对什么人都开放;然后Q港口就是穷人聚集;而C港口等级1的乘客最多,应该是对有些人是不开放的,应该是比较高档的港口。另外可以看到C港口的乘客和其他港口的乘客相比更容易获救。根据3和4的分析更能肯定登船港口是个重要特征。

5.分析堂兄弟妹个数与是否获救的关系

survived_sibsp_0 = train_data.SibSp[train_data.Survived == 0].value_counts()
survived_sibsp_1 = train_data.SibSp[train_data.Survived == 1].value_counts()
df = pd.DataFrame({'no_survived':survived_sibsp_0,'survived':survived_sibsp_1})
df.plot(kind='bar', stacked=True, color=['lightcoral', 'lightgreen'])
plt.xlabel('SibSp')
plt.ylabel('sum')
plt.title('SibSp-Survived')
plt.show()

可以看到SibSp越少越容易获救,这个之前的猜想完全相反,很重要的特征。

6.分析父母/子女个数与是否获救的关系

survived_parch_0 = train_data.Parch[train_data.Survived == 0].value_counts()
survived_parch_1 = train_data.Parch[train_data.Survived == 1].value_counts()
df = pd.DataFrame({'no_survived':survived_parch_0,'survived':survived_parch_1})
df.plot(kind='bar', stacked=True, color=['lightcoral', 'lightgreen'])
plt.xlabel('Parch')
plt.ylabel('sum')
plt.title('Parch-Survived')
plt.show()

可以看到Parch越小越容易获救,有用特征。

7.查看Cabin与是否获救的关系

cabin_count = set(train_data.Cabin.values)
print(cabin_count)
print(len(cabin_count))

cabin_S = train_data.Cabin[train_data.Embarked == 'S']
cabin_C = train_data.Cabin[train_data.Embarked == 'C']
cabin_Q = train_data.Cabin[train_data.Embarked == 'Q']
cabin_S_set = list(set(cabin_S.values))
cabin_C_set = list(set(cabin_C.values))
cabin_Q_set = list(set(cabin_Q.values))
ll = [ca for ca in cabin_Q_set if (ca in cabin_S_set) | (ca in cabin_C_set)]
print(ll)

cabin_survived = train_data.Cabin[train_data.Survived == 0]
cabin_non_survied = train_data.Cabin[train_data.Survived == 1]
cabin_survived_list = list(set(cabin_survived))
cabin_non_survived_list = list(set(cabin_non_survied))
print(len(cabin_survived_list), len(cabin_non_survived_list))

cabin_null_survived = train_data.Survived[train_data.Cabin.isnull()]
cabin_notnull_survived = train_data.Survived[train_data.Cabin.notnull()]
print(cabin_null_survived.value_counts())
print(cabin_notnull_survived.value_counts())

首先统计出总共Cabin的取值有148个,数量太多,必须做处理,每个登陆港口的Cabin,发现登陆港口之间的Cabin是有重叠的,所以就不能依据登陆港口来对Cabin进行划分;统计获救与未获救的Cabin,这两组Cabin有重叠,依据实际情况也不能简单的将不重叠的部分依据获救与未获救完全区分;统计Cabin为null和不为null时获救人数和未获救人数,发现Cabin为null时获救几率低于Cabin不为null时,所以在这里将Cabin是否为null设置为0和1.

8.分析年龄与是否获救的关系

plt.scatter(train_data.Age, train_data.Survived)

看起来年龄与是否获救没什么关系

age_1 = train_data.Age[train_data.Pclass == 1]
age_2 = train_data.Age[train_data.Pclass == 2]
age_3 = train_data.Age[train_data.Pclass == 3]
age_1 = age_1[age_1.notnull()]
age_2 = age_2[age_2.notnull()]
age_3 = age_3[age_3.notnull()]
y1 = np.arange(0, len(age_1), 1)
y2 = np.arange(0, len(age_2), 1)
y3 = np.arange(0, len(age_3), 1)
plt.scatter(age_1, y1, color='r')
plt.scatter(age_2, y2, color='g')
plt.scatter(age_3, y3, color='b')

sns.distplot(age_1, color='r')
sns.distplot(age_2, color='b')
sns.distplot(age_3, color='y')
plt.legend(('class1', 'class2', 'class3'), loc='best')

train_data.Age[train_data.Pclass == 1].plot(kind='kde')
train_data.Age[train_data.Pclass == 2].plot(kind='kde')
train_data.Age[train_data.Pclass == 3].plot(kind='kde')
plt.title('age-pclass')
plt.xlabel('age')
plt.ylabel('density')
plt.legend(('class-1', 'class-2', 'class-3'), loc='best')

可以看到等级1的乘客年龄更大,等级2的乘客年龄次之,等级3的年龄最小,等级1的年龄集中在40岁,等级2的年龄集中在30岁,等级3的年龄集中在20岁,这个符合常识。

9.分析票价与是否获救的关系

plt.scatter(train_data.Fare, train_data.Survived)

train_data.Fare[train_data.Survived == 0].plot(kind='kde')
train_data.Fare[train_data.Survived == 1].plot(kind='kde')
plt.xlabel('fare')
plt.ylabel('density')
plt.title('fare-survived')
plt.legend(('survived_0', 'survived_1'), loc='best')

可以看到票价越高越容易获救,是一个有用的字段。

综上所述,删除字段Age、Name、Ticket、PassangerId。剩余字段为Pclass、Sex、SibSp、Parch、Fare、Cabin、Embarked。

Cabin与Embarked存在缺失值。对这两个字段进行处理

1.处理Cabin字段

train_data.Cabin = train_data.Cabin.isnull().astype(int)

2.处理Embarked字段

embarked = train_data[train_data.Embarked.isnull()]
print(embarked)

Embarked只有两个缺失值,都获救,而且都是等级1的乘客,票价也不低,之前分析中港口C最容易获救,但是不能绝对的将其分为港口C,S是乘客最大的并且获救几率也不低以及缺失值只有2个,所以将缺失值填充为S。

train_data.Embarked[train_data.Embarked.isnull()] = 'S'

分析完训练集之后,依据训练集的原则对测试集做处理。

可以看到在测试集中Fare、Cabin存在缺失值,Cabin同训练集处理方式,下面考虑Fare

直观来说,Fare与Pclass、Cabin有关,使用Pclass与Cabin相同的Fare的中位数填充。

fare_null_test = test_data[test_data.Fare.isnull()]
fare_notnull_test = test_data[test_data.Fare.notnull()]
pclass = fare_null_test.Pclass.values
cabin = fare_null_test.Cabin.values
print(pclass, cabin)

fare_test = fare_notnull_test.Fare[(fare_notnull_test.Pclass == 3) & (fare_notnull_test.Cabin.isnull())]
fare = fare_test.values
fare.sort()
print(fare[int(len(fare) / 2)])
test_data.Fare[test_data.Fare.isnull()] = fare[int(len(fare) / 2)]

参考资料https://blog.csdn.net/u011462357/article/details/78708200

猜你喜欢

转载自blog.csdn.net/wangrongrongwq/article/details/85848582