前言:

泰坦尼克号数据集,是kaggle竞赛(Titanic: Machine Learning from Disaster)上入门机器学习(ML)的一个高质量的可选数据集,我们可以用这个数据集实践我们的机器学习知识,熟悉数据分析“数据获取→数据清洗→特征工程→建模分析→网格调参(超参数)→数据可视化”这个流程中每个环节。

探索的问题:

探寻泰坦尼克号上乘客的生还率和各个因素如(客舱等级、年龄、性别、上船港口等)的关系。

数据导入

在数据分析中,当拿到一个数据集后,第一步是观察数据的内容和质量。观察数据集中的缺失值,异常值等,对数据集进行数据清洗。csv格式的数据,直接利用pandas的IO函数pd.read_csv()读取数据。

#先导入需要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#配置jupyter notebook
%matplotlib inline
%config InlineBackend.figure_format = "retina"
#导入数据
titanic_df = pd.read_csv('D:/titanic/train.csv',encoding='utf8')

数据观察

数据读取工作完成后,可以开始对数据进行简单的预览。预览内容主要包括了解数据表的大小,字段的名称,数据格式等等。为后续的数据处理工作做准备。观察到数据主要有12列字段,891行,可以看到Age和Cabin字段有较多缺失值,Embanked字段有2个缺失值,数据类型为:float64(2), int64(5), object(5)。这时我们可以查看数据集前五行

titanic_df.head())#查看前五行数据

titanic_df.isnull.sum()#观察整个数据集缺失值的个数

数据清洗

缺失值

经过前面的数据观察,我们知道有三列数据有空值:Age,Cabin,Embarked,其中Cabin这列数据,缺失值太多,基本无价值(不能用此数据分析出 Cabin 不同对生存率的影响),因此真正需要我们处理的就是Age(数值型数据),Embarked(分类型数据)。

对于数值型数据,常用该列的数据的均值或者中位数进行替换,对于分类型数据,可利用该列数据的出现频数最多的数据(众数)来填充。

1.数值型数据缺失值处理

#Age列处理
经过多次比较,分组计算不同舱位男女年龄的中位数,然后再进行填充的表现比较出色。
age_median_psex = titanic_df.groupby(["Pclass","Sex"]).Age.median()#分组计算不同舱位男女年龄的中位数
titanic_df.set_index(["Pclass","Sex"],inplace=True)#设置Pclass, Sex为索引, inplace=True表示在原数据titanic_df上直接进行修改
titanic_df.Age.fillna(age_median_psex,inplace=True)#用fillna填充缺失值,根据索引值填充
titanic_df.reset_index(inplace=True)#重置索引,取消Sex,Pclass索引
titanic_df.Age.describe()# 查看Age列的描述性统计值

2.分类型数据缺失值处理

#Embarked列处理
embarked=titanic_df.groupby("Embarked").count()
embarked
titanic_df.fillna({"Embarked":"S"},inplace=True)
非数值变量数值化
把机器学习不能处理的自字符值转换成能处理的数值
(1)Sex列处理
#titanic_df["Sex"].unique()
#将性别中的男女设置为0 1 值 把机器学习不能处理的自字符值转换成能处理的数值
#loc定位到哪一行,将titanic['Sex'] == 'male'的样本Sex值改为0
titanic_df.loc[titanic_df['Sex'] == 'male','Sex'] = 0
titanic_df.loc[titanic_df['Sex'] == 'female','Sex'] = 1
print(titanic_df["Sex"].head())
(2)港口列处理:S-0, C-1, Q-2
#同上进行数值化处理
titanic_df.loc[titanic_df['Embarked']=='S','Embarked']=0
titanic_df.loc[titanic_df['Embarked']=='C','Embarked']=1
titanic_df.loc[titanic_df['Embarked']=='Q','Embarked']=2
特征提取
predictors=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
特征工程
(1)FamilySize = SibSp + ParCh
titanic_df['FamilySize']=titanic_df['SibSp']+titanic_df['Parch']
(2)NameLength = len (Name)
titanic['Namelength']=titanic['Name'].apply(lambda x:len(x)) #匿名函数,允许快速定义单行函数
(3)Titles 列定义 一些特殊的称号如:miss / doctor / professor......
import re #re 模块使 Python 语言拥有全部的正则表达式功能。
def get_title(name):
title_search=re.search(' ([A-Za-z]+)\.',name)
#提取出的title有这么多种,而且都是文字信息,为了便于分析,要将其映射到数值,可采用批量的方法:
title_mapping={'Mr':1,'Miss':2,'Mrs':3,'Master':4,'Dr':5,'Rev':6,'Major':7,'Mlle':7,'Col':7,'Jonkheer':8,'Capt':8,'Don':8,'Mme':8,'Sir':8,'Lady':8,'Ms':8,'Countess':8}
for k,v in title_mapping.items():
titles[titles==k]=v
print(pd.value_counts(titles))
titanic_df['Titles']=titles
扫描整个字符串并返回第一个#成功的匹配。name是要进行检索的,前面是要匹配的
if title_search:
return title_search.group(1) #查看匹配的情况
return ""
titles=titanic_df['Name'].apply(get_title)
print(pd.value_counts(titles))
建模分析
# 逻辑回归
from sklearn import cross_validation
#该模块最新版本已废弃
from sklearn.linear_model import LogisticRegression
predictors=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
alg=LogisticRegression(random_state=1)
scores = cross_validation.cross_valscore(alg, titanic_df[predictors], titanic_df['Survived'], cv=10)
print(scores.mean()) #结果为0.7901234567901234
#随机森林
from sklearn import cross_validation
from sklearn.ensemble import RandomForestClassifier
predictors=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked'] #用于预测的项
#n_estimators 森林中树的数目
rf_alg=RandomForestClassifier(random_state=1, n_estimators=50, 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(rf_alg,titanic[predictors],titanic['Survived'],cv=kf)
print(scores)#结果[0.78114478 0.82491582 0.84175084]
print(scores.mean()) #取平均值0.8159371492704826
上述两模型相比后者平均分数有所提高,说明后者预测更准
网格调参
from sklearn.model_selection import GridSearchCV
param={"random_state":[0.1,0.3,1,3,10]}
gc=GridSearchCV(alg,param_grid=param,cv=10)
数据可视化
from sklearn.feature_selection import SelectKBest, f_classif
import matplotlib.pyplot as plt
predictors2=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked','FamilySize','Namelength']
selector=SelectKBest(f_classif,k=5)#选择5个特征
# Get the raw p-values for each feature, and transform from p-values into scores
selector.fit(titanic_df[predictors2],titanic_df['Survived'])
scores=-np.log10(selector.pvalues_)
plt.bar(range(len(predictors2)),scores)
plt.xticks(range(len(predictors2)),predictors2,rotation='vertical')
plt.show()

小结

1.在该项目中我综合分析了逻辑回归与随机森林,相比较而言后者预测更准,准确率达到

0.8159371492704826。

2.多模型的应用与融合及新特征的构建有助于提高模型的准确率。