无意间在网易云课堂上找了一个Kaggle案例,泰坦尼克获救船员预测,在此之前我是从没接触过kaggle,毕竟是刚入门的小白,看着视频,算是真正实战了一次,主要是在这个过程中学到了很多东西。 
下面视频地址 
http://study.163.com/course/courseLearn.htm?courseId=1003551009#/learn/video?lessonId=1004052093&courseId=1003551009

还有数据集,是在GitHub里面找的 
https://github.com/fayduan/Kaggle_Titanic 
里面有大佬的ipython 源码,不过我也没仔细去看。还是按照视频上的一步一步下来。 
首先是整体的流程我大概总结了一下。

  1. 拿到数据集分析数据
  2. 找出数据集中每个特征中是否含有缺失值或者异常值,填充缺失值
  3. 将特征中为字符的特征值转换为数值型,比如将性别男女用0和1表示
  4. 分析数据集适合采用什么算法进行预测,比如适合用分类算法还是适合用回归算法
  5. 建立特征工程(这算是整个过程下来最重要的)
  6. K阶交叉验证,划分数据集(k-1份训练,1份验证,每次换一个。重复k次,用来调优),
  7. 将交叉验证后的数据集扔进算法中进行训练及测试准确率。

    接下来代码实现(按照视频教程实现)。 
    1导入数据,进行分析

import pandas as pd
import numpy as np
titanic = pd.read_csv("数据集/titannike/train.csv")
#将数据集中所有的样本特征属性打印出来,每一列的相关数据信息
titanic

2数据预处理

#数据预处理, 填充缺失值以及将特征中含有字符的转换为数值型#将年龄这一列的数据缺失值进行填充
titanic["Age"] = titanic["Age"].fillna(titanic["Age"].median())
#titanic
print(titanic.describe())
#打印这一列特征中的特征值都有哪些
print(titanic["Sex"].unique())
#将性别中的男女设置为0 1 值 把机器学习不能处理的自字符值转换成能处理的数值
#loc定位到哪一行,将titanic['Sex'] == 'male'的样本Sex值改为0
titanic.loc[titanic["Sex"] == "male","Sex"] = 0
titanic.loc[titanic["Sex"] == "female","Sex"] = 1
#print(titanic["Sex"].unique)
#print(titanic["Embarked"].unique())
#通过统计三个登船地点人数最多的填充缺失值
titanic["Embarked"] = titanic["Embarked"].fillna("S")
#将登船地点同样转换成数值
titanic.loc[titanic["Embarked"] == "S","Embarked"] = 0
titanic.loc[titanic["Embarked"] == "C","Embarked"] = 1
titanic.loc[titanic["Embarked"] == "Q","Embarked"] = 2
print(titanic["Embarked"].unique())

3通过线性回归进行预测(拿回归做分类确实有点鸡肋)

import numpy as np#将sklearn中的线性回归的类导入进去,采用二分类进行分类预测
from sklearn.linear_model import LinearRegression
#交叉验证库,将训练集进行切分交叉验证取平均
from sklearn.cross_validation import KFold#这里,人为的先选取部分有用特征
predictors = ["Pclass","Sex","Age","SibSp","Parch","Fare","Embarked"]
#将线性回归方法导进来
alg = LinearRegression()
#将m个样本分成三份 n_folds 代表的是交叉验证划分几层(几份)
kf = KFold(titanic.shape[0],n_folds=3,random_state=1)#该行代码做的是交叉验证predictions = []
for train,test in kf:#将训练数据拿出来,对原始数据取到建立好的特征 然后取出用于训练的那一部分train_predictors = (titanic[predictors].iloc[train,:])#print(train_predictors)#获取到数据集中交叉分类好的标签,即是否活了下来train_target = titanic["Survived"].iloc[train]#print(train_target)#将数据放进去做训练alg.fit(train_predictors,train_target)#训练完后,使用测试集进行测试误差test_predictions = alg.predict(titanic[predictors].iloc[test,:])predictions.append(test_predictions)#使用线性回归得到的结果是在区间[0,1]上的某个值,需要将该值转换成0或1
predictions = np.concatenate(predictions,axis=0)
#print(predictions)
#print(type(titanic["Survived"]))predictions[predictions >.5] = 1
predictions[predictions <=.5] = 0
predictions.dtype = "float64"titanic["Survived"] = titanic["Survived"].astype(float)print("测试数据总数量",len(predictions))
#print("正确的数量:",sum(predictions[predictions == titanic["Survived"]]))
print("正确的数量:",sum(predictions == titanic["Survived"]))
accuracy = sum(predictions == titanic["Survived"]) / len(predictions)print("准确率为:",accuracy)
  • 结果: 

这里有个坑:我按照视频教程一步一部来,结果最后测试准确率竟然只有26%左右,想着是不是predictors里面的数据类型跟实际数据集里面Survived标签不一样,然后我都将类型转换为了float64,结果,没有什么变化,只是从26%提高到了36%,显然主要不是这的原因,最后无意间发现是python2跟python3的语法问题。

#这是Python2的代码
sum(predictions[predictions == titanic["Survived"]])
#在Python3中应该为
sum(predictions == titanic["Survived"])

然后准确率就达到78%左右了, 
显然这个结果并不算好,所以要试一下用其他算法,比如逻辑回归,或者随机森林。(在此还没想到建立特征工程了)

进行下面的步骤之前,我们首先要了解一些参数的意义

random_state作为每次产生随机数的种子作为随机种子对于调参过程是很重要的,如果每次都用不同的随机种子。即使参数值没变,每次出来的结果也会不同,不利于比较不同模型的结果任一个随机样本都有可能导致过度你和,可以用不同的随机样本建模来减少过拟合到的可能
n_estimators定义了需要用到的决策树的数量min_samples_split定义了书中一个节点所需要用来分裂的最少样本数可以避免过拟合,如果用于分类的样本数太小,模型可能只试用于用来训练样本的分类,而用较多的样本数则可以避免这个问题如果设定的值过大,就可能出现欠拟合现象,所以可以用cv值(离散数量)考量调节效果
min_samples_leaf定义了树中终点节点所需要用来分裂的最少样本数同样,可以防止过度拟合不均等分类问题中,一般这个参数需要设定为较小的值。因为大部分少数类别含有的样本都比较小
min_weight_fraction_leaf和上面的min_simples_leaf 很像,,不同的是这个参数需要被设定为较小的值,因为大部分少数类别含有的样本都比较小#2和#3只需要定义一个就行了
max_depth定义和树的最大深度也可以控制过拟合,树越深,越容易过拟合也可以用CV值检验
max_leaf_nodes定义了决策树里最多能有多少个终点节点这个属性可能在上面的max_depth里就被定义了,深度为n的二叉树就有最多2的n次方的终点节点如果定义max_leaf_nodes GBM就会忽略前面的  max_depth
max_features决定了用于分类的特征树,是认为随机定义的根据经验一般选择总特征数的平方根就可以工作的很好,最多可以尝试总特征数的30%-40%

4通过逻辑回归进行预测判断

#通过逻辑回归做分类
from sklearn import cross_validation
from sklearn.linear_model import LogisticRegression
alg = LogisticRegression(random_state = 1)
#使用逻辑回归做交叉验证
score = cross_validation.cross_val_score(alg,titanic[predictors],titanic["Survived"],cv=3)
print(score.mean())
#out  0.787878787879

比用线性回归得分稍微高一点,但是也没搞多少 
5用随机森林模型

#随机森林模型
from sklearn import cross_validation
from sklearn.ensemble import RandomForestClassifier
predictors = ["Pclass","Sex","Age","SibSp","Parch","Fare","Embarked"]#各个参数的意思 n_estimators 表示的是指定随机森林中需要多少的决策树  min_samples_split min_samples_leaf
#   表示的是划分树的控制的结束条件,划分到哪个节点上停止划分。 一个通过样本个数,一个通过叶子节点个数
alg = RandomForestClassifier(random_state=1,n_estimators = 100,min_samples_split=4,min_samples_leaf=2)#依然做三次交叉验证
kf = cross_validation.KFold(titanic.shape[0],n_folds=3,random_state=1)
scores = cross_validation.cross_val_score(alg,titanic[predictors],titanic["Survived"],cv=kf)print(scores.mean())#out  0.814814814815
  • 可以看出,明显比线性回归和逻辑回归得到的分数高很多 
    当然,分数应该还能再高点,因为我们到目前为止还没建立特征工程,特征工程部做好,其实用什么算法,用什么交叉验证都是无用的

6:通过再一次分析数据集,我们可以衍生出来两个特征 
1 通过每个乘客的SibSp 和Parch 亲友人数建立一个家庭大小特征FamilySize 
2用点神学,是不是获救的可能性跟每个乘客的名字或者名字长度有关系 
然后这就衍生出来两个特征 
代码实现

#建立特征工程 根据数据集中已有特征进行特征分析,可以添加相关特征
#将船上所有人的亲属朋友关系加起来,新建一个特征,用来表示每个人的亲属关系
#提取的第一个特征
titanic["FamilySize"] = titanic["SibSp"] + titanic["Parch"]
#提取的第二个特征 根据名字长度
titanic["NameLength"] = titanic["Name"].apply(lambda x:len(x))
titanic


接下来提特征

import re
import pandas as pd
def get_title(name):title_search = re.search(' ([A-Za-z]+)\.',name)if title_search:return title_search.group(1)return ""titles = titanic["Name"].apply(get_title)
print(pd.value_counts(titles))
#将称号转换成数值表示
title_mapping = {"Mr":1,"Miss":2,"Mrs":3,"Master":4,"Dr":5,"Rev":6,"Major":7,"Col":7,"Mlle":8,"Mme":8,"Don":9,"Lady":10,"Countess":10,"Jonkheer":10,"Sir":9,"Capt":7,"Ms":2}for k,v in title_mapping.items():titles[title == k] = vprint(pd.value_counts(titles))
#添加Title特征
titanic["Title"] = titles

7:通过特征选择库,对选择的特征进行进一步筛选,看看哪些特征比较重要

import numpy as np#通过 feature_selection 对选择的特征进行进一步选择,画出保护直方图可以直观的看出哪些特征对最终的准确率影响较大
from sklearn.feature_selection import SelectKBest,f_classif
import matplotlib.pyplot as pltpredictors = ["Pclass","Sex","Age","SibSp","Parch","Fare","Embarked","FamilySize","Title","NameLength"]selector = SelectKBest(f_classif,k=5)
selector.fit(titanic[predictors],titanic["Survived"])scores = -np.log10(selector.pvalues_)plt.bar(range(len(predictors)),scores)plt.xticks(range(len(predictors)),predictors,rotation="vertical")
plt.show()predictors = ["Pclass","Sex","Fare","Title"]
alg = RandomForestClassifier(random_state=1,n_estimators=50,min_samples_split=8,min_samples_leaf=4)#依然做三次交叉验证
kf = cross_validation.KFold(titanic.shape[0],n_folds=3,random_state=1)
scores = cross_validation.cross_val_score(alg,titanic[predictors],titanic["Survived"],cv=kf)print(scores.mean())

同时,我在这里面又加上了随机森林模型,对建立好的特征进行再一次预测 
发现准确率达到了81.9%,比没有建立特征工程的随机森林模型多了大约0.5% 
,果然还是有用的。

最后,将两个算法结合着使用,Boosting和逻辑回归结合使用

from sklearn.ensemble import GradientBoostingClassifier
import numpy as npalgorithms = [[GradientBoostingClassifier(random_state=1,n_estimators=50,max_depth=6),['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked','FamilySize','NameLength','Title']],[LogisticRegression(random_state=1),['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked','FamilySize','NameLength','Title']] ]kf = KFold(titanic.shape[0],n_folds=3,random_state=1)
predictions = []
for train, test in kf:  train_target = titanic['Survived'].iloc[train]  full_test_predictions = []  for alg,predictors in algorithms:        alg.fit(titanic[predictors].iloc[train,:],train_target)    test_prediction = alg.predict_proba(titanic[predictors].iloc[test,:].astype(float))[:,1]  full_test_predictions.append(test_prediction)test_predictions = (full_test_predictions[0] + full_test_predictions[1]) / 2  test_predictions[test_predictions >.5] = 1  test_predictions[test_predictions <=.5] = 0        predictions.append(test_predictions)
predictions = np.concatenate(predictions,axis=0)
accury = sum(predictions == titanic['Survived']) / len(predictions)#测试准确率
print(accury) #out  0.82379349046 

感觉这个结果很不可思议了,因为之前刚写好的时候是81%多点,还没单纯的用随机森林模型预测的准确率高,然后调节了一下参数,准确率达到82.3% 
还算不错,不过还是有提升空间,但是仅通过调参已经不能再提高多少了,,所以就应该从特征工程上下手,将特征重要性排序,重要性不高的特征适当去掉,又或者衍生出更多比较重要的特征,这是提高准确率的最重要的方法。 
另外,在CSDN找到的有关特征工程和k折交叉验证的博客 
机器学习中的特征工程 
http://blog.csdn.net/xiaodongxiexie/article/details/55830550 
K折交叉验证 
http://blog.csdn.net/light_blue_love/article/details/42004041 
以及Kaggle入门系列 
http://m.blog.csdn.net/u013115001/article/details/78012553

Kaggle案例之泰坦尼克船员幸存预测相关推荐

  1. Kaggle案例之泰坦尼克船员幸存预测(sklearn机器学习库)

    无意间在网易云课堂上找了一个Kaggle案例,泰坦尼克获救船员预测,在此之前我是从没接触过kaggle,毕竟是刚入门的小白,看着视频,算是真正实战了一次,主要是在这个过程中学到了很多东西. 下面视频地 ...

  2. 泰坦尼克船员生存预测

    1.任务背景 1.赛题任务 泰坦尼克号的沉没是历史上最为声名狼藉的沉船事件之一.1912 年 4 月 15 日,被广泛认为是"永不沉没的"泰坦尼克号在处女航中与冰山相撞后沉没.不幸 ...

  3. kaggle入门之泰坦尼克幸存预测

    kaggle入门之泰坦尼克幸存预测 # 数据集什么的就不介绍了,官网上都有 主要的工作步骤 1.提出和定义问题 2.获取训练和测试数据 3.获取,准备和清洗数据 4.分析,识别,探究数据 5.建模,预 ...

  4. kaggle竞赛:泰坦尼克幸存者预测

    kaggle竞赛:泰坦尼克幸存者预测--(一) import pandas as pd import numpy as np import matplotlib.pyplot as plt impor ...

  5. 集成算法-随机森林与案例实战-泰坦尼克获救预测

    集成算法-随机森林 Ensemble learning 目的:让机器学习效果更好,单个不行,群殴走起 Bagging:训练多个分类器取平均 f ( x ) = 1 / M ∑ m = 1 M f m ...

  6. Kaggle竞赛——Titanic泰坦尼克之灾(0.76315==>0.79186)

    Kaggle竞赛网址:https://www.kaggle.com/c/titanic 上一章:Kaggle竞赛--Titanic泰坦尼克之灾(保姆级基础版) 本次Kaggle泰坦尼克之灾分析过程大致 ...

  7. 19丨决策树(下):泰坦尼克乘客生存预测

    在前面的两篇文章中,我给你讲了决策树算法.决策树算法是经常使用的数据挖掘算法,这是因为决策树就像一个人脑中的决策模型一样,呈现出来非常直观.基于决策树还诞生了很多数据挖掘算法,比如随机森林(Rando ...

  8. python mean dropna_小丸子踏入python之路:python_day05(用Pandas处理泰坦尼克船员获救数据titanic_train.csv)...

    泰坦尼克船员获救数据: titanic_train.csv 用excel打开数据集.显示如下: 写在前边: 为了方便以后运用numpy和pandas的库,分别造它们的别名np和pd. import p ...

  9. 基于深度学习的泰坦尼克旅客生存预测

    基于深度学习的泰坦尼克旅客生存预测 摘要:近年来,随着深度学习的迅速发展和崛起,尤其在图像分类方向取得了巨大的成就.本文实验基于Windows10系统,仿真软件用的是Anaconda下基于python ...

最新文章

  1. 《自己动手写Docker》书摘之三: Linux UnionFS
  2. boost::shared_lock相关的测试程序
  3. Maven教程(一)
  4. ActiveXObject 安装
  5. ajax返回html页面执行,【提问】ajax请求返回整个html页面
  6. UUID 查看linux的UUID 与 SVN 工程的 UUID。(两者之间没有联系)
  7. 简易效率的抽奖算法(转)
  8. 构造函数SimpleAdapter()
  9. 卷积层、池化层和全连接层 区别和作用
  10. linux 程序 监听端口,linux和windows下如何知道端口是被那个程序监听占用?
  11. c语言单链表怎么循环链表,链表之循环单链表(用C语言描述)
  12. 九款好看的后台管理系统登录模板
  13. Linux 下的Bluetooth 架构
  14. 最优化理论与凸优化的用处
  15. Error: ImageIO: PNG invalid PNG file: iDOT doesn't point to valid IDAT chunk 解决
  16. Linux系统配置(shell函数与数组)
  17. JS纯前端实现卡通人物图片的动态效果
  18. autoApprove
  19. UVA - 1103:Ancient Messages
  20. 网卡链路聚合之team

热门文章

  1. C语言编程对一个逆波兰式进行求值,算式与逆波兰式
  2. C语言编程>第二十五周 ③ 下列给定程序中,函数fun的功能是:根据输入的三个边长(整型值),判断能否构成三角形;构成的是等边三角形,还是等腰三角形。若能构成等边三角形函数返回3,若能构成……
  3. nodemcu的led显示驱动
  4. R语言 数据格式转换1
  5. 微型计算机的由来思维导图,央视专访:思维导图的由来!看发明人博赞先生怎么说~...
  6. python包_3_随机函数— random包
  7. Modbus转OPC UA网关的实现
  8. 短链接生成-短网址生成-短网址生成接口-短网址URL生成-短链接-短链接URL生成接口
  9. CF700E Cool Slogans
  10. 如何通过网关做服务编排?