第12章 决策树

12-1 什么是决策树

Notbook 示例

疑问:改变max_features 的值,图像具有一定随机性

notbook 源码

[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
[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])
<matplotlib.collections.PathCollection at 0x2728e9a1ee0>

[4]
from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier(max_depth=2,max_features=2, criterion='entropy')
dt_clf.fit(X,y)
DecisionTreeClassifier(criterion='entropy', max_depth=2, max_features=2)
[5]
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','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
[6]
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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_15136\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x2728f874df0>

[7]
dt_clf2 = DecisionTreeClassifier(max_depth=2,max_features=1, criterion='entropy')
dt_clf.fit(X,y)

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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_15136\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x2728f2036a0>

 12-2 信息熵

Notbook 示例

Notbook 源码

信息熵
[2]
import numpy as np
import matplotlib.pyplot as plt
[6]
def entropy(p):
    return -p * np.log(p) - (1-p) * np.log(1-p)
[7]
X = np.linspace(0.01, 0.99, 200)
[8]
plt.plot(X,entropy(X))
[<matplotlib.lines.Line2D at 0x2c50e4f70a0>]

12-3 使用信息熵寻找最优划分

Notbook 示例

Notbook 源码

使用信息熵寻找最优划分
[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
[3]
from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier(max_depth=2,max_features=2, criterion='entropy')
dt_clf.fit(X,y)
DecisionTreeClassifier(criterion='entropy', max_depth=2, max_features=2)
[4]
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','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
[5]
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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_13528\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x20ab8e898e0>

模拟使用信息熵进行划分
[6]
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]
[7]
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
                X_l, X_r, y_l, y_r = split(X, y, d, v)
                e = entropy(y_l) + entropy(y_r)
                if e< best_entropy:
                    best_entropy, best_d,best_v = e, d, v
    return best_entropy, best_d,best_v
               
                
[8]
try_split(X,y)
(0.6931471805599453, 0, 2.45)
[9]
best_entropy, best_d, best_v = try_split(X,y)
print('best_entropy = ', best_entropy)
print("best_d = ", best_d)
print("best_v = ",best_v)
best_entropy =  0.6931471805599453
best_d =  0
best_v =  2.45

[10]
X1_l, X1_r, y1_l, y1_r = split(X, y, best_d, best_v)
[11]
entropy(y1_l)
0.0
[12]
entropy(y1_r)
0.6931471805599453
[13]
best_entropy2, best_d2, best_v2 = try_split(X1_r,y1_r)
print('best_entropy2 = ', best_entropy2)
print("best_d2 =", best_d2)
print("best_v =", best_v2)
best_entropy2 =  0.4132278899361904
best_d2 = 1
best_v = 1.75

[14]
X2_l, X2_r, y2_l, y2_r = split(X1_r, y1_r, best_d2, best_v2)
[15]
entropy(y2_l)
0.30849545083110386
[16]
entropy(y2_r)
0.10473243910508653

12-4 基尼系数

 Notbook 示例

Notbook 源码

基尼系数
[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
[3]
from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier(max_depth=2, max_features=2,criterion='gini')
dt_clf.fit(X,y)
DecisionTreeClassifier(max_depth=2, max_features=2)
[4]
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','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
[5]
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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_2040\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x209ca6737c0>

模拟使用基尼系数划分
[6]
from collections import Counter
from math import log

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]

def gini(y):
    counter = Counter(y)
    res = 1.0
    for num in counter.values():
        p = num / len(y)
        res -= p **2 
    return res

def try_split(X, y):
    
    best_g = 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
                X_l, X_r, y_l, y_r = split(X, y, d, v)
                g = gini(y_l) + gini(y_r)
                if g < best_g:
                    best_g, best_d, best_v = g, d, v
                    
    return best_g, best_d, best_v
               
                
[7]
best_entropy, best_d, best_v = try_split(X,y)
print('best_g = ', best_entropy)
print("best_d = ", best_d)
print("best_v = ",best_v)
best_g =  0.5
best_d =  0
best_v =  2.45

[8]
X1_l, X1_r, y1_l, y1_r = split(X, y, best_d, best_v)
[9]
gini(y1_l)
0.0
[10]
gini(y1_r)
0.5
[11]
best_g2, best_d2, best_v2 = try_split(X1_r,y1_r)
print('best_g2 = ', best_g2)
print("best_d2 =", best_d2)
print("best_v =", best_v2)
best_g2 =  0.2105714900645938
best_d2 = 1
best_v = 1.75

[12]
X2_l, X2_r, y2_l, y2_r = split(X1_r, y1_r, best_d2, best_v2)
[13]
gini(y2_l)
0.1680384087791495
[14]
gini(y2_r)
0.04253308128544431

12-5 CART与决策树中的超参数

Notbook 示例

Notbook 源码

CART 和 决策树中的超参数
[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

X,y = datasets.make_moons(noise=0.25,random_state=666)
[3]
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
<matplotlib.collections.PathCollection at 0x1ac3b9a9160>

[4]
from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier()
dt_clf.fit(X,y)
DecisionTreeClassifier()
[5]
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','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
[6]
plot_decision_boundary(dt_clf, axis=[-1.5, 2.5, -2.0, 1.5])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_440\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1ac3c30a280>

[7]
dt_clf2 = DecisionTreeClassifier(max_depth=2)
dt_clf2.fit(X,y)

plot_decision_boundary(dt_clf2, axis=[-1.5, 2.5, -2.0, 1.5])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_440\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1ac3be96f70>

[8]
dt_clf3 = DecisionTreeClassifier(min_samples_split=10)
dt_clf3.fit(X,y)

plot_decision_boundary(dt_clf3, axis=[-1.5, 2.5, -2.0, 1.5])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_440\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1ac3bed7f10>

[9]
dt_clf4 = DecisionTreeClassifier(min_samples_leaf=6)
dt_clf4.fit(X,y)

plot_decision_boundary(dt_clf4, axis=[-1.5, 2.5, -2.0, 1.5])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_440\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1ac3bf1ff10>

[10]
dt_clf5 = DecisionTreeClassifier(max_leaf_nodes=4)
dt_clf5.fit(X,y)

plot_decision_boundary(dt_clf5, axis=[-1.5, 2.5, -2.0, 1.5])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_440\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1ac3bfa26d0>

12-6 决策树解决回归问题

Notbook 示例

Notbook 源码

决策树解决回归问题
[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

boston = datasets.load_boston()
X = boston.data
y = boston.target
F:\anaconda\lib\site-packages\sklearn\utils\deprecation.py:87: FutureWarning: Function load_boston is deprecated; `load_boston` is deprecated in 1.0 and will be removed in 1.2.

    The Boston housing prices dataset has an ethical problem. You can refer to
    the documentation of this function for further details.

    The scikit-learn maintainers therefore strongly discourage the use of this
    dataset unless the purpose of the code is to study and educate about
    ethical issues in data science and machine learning.

    In this special case, you can fetch the dataset from the original
    source::

        import pandas as pd
        import numpy as np


        data_url = "http://lib.stat.cmu.edu/datasets/boston"
        raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
        data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
        target = raw_df.values[1::2, 2]

    Alternative datasets include the California housing dataset (i.e.
    :func:`~sklearn.datasets.fetch_california_housing`) and the Ames housing
    dataset. You can load the datasets as follows::

        from sklearn.datasets import fetch_california_housing
        housing = fetch_california_housing()

    for the California housing dataset and::

        from sklearn.datasets import fetch_openml
        housing = fetch_openml(name="house_prices", as_frame=True)

    for the Ames housing dataset.
    
  warnings.warn(msg, category=FutureWarning)

[3]
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y, random_state=666)
Decision Tree Regression
[5]
from sklearn.tree import DecisionTreeRegressor

dt_reg = DecisionTreeRegressor()
dt_reg.fit(X_train,y_train)
DecisionTreeRegressor()
[6]
dt_reg.score(X_test,y_test)
0.6892800402527158
[7]
dt_reg.score(X_train,y_train)
1.0

12-7 决策树的局限性

Notbook 示例

Notbook 源码

决策树的局限性
[1]
import numpy as np
import matplotlib.pyplot as plt
[2]
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
[3]
from sklearn.tree import DecisionTreeClassifier
tree_clf = DecisionTreeClassifier(max_depth=2,max_features=1, criterion='entropy')
tree_clf.fit(X,y)
DecisionTreeClassifier(criterion='entropy', max_depth=2, max_features=1)
[4]
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','#FFF59D','#90CAF9'])
    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
[5]
plot_decision_boundary(tree_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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_17836\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1b8f722d8e0>

[6]
X_new = np.delete(X, 138, axis=0)
y_new = np.delete(y, 138)
[7]
X_new.shape
(149, 2)
[8]
y_new.shape
(149,)
[9]
tree_clf2 = DecisionTreeClassifier(max_depth=2,criterion='entropy')
tree_clf2.fit(X_new,y_new)
DecisionTreeClassifier(criterion='entropy', max_depth=2)
[10]
plot_decision_boundary(tree_clf2, 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])
C:\Users\Administrator\AppData\Local\Temp\ipykernel_17836\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth'
  plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

<matplotlib.collections.PathCollection at 0x1b8f6bba6a0>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值