數據挖掘入門系列教程(四)之基於scikit-lean實現決策樹

數據挖掘入門系列教程(四)之基於scikit-lean決策樹處理Iris

在上一篇博客,咱們介紹了決策樹的一些知識。若是對決策樹還不是很瞭解的話,建議先閱讀上一篇博客,在來學習這一篇。html

本次實驗基於scikit-learn中的Iris數據。說了很久的Iris,從OneR到決策樹,那麼Iris到底長啥樣呢?node


加載數據集

首先咱們仍是須要先加載數據集,數據集來自scikit自帶的iris數據集,數據集的內容能夠參考之前的博客,這裏就不在贅述。python

首先讓咱們從scikit-learn中加載數據集。git

from sklearn.datasets import load_iris
dataset = load_iris()
data = dataset.data
target = dataset.target

而後咱們再使用pandas將數據進行格式化如下,添加Iris的屬性到數據集中。github

import numpy as np
import pandas as pd
data = pd.DataFrame(data,columns=["sepal_length","sepal_width","petal_length","petal_width"])
data["class"] = target

data的數據以下所示:算法


class表明類別。其餘的就是Iris的屬性了。markdown

數據特徵

這裏咱們主要是用畫圖來看一看Iris數據集的特徵。原本覺得畫圖就matpotlib就好了,可是沒想到有seaborn這個好使用的庫,來自B站up主的提示。使用的庫以下:dom

  • matplotlib
  • seaborn

首先咱們畫散點圖:ide

import matplotlib.pyplot as plt
import seaborn as sb
# data.dropna()去除裏面的none元素
sb.pairplot(data.dropna(),hue="class")

圖像以下所示:svg


上面的這幅圖展現了在四個屬性中的類別的分別狀況。

同時咱們還能夠畫小提琴圖:

plt.figure(figsize=(20, 20))
for column_index, column in enumerate(data.columns):
    if column == 'class':
        continue
    plt.subplot(2, 2, column_index + 1)
    sb.violinplot(x='class', y=column, data=data)

畫出的圖以下:


經過上面的這幅圖咱們能夠直觀的比較出哪個變量更具備表明性。好比說petal_width 對類別0更加的友好。

接下來就是進行訓練了。

訓練

首先的首先,咱們仍是須要從數據集中抽出訓練集和測試集。這個內容在前面講過了,就很少講了。

from sklearn.model_selection import train_test_split

input_data = data[["sepal_length","sepal_width","petal_length","petal_width"]]
input_class =  data["class"]

train_data,test_data,train_class,test_class = train_test_split(input_data,input_class,random_state = 14)

then,讓咱們來開始進行訓練吧,在scikit-learn中實現了決策樹,和前面的K近鄰算法同樣咱們直接引用就行,調用fit(訓練)和predict(預測)函數。使用以下所示:

from sklearn.tree import DecisionTreeClassifier

decision_tree = DecisionTreeClassifier(random_state=14)
decision_tree.fit(train_data,train_class)
predict_class = decision_tree.predict(test_data)
predict_score = np.mean(predict_class == test_class)
print("預測的準確度爲{}".format(predict_score))

DecisionTreeClassifier其餘的參數在後面說,這裏主要說一下random_state參數。爲何決策樹還須要random_state這個參數,如下知乎上面的兩位博主的說法。



至於哪一個說法是正確的,我暫時也不知道,若是有知道的,能夠在評論區留言哦!

最後獲得的預測結果以下所示:


這裏值得注意的是DecisionTreeClassifier()函數,裏面能夠添加不少參數。官方文檔在這裏: https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

這裏仍是稍微的說一下參數。

# criterion gini(默認)/tropy:這裏對應的就是以前的熵增益和Gini係數

# splitter best(默認)/random 每一個結點選擇的拆分策略

# max_depth 樹的最大深度。

# min_samples_split int類型或者float(默認2) 若是某節點的樣本數少於min_samples_split,則不會進行拆分了。浮點值表示分數,表明所佔比例

# min_samples_leaf 默認=1 這個值限制了葉子節點最少的樣本數,若是某葉子節點數目小於樣本數,則會和兄弟節點一塊兒被剪枝。

# min_weight_fraction_leaf float(默認0.0) 這個值限制了葉子節點全部樣本權重,若是小於這個值,則會和兄弟節點一塊兒被剪枝。通常來講,若是咱們有較多樣本有缺失值,或者分類樹樣本的分佈類別誤差很大,就會引入樣本權重,這時咱們就要注意這個值了。

# max_features int, float or {「auto」, 「sqrt」, 「log2」}(默認0.0)

# max_leaf_nodes 經過限制最大葉子節點數,能夠防止過擬合,默認是"None」,即不限制最大的葉子節點數。若是加了限制,算法會創建在最大葉子節點數內最優的決策樹。

# class_weight dict/balanced 指定樣本各種別的的權重,主要是爲了防止訓練集某些類別的樣本過多致使訓練的決策樹過於偏向這些類別。這裏能夠本身指定各個樣本的權重。「balanced」,則算法會本身計算權重,樣本量少的類別所對應的樣本權重會高。

# min_impurity_split 這個值限制了決策樹的增加,若是某節點的不純度(基尼係數,信息增益,均方差,絕對差)小於這個閾值則該節點再也不生成子節點。即爲葉子節點 。

更多的能夠去看官網細節。

而後咱們能夠將這個樹的結構可視化,將文件保存在「tree.dot」中:

from sklearn.tree import export_graphviz
with open("tree.dot",'w') as f:
    export_graphviz(decision_tree, feature_names =['sepal_length', 'sepal_width', 'petal_length', 'petal_width'], out_file = f)

這個是決策樹的圖:


一樣,咱們還可使用交叉驗證,具體的使用能夠參考別人的博客,或者看個人這一篇博客

from sklearn.model_selection import cross_val_score
decision_tree = DecisionTreeClassifier()
scores = cross_val_score(decision_tree,input_data,input_class,scoring='accuracy')
print("交叉驗證結果: {0:.2f}%".format(np.mean(scores) * 100))

經過交叉驗證獲得的準確度以下:


比上面的結果略低,不過這個是正常的。

隨機森林

前面的博客介紹了隨機樹,這裏很少作介紹,直接看使用吧。咱們經過導入RandomForestClassifier模塊,並指令森林中樹的個數爲30,具體的參數看官網

from  sklearn.ensemble import RandomForestClassifier
rft = RandomForestClassifier(n_estimators=20,random_state=14)
rft.fit(train_data,train_class)
predict_class = rft.predict(test_data)
predict_score = np.mean(predict_class == test_class)
print("隨機森林預測的準確度爲{}".format(predict_score))

最後的結果以下圖

而後進行交叉驗證:

scores = cross_val_score(rft,input_data,input_class,scoring='accuracy')
print("Accuracy: {0:.2f}%".format(np.mean(scores) * 100))

結果以下:


emm,好像和上面的結果同樣,由於這個數據集很小,可能會有這種狀況。

調參工程師

首先,咱們能夠對決策樹的max_feature和max_depth進行調參,改變其值,最終的結果以下:


在隨機森林中,咱們能夠對樹的個數進行調參,結果以下圖:


結尾

此次並無使用《 Python數據挖掘入門與實踐 》書上的例子,實在是它打籃球的數據找不到,emm。相比較與oneR算法的70%左右的正確率,決策樹95%正確率已經算足夠優秀了。

儘管代碼寫起來很簡單,也很容易實現獲得結果,可是咱們真正應該瞭解的是裏面的內涵:決策樹是什麼?裏面是怎樣工做的?以及所蘊含的含義……

項目地址:GitHub

相關文章
相關標籤/搜索