通过Kaggle上的入门项目,建立模型,预测生存概率。
1.提出问题
什么样的人在泰坦尼克号中更容易存活?
2.理解数据
2.1 采集数据
从kaggle下载数据
2.2 导入数据
*#忽略警告提示*``**import**`` warnings warnings``**.**``filterwarnings('ignore') ``*#导入处理数据包*``**import**`` numpy ``**as**`` np ``**import**`` pandas ``**as**`` pd ``*#导入数据*``*#训练数据集*``train``**=**``pd``**.**``read_csv('./train.csv') ``*#测试数据集*``test``**=**``pd``**.**``read_csv('./test.csv') ``**print**``('训练数据集:',train``**.**``shape,'测试数据集:',test``**.**``shape) rowNum_train``**=**``train``**.**``shape[0] rowNum_test``**=**``test``**.**``shape[0] ``**print**``('训练数据集行数:',rowNum_train, '测试数据集行数:',rowNum_test) ``*#合并数据集,方便同时对两个数据集进行清洗*``full``**=**``train``**.**``append(test,ignore_index``**=**``True) ``**print**``('合并后的数据集:',full``**.**``shape)

2.3 查看数据集信息
*#查看数据*``full``**.**``head() full``**.**``describe() ``*#查看数据类型,总和*``full``**.**``info()

查看数据开头


查看数据总和可以看出,数据总和有1309行。
-
有缺失数据的数据类型列:Age(年龄),Fare(船票价格)
-
有缺失数据的字符串列:Embarked(登船港口),Cabin(船舱号),Survived(存活)
3.数据清洗(Data Preparation)
3.1 数据预处理
缺失值处理
机器学习算法为了训练模型,要求特征中不能有空值。下面是处理方法:
-
如果是数值类型,用平均值取代
-
如果是分类数据,用最常见的类别取代
-
使用模型预测缺失值,例如:K-NN
`#处理数据类型列:Age, Fare**print**(‘处理前:’)
full**.**info()
*#Age(年龄)*full[‘Age’]**=**full[‘Age’]**.**fillna(full[‘Age’]**.**mean())
*#Fare(船票价格)*full[‘Fare’]**=**full[‘Fare’]**.**fillna(full[‘Fare’]**.**mean())
**print**(‘处理后:’)
full**.**info()
*#检查数据处理是否正常*full**.**head()
'''
处理字符串列:
- Embarked(登船港口)只缺失2条数据,用最常见的数据取代
- Cabin(船舱号)缺失1014条数据
'''
*#Embarked:查看数据信息*''' 简称如下: 出发地点:S=英国 南安普顿Southampton 途径地点1:C=法国 瑟堡市Cherbourg 途径地点2:Q=爱尔兰 昆士敦Queestown ''' full[‘Embarked’]**.**head()*#分类变量Embarked用最常见的变量填充*full[‘Embarked’]**.**value_counts()*#从计数结果来看,S类别最多,进行填充*full[‘Embarked’]**=**full[‘Embarked’]**.**fillna(‘S’)*#Cabin(船舱号):查看数据信息*full[‘Cabin’]**.**head()*#缺失数据较多,用U来填充,表示未知(Unknown)*full[‘Cabin’]**=**full[‘Cabin’]**.**fillna(‘U’)*#检查数据集是否正常*full**.**head()*#查看缺失值处理情况,Survived(生存情况生存情况)是标签,用于机器学习预测,不用处理*full**.**info()`





3.2 特征提取
3.2.1 数据分类
查看数据类型,分为三种。对类别数据处理,用数值代替类别,并进行ont-hot编码
- 数值类型:乘客编号(PassengerId),年龄(Age),船票价格(Fare),同代直系亲属人数(SibSp),不同代直系亲属人数(Parch)
- 时间序列:无
- 分类数据:
- 3.1 有直接类别:
- 乘客性别(Sex):男性male,女性female
- 登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
- 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱
- 3.2 字符串类型:
- 乘客姓名(Name)
- 客舱号(Cabin)
- 船票编号(Ticket)
full``**.**``info()

3.2.1 分类数据:有直接类别
- 乘客性别(Sex): 男性male,女性female
- 登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
- 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱 性别
*#查看性别数据*``full['Sex']``**.**``head() ``*#将性别的值映射为数值:male-1,female-0*``sex_mapDict``**=**``{'male':1, 'female':0} ``*#用map函数,对Series每个数据应用自定义的函数计算*``full['Sex']``**=**``full['Sex']``**.**``map(sex_mapDict) full``**.**``head()

登船港口(Embarked)
*#查看数据内容*``full['Embarked']``**.**``head() ``*#存放提取后的特征*``embarkedDf``**=**``pd``**.**``DataFrame() ``*#用get_dummies进行one-hot编码,产生虚拟变量(dummy variables),前缀是embarked*``embarkedDf``**=**``pd``**.**``get_dummies(full['Embarked'],prefix``**=**``'Embarked') embarkedDf``**.**``head() ``*#添加one-hot产生的虚拟变量到数据集full*``full``**=**``pd``**.**``concat([full,embarkedDf],axis``**=**``1) full``**.**``drop('Embarked',axis``**=**``1,inplace``**=**``True) full``**.**``head()


客舱等级
*#存放提取后的特征*``pclassDf``**=**``pd``**.**``DataFrame() ``*#使用get_dummies进行Ont-hot编码,前缀是Pclass*``pclassDf``**=**``pd``**.**``get_dummies(full['Pclass'],prefix``**=**``'Pclass') pclassDf``**.**``head() ``*#添加one-hot编码产生的虚拟变量到数据集full*``full``**=**``pd``**.**``concat([full,pclassDf],axis``**=**``1) ``*#删除客舱等级(Pclass)列*``full``**.**``drop('Pclass',axis``**=**``1,inplace``**=**``True) full``**.**``head()


3.2.1 分类数据:字符串类型
- 乘客姓名(Name)
- 客舱号(Cabin)
- 船票编号(Ticket) 从姓名中提取头衔
*#可以把乘客的头衔提取出来形成一个新的变量,查看内容*``full['Name']``**.**``head() ``*#以逗号为分隔符,利用split进行分列*``name1``**=**``'Braund, Mr. Owen Harris' str1``**=**``name1``**.**``split(',')[1] ``*#以圆点进行拆分*``str2``**=**``str1``**.**``split('.')[0] ``*#用strip移除字符串头尾指定的字符(默认是空格)*``str3``**=**``str2``**.**``strip() str3 ``*#定义函数,从姓名中提取头衔*``**def**`` ``**getTitle**``(name): str1``**=**``name``**.**``split(',')[1] str2``**=**``str1``**.**``split('.')[0] str3``**=**``str2``**.**``strip() ``**return**`` str3 ``*#存放提取后的特征*``titleDf``**=**``pd``**.**``DataFrame() ``*#map函数:对Series每个数据应用自定义函数计算*``titleDf['Title']``**=**``full['Name']``**.**``map(getTitle) titleDf``**.**``head() ''' 定义以下几种头衔类别: Officer政府官员 Royalty王室(皇室) Mr已婚男士 Mrs已婚妇女 Miss年轻未婚女子 Master有技能的人/教师 ''' ``*#姓名中头衔字符串与定义头衔类别的映射关系*``title_mapDict ``**=**`` { "Capt": "Officer", "Col": "Officer", "Major": "Officer", "Jonkheer": "Royalty", "Don": "Royalty", "Sir" : "Royalty", "Dr": "Officer", "Rev": "Officer", "the Countess":"Royalty", "Dona": "Royalty", "Mme": "Mrs", "Mlle": "Miss", "Ms": "Mrs", "Mr" : "Mr", "Mrs" : "Mrs", "Miss" : "Miss", "Master" : "Master", "Lady" : "Royalty" } ``*#map函数*``titleDf['Title']``**=**``titleDf['Title']``**.**``map(title_mapDict) ``*#get_dummies进行One-hot编码*``titleDf``**=**``pd``**.**``get_dummies(titleDf['Title']) titleDf``**.**``head() ``*#添加one-hot编码产生的虚拟变量到数据集full*``full``**=**``pd``**.**``concat([full,titleDf],axis``**=**``1) ``*#删除姓名列*``full``**.**``drop('Name',axis``**=**``1,inplace``**=**``True) full``**.**``head()


从客舱号中提取客舱类别
*#匿名函数:lambda 参数1,参数2:函数体或表达式*``*#定义匿名函数:对两个数相加*``sum``**=**``**lambda**`` a,b: a``**+**``b ``*#调用sum函数*``**print**``('相加后',sum(10,20)) ``*#客舱号的首字母是客舱的类别,查看内容*``full['Cabin']``**.**``head() ``*#存放客舱号信息*``cabinDf``**=**``pd``**.**``DataFrame() full['Cabin']``**=**``full['Cabin']``**.**``map(``**lambda**`` c:c[0]) ``*#one hot 编码*``cabinDf``**=**``pd``**.**``get_dummies(full['Cabin'],prefix``**=**``'Cabin') cabinDf``**.**``head() ``*#将one-hot产生的虚拟变量添加到数据集full*``full``**=**``pd``**.**``concat([full,cabinDf],axis``**=**``1) ``*#删除客舱号列*``full``**.**``drop('Cabin',axis``**=**``1,inplace``**=**``True) full``**.**``head()


建立家庭人数和家庭类别
*#存放家庭信息*``familyDf``**=**``pd``**.**``DataFrame() ``*#家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己*``familyDf['FamilySize']``**=**``full['Parch']``**+**``full['SibSp']``**+**``1 ''' 家庭类别: 小家庭Family_Single:家庭人数=1 中等家庭Family_Small: 2<=家庭人数<=4 大家庭Family_Large: 家庭人数>=5 ''' ``*#if条件为真的时候返回前面内容,否则返回0*``familyDf['Family_Single']``**=**``familyDf['FamilySize']``**.**``map(``**lambda**`` s:1 ``**if**`` s``**==**``1 ``**else**`` 0) familyDf['Family_Small']``**=**``familyDf['FamilySize']``**.**``map(``**lambda**`` s:1 ``**if**`` 2``**<=**``s``**<=**``4 ``**else**`` 0) familyDf['Family_Large']``**=**``familyDf['FamilySize']``**.**``map(``**lambda**`` s:1 ``**if**`` 5``**>=**``s ``**else**`` 0) familyDf``**.**``head() ``*#添加One-hot编码产生的虚拟变量到数据集full*``full``**=**``pd``**.**``concat([full,familyDf],axis``**=**``1) full``**.**``head() ``**print**``('到目前为至的特征值:',full``**.**``shape)


3.3 特征选择
相关系数法:计算各特征的相关系数
*#相关性矩阵*``corrDf``**=**``full``**.**``corr() corrDf ``*#查看各个特征与生成情况(Survived的相关系数*``corrDf['Survived']``**.**``sort_values(ascending``**=**``False)




根据各个特征与生成情况(Survived)的相关系数大小,选择以下特征作为模型的输入:
头衔(前面所在的数据集titleDf)、客舱等级(pclassDf)、家庭大小(familyDf)、船票价格(Fare)、船舱号(cabinDf)、登船港口(embarkedDf)、性别(Sex)
*#特征选择*``full_X``**=**``pd``**.**``concat([titleDf,pclassDf,familyDf,full['Fare'],cabinDf,embarkedDf,full['Sex']],axis``**=**``1) full_X``**.**``head()

4. 构建模型
4.1 建立训练数据集和测试数据集
*#原始数据集有891行*``sourceRow``**=**``891 ``*#因为行号从0开始,需要减去1*``*#原始数据集:特征*``source_X``**=**``full_X``**.**``loc[0:sourceRow``**-**``1,:] ``*#原始数据集:标签*``source_y``**=**``full``**.**``loc[0:sourceRow``**-**``1,'Survived'] ``*#预测数据集:特征*``pred_X``**=**``full_X``**.**``loc[sourceRow:,:] ``*#原始数据集有多少行*``**print**``('原始数据集有多少行:',source_X``**.**``shape[0]) ``*#预测数据集大小*``**print**``('原始数据集有多少行:',pred_X``**.**``shape[0]) ``**from**`` sklearn.cross_validation ``**import**`` train_test_split ``*#建立模型用的训练数据集和测试数据集*``train_X,test_X,train_y,test_y``**=**``train_test_split(source_X,source_y,train_size``**=.**``8) ``*#输出数据集大小*``**print**``('原始数据集特征:',source_X``**.**``shape, '训练数据集特征:',train_X``**.**``shape, '测试数据集特征',test_X``**.**``shape) ``**print**``('原始数据集标签:',source_y``**.**``shape, '训练数据集标签:',train_y``**.**``shape, '测试数据集标签:',test_y``**.**``shape) ``*#原始数据查看*``source_y``**.**``head()

4.2 选择机器学习算法
选择机器学习算法,用于训练模型。新手可以从逻辑回归开始。
*#第1步:导入算法*``**from**`` sklearn.linear_model ``**import**`` LogisticRegression ``*#第2步:创建模型:逻辑回归*``model``**=**``LogisticRegression()

4.3 训练模型
*#第3步:训练模型*``model``**.**``fit(train_X,train_y)

5. 评估模型
*#分类问题,score得到的是模型的正确率*``model``**.**``score(test_X,test_y)

6. 方案实施
6.1 得到预测结果上传Kaggle
*#对预测数据集中的生存情况进行预测*``pred_Y``**=**``model``**.**``predict(pred_X) ``*#转把浮点数转换成整型*``Pred_Y``**=**``pred_Y``**.**``astype(int) ``*#乘客ID*``passenger_id``**=**``full``**.**``loc[sourceRow:,'PassengerId'] ``*#数据框:乘客id,预测生存情况的值*``predDf``**=**``pd``**.**``DataFrame({'PassengerId':passenger_id, 'Survived':pred_Y}) predDf``**.**``shape predDf``**.**``head() ``*#保存结果*``predDf``**.**``to_csv('titanic_pred.csv',index``**=**``False)