决策树和随机森林实例——泰坦尼克号存活问题

1、背景介绍

大家都看过电影泰坦尼克号,是历史上一件家喻户晓的灾难性事件;泰坦尼克号沉船事故,1912年,当时属于英国的世界级豪华客轮泰坦尼克号,因在处女航行中不幸撞上北大西洋冰山而沉没。这场事故使得1500多名乘客患难。后来,这场震惊世界的惨剧被详细地调查,而且遇难乘客的信息也逐渐被披露。在当时救援条件下,无法短时间内确认每位乘客生还的可能性。而今,许多科学家视图通过计算机模拟和分析找出潜藏在数据背后的生还逻辑。我们也尝试通过代码,揭开尘封了100多年的数据的面纱。

数据简介

在这里插入图片描述

任务目标

任务:预测泰坦尼克号乘客能否存活 预测模型 分类问题

2、导入模块和数据

from sklearn.tree import export_graphviz
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
from sklearn.metrics import classification_report
import seaborn as sns
import numpy as np
# 导入测试集数据和训练集数据
train_df = pd.read_csv('mytrain.csv')
test_df = pd.read_csv('mytest.csv')
# 导入测试集答案
test_y = pd.read_csv('mygender.csv')
test_y = test_y[['Survived']]
train_df

在这里插入图片描述

# 合并训练集合测试集的数据,drop无用的特征
all_df = train_df.append(test_df, ignore_index=True)
all_df.drop(['Unnamed: 12', 'Unnamed: 11'], axis=1, inplace=True)
all_df.info()

在这里插入图片描述

3、 描述性分析:分析各个特征跟存活率之间的关系

# 查看各个特征和存活之间的关系
# 'Embarked' 和 'Survived'的关系
sns.barplot(data=train_df, x='Embarked', y='Survived')

# 从以下图可以看出,Embarked为"C"的乘客存活率较高

在这里插入图片描述

# 进一步探究不同Embarked与所属仓位的关系
sns.catplot(x='Pclass', col='Embarked', data=train_df, kind='count')

# Embarked=S 的 1等座乘客所占比例最多

在这里插入图片描述

# Parch与Survived
sns.barplot(data=train_df, x='Parch', y='Survived')

# 同行乘客中父母及子女的数量为1-3人的存活率较高

在这里插入图片描述

# SibSp与Survived
sns.barplot(data=train_df, x='SibSp', y='Survived')
# 与乘客同行的同辈数量为1-2的存活率较高

在这里插入图片描述

# Pclass与Survived
sns.barplot(data=train_df, x='Pclass', y='Survived')

# 1等座的乘客存活率最高

在这里插入图片描述

# Sex与Survived
sns.barplot(data=train_df, x='Sex', y='Survived')

# 女性的存活率远高于男性

在这里插入图片描述

# Age与Survived
# 创建坐标轴
ageFacet = sns.FacetGrid(data=train_df, hue='Survived', aspect=3)
# 选择图形类型
ageFacet.map(sns.kdeplot, 'Age', shade=True)
# 设置坐标轴
ageFacet.set(xlim=(0, train_df.Age.max()))
# 添加标签
ageFacet.add_legend()

# 从图中可以看出0-10岁的存活率高于普通值

在这里插入图片描述

# Fare与Survived
# 创建坐标轴
ageFacet = sns.FacetGrid(data=train_df, hue='Survived', aspect=3)
# 选择图形类型
ageFacet.map(sns.kdeplot, 'Fare', shade=True)
# 设置坐标轴
ageFacet.set(xlim=(0, train_df.Fare.max()))
# 添加标签
ageFacet.add_legend()

# 票价较高的乘客,存活率较高一些。

在这里插入图片描述

# 查看票价的特征分布
farePlot = sns.displot(all_df['Fare'][all_df['Fare'].notnull()], label='skewness:%.2f'%(all_df['Fare'].skew()))
farePlot.legend

# 票价整体呈左偏,需要进行对数处理
# Fare缺失,采用相同类型乘客补充
all_df[all_df['Fare'].isnull()]
all_df['Fare'] = all_df['Fare'].fillna(all_df[(all_df['Cabin']=='U')&(all_df['Embarked']=='S')&(all_df['Pclass']==3)]['Fare'].mean())

all_df['Fare'] = all_df['Fare'].map(lambda x: np.log(x) if x>0 else 0)

在这里插入图片描述

4、数据处理和特征工程:补充缺失值和异常值

# 数据清洗
# 对数据的缺失值、异常值进行处理
# Cabin
all_df['Cabin'] = all_df['Cabin'].fillna('U')
all_df['Cabin'].value_counts()
# Embarked只缺失两个,补充最多登录的就好
all_df['Embarked'].value_counts()
all_df['Embarked'].fillna('S', inplace=True)
all_df.info()

特征工程:增加特征项

# 特征工程
# Name中的头衔信息-Title
all_df['Title'] = all_df['Name'].map(lambda x:x.split(',')[1].split('.')[0].strip())
all_df['Title'].value_counts()

在这里插入图片描述

TitleDict={}
TitleDict['Mr']='Mr'
TitleDict['Mlle']='Miss'
TitleDict['Miss']='Miss'
TitleDict['Master']='Master'
TitleDict['Jonkheer']='Royalty'
TitleDict['Mme']='Mrs'
TitleDict['Ms']='Mrs'
TitleDict['Mrs']='Mrs'
TitleDict['Don']='Royalty'
TitleDict['Sir']='Royalty'
TitleDict['the Countess']='Royalty'
TitleDict['Dona']='Royalty'
TitleDict['Lady']='Royalty'
TitleDict['Capt']='Officer'
TitleDict['Col']='Officer'
TitleDict['Major']='Officer'
TitleDict['Dr']='Officer'
TitleDict['Rev']='Officer'

all_df['Title'] = all_df['Title'].map(TitleDict)
all_df['Title'].value_counts()

在这里插入图片描述

sns.barplot(data=all_df, x='Title', y='Survived')
# 男性和office的存活率较低

在这里插入图片描述

# 将随行的人员和家庭成员合并
all_df['FamilyNum'] = all_df['SibSp'] + all_df['Parch'] + 1
sns.barplot(data=all_df, x='FamilyNum', y='Survived')
# 家庭成员在2-4人的存活率较高

在这里插入图片描述

all_df['Desk'] = all_df['Cabin'].map(lambda x:x[0])
sns.barplot(data=all_df, x='Desk', y='Survived')

# Desk为E、D、B的存活率较高,U和T的存活率较低

在这里插入图片描述

all_df['TicketCot'] = all_df['Ticket'].map(all_df['Ticket'].value_counts())
sns.barplot(data=all_df, x='TicketCot', y='Survived')
# 共乘票为2-4的存活率较高

在这里插入图片描述

all_df.info()

在这里插入图片描述

# 对部分变量进行分组
def familysize(num):
    if num == 1:
        return 0
    elif (num>=2) & (num<=4):
        return 1
    else:
        return 2
    
def tickgroup(num):
    if (num>=2)&(num<=4):
        return 0
    elif (num==1)|((num>=5)&(num<=8)):
        return 1
    else:
        return 2
    
all_df['TickGroup'] = all_df['TicketCot'].map(tickgroup)
all_df['FamilySize'] = all_df['FamilyNum'].map(familysize)
all_df.head()

在这里插入图片描述

经过以上处理,我们将除了age外的其他特征的缺失值都补充完成,并且还增加了几个特征值。

使用随机森林回归进行age预测

# 缺失的年龄用线性回归进行模拟
corr_df = all_df.corr()
corr_df['Age'].sort_values()

在这里插入图片描述

# 筛选数据
Age_df = all_df[['Age','Parch','Pclass','SibSp','Title','FamilyNum','TicketCot']]
Age_df = pd.get_dummies(Age_df)
ParAge = pd.get_dummies(Age_df['Parch'], prefix='Parch')
SibAge = pd.get_dummies(Age_df['SibSp'], prefix='SibSp')
PclAge = pd.get_dummies(Age_df['Pclass'], prefix='Pclass')
Agecorr = Age_df.corr()
Agecorr['Age'].sort_values()
sns.heatmap(data=Agecorr, cmap='BrBG', linewidths=0.5)

在这里插入图片描述

# 合并用于预测年龄的数据集
Age_df = pd.concat([Age_df,ParAge,SibAge,PclAge], axis=1)
Age_df.head()

在这里插入图片描述

# 拆分数据
from sklearn.ensemble import RandomForestRegressor
AgeKnow = Age_df[Age_df['Age'].notnull()]
AgeUnknow = Age_df[Age_df['Age'].isnull()]

Age_train_X = AgeKnow.drop(['Age'], axis=1)
Age_train_y = AgeKnow['Age']

Age_test_X = AgeUnknow.drop(['Age'], axis=1)

# 建立随机森林回归模型
rfr = RandomForestRegressor(random_state=None, n_estimators=500, n_jobs=-1)
rfr.fit(Age_train_X,Age_train_y)
# 模拟得分
rfr.score(Age_train_X,Age_train_y)
# 进行年龄预测
Age_predict = rfr.predict(Age_test_X)
all_df.loc[all_df['Age'].isnull(), ['Age']] = Age_predict
all_df.info()

在这里插入图片描述

特征筛选

我们已经处理完所有的特征值缺失,并进行了特征构造,接下来需要进行特征筛选,防止特征之间较高的共线性影响模型的预测结果。

# 进行特征筛选
full_df = all_df.drop(['PassengerId','Name','Ticket','Cabin'],axis=1)
corr_df = full_df.corr()
corr_df['Survived'].sort_values()

在这里插入图片描述

sns.heatmap(corr_df, cmap='BrBG', linewidths=0.5)

在这里插入图片描述

# 删除相关性不大的特征
full_df = full_df.drop(['SibSp','FamilyNum','TicketCot','Parch'], axis=1)
# 进行one-hot处理
full_df = pd.get_dummies(full_df)
full_df.head()

在这里插入图片描述

5、决策树模型搭建和预测

模型搭建和预测

# 划分数据集,建立模型
train_df = full_df[full_df['Survived'].notnull()]
test_df = full_df[full_df['Survived'].isnull()]

train_X = train_df.drop(['Survived'], axis=1)
train_y = train_df['Survived']
test_X = test_df.drop(['Survived'], axis=1)
# 决策树模型
from sklearn.tree import DecisionTreeClassifier
dtc = DecisionTreeClassifier()
dtc.fit(train_X, train_y)
y_predict = dtc.predict(test_X)
# 导入测试集答案
test_y = pd.read_csv('mygender.csv')
test_y = test_y[['Survived']]
dtc.score(test_X,test_y)

在这里插入图片描述

模型评分

from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_curve, auc
print('召回率等评分')
print(classification_report(y_predict, test_y, target_names=['died','survived']))
print('混淆矩阵')
print(confusion_matrix(y_predict, test_y))

在这里插入图片描述

# roc曲线
import matplotlib.pyplot as plt
fpr, tpr, thresholds= roc_curve(y_true=test_y, y_score=y_predict, pos_label=1)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(10,10))
plt.plot(fpr, tpr, color='r', label= 'ROC curve (area = %0.3f)'%roc_auc)
plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Titanic DecisionTree Model')
plt.legend(loc="lower right")

在这里插入图片描述

6、随机森林模型搭建和评分

# 随机森林
import warnings
warnings.filterwarnings("ignore")
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold
kfold=StratifiedKFold(n_splits=10)
gbc = GradientBoostingClassifier()
gb_param_grid = {'loss' : ["deviance"],
              'n_estimators' : [100,200,300],
              'learning_rate': [0.1, 0.05, 0.01],
              'max_depth': [4, 8],
              'min_samples_leaf': [100,150],
              'max_features': [0.3, 0.1] 
              }
modelgsGBC = GridSearchCV(gbc,param_grid = gb_param_grid, cv=kfold, 
                                     scoring="accuracy", n_jobs= -1, verbose = 1)
modelgsGBC.fit(train_X,train_y)
print('modelgsGBC模型得分为:%.3f'%modelgsGBC.best_score_)

在这里插入图片描述

# 随机森林的模型报告
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_curve, auc
y_predict = modelgsGBC.predict(test_X)
print('召回率等评分')
print(classification_report(y_predict, test_y, target_names=['died','survived']))
print('混淆矩阵')
print(confusion_matrix(y_predict, test_y))

# roc曲线
import matplotlib.pyplot as plt
fpr, tpr, thresholds= roc_curve(y_true=test_y, y_score=y_predict, pos_label=1)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(10,10))
plt.plot(fpr, tpr, color='r', label= 'ROC curve (area = %0.3f)'%roc_auc)
plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Titanic GradientBoostin Model')
plt.legend(loc="lower right")

在这里插入图片描述
在这里插入图片描述

绘制决策树图形

# 绘制决策树分类图形
from sklearn.tree import export_graphviz 

# windows 系统添加此行代码,Graphviz路径
# os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'


dot_data = export_graphviz(dtc # 模型命名
                                ,out_file = 'tatiantic_tree' # dot文件名字,在jupyter文件目录下
                                ,feature_names= train_X.columns # 特征名称,没有得话以数列下标显示
                                ,class_names=["is_date:no","is_date:yes"] # 分类目标的名称
                                ,filled=True
                                ,rounded=True
                                )

用文件软件打开同目录文件下的dot文件,将内容全部复制进http://dreampuf.github.io/GraphvizOnline/,即可完成绘制,点击download进行下载。

7、总结

在本次案例中,随机森林的各方面性能和评分会比决策树更好一些。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
为了进行泰坦尼克号幸存者预测,我们可以使用随机森林算法。随机森林是一种集成学习方法,它通过构建多个决策树来提高预测准确率。下面是使用Python中的scikit-learn库实现随机森林算法进行泰坦尼克号幸存者预测的步骤: 1. 导入必要的库和数据集 ```python import pandas as pd from sklearn.ensemble import RandomForestClassifier # 读取训练集和测试集 train_data = pd.read_csv('train.csv') test_data = pd.read_csv('test.csv') ``` 2. 数据预处理 ```python # 删除无用的列 train_data.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1, inplace=True) test_data.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1, inplace=True) # 处理缺失值 train_data['Age'].fillna(train_data['Age'].median(), inplace=True) test_data['Age'].fillna(test_data['Age'].median(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].median(), inplace=True) # 将分类变量转换为数值变量 train_data = pd.get_dummies(train_data) test_data = pd.get_dummies(test_data) # 对齐训练集和测试集的列 train_data, test_data = train_data.align(test_data, join='outer', axis=1, fill_value=0) ``` 3. 训练模型并进行预测 ```python # 分离特征和标签 X_train = train_data.drop('Survived', axis=1) y_train = train_data['Survived'] X_test = test_data # 训练模型 rfc = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1) rfc.fit(X_train, y_train) # 进行预测 y_pred = rfc.predict(X_test) ``` 4. 保存预测结果 ```python # 保存预测结果 output = pd.DataFrame({'PassengerId': pd.read_csv('test.csv')['PassengerId'], 'Survived': y_pred}) output.to_csv('submission.csv', index=False) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGC人工智残

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值