【機器學習】決策樹01
阿新 • • 發佈:2019-04-28
.sh sca ted decision 之前 del png 數據 linspace
什麽是決策樹 - 從一個實際生活的例子入手
如何判斷一個人是否勝任機器學習算法工程師?
這裏的決策樹的每一個節點的判斷都是一個是否問題
使用scikit-learn庫實現的決策樹
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris() X = iris.data[:, 2:] y = iris.target plt.scatter(X[y==0, 0], X[y==0,1]) plt.scatter(X[y==1, 0], X[y==1,1]) plt.scatter(X[y==2, 0], X[y==2,1]) plt.show() from sklearn.tree import DecisionTreeClassifier # max_depth表示決策樹的最大深度 # criterion表示決策樹節點分支的標準,entropy表示利用信息熵作為判斷的標準 dt_clf = DecisionTreeClassifier(max_depth=2, criterion="entropy") dt_clf.fit(X, y) def plot_decision_boundary(model, axis): x0,x1=np.meshgrid( np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(1,-1), np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(1,-1) ) X_new=np.c_[x0. ravel(),x1. ravel()] y_predict=model.predict(X_new) zz=y_predict. reshape(x0. shape) from matplotlib. colors import ListedColormap custom_cmap=ListedColormap(['#EF9A9A','#FFE59D','#90CAF9']) plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3]) plt.scatter(X[y==0, 0], X[y==0,1]) plt.scatter(X[y==1, 0], X[y==1,1]) plt.scatter(X[y==2, 0], X[y==2,1]) plt.show()
數據展示如下:
對上述這個決策樹分類的解釋
決策樹的一些特征
- 非參數學習算法
- 可以解決分類問題,尤其是天然支持多分類問題
- 也可以解決回歸問題
- 具有良好的可解釋性
決策樹的劃分依據
決策樹的核心問題是:
- 每個節點在哪個維度做劃分
- 每個維度在哪個值上做劃分
信息熵
信息熵表示數據的不確定性
嫡越大,數據的不確定性越高
嫡越小,數據的不確定性越低
信息熵的計算公式:
\[ H=-\sum_{i=1}^{k} p_{i} \log \left(p_{i}\right) \]
\(p_{i}\)表示每種可能的取值的概率
對於一個二分類問題,信息熵公式可以表示為
\[ H=-x \log (x)-(1-x) \log (1-x) \]
其中,\(x\)表示一個“1”類別的概率
使用信息熵的決策樹的劃分思想
使用信息熵的決策樹的劃分思想是劃分之後使得信息熵降低
使用遍歷的方法,對每個維度的每個閾值都進行信息熵運算,找到最佳劃分
使用信息熵尋找最優劃分
模擬使用信息熵進行劃分
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris() X = iris.data[:, 2:] y = iris.target def split(X, y, d, value): index_a = (X[:, d] <= value) index_b = (X[:, d] > value) return X[index_a], X[index_b], y[index_a], y[index_b] from collections import Counter from math import log def entropy(y): counter = Counter(y) res = 0.0 for num in counter.values(): p = num / len(y) res += -p * log(p) return res def try_split(X, y): best_entropy = float('inf') best_d, best_v = -1, -1 for d in range(X.shape[1]): # 遍歷每一個特征值,找到最佳劃分所在的維度 sorted_index = np.argsort(X[:, d]) # 對所有樣本按照一個維度的值進行排序 for i in range(1, len(X)): # 遍歷每一個相鄰樣本對,嘗試在這裏進行劃分 if X[sorted_index[i - 1], d] != X[sorted_index[i], d]: v = (X[sorted_index[i - 1], d] + X[sorted_index[i], d]) / 2 # v表示相鄰樣本對的該維度特征值的平均值 X_l, X_r, y_l, y_r = split(X, y, d, v) # 使用該平均值對樣本進行分割 e = entropy(y_l) + entropy(y_r) # 對y(分類值0,1,2)分別計算信息熵 if e < best_entropy: best_entropy = e best_d = d best_v = v return best_entropy, best_d, best_v best_entropy, best_d, best_v = try_split(X, y) print("best_entropy=", best_entropy) # best_entropy= 0.6931471805599453 print("best_d=", best_d) # best_d= 0 print("best_v=", best_v) # best_v= 2.45
通過上述代碼就模擬了第一次進行劃分的過程,可以看到,與之前調用sklearn庫的結果相近。
基尼系數
$
G=1-\sum_{i=1}^{k} p_{i}^{2}
$
基尼系數(英語:Gini coefficient),是20世紀初意大利學者科拉多·基尼(另一說赫希曼)根據勞倫茨曲線所定義的判斷年收入分配公平程度的指標,是比例數值,在0和1之間。在民眾收入中,基尼系數最大為“1”,最小為“0”。前者表示居民之間的年收入分配絕對不平均(即該年所有收入都集中在一個人手裏,其余的國民沒有收入),而後者則表示居民之間的該年收入分配絕對平均,即人與人之間收入絕對平等。
使用scikit-learn庫中提供的決策樹
from sklearn.tree import DecisionTreeClassifier
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data[:, 2:]
y = iris.target
plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.scatter(X[y == 2, 0], X[y == 2, 1])
plt.show()
# max_depth表示決策樹的最大深度;
# criterion表示決策樹節點分支的標準,gini表示使用基尼系數
dt_clf = DecisionTreeClassifier(max_depth=2, criterion="gini")
dt_clf.fit(X, y)
def plot_decision_boundary(model, axis):
x0, x1 = np.meshgrid(
np.linspace(axis[0], axis[1], int(
(axis[1] - axis[0]) * 100)).reshape(1, -1),
np.linspace(axis[2], axis[3], int(
(axis[3] - axis[2]) * 100)).reshape(1, -1))
X_new = np.c_[x0.ravel(), x1.ravel()]
y_predict = model.predict(X_new)
zz = y_predict.reshape(x0.shape)
from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#EF9A9A', '#FFE59D', '#90CAF9'])
plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3])
plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.scatter(X[y == 2, 0], X[y == 2, 1])
plt.show()
信息熵 vs. 基尼系數
信息熵的計算比基尼系數稍慢
scikit-learn中默認為基尼系數
大多數時候兩者沒有特別的效果優劣
CART(Classification And Regression Tree)
根據某一個維度d和某一閾值v進行二分
scikit-learn中的決策樹實現:CART
其他的決策樹:ID3, C4.5, C5.0
【機器學習】決策樹01