我們之前所學的基本 Python 的語法與套件都是為了這一刻吧... (不是變強嗎?)沒錯,我們要變超人了,也就是跳入機器學習/深度學習系列的 Python 套件/程式碼了~

當然,這系列的文章並非機器學習的教學,因此在此不會先不考慮解釋一些理念的東西。有興趣的朋友都可以到這裡閱讀我其他的文章。在程式碼的部分,這系列的文章主要是為了要讓大家可以快速入門如何使用套件,不一定會是解決這些的問題的最佳方式。後面就只能靠大家的想像力了(讀多一點paper

scikit-learn(a.k.a sklearn)

在入門機器學習時,我們通常都會先利用 scikit-learn 的套件來對現有的資料做一些快速的觀察。他集合了非常多機器學習/資料探勘所會用到的技術。而我們只需要呼叫 API 就可以了~ 感謝大大,讚歎大大~

在機器學習裡面,對初學者來說最容易理解的分類模型就是決策樹(Decision Tree)。顧名思義,我們可以猜出這個模型就是透過資料中的屬性經過一系列的 if ... else ... 判斷式來找出標籤。而我們等等也會透過一些外掛套件來劃出我們的樹,並且再從中可以更理解我們呼叫的模組到底在做什麼。我們這次會使用在之前 Pandas 教學 裡面鐵達尼號的資料集,並且對這個資料集做出預測死亡的模型。

# 安裝 scikit-learn 模組
pip install scikit-learn
# 下載資料集
curl http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic3.csv

Prerequisites

下載完所需要套件以及資料集之後,我們就可以來開始寫 Code 了啦。

# 載入所需要的模組
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
import sklearn.tree as tree
import pandas as pd

Preprocessing

那我們在讀取資料集之後,我們需要先看看資料集並且來對資料集一些了解。在 Kaggle 上有資料集各個欄位的敘述。那我們在前處理的部分可以將所需要欄位。需要注意的一些細節是,scikit-learn 里的 Decision Tree 是只能夠吃數字型的資料。因此,我們需要將一些字串型的資料轉換成數字哦~

# Drop unnecessary columns
columns = ['survived', 'sex', 'age', 'fare', 'sibsp', 'parch']
df = df[columns]

# Convert sex to numbers
df.sex[df.sex == 'female'] = 0
df.sex[df.sex == 'male'] = 1

# Drop n/a rows  (noise)
df = df.dropna()

那我們將我們的資料集處理之後,在把資料丟入模型之前我們需要將資料分成 data(x)和 label(y)。並且將資料集分成訓練集以及測試集。

# Split data into training and testing
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.1)

Train & Evaluate

首先我們需要初始化我們的模型,並且設置樹要長得多深。設置樹的深度是為了不要讓這個決策樹擬合過度(Overfit)以至於不夠 Generalized,並且 bias 過高而造成容易被 noise 所影響。太淺則會讓我們的模型擬合不足(Underfit),並且 variance 過高,模型根本就是亂猜。再來我們將我們的訓練資料集 x_trainy_train 丟到模型裡面去做訓練 (model.fit())。講了這麼多,其實就只是寫了兩行程式碼。

接下來我們可以看到這個模型在測試資料中判斷類別的表現。主要我們的 accuracy 時 77%,也就是100 比資料中我們的模型會有 77% 的機率會猜對答案。這裡就不細說其他的東西,以後有空再深入講解。

# Initialize and train model
model = DecisionTreeClassifier(max_depth=3)
model.fit(x_train, y_train)

# Test and evaluate model
y_pred = model.predict(x_test)
print(classification_report(y_test, y_pred, labels=[0, 1]))

Visualization

我們也可以透過將我們的樹畫出來,查出我們模型為何表現得那樣。這裡可能大家比較看不懂的地方就是 gini 這個東西。Gini index 基本上代表我們在目前這個 node 裡面資料分布的純度。並且決策樹用來判斷使用哪一個 attribute 來將資料切開來。那我們第一個 node 的純度基本上就是:

G = (551÷940)(1−(551÷940)) + (389÷940)(1−(389÷940))
    = 0.2426 + 0.2426
    = 0.4852

在看這張圖的時候,我們可以發掘一些有趣的事情,例如:我們模型裡面最上面的 attribute 是 sex,而當它的值 ≤0.5 時,也就是女性,大部分都活了下來(所以 Rose 本來死的機率就比較高。所以後面模型在做判斷時都會依據這樣的“規劃”來判斷乘客的死活。

# Import required modules
from IPython.display import SVG
import graphviz
import pydotplus

# Display tree using Graphviz
graph = graphviz.Source(
    tree.export_graphviz(
        model,
        out_file=None,
        class_names=['died', 'survived'], # the target names.
        feature_names=x.columns, # the feature names.
        filled=True, # Whether to fill in the boxes with colours.
        rounded=True, # Whether to round the corners of the boxes.
        special_characters=True)
)
SVG(graph.pipe(format='svg'))

Conclusion

各位在處理這個資料集的時候,其實也可以做出一些不一樣的東西,例如增加一些欄位、將一些欄位離散化、對特定欄位依照相關性設置權重等等來增加模型的準確度。你們甚至可以拿其他的模型如: Naive Bayes、k-NN、SVM等...

最後,這篇文章完整的程式碼可以到這裡看哦~

Reference:

scikit-learn
kaggle
KDNuggets

Leave a Reply

Your email address will not be published. Required fields are marked *