Sklearn分類樹在合成數集上的表現

  小夥伴們你們好~o( ̄▽ ̄)ブ,今天咱們開始來看一下Sklearn分類樹的表現,個人開發環境是Jupyter lab,所用的庫和版本你們參考:python

  Python 3.7.1(你的版本至少要3.4以上)算法

  Scikit-learn 0.20.0 (你的版本至少要0.20)數據庫

  Graphviz 0.8.4 (沒有畫不出決策樹哦,安裝代碼conda install python-graphviz)數組

  Numpy 1.15.3, Pandas 0.23.4, Matplotlib 3.0.1, SciPy 1.1.0網絡

 

  在這裏,咱們使用SKlearn構建三種不一樣分佈的數據,而後在這些數據集上測試一下決策樹的效果,讓你們更好地理解決策樹。下圖就是三種表現結果,後面會詳細介紹實現過程~dom

1. 導入須要的庫

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.tree import DecisionTreeClassifier

 

2. 生成三種數據集

  咱們先從sklearn自帶的數據庫中生成三種類型的數據集:1)月亮型數據,2)環形數據,3)二分型數據函數

#make_classification庫生成隨機的二分型數據
X, y = make_classification(n_samples=100, #生成100個樣本
                           n_features=2,  #包含2個特徵,即生成二維數據
                           n_redundant=0, #添加冗餘特徵0個
                           n_informative=2, #包含信息的特徵是2個
                           random_state=1,  #隨機模式1
                           n_clusters_per_class=1 #每一個簇內包含的標籤類別有1個
                          )

 

  在這裏能夠查看一下X和y,其中X是100行帶有兩個2特徵的數據,y是二分類標籤 也能夠畫出散點圖來觀察一下X中特徵的分佈測試

plt.scatter(X[:,0],X[:,1])

 

  從圖上能夠看出,生成的二分型數據的兩個簇離彼此很遠,這樣不利於咱們測試分類器的效果,所以咱們使用np生成隨機數組,經過讓已經生成的二分型數據點加減0~1之間的隨機數,使數據分佈變得更散更稀疏。spa

  【注意】這個過程只可以運行一次,由於屢次運行以後X會變得很是稀疏,兩個簇的數據會混合在一塊兒,分類器的效應會繼續降低3d

rng = np.random.RandomState(2) #生成一種隨機模式
X += 2 * rng.uniform(size=X.shape) #加減0~1之間的隨機數
linearly_separable = (X, y) 

 

  生成了新的X,依然能夠畫散點圖來觀察一下特徵的分佈

plt.scatter(X[:,0],X[:,1]);

 

 

#用make_moons建立月亮型數據,make_circles建立環形數據,並將三組數據打包起來放在列表datasets中
datasets = [make_moons(noise=0.3, random_state=0),
            make_circles(noise=0.2, factor=0.5, random_state=1),
            linearly_separable]

 

3. 畫出三種數據集和三棵決策樹的分類效應圖像

#建立畫布,寬高比爲6*9
figure = plt.figure(figsize=(6, 9))
#設置用來安排圖像顯示位置的全局變量i
i = 1#開始迭代數據,對datasets中的數據進行for循環
for ds_index, ds in enumerate(datasets):
    
    #對X中的數據進行標準化處理,而後分訓練集和測試集
    X, y = ds
    X = StandardScaler().fit_transform(X) 
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4, random_state=42)
    
    #找出數據集中兩個特徵的最大值和最小值,讓最大值+0.5,最小值-0.5,創造一個比兩個特徵的區間自己更大一點的區間
    x1_min, x1_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    x2_min, x2_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    
    #用特徵向量生成網格數據,網格數據,其實就至關於座標軸上無數個點
    #函數np.arange在給定的兩個數之間返回均勻間隔的值,0.2爲步長
    #函數meshgrid用以生成網格數據,可以將兩個一維數組生成兩個二維矩陣。
    #若是第一個數組是narray,維度是n,第二個參數是marray,維度是m。那麼生成的第一個二維數組是以narray爲行,m行的矩陣,而第二個二維數組是以marray的轉置爲列,n列的矩陣
    #生成的網格數據,是用來繪製決策邊界的,由於繪製決策邊界的函數contourf要求輸入的兩個特徵都必須是二維的
    array1,array2 = np.meshgrid(np.arange(x1_min, x1_max, 0.2),
                         np.arange(x2_min, x2_max, 0.2))
​
    #接下來生成彩色畫布
    #用ListedColormap爲畫布建立顏色,#FF0000正紅,#0000FF正藍
    cm = plt.cm.RdBu
    cm_bright = ListedColormap(['#FF0000', '#0000FF'])
    
    #在畫布上加上一個子圖,數據爲len(datasets)行,2列,放在位置i上
    ax = plt.subplot(len(datasets), 2, i)
    
    #到這裏爲止,已經生成了0~1之間的座標系3個了,接下來爲咱們的座標系放上標題
    #咱們有三個座標系,但咱們只須要在第一個座標系上有標題,所以設定if ds_index==0這個條件
    if ds_index == 0:
        ax.set_title("Input data")
    
    #將數據集的分佈放到咱們的座標系上
    #先放訓練集
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, 
               cmap=cm_bright,edgecolors='k')
    #放測試集
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, 
               cmap=cm_bright, alpha=0.6,edgecolors='k')
    
     #爲圖設置座標軸的最大值和最小值,並設定沒有座標軸
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    ax.set_xticks(())
    ax.set_yticks(())
    
    #每次循環以後,改變i的取值讓圖每次位列不一樣的位置
    i += 1
    
    #至此爲止,數據集自己的圖像已經佈置完畢,運行以上的代碼,能夠看見三個已經處理好的數據集
    
    #############################從這裏開始是決策樹模型##########################
    
    #迭代決策樹,首先用subplot增長子圖,subplot(行,列,索引)這樣的結構,並使用索引i定義圖的位置
    #在這裏,len(datasets)其實就是3,2是兩列
    #在函數最開始,咱們定義了i=1,而且在上邊創建數據集的圖像的時候,已經讓i+1,因此i在每次循環中的取值是2,4,6
    ax = plt.subplot(len(datasets),2,i)
    
    #決策樹的建模過程:實例化 → fit訓練 → score接口獲得預測的準確率
    clf = DecisionTreeClassifier(max_depth=5)
    clf.fit(X_train, y_train)
    score = clf.score(X_test, y_test)
    
    #繪製決策邊界,爲此,咱們將爲網格中的每一個點指定一種顏色[x1_min,x1_max] x [x2_min,x2_max]
    #分類樹的接口,predict_proba,返回每個輸入的數據點所對應的標籤類機率
    #類機率是數據點所在的葉節點中相同類的樣本數量/葉節點中的樣本總數量
    #因爲決策樹在訓練的時候導入的訓練集X_train裏面包含兩個特徵,因此咱們在計算類機率的時候,也必須導入結構相同的數組,便是說,必須有兩個特徵
    #ravel()可以將一個多維數組轉換成一維數組
    #np.c_是可以將兩個數組組合起來的函數
    #在這裏,咱們先將兩個網格數據降維降維成一維數組,再將兩個數組連接變成含有兩個特徵的數據,再帶入決策樹模型,生成的Z包含數據的索引和每一個樣本點對應的類機率,再切片,且出類機率
    Z = clf.predict_proba(np.c_[array1.ravel(),array2.ravel()])[:, 1]
    
    #np.c_[np.array([1,2,3]), np.array([4,5,6])]
    
    #將返回的類機率做爲數據,放到contourf裏面繪製去繪製輪廓
    Z = Z.reshape(array1.shape)
    ax.contourf(array1, array2, Z, cmap=cm, alpha=.8)
    
    #將數據集的分佈放到咱們的座標系上
    # 將訓練集放到圖中去
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright,
               edgecolors='k')
    # 將測試集放到圖中去
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright,
               edgecolors='k', alpha=0.6)
    
    #爲圖設置座標軸的最大值和最小值
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    #設定座標軸不顯示標尺也不顯示數字
    ax.set_xticks(())
    ax.set_yticks(())
    
    #咱們有三個座標系,但咱們只須要在第一個座標系上有標題,所以設定if ds_index==0這個條件
    if ds_index == 0:
        ax.set_title("Decision Tree")
    
    #寫在右下角的數字    
    ax.text(array1.max() - .3, array2.min() + .3, ('{:.1f}%'.format(score*100)),
            size=15, horizontalalignment='right')
    
    #讓i繼續加一
    i += 1
​
plt.tight_layout()
plt.show()

 

  運行的結果以下所示:

 

  從圖上來看,每一條線都是決策樹在二維平面上畫出的一條決策邊界,每當決策樹分枝一次,就有一條線出現。當數據的維度更高的時候,這條決策邊界就會由線變成面,甚至變成咱們想象不出的多維圖形。

  同時,很容易看得出,分類樹天生不擅長環形數據。每一個模型都有本身的決策上限,因此一個怎樣調整都沒法提高表現的可能性也是有的。當一個模型怎麼調整都不行的時候,咱們能夠選擇換其餘的模型使用,不要在一棵樹上吊死。順便一說,最擅長月亮型數據的是最近鄰算法,RBF支持向量機和高斯過程;最擅長環形數據的是最近鄰算法和高斯過程;最擅長對半分的數據的是樸素貝葉斯,神經網絡和隨機森林。

相關文章
相關標籤/搜索