参加了Kaggle的Getting Started Competition体验一下参赛流程。在此记录一下赛题思路和Python实现代码。
题目信息
赛题原址:Titanic: Machine Learning from Disaster
Kaggle-Getting Started Prediction Competition
Titanic: Machine Learning from Disaster
It is your job to predict if a passenger survived the sinking of the Titanic or not.
For each in the test set, you must predict a 0 or 1 value for the variable.
1 数据概况
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
csv_data = pd.read_csv("C:\\Users\\rinnki\\Desktop\\train.csv")
df_train=pd.DataFrame(csv_data)#转换成dataframe格式
print(df_train.head)
#瞧瞧训练集里存活和死亡比例再看看缺失值情况
df_train_pclass = df_train.groupby('Pclass')
countF1Sum = df_train_pclass['Survived'].count()
countF1T = pd.DataFrame(countF1Sum)
print(df_train.isnull().sum())
缺失值情况如下:
[891 rows x 12 columns]>
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
可知Age内有部分缺失,可稍后考虑填充方式。Cabin缺失值较多,可以考虑舍弃该特征或者从其中提取信息使用。Embarked缺失值很少,可以考虑使用众数填充。
接下来再来看看数据中各特征对应的存活情况,写个出图的函数:
def quickBarh(string_name):
df_train1 = df_train.groupby(string_name)
countF1E = df_train1['Survived'].apply(pd.value_counts)
countF1S = countF1E.unstack() #unstack方法救命
#print(countF1S)
countF1S.plot.barh(stacked=True, alpha=0.5) #为了方便直接用pandas的barh方法了
查看一下无需复杂缺失值处理和特征提取的数据分布,如‘Pclass’、‘Sex’、‘SibSp’、‘Parch’和‘Embarked’。
quickBarh('Pclass')
quickBarh('Sex')
quickBarh('SibSp')
quickBarh('Parch')
quickBarh('Embarked')
舱位应该和泰坦尼克号乘客存活有很大关系,可以看到训练集中各舱乘客数3>1>2,但存活比例1>2>3,与电影情节一致,舱位高的客人可能有优先权逃离并且较早获得沉船的消息。
性别应该也和乘客存活有很大关系,虽然训练集中男性乘客较多,但女性存活比例大,有可能是男性遵循传统让女士先上救生艇或是带孩子的女士优先逃离。
看起来是兄弟姐妹越少存活比例越大。
看起来是亲族越少存活比例越高。
登舱人数S>C>Q,存活人数S>C>Q,存活比例C>S>Q。
接下来处理一些需要提取特征或者填充缺失值的特征来观看它们的数据分布。
Name:
姓名乍一看上去对结果没什么影响,但其实里边蕴含着乘客的身份信息,提取这些信息也是feature engineering的一步,就像Kaggle官方给的hint一样:‘We can at least extract the title from the name,reduce them all to Mrs,Miss, Mr and Master.’
def substrings_in_string(big_string, substrings):
for substring in substrings:
if big_string.find(substring) != -1:
return substring
print(big_string)
return np.nan #没有头衔的乘客就返回nan
title_list=['Mrs', 'Mr', 'Master', 'Miss', 'Major', 'Rev',
'Dr', 'Ms', 'Mlle','Col', 'Capt', 'Mme', 'Countess',
'Don', 'Jonkheer'] #这些个就是我们要提取的身份信息了
#新建一列显示乘客头衔身份的特征
df_train['Title']=df_train['Name'].map(lambda x: substrings_in_string(x, title_list))
#replacing all titles with mr, mrs, miss, master--统一拼写/等级同化
def replace_titles(x):
title=x['Title']
if title in ['Don', 'Major', 'Capt', 'Jonkheer', 'Rev', 'Col']:
return 'Mr'
elif title in ['Countess', 'Mme']:
return 'Mrs'
elif title in ['Mlle', 'Ms']:
return 'Miss'
elif title =='Dr':
if x['Sex']=='Male':
return 'Mr'
else:
return 'Mrs'
else:
return title
df_train['Title'] = df_train.apply(replace_titles, axis=1) #更新头衔列
quickBarh('Title')
头衔为Mr.的乘客人数最多,但可以看出Mrs和Miss的存活比例明显高于其他头衔。
年龄:
Age这个特征有较多缺失值,考虑填补年龄的方法会比较好。接下来以如下填补原则进行缺失值填充:统计title为Mrs, Miss, Mr, Master, nan,而Age不为空的乘客的平均年龄,以对应title将年龄补上。
进行完缺失值填充之后,将其分段作图初步查看年龄分布及存活情况。
def replaceNanAge(x):
title = x['Title']
Age = x['Age']