用決策樹做泰坦尼克號乘客的生存預測


前言

前些天學習了一下決策樹算法(ID3、C4.5、cart算法),今天實際練習一下。

數據集、測試集地址:

https://github.com/cystanford/Titanic_Data

原始數據:

train.csv 是訓練數據集,包含特征信息和存活與否的標簽;

test.csv: 測試數據集,只包含特征信息。

我們需要做的,就是使用訓練集的數據,構建決策樹,然后對測試集數據進行預測。

訓練集中的數據特征:

數據分析流程:

 

 

接下來我們會按照以上這6個步驟,去對泰坦尼克號乘客進行生存預測。

數據探索:

數據探索,其實就是對現有數據進行分析。比如行數、列數、數據完整度等。

進行數據探索,你需要知道如下幾個函數:

使用info()查看數據表的基本信息:行數、列數、每列的數據類型、數據完整度;

使用describe()了解數據表的統計情況:總數、平均值、標准值、最小值、最大值等;

使用describe(include=['0'])查看字符串(非數字)類型的整體情況

使用head查看前幾行數據(默認5行)

使用tail查看后幾行數據(默認后5行)

接下來我們執行一下這些命令

import pandas as pd

# 數據加載
train_data = pd.read_csv('../niki/train.csv')

info()查看數據表基本信息

# 數據探索
print(train_data.info())

可以看到它展示了:行數、數據完整度、數據類型、字段名、數據類型數、內存使用情況。

describe()查看數據表的統計信息:

# 數據探索
print(train_data.describe())

 可以看出,它展示的依次是:數據量、平均值、標准差、最小值、還有25%、50%、75%所含的數據、最大值

上面的輸出結果只展示了部分數據,如果想展示全部的數據,只需要在describe方法執行之前,加上上面兩句指令即可:

# 顯示所有列
pd.set_option('display.max_columns', None)
# 顯示所有行
pd.set_option('display.max_rows', None)

describe(include=['0'])查看字符串類型整體情況:

# 數據探索
print(train_data.describe(include=['O']))

 

 展示了數據的數量,有多少數據是不等的,出現數量最多的數據是什么,出現了幾次。

head tail查看數據的前幾行和后幾行:

這兩條命令和linux查看文件的命令是一樣的。

# 數據探索
print(train_data.head())
print('-'*50)
print(train_data.tail())

 

數據清洗:

我們對訓練集和測試集中的數據進行探索,可以得知:

Age、Fare、Cabin、Embarked存在缺失,Age數值型,代表年齡。我們可以用平均值補齊,Fare是船票價格,同理。

# 數據清洗
train_data['Age'].fillna(train_data['Age'].mean(), inplace=True)
test_data['Age'].fillna(test_data['Age'].mean(), inplace=True)

train_data['Fare'].fillna(train_data['Fare'].mean, inplace=True)
test_data['Fare'].fillna(test_data['Fare'].mean, inplace=True)

Cabin為船艙信息,由於訓練集和測試集中有大量的缺失數據,所以無法進行補齊。

Embarked是港口信息,我們可以使用value_counts()方法進行觀察:

print(train_data['Embarked'].value_counts())

發現S的占比超過了70%,所以我們可以用s值進行補齊

train_data['Embarked'].fillna('S', inplace=True)
test_data['Embarked'].fillna('S', inplace=True)

特征選擇:

通過數據探索,我們可以發現PassengerId為乘客的編號,對分類沒有作用,可以舍棄,Name為乘客姓名,也可以舍棄,Cabin缺失值太多,可以舍棄,Ticket為船票號碼,雜亂無章,可以舍棄,剩余的字段包括:Pclass、Sex、Age、SibSp、Parch 和 Fare,這些屬性分別表示了乘客的船票等級、性別、年齡、親戚數量以及船票價格,可能會和乘客的生存預測分類有關系。 

我們現將這些值放到特征向量里:

# 特征選擇
features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
train_features = train_data[features]
train_labels = train_data['Survived']
test_features = test_data[features]

特征值中,有一些是字符串類型的值,不利於后續的運算,需要轉成數字的類型,比如 Sex 字段,有 male 和 female 兩種取值。我們可以把它變成 Sex=male 和 Sex=female 兩個字段,數值用 0 或 1 來表示。我們可以用klearn 特征選擇中的 DictVectorizer 類進行上述操作:

from sklearn.feature_extraction import DictVectorizer
dvec = DictVectorizer(sparse=False)
train_features = dvec.fit_transform(train_features.to_dict(orient='record'))

fit_transfrom可以將特征向量轉換成特征矩陣,然后我們可以通過查看dvec的feature_name_屬性來獲取特征值。

 

 

 這樣我們就得到了一個10個特征值,891個樣本的10列的特征矩陣。

決策樹模型:

我們可以使用ID3算法構建決策樹,即創建DecisionTreeClassifier的時候,設置criterion='entropy'

from sklearn.tree import DecisionTreeClassifier

# 構造ID3決策樹
clf = DecisionTreeClassifier(criterion='entropy')
# 決策樹訓練
clf.fit(train_features, train_labels)

模型的預測 & 評估:

我們首先應該得到測試集的特征矩陣,然后使用訓練好的clf樹進行預測。

test_features=dvec.transform(test_features.to_dict(orient='record'))
# 決策樹預測
pred_labels = clf.predict(test_features)

在模型評估中,我們可以使用決策樹的score函數得到准確率,但是由於我們不知道測試集中的結果,所以我們這里使用訓練集的數據,進行一下預測。

  但是這么做顯然是不准確的,因為我們的決策樹是通過訓練集數據構建出來的。所以它的正確率會趨近於100%,那么有沒有什么方法可以在不知道測試機數據結果的時候,來統計決策樹的准確率呢?

這里就會使用k折交叉驗證的方式。

    1. K折交叉驗證是這樣的,我們將整個訓練集分成k等份
    2. 使用其中的1份作為測試數據,其余的數據作為訓練數據
    3. 計算測試數據的准確性
    4. 使用不同的訓練集重復2、3動作

sklearn的model_selection模型中,就提供了用於k折交叉驗證的函數,cross_val_score,參數cv代表將原始數據划分成多少份。

import numpy as np
from sklearn.model_selection import cross_val_score
# 使用K折交叉驗證 統計決策樹准確率
print(u'cross_val_score准確率為 %.4lf' % np.mean(cross_val_score(clf, train_features, train_labels, cv=10)))

 可以看出,結果差異還是比較大的

決策樹可視化:

我們可以用Grapviz進行決策樹的可視化:

import graphviz
from sklearn import tree

# 決策樹可視化
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.view()

結果:

 

 

 決策樹下載地址:https://github.com/cystanford/Titanic_Data

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM