泰坦尼克号幸存者预测

泰坦尼克号幸存者预测_第1张图片
泰坦尼克号的沉没是世界上最严重的海滩事故之一,通过模型来预测哪些人可能成为幸存者。

1、导入基本所需的库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
plt.style.use('fivethirtyeight')

import warnings
warnings.filterwarnings('ignore')

2、导入数据集,探索数据

data = pd.read_csv('train.csv')
data.head()

离散型的变量有:Survived,Sex 和 Embarked。基于序列的有:Pclass
连续型的数值特征有:Age,Fare。离散型数值有:SibSp,Parch
混合型变量:Ticket和Cabin
Name的特征可能包含错误或者打字错误

data.isnull().sum()

这些特征包含null值的数量大小为:Cabin > Age > Embarked

data.info()

有7个特征是int型或float 型
有5个特征是object类型

#数值型特征的数值分布
data.describe()

#离散型数据的分布
data.describe(include=['object'])
# 标签比例 获救比例情况
f,ax = plt.subplots(1,2,figsize=(10,6))
data['Survived'].value_counts().plot.pie(explode=[0,0.1],
                                        autopct='%1.1f%%',
                                        ax=ax[0],shadow=True)
ax[0].set_title('Survived')

sns.countplot('Survived',data=data,ax=ax[1])

3、特征分析

# 标签比例 获救比例情况
f,ax = plt.subplots(1,2,figsize=(10,6))
data['Survived'].value_counts().plot.pie(explode=[0,0.1],
                                        autopct='%1.1f%%',
                                        ax=ax[0],shadow=True)
ax[0].set_title('Survived')

sns.countplot('Survived',data=data,ax=ax[1])

泰坦尼克号幸存者预测_第2张图片

# 不同性别下存活人数
data.groupby(['Sex','Survived'])['Survived'].count()

sns.countplot('Sex',hue='Survived',data=data)

泰坦尼克号幸存者预测_第3张图片
男人的人数多,但是女人存活率更高

# Pclass和获救之间的关系
pd.crosstab(data.Pclass,data.Survived,margins=True).style.background_gradient(cmap='GnBu_r')

sns.countplot('Pclass',hue='Survived',data=data)

泰坦尼克号幸存者预测_第4张图片
观察到Pclass=1生存率高

#数值型特征age与Survived之间的联系
g = sns.FacetGrid(data, col='Survived')
g.map(plt.hist, 'Age', bins=20)
plt.show()

泰坦尼克号幸存者预测_第5张图片
婴儿(Age<=4)有较高的生存率(20个bin,每个bin为4岁)
老人(Age=80)全部生还
大量的15-25年纪的乘客没有生还
乘客主要在15-35的年纪范围内

#不同性别下不同船舱存活情况
pd.crosstab([data.Sex,data.Survived],data.Pclass,margins=True)  #pclass在纵轴

sns.factorplot('Pclass','Survived',hue='Sex',data=data)  #三维数据压成二维画图

泰坦尼克号幸存者预测_第6张图片
女性乘客相对于男性乘客有着更高的存活率
pclass=1 存活率更高

#分析不同embarked港口和船舱等级
sns.countplot('Embarked',hue='Pclass',data=data)

泰坦尼克号幸存者预测_第7张图片

#查看Embarked(离散非数值型),Sex(离散非数值型),Fare(连续数值型)与Survived(离散数值型)之间的关系
grid = sns.FacetGrid(data, row='Embarked', col='Survived', size=2.2, aspect=1.6)
grid.map(sns.barplot, 'Sex', 'Fare', order=data.Sex.unique(),alpha=.5, ci=None)
grid.add_legend()
plt.show()

付了高票价的乘客有着更高的生存率
Embarked与生存率相关

5、缺失值填充

# 通过提取name中的称谓对应age的区间,来填补age缺失值
data['initial'] = data.Name.str.extract('([A-Za-z]+)\.')   #正则表达式提取
data['initial']

pd.crosstab(data.initial,data.Sex).T

#人数很少的称谓都替换成other
re=[]
for i in data.initial.values:
    if i!='Master' and i!='Miss' and i!='Mr' and i!='Mrs':
        re.append(i.replace(i,'other'))
    else:
        re.append(i)
        
#称谓和存活的关系
sns.countplot('re',hue='Survived',data=data)

#计算每一个称谓所对应的的年龄的均值
data.groupby('re')['Age'].mean()
#用循环实现将年龄的均值转化为整数并且填补
for i in data.re.values:
    data.loc[(data.Age.isnull())&(data.re==i),'Age']=int(data.groupby('re')['Age'].mean()[i])
#检查是否填充完毕
data.Age.isnull().sum()
#填补Embarked 用众数填
data['Embarked'].fillna('S',inplace=True)

6、数据预处理

#Age离散化
data['Age_band']=0
data.loc[data['Age']<=16,'Age_band']=0
data.loc[(data['Age']>16)&(data['Age']<=32),'Age_band']=1
data.loc[(data['Age']>32)&(data['Age']<=48),'Age_band']=2
data.loc[(data['Age']>48)&(data['Age']<=65),'Age_band']=3
data.loc[data['Age']>65,'Age_band']=4
data.head(1)
#将类别 数值化Sex、Embarked、re
from sklearn import preprocessing   #导入数据预处理模块

lbl = preprocessing.LabelEncoder()           #标签编码 实例化
data['Sex']=lbl.fit_transform(data['Sex'])  
data['Embarked']=lbl.fit_transform(data['Embarked'])
data['re']=lbl.fit_transform(data['re'])
#港口无大小关系,但编码后有大小关系,需要处理(哑变量)
data['Embarked'].unique()

one_hot=preprocessing.OneHotEncoder(sparse=False)    #独热编码 实例化 sparse=false不会升维
data['Embarked']=one_hot.fit_transform(data[['Embarked']])  #使用独热编码  必须是数值类型,字符类型不能直接做。其中必须 fit 二维数据,因此data两层中括号
#组合Parch和SibSp特征,创建一个新的FamilySize特征
data['FamilySize'] = data['SibSp'] + data['Parch'] + 1

data[['FamilySize', 'Survived']].groupby(['FamilySize'], as_index=False).mean().sort_values(by='Survived', ascending=False)

#创建另一个名为IsAlone的特征
data['IsAlone'] = 0
data.loc[data['FamilySize'] == 1, 'IsAlone'] = 1

data[['IsAlone', 'Survived']].groupby(['IsAlone'], as_index=False).mean()

一个人存活率低

#将Fare分段
data['FareBand'] = pd.qcut(data['Fare'], 4)
data[['FareBand', 'Survived']].groupby(['FareBand'], as_index=False).mean().sort_values(by='FareBand', ascending=True)

#分段后的特征FareBand,将Fare转换为有序的数值型特征
lbl = preprocessing.LabelEncoder()  
data['FareBand']=lbl.fit_transform(data['FareBand'])
data['Age_band*Class'] = data.Age_band * data.Pclass

data.loc[:, ['Age_band*Class', 'Age_band', 'Pclass']].head(10)
#删除无用列
data.drop(['PassengerId','Name','Age','Ticket','Fare','Cabin','initial','FamilySize','SibSp','Parch'],axis=1,
         inplace=True)

泰坦尼克号幸存者预测_第8张图片
7、Survived与其他特征之间的相关性

# 相关性热图
sns.heatmap(data.corr(),annot=True,linewidths=0.2,cmap='summer_r')  #data.corr()返回相关性的值
fig = plt.gcf()           #建立画布
fig.set_size_inches(8,6)  #画布尺寸

泰坦尼克号幸存者预测_第9张图片
8、建模
现在对算法的需求是:有监督学习加上分类与回归

from sklearn.neighbors import KNeighborsClassifier                      #knn算法
from sklearn.tree import DecisionTreeClassifier                         #决策树
from sklearn.naive_bayes import GaussianNB                              #高斯贝叶斯
from sklearn.linear_model import LogisticRegression                     #逻辑回归
from sklearn.ensemble import RandomForestClassifier                     #随机森林

from sklearn.model_selection import train_test_split                    #划分数据集
X = data.iloc[:,data.columns!='Survived']
y = data.iloc[:,data.columns=='Survived']

Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.2,
                                           random_state=10)

逻辑回归

# 逻辑回归
logreg = LogisticRegression()
logreg.fit(Xtrain, Ytrain)
Y_pred = logreg.predict(Xtest)
acc_log = round(logreg.score(Xtrain, Ytrain) * 100, 2)
acc_log    

#77.67

KNN

score=[]

for i in list(range(1,11)):
    KNN = KNeighborsClassifier(n_neighbors=i)
    CVS = cross_val_score(KNN,Xtrain,Ytrain,cv=5)   #交叉验证
    score.append(CVS.mean())
    
plt.plot([*range(1,11)],score)  # *range 激活成列表
fig = plt.gcf()
fig.set_size_inches(12,6)

#最优k=7
knn = KNeighborsClassifier(n_neighbors = 7)
knn.fit(Xtrain, Ytrain)
Y_pred = knn.predict(Xtest)
acc_knn = round(knn.score(Xtrain, Ytrain) * 100, 2)
acc_knn

#82.58

朴素贝叶斯

gaussian = GaussianNB()
gaussian.fit(Xtrain, Ytrain)
Y_pred = gaussian.predict(Xtest)
acc_gaussian = round(gaussian.score(Xtrain, Ytrain) * 100, 2)
acc_gaussian

#73.6

决策树

#网格搜索
from sklearn.model_selection import GridSearchCV

# 设置可选参数
param_grid = {
     'criterion':['entropy','gini'],
             'max_depth':range(2,10),
             'min_samples_leaf':range(1,10),
             'min_samples_split':range(2,10)}
# 设置网格
GR = GridSearchCV(DecisionTreeClassifier(),param_grid,cv=5)

# 建模
GR.fit(Xtrain,Ytrain)

# 输出接口  最优的取值
GR.best_params_

#{'criterion': 'entropy', 'max_depth': 8, 'min_samples_leaf': 3,'min_samples_split': 9}
decision_tree = DecisionTreeClassifier(criterion='entropy',max_depth=8,
                            min_samples_leaf=3,min_samples_split=9).fit(Xtrain,Ytrain)
decision_tree.fit(Xtrain, Ytrain)
Y_pred = decision_tree.predict(Xtest)
acc_decision_tree = round(decision_tree.score(Xtrain, Ytrain) * 100, 2)
acc_decision_tree

#84.13

使用决策树的算法使得正确率达到了一个更高的值

#特征重要性可视化
decision_tree.feature_importances_   
pd.Series(decision_tree.feature_importances_,X.columns).sort_values(ascending=True).plot.barh(width=0.8)

泰坦尼克号幸存者预测_第10张图片

随机森林

random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(Xtrain, Ytrain)
Y_pred = random_forest.predict(Xtest)
acc_random_forest = round(random_forest.score(Xtrain, Ytrain) * 100, 2)
acc_random_forest

#85.96

9、模型评价


models = pd.DataFrame({
     
    'Model': [ 'KNN','Logistic Regression','GaussianNB',
              'Random Forest','Decision Tree'],
    'Score': [acc_knn,acc_log,acc_gaussian,
              acc_random_forest,acc_decision_tree]})

models.sort_values(by='Score', ascending=False)

泰坦尼克号幸存者预测_第11张图片
其中决策树与随机森林的正确率最高,但是我们在这里会选择随机森林算法,因为它相对于决策树来说,弥补了决策树有可能过拟合的问题。

你可能感兴趣的:(数据分析,机器学习,数据挖掘)