题目来自:Titanic
参考资料来自:An Interactive Data Science Tutorial
Titanic 生存预测比赛是一个二分类问题,根据乘客的信息来判断是否在沉船事故中存活了下来。
首先还是导入必要的库:
1 | # Ignore warnings |
其次是一些用于绘图的功能性函数:
1 | def plot_histograms( df , variables , n_rows , n_cols ): |
训练集与测试集
接下来就是导入训练集和测试集了,以及对两个数据集进行了合并,以便于后面进行数据分析,特征工程等:
1 | train_data = pd.read_csv('train.csv') |
输出:
full: (1309, 12) ;titanic: (891, 12)
数据分析
使用full.head()可以查看前几个数据的样式,如下所示:
使用titanic.info可以获取训练集每个column数据信息:
使用test_data.info可以获取测试集每个column数据信息:
关于各个column的信息如下:
Age:年龄,有中等数量的缺失
cabin:座舱号,有大量的缺失
Embarked:登船口,在训练集中有很少量的缺失(2个),包括C,Q,S三种
Fare:乘客的票价,在测试集中有很少量的缺失(1个)
Name:姓名
Parch:乘客的父母和孩子的个数
PassengerId: 自增数值,无意义
Pclass:票的等级,有三级:1,2,3
Sex:性别,male和female
SibSp:乘客的兄弟和配偶的个数
Survived:是否存活,0 = No, 1 = Yes
ticket:票的编号
绘制相关性的heat map,可能可以知道哪些变量是很重要的
1 | plot_correlation_map(titanic) |
输出如下图:
接下来绘制一些特征与存活与否之间的关系
首先是Age,Sex与Survived关系图:
1 | plot_distribution(titanic , var = 'Age' , target = 'Survived' , row = 'Sex') |
输出如下图:
两个线差别较大的地方,代表了更好的区分度。可以看到年龄小的男性更多的存活,中等年龄的男性更多的死亡
Fare和Survived的关系图:
1 | plot_distribution(titanic , var = 'Fare' , target = 'Survived' ) |
输出如下图:
可以看到,低票价有着更高的死亡率
接下来看Embarked与Survived的关系:
1 | print(titanic.Embarked.value_counts()) |
输出:
S 644
C 168
Q 77
Name: Embarked, dtype: int64
可以看到S的数目是最多的,但是存活率是最低的
再看Sex与Survived的关系:
1 | print(titanic.Sex.value_counts()) |
输出:
male 577
female 314
Name: Sex, dtype: int64
可以看到女性人数少,但是有着绝对的更大的存活率。
对于Pclass与Survived的关系
1 | print(titanic.Pclass.value_counts()) |
输出:
3 491
1 216
2 184
Name: Pclass, dtype: int64
等级1人最少,却有着最多的存活率,等级3人最多,却是最少的存活率
对于SibSp和Parch两个数据,可以进行求和,并分成0和不为0两类
1 | titanic['Family_All'] = titanic['SibSp'] + titanic['Parch'] |
输出:
0 537
1 354
Name: Family_All, dtype: int64
可以看到为0的,存活率相较于不为0的,是要低很多的
大致的通过图表分析过后,对原始数据进行些处理。
首先是将sex的male和female转为1和0
1 | my_sex = pd.DataFrame() |
Embarked数据存在极少量的缺失,这里打算用最多的‘S’来填补,再使用pd.get_dummies来将多个变量转为one_hot编码
1 | my_embarked = pd.DataFrame() |
输出:
对于Pclass,没有缺失值,只需要转为one_hot即可
1 | my_pclass = pd.DataFrame() |
对于Fare,由于在测试集中有一个缺失值,所以可以采用平均数的方法来填补该缺失值,并且可以对Fare进行区间划分,并转为one_hot
1 | my_fare = pd.DataFrame() |
对于Age,缺失值较多,可以根据已有数据的平均值和标准差随机生成填充数,并进行区间划分,转为one_hot
1 | my_age = pd.DataFrame() |
根据Name中的内容可以生成title,并转为one_hot
1 | title = pd.DataFrame() |
输出:
对于Parch和SibSp,合并为Family_All
1 | my_family = pd.DataFrame() |
Cabin的缺失值过多,先暂时舍弃
ticket也先舍弃
开始训练
将刚才处理过的数据进行一个综合,并生成训练集和测试集
1 | full_X = pd.concat( [my_family, title, my_age, my_embarked, my_fare, my_pclass, my_sex] , axis=1 ) |
选择模型,并进行5折交叉验证
1 | from sklearn.model_selection import cross_val_score |
输出:
0.8215596071618176
最后进行训练与预测
1 | model.fit( train_X , train_y ) |
最后上传到kaggle的成绩是0.78947,排在Top32%