資料鏈接:https://scikit-learn.org/dev/modules/tree.html
決策樹Decision Trees是一種用於分類和迴歸( classification and regression)的無監督學習方法。目標是創建一個模型,從數據特徵中學習簡單的決策規則來預測目標變量的值。
例如,在下面的示例中,決策樹通過if-then-else的決策規則來學習數據從而估測到一個正弦曲線。樹越深,決策規則越複雜,模型對數據的擬合效果就越好。
關於決策樹的一些優點:
- 便於理解和解釋。樹可以可視化。
- 訓練需要的數據少,其他的模型方法通常需要數據規範化 ,比如創建虛擬變量並且刪除缺失值(注意,這個模型不支持缺失值)。
- 訓練模型的時間複雜度是參與訓練數據點的對數值(訓練決策樹的數據點的數據量導致了)。
- 使用白盒模型。如果某種給定的情況在模型中是可以觀測的,那麼就可以通過布爾邏輯解釋這種情況。相比之下,在黑盒模型中(比如,人的神經網絡)的結果就難以解釋。
- 可以用數值統計測試來驗證模型。使解釋驗證該模型的可靠性成爲可能。
- 即使該模型假設的結果與真實模型所提供的數據有出入,但模型的效果仍舊很好。
決策樹的一些缺點:
- 容易過擬合
- 決策樹可能不穩定,數據中微小的變化都可能導致生成完全不同的樹。在集成中使用決策樹可以緩解這個問題。
- 學習最優決策樹的問題通常是一個NP難問題。因此,實際的決策樹學習算法是基於啓發式算法。
- 有些概念難以學習,決策樹不容易表達。例如XOR,奇偶或者複用器的問題
分類
與其他分類器一樣, DecisionTreeClassifier將兩個數組作爲輸入:一個數組X,用
[n_samples, n_features]存放訓練樣本;Y數組用[n_samples]來存放訓練樣本的類標籤。
#導入sklearn包
>>> from sklearn import tree
>>> X = [[0, 0], [1, 1]]
>>> Y = [0, 1]
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(X, Y)
接下來,模型可以預測樣本的類別。
>>> clf.predict([[2., 2.]])
array([1])
或者,可以預測每個類的概率,這個概率是葉子中同類訓練樣本的比例.predict_proba返回的是一個 n 行 k 列的數組, 第 i 行 第 j 列上的數值是模型預測 第 i 個預測樣本爲某個標籤的概率,並且每一行的概率和爲1。
>>> clf.predict_proba([[2., 2.]])
array([[0., 1.]])
所以結果表示預測[2.,2.]的標籤是0的概率是0,是1的概率是1。
DecisionTreeClassifier既支持二分類(其標籤爲[-1,1]),也支持多分類(
[0, …, K-1])。
利用Iris數據集,我們可以構建如下樹:
>>> from sklearn.datasets import load_iris
>>> from sklearn import tree
>>> X, y = load_iris(return_X_y=True)
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(X, y)
一旦經過訓練,可以用plot_tree 函數繪製樹,也可以通過graphviz將樹可視化。首先要安裝一下這個包,如果用conda管理包可以用指令 conda install python-graphviz安裝,我是先用系統安裝了一下再用python安裝。指令:brew install graphviz // pip3 install graphviz
>>> import graphviz
>>> dot_data = tree.export_graphviz(clf, out_file=None)
>>> graph = graphviz.Source(dot_data)
>>> graph.render("iris")
這樣就已經生成一個pdf文件
export_graphviz也支持各種美化圖形。加入各種參數
dot_data = tree.export_graphviz(clf, out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, rounded=True)
graph=graphviz.Source(dot_data)
graph.render("iris")
接下來的示例用的是iris數據集。Iris 鳶尾花數據集是一個經典數據集,在統計學習和機器學習領域都經常被用作示例。數據集內包含 3 類(Iris Setosa,Iris Versicolour,Iris Virginica)共 150 條記錄,每類各 50 個數據,每條記錄都有 4 項特徵:花萼長度、花萼寬度、花瓣長度、花瓣寬度,可以通過這4個特徵預測鳶尾花卉屬於哪一品種。
基於iris數據集繪製決策樹
print(__doc__)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
# Parameters
n_classes = 3
plot_colors = "ryb"
plot_step = 0.02
# Load data
iris = load_iris()
for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3],
[1, 2], [1, 3], [2, 3]]):
# We only take the two corresponding features
#從四列數據中選取兩個特徵進行訓練
X = iris.data[:, pair]
y = iris.target
# Train
clf = DecisionTreeClassifier().fit(X, y)
# Plot the decision boundary
plt.subplot(2, 3, pairidx + 1)
#subplot直接指定劃分方式和位置進行繪圖,2行3列排列圖片
#繪製決策邊界,選擇最大值,最小值
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
# numpy.meshgrid()——生成網格點座標矩陣。numpy.arange()分割數
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
np.arange(y_min, y_max, plot_step))
# tight_layout() 進行自動控制圖像佈局,通過參數pad, w_pad, h_pad設置佈局細節
plt.tight_layout(h_pad=0.5, w_pad=0.5, pad=2.5)
# 按照第一個循環,把第一列花萼長度數據按h取等分,作爲行,然後複製多行,得到xx網格矩陣
#把第二列的花萼寬度數據按h取等分,作爲列,複製多列,得到網格矩陣
#np.c_是按列連接兩個矩陣,就是把兩矩陣左右相加,要求行數相等,類似於pandas中的merge()
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
#繪製等高線的,contour和contourf都是畫三維等高線圖的
#不同點在於contour() 是繪製輪廓線,contourf()會填充輪廓。
#matplotlib.cm是色彩映射函數。
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.RdYlBu)
#橫縱座標label特徵名稱
plt.xlabel(iris.feature_names[pair[0]])
plt.ylabel(iris.feature_names[pair[1]])
# Plot the training points 繪製每個類別的鳶尾花數據的散點圖
for i, color in zip(range(n_classes), plot_colors):
# 這裏的numpy.where()只有一個參數,返回條件爲True的索引
#所以這裏會依次返回每種鳶尾花的樣本索引。
idx = np.where(y == i)
#取出樣本的第0列,第1列
plt.scatter(X[idx, 0], X[idx, 1], c=color, label=iris.target_names[i],
cmap=plt.cm.RdYlBu, edgecolor='black', s=15)
plt.suptitle("Decision surface of a decision tree using paired features")
plt.legend(loc='lower right', borderpad=0, handletextpad=0)
plt.axis("tight")
plt.figure()
clf = DecisionTreeClassifier().fit(iris.data, iris.target)
plot_tree(clf, filled=True)
plt.show()
得到兩個圖
上述代碼中其中,iris.data數據如下
此時X= iris.data[:,pair],第一個循環中取iris.data數據中的第0列和第1列即iris.data[: , [0,1] ]
代碼中numpy.where(condition[,x,y])
參數: |
condition : 數組,bool值 如果爲True, 則產生 x, 否則產生 y. x, y : array_like, 可選 x與y的shape要相同,當condition中的值是true時返回x對應位置的值,false是返回y的 |
---|---|
返回值: |
out : ndarray 或ndarray 原組 ①如果參數有condition,x和y,它們三個參數的shape是相同的。那麼,當condition中的值是true時返回x對應位置的值,false是返回y的。 ②如果參數只有condition的話,返回值是condition中元素值爲true的位置索引,切是以元組形式返回,元組的元素是ndarray數組,表示位置的索引 |