泰坦尼克沉船數據預測及可視化分析

1、背景介紹

泰坦尼克號沉船事件發生在1912年4月。泰坦尼克號是當時世界上最大的客運輪船,首航泰坦尼克號從英國南安普敦出發,途經法國瑟堡-奧克特維爾以及愛爾蘭昆士敦,計劃中的目的地爲美國紐約。由於航行途中瞭望員沒有及時發現前方的冰峯,船撞上冰峯發生船難。隨後,泰坦尼克號沉沒,2224名乘客和機組人員中有1502人遇難。沉船導致大量傷亡的原因之一是沒有足夠的救生艇給乘客和船員。一些人可能比其他人更有可能生存,比如婦女,兒童和上層階級,但,倖存下來的因素研究及討論一直沒有停止過。

2、數據集說明

數據集來自Kaggle2,包括泰坦尼克號上 2224 名乘客和船員中 891 名的人口學數據和乘客基本信息。分析其中的數據,探索生還率和某些因素的關係,什麼樣的人在泰坦尼克號中更容易存活?
決策樹算法依據對一系列屬性取值的判定得出最終決策。在每個非葉子節點上進行一個特徵屬性的測試,每個分支表示這個特徵屬性在某個值域上的輸出,而每個葉子節點對應於最終決策結果。使用決策樹進行決策的過程就是從根節點開始,測試待分類項中相應的特徵屬性,並按照其值選擇輸出分支,直到到達葉子節點,將葉子節點對應的類別作爲決策結果。算法的目的是產生一棵泛化性能強,即處理未見數據能力強的決策樹。
數據集共有891行、12列。每條數據有12個特徵,含義如下:
• PassengerId => 乘客ID
• Survived => 獲救情況(1爲獲救,0爲未獲救)
• Pclass => 乘客等級(1/2/3等艙位)
• Name => 乘客姓名
• Sex => 性別
• Age => 年齡
• SibSp => 堂兄弟/妹個數
• Parch => 父母與小孩個數
• Ticket => 船票信息
• Fare => 票價
• Cabin => 客艙
• Embarked => 登船港口
數據下載地址:https://www.kaggle.com/hesh97/titanicdataset-traincsv。

3、具體要求

1、數據清理
a)查看數據行列情況,判斷是否有空行,進行刪除;
b)查看空值情況,按照自己分析的需求及考慮進行刪除或填充操作;

from pandas import DataFrame,Series
import pandas as pd
import numpy as np
#導入混淆矩陣
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
names=['PassengerId','Survived','Pclass','Name','Sex','Age','SibSp','Parch','Ticket','Fare','Cabin','Embarked']
titanic = pd.read_csv("train.csv",header=None,names=names)
print(titanic)
print("判斷空行數量:",titanic.isnull().T.all().sum())
print("數據集情況:")
titanic.info()

#對年齡用均值填充
titanic["Age"] = titanic["Age"].fillna(titanic["Age"].mean())
#將登船港口拿衆數填充,默認使用第一個衆數值
titanic["Embarked"] = titanic["Embarked"].fillna(titanic["Embarked"].mode()[0])
#刪除缺失值較多無法使用的屬性
titanic.drop(['Cabin'],axis=1,inplace=True)
print("對數據集空值處理後的情況:")
titanic.info()

在這裏插入圖片描述在這裏插入圖片描述實驗結果分析:
由數據集信息可知,Age、Cabin、Embarked存在空值,其中屬性Cabin缺失值過多,對後續分析用處不大,因此此處刪除數據,屬性Embarked僅有兩個空缺值,可採用衆數填充,默認選用第一個衆數,屬性Age數值型數據,採用均值對空缺值進行填充。對空值處理後效果爲:
在這裏插入圖片描述2、使用可視化方法,判斷哪些屬性對倖存影響大
思路:要想對數據進行分析,首先需要對數據預處理,對於此數據集,先將字符型數據進行數值化,由於屬性年齡、票價差距太大,因此統一對數據進行標準化處理。

#數據集預處理——數值化
lables = ["Name","Sex","Ticket","Embarked"]
#可以知道字符型的有5列
i = 0
while(i<4):
    y_flag = titanic[lables[i]].unique()
    titanic[lables[i]] = titanic[lables[i]].apply(lambda x : y_flag.tolist().index(x))
    i = i+1
print(titanic.head())
#原因屬性
x = titanic.iloc[:,2:]
# print(x)
#目標屬性
y = titanic["Survived"]
X_lables = x.columns
print(X_lables)
#將數據集進行標準化處理
from sklearn.preprocessing import StandardScaler
standard = StandardScaler()
#對所有數據進行特徵化處理
X = standard.fit_transform(x)
X = DataFrame(X,columns=X_lables)
print(X.head())

數據預處理後效果:
在這裏插入圖片描述分別將兩個目標類被救和未被就區分開,畫出柱狀圖

# 找到類別都爲0 的
cond_0 = y == 0
cond_1 = y == 1
#獲取到類別爲0的Pclass的數據
az = plt.subplot(1,1,1)
X['Pclass'][cond_0].plot(kind='hist',bins=100,density = True)
X['Pclass'][cond_1].plot(kind='hist',bins=10,density = True,alpha = 0.8)
az.set_title("乘客等級")
plt.show()
# 使用循環,將10中類別畫出來
plt.figure(figsize=(9, 10 * 4))
for i in range(0, 9):
    ax = plt.subplot(111)

    X[X_lables[i]][cond_0].plot(kind='hist', bins=100, density=True, ax=ax)
    X[X_lables[i]][cond_1].plot(kind='hist', bins=10, density=True, ax=ax, alpha=0.8)
    # 添加標題
    ax.set_title(X_lables[i])
    plt.show()

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述實驗結果分析:
由實驗結果可知,屬性Name、Ticket重合度較高,分辨價值較低,在判別是否與被救有關係上作用不大。
利用GBDT梯度提升決策樹進行特徵重要性排序:

#將以上得出作用不大的列刪除
droplabels = ["Name","Ticket"]
X2 = X.drop(droplabels,axis=1)
# print(X2.head())
from sklearn.ensemble import GradientBoostingClassifier

gbdt = GradientBoostingClassifier()
gbdt.fit(X2,y)
print(gbdt.feature_importances_)
argsort = gbdt.feature_importances_.argsort()[::-1]
print(argsort)
plt.figure(figsize=(8,5))
plt.bar(np.arange(7),gbdt.feature_importances_[argsort])
_ = plt.xticks(np.arange(9),X2.columns[argsort])
plt.show()

在這裏插入圖片描述用GBDT進行梯度提升決策樹後得出的結果來看,屬性Parch、Embarked、Sibsp對是否被就分辨率較低,因此可忽略這些屬性,綜合以上結果可得出,屬性Sex、Fare、Pclass以及Pclass對判斷是否倖存的影響大。
3、設計兩個以上決策樹分類模型實驗,進行比較,並說明設計的理由。
使用信息熵作爲依據創建決策樹:

#使用決策樹
from sklearn import tree
#數據集轉換成訓練集和測試集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
# 創建決策樹對象,使用信息熵作爲依據
clf = tree.DecisionTreeClassifier(criterion='entropy')
clf.fit(X_train,y_train)
print("準確率:",clf.score(X_test,y_test))
#生成混淆矩陣,查看召回率
y_ = clf.predict(X_test)
#先生成一個混淆矩陣
cm = confusion_matrix(y_test,y_)
plot_confusion_matrix(cm,classes=[0,1])

在這裏插入圖片描述在這裏插入圖片描述基尼指數作爲依據創建決策樹:

# #使用GINi指數
clfg = tree.DecisionTreeClassifier(criterion='gini')
clfg.fit(X_train,y_train)
print("GINI指數作爲依據的準確率",clfg.score(X_test,y_test))
#生成混淆矩陣,查看召回率
y_ = clfg.predict(X_test)
#先生成一個混淆矩陣
cm = confusion_matrix(y_test,y_)
plot_confusion_matrix(cm,classes=[0,1])

在這裏插入圖片描述在這裏插入圖片描述實驗結果分析:
通過分別使用信息熵和基尼指數作爲依據構建決策樹,在使用信息熵作爲依據的決策樹中準確率達77.1%,召回率達67.0%,在使用基尼指數作爲依據的決策樹中準確率達74.4%,召回率達58.1。因此我們可以選擇以信息熵爲依據構建決策樹。
4、在此分析中,選擇模型評估度量,並說明理由
使用循環來調整決策樹參數:

i = 2
recall = []
accuracy = []
plt.figure(figsize=(24,27))
#讓最大深度爲16

while(i<17):
    clf = tree.DecisionTreeClassifier(criterion='entropy',max_depth=i)
    clf.fit(X_train,y_train)
    #生成混淆矩陣,查看召回率
    y_ = clf.predict(X_test)
    #先生成一個混淆矩陣
    cm = confusion_matrix(y_test,y_)
    # print("****************")
    # print(cm)
    # print("****************")

    print('maxdepth:%d,score:%0.4f,Recall:%0.4f'%(i,(cm[0,0]+cm[1,1])/cm.sum(),cm[1,1]/cm[1].sum()))
    recall.append(cm[1,1]/cm[1].sum())
    accuracy.append((cm[0,0]+cm[1,1])/cm.sum())
    plot_confusion_matrix(i,cm,classes=[0,1])
    i = i + 1
plt.show()
print(recall)
print(accuracy)
plt.plot(np.arange(2,17),recall,color = 'green')

plt.plot(np.arange(2,17),accuracy,color='red')
plt.show()

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述實驗結果分析:
有實驗結果可得出當最大深度爲3是準確率達到最大值0.8251,此時召回率只有0.6849,看似準確率及召回率均達到了最大值。
5、將建立的決策樹進行可視化
根據上一問實驗結果使決策樹最大深度爲2,畫出決策樹

import pydotplus
from IPython.display import Image
clf = tree.DecisionTreeClassifier(criterion='gini',max_depth=2)
clf.fit(X_train,y_train)
dot_data = tree.export_graphviz(clf, out_file=None)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.get_nodes()[7].set_fillcolor("#FFF2DD")
graph.write_png('titanic.png')

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章