决策树也是机器学习中的一个重要算法,但是我们可能平时在决策的时候就常常用到,比如以下天气和怎么出行的问题:
example
决策树是一种非参数学习算法,可以解决分类(包括多分类)问题,还可以解决回归问题。
如下的例子,用iris简单看一下决策树。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris()
iris_all = pd.DataFrame(data=iris.data, columns=iris.feature_names).copy()
# target = iris.target
iris_all['target'] = iris.target
# 为了方便可视化,仅使用两个特征
iris = iris_all.iloc[:,2:]
sns.scatterplot(data=iris, x = iris.columns.values[0], y = iris.columns.values[1],hue='target',palette="Set1")
plt.show()
# 决策边界函数
def plot_boundary(model, X, y):
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
h = .02 # step size in the mesh
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.figure(1, figsize=(4, 3))
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Set3_r)
# Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=plt.cm.Accent)
plt.show()
from sklearn.tree import DecisionTreeClassifier
np.random.seed(2)
iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
dt_clf = DecisionTreeClassifier(max_depth=2, criterion='entropy',) # max_depth 最大深度;criterion选择熵
dt_clf.fit(X, y)
plot_boundary(dt_clf, X, y)
在决策树中,每个节点在哪里划分,是如何确定呢?
信息熵是一种判断方法。熵是信息论中衡量随机变量不确定度的,这个值越大则数据的不确定性越高;反之,越小则数据的不确定性越低。信息熵是度量样本集合纯度最常用的一个指标,假如当前样本集合D中第i类样本所占的比例为
,则D的信息熵为:
假如有一个集合,有三类样本,比例分别为
,那么可求得信息熵为:
假如还有另一个集合,三个分类比例为
,则信息熵为:
第二个集合比第一个集合的信息熵要小。第一个集合的比例都一致,更不确定哪个分类。
假如集合分类是
,那么信息熵可求得为0.
当仅有两个分类时,一个分类的比例为x,则另一个则为1-x,那么公式为:
可视化为:
def entropy(p):
return -p * np.log2(p) - (1-p) * np.log2(1-p)
x = np.linspace(0.001, 0.999, 1000)
plt.plot(x, entropy(x))
plt.show()
基尼系数是另外一种判断方法,其公式为:
同样是像上面的三个例子,它们的基尼系数分别为:
与上面类似,当基尼系数为0时,分类是确定的。当仅有两个分类时,一个分类的比例为x,则另一个则为1-x,那么公式为:
这个抛物线的对称轴也是1/2,在1/2时,信息熵为0,分类最不确定。
from sklearn.tree import DecisionTreeClassifier
np.random.seed(2)
iris = datasets.load_iris()
X = iris.data[:,2:]
y = iris.target
dt_clf = DecisionTreeClassifier(max_depth=2, criterion='gini') # 改成gini系数
dt_clf.fit(X, y)
plot_boundary(dt_clf, X, y)