1 決策樹概述python
決策樹(decision tree)是一個樹結構(能夠是二叉樹或非二叉樹)。其每一個非葉節點表示一個特徵屬性上的測試,每一個分支表明這個特徵屬性在某個值域上的輸出,而每一個葉節點存放一個類別。使用決策樹進行決策的過程就是從根節點開始,測試待分類項中相應的特徵屬性,並按照其值選擇輸出分支,直到到達葉子節點,將葉子節點存放的類別做爲決策結果。算法
以前介紹的K-近鄰算法能夠完成不少分類任務,可是它最大的缺點就是沒法給出數據的內在含義,決策樹的主要優點就在於數據形式很是容易理解。
決策樹算法可以讀取數據集合,構建相似於上面的決策樹。決策樹不少任務都是爲了數據中所蘊含的知識信息,所以決策樹可使用不熟悉的數據集合,並從中提取出一系列規則,機器學習算法最終將使用這些機器從數據集中創造的規則。專家系統中常用決策樹,並且決策樹給出結果每每能夠匹敵具備幾十年工做經驗的人類專家dom
2 決策樹分類機器學習
分類樹函數
分類樹用於分類標籤值,如晴天/陰天、用戶性別、網頁是不是垃圾頁面,分類的值是定性的學習
迴歸樹測試
回 歸樹用於預測實數值,如明天的溫度、用戶的年齡、網頁的相關程度,迴歸樹的值是定量的spa
3 構造決策樹3d
構造決策樹的關鍵步驟是分裂屬性。所謂分裂屬性就是在某個節點處按照某一特徵屬性的不一樣劃分構造不一樣的分支,其目標是讓各個分裂子集儘量地「純」。儘量「純」就是儘可能讓一個分裂子集中待分類項屬於同一類別。日誌
分裂屬性分爲三種不一樣的狀況:
一、屬性是離散值且不要求生成二叉決策樹。此時用屬性的每個劃分做爲一個分支。
二、屬性是離散值且要求生成二叉決策樹。此時使用屬性劃分的一個子集進行測試,按照「屬於此子集」和「不屬於此子集」分紅兩個分支。
三、屬性是連續值,此時肯定一個值做爲分裂點split_point,按照>split_point和<=split_point生成兩個分支
構造決策樹的關鍵性內容是進行屬性選擇度量,屬性選擇度量是一種選擇分裂準則,它決定了拓撲結構及分裂點split_point的選擇。
屬性選擇度量算法有不少,通常使用自頂向下遞歸分治法,並採用不回溯的貪心策略。這裏介紹經常使用的ID3算法。
貪心算法(又稱貪婪算法)是指,在對問題求解時,老是作出在當前看來是最好的選擇。即不從總體最優上加以考慮,他所作出的是在某種意義上的局部最優解.
4 ID3算法
ID3算法就是在每次須要分裂時,計算每一個屬性的增益率,而後選擇增益率最大的屬性進行分裂
劃分原則: 將無序的數據變得更加有序.
熵: 用於度量無序程度
一個系統越是有序,信息熵就越低,反之一個系統越是混亂,它的信息熵就越高。因此信息熵能夠被認爲是系統有序化程度的一個度量。
信息增益
組織雜亂無章數據的一種方法就是使用信息論度量信息,信息論是量化處理信息的分支科學。
在劃分數據集以前以後信息發生的變化稱爲信息增益,知道如何計算信息增益,咱們就能夠計算每一個特徵值劃分數據集得到的信息增益,得到信息增益最高的特徵就是最好的選擇。
(1) 計算公式: p(x)是選擇該分類的機率
(2) 爲了計算熵,咱們須要計算全部類別全部可能值包含的信息指望值,經過下面的公式獲得:
n是分類的數目
(3) 在決策樹當中,設D爲用類別對訓練元組進行的劃分,則D的熵(entropy)表示爲:
其中pi表示第i個類別在整個訓練元組中出現的機率,能夠用屬於此類別元素的數量除以訓練元組元素總數量做爲估計。熵的實際意義表示是D中元組的類標號所須要的平均信息量
(4) 如今咱們假設將訓練元組D按屬性A進行劃分,則A對D劃分的指望信息爲:
則信息增益爲二者的差值:
ID3算法就是在每次須要分裂時,計算每一個屬性的增益率,而後選擇增益率最大的屬性進行分裂。下面咱們繼續用SNS社區中不真實帳號檢測的例子說明如何使用ID3算法構造決策樹。咱們假設訓練集合包含10個元素:
import numpy as np import pandas as pd from pandas import Series,DataFrame import math # no p = 3/10 0.3 # yes p = 0.7 # 按照類別對訓練數據進行的劃分 # 數據樣本原始的熵 info_D = -0.3*math.log2(0.3) -0.7*math.log2(0.7) info_D #輸出 0.8812908992306927
按照日誌密度劃分信息增益
# s 0.3 no yes no -- no 2/3 yes 1/3 # l 0.3 yes yes yes -- no 0 yes 1 # m 0.4 yes yes no yes -- no 1/4 yes 3/4 info_L_D = 0.3*(-2/3*math.log2(2/3)-1/3*math.log2(1/3)) + 0.3*(-1*math.log2(1)) + 0.4*(-1/4*math.log2(1/4)-3/4*math.log2(3/4)) info_L_D #輸出 0.6 info_D - info_L_D #輸出 0.2812908992306927
計算按照好友密度劃分的信息熵
# 計算按照好友密度劃分的信息熵 # s 0.4 no no yes no --- no 3/4 yes 1/4 # l 0.2 yes yes --- no 0 yes 1 # m 0.4 yes yes yes yes -- no 0 yes 1 info_F_D = 0.4*(-3/4*math.log2(3/4)-1/4*math.log2(1/4)) info_F_D #輸出 0.32451124978365314 info_D - info_F_D #輸出 0.5567796494470396
按照是否使用真實頭像的熵
# no 0.5 no yes no yes yes --- no 2/5 yes 3/5 # yes 0.5 yes yes yes yes no --- no 1/5 yes 4/5 info_H_D = 0.5*(-2/5*math.log2(2/5)-3/5*math.log2(3/5)) + 0.5*(-1/5*math.log2(1/5)-4/5*math.log2(4/5)) info_H_D #輸出 0.8464393446710154 info_D - info_H_D #輸出 0.034851554559677256
實戰
1 比較KNN 邏輯斯蒂 決策樹進行分類
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.linear_model import LogisticRegression #導入IRIS數據集,加載IRIS的數據集 iris = datasets.load_iris() X = iris.data y = iris.target #max_depth 設置決策樹的最大深度 reg1 = DecisionTreeClassifier(max_depth=5) reg1.fit(X,y).score(X,y) #輸出 1.0 #KNN reg2 = KNeighborsClassifier() reg2.fit(X,y).score(X,y) #輸出0.967 #邏輯斯蒂 reg3 = LogisticRegression() reg3.fit(X,y).score(X,y) #輸出0.96
從結果可知,決策樹得分最高,預測最準確.
2 預測一個橢圓
#導包 import numpy as np import matplotlib.pyplot as plt from sklearn.tree import DecisionTreeRegressor # 建立X與y rng = np.random.RandomState(1) #僞隨機數 == np.random.seed(1) 可預知的隨機數 #隨機生成-100 到100的數字,這些數字就是角度 X = np.sort(200 * rng.rand(100,1) - 100,axis = 0) #根據角度生成正弦值和餘弦值,這些值就是圓上面的點 y = np.array([np.pi * np.sin(X).ravel(),np.pi * np.cos(X).ravel()]).transpose() #添加噪聲 y[::5,:] += (0.5 -rng.rand(20,2)) #參數max_depth越大,越容易過擬合 # 第1步:訓練 regr1 = DecisionTreeRegressor(max_depth=2) regr2 = DecisionTreeRegressor(max_depth=5) regr3 = DecisionTreeRegressor(max_depth=8) regr1.fit(X,y) regr2.fit(X,y) regr3.fit(X,y) # 第2步:預測 X_test = np.arange(-100.0,100.0,0.01)[:,np.newaxis] y_1 = regr1.predict(X_test) y_2 = regr2.predict(X_test) y_3 = regr3.predict(X_test)
根據數據繪製橢圓圖
# 顯示圖像 plt.figure(figsize=(12,8)) s = 50 plt.subplot(221) plt.scatter(y[:,0],y[:,1],c='navy',s=s,label='data') plt.legend() plt.subplot(222) plt.scatter(y_1[:,0],y_1[:,1],c='b',s=s,label='data') plt.legend() plt.subplot(223) plt.scatter(y_2[:,0],y_2[:,1],c='r',s=s,label='data') plt.legend() plt.subplot(224) plt.scatter(y_3[:,0],y_3[:,1],c='g',s=s,label='data') plt.legend() plt.show()
3 下面咱們對鳶尾花的案例再次進行分析
from sklearn.tree import DecisionTreeClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.linear_model import LogisticRegression #導包加載數據 from sklearn.datasets import load_iris iris = load_iris() data = iris.data target = iris.target
# 特徵選擇?? 方差選擇 data.std(axis=0) # array([0.82530129, 0.43214658, 1.75852918, 0.76061262]) train = data[:,[0,3]] import matplotlib.pyplot as plt %matplotlib inline plt.scatter(train[:,0],train[:,1],c=target)
# 獲取預測集(屏幕中全部的點) xmin,xmax = train[:,0].min(),train[:,0].max() ymin,ymax = train[:,1].min(),train[:,1].max() x = np.linspace(xmin,xmax,300) y = np.linspace(ymin,ymax,300) #meshgrid函數用兩個座標軸上的點在平面上畫格。 xx,yy = np.meshgrid(x,y) X_test = np.c_[xx.ravel(),yy.ravel()]
使用決策樹算法
# max_depth 決策樹深度,通常設置的值不要超過特徵數量 # max_depth 值越大,擬合度越高 tree = DecisionTreeClassifier(max_depth=1) tree.fit(train,target)
使用KNN算法
knn = KNeighborsClassifier(n_neighbors=3) knn.fit(train,target)
使用邏輯斯蒂迴歸算法
logistic = LogisticRegression() logistic.fit(train,target)
預測數據
results = [tree.predict(X_test),knn.predict(X_test),logistic.predict(X_test)]
圖形繪製
from matplotlib.colors import ListedColormap cmap = ListedColormap(['#00aaff','#ff00aa','#aaff00']) titles = ['DecisonTree','Knn','Logistic'] plt.figure(figsize=(12,3)) for i,y_ in enumerate(results): axes = plt.subplot(1,3,i+1) axes.scatter(X_test[:,0],X_test[:,1],c=y_,cmap=cmap) axes.set_title(titles[i]) axes.scatter(train[:,0],train[:,1],c=target)