|
决策树的实施过程主要包含特征选择、决策树的生成与树的修剪
1. 特征选择
(1)熵
--离散变量x取值为i的概率

熵越大,数据的不确定越大。
(2)条件熵

(3)信息增益

(4)信息增益率

(5)基尼系数

对于样本D,假设K个类别,第k个类别的数量为|Ck|,则样本D的基尼系数表达式:
![Gini(D)=1-\sum_{k=1}^k\left [ \frac{|C_k|^2}{|D|} \right ]](https://private.codecogs.com/gif.latex?Gini%28D%29%3D1-%5Csum_%7Bk%3D1%7D%5Ek%5Cleft%20%5B%20%5Cfrac%7B%7CC_k%7C%5E2%7D%7B%7CD%7C%7D%20%5Cright%20%5D)
对于样本D,根据特征j的某个值s,把D分成|D1|和|D2|,则在特征A的条件下,样本D的基尼系数表达式为:

2.决策树生成
(1)ID3
在特征学习的过程中,选用信息增益的原则进行。
(2)C4.5
在特征选择的过程中,选用信息增益比的原则进行。
(3)比较
ID3:会倾向于选择取值较多的特征。
C4.5:可在过程中进行剪枝,减弱了对取值较多的特征的偏好性,对连续变量进行了离散化处理,对缺失值不敏感。
决策树分类规则较为清晰,具有较强的可解释性。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn import model_selection
def load_data():
iris = datasets.load_iris()
X_train = iris.data
y_train = iris.target
return model_selection.train_test_split(X_train, y_train, test_size=0.25,
random_state=0, stratify=y_train)
"""
决策树分类:DecisionTreeClassifier
_init__(self,
criterion="gini", 切分质量的评价准则 gini:基尼系数 entropy:熵
splitter="best", 指定切分原则,best/random
max_depth=None, 指定树的最大深度,整数
min_samples_split=2, 内部节点包含最少的样本数
min_samples_leaf=1, 叶子节点包含最少的样本数
min_weight_fraction_leaf=0., 叶子节点中最小权重系数
max_features=None, 指定了寻找best spilt时的最优特征数量
random_state=None,
max_leaf_nodes=None, 最大叶子节点数量
min_impurity_decrease=0.,
min_impurity_split=None,
class_weight=None, 指定分类的权重
presort=False): 布尔值,指定是否需要提前排序数据
属性:
classes_:分类的标签值
feature_importances_:特征的重要程度
max_features:max_features的推断值
n_outputs_:执行fit后,输出的数量
n_features_:执行fit后,特征的数量
n_classes_:分类的数量
tree_:底层决策树
方法:
fit()
score()
predict()
predict_log_prob(x) x属于各个类别的概率值的对数
predict_prob(x) x属于各个类别的概率值
"""
def test_DecisionTreeClassifier(*args):
X_train, X_test, y_train, y_test =args
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
from sklearn.tree import export_graphviz
export_graphviz(clf, "E:/deep learning/code/machine learning/algorithmtest/out ")
print("training score", clf.score(X_train, y_train))
print("test score", clf.score(X_test, y_test))
if __name__ == '__main__':
X_train, X_test, y_train, y_test = load_data()
test_DecisionTreeClassifier(X_train, X_test, y_train, y_test)
3.剪枝
剪枝损失函数:

T表示一颗决策树,该树共有|T|个节点,每个节点上包含训练样本 个, 表示训练样本 的经验熵。
该损失函数包括决策树分类结果的熵与决策树的叶子节点数量。优化过程需要决策树分类过程后的数据熵很小,同时也需要满足决策树叶子节点数目不能太多。
4.随机森林
随机森林是利用多棵决策树对样本进行预训练并预测的一种方法。随机森林实施过程中,使用CART决策树。
(1)CART回归树
回归树满足以下损失函数,并以此为原则进行特征空间的划分:
![min_{j,s}[min_{c_1}\sum_{x_i\epsilon R_1(j,s)}(y_i-c_1)^2+min_{c_2}\sum_{x_j\epsilon R_1(j,s)}(y_i-c_2)^2]](https://private.codecogs.com/gif.latex?min_%7Bj%2Cs%7D%5Bmin_%7Bc_1%7D%5Csum_%7Bx_i%5Cepsilon%20R_1%28j%2Cs%29%7D%28y_i-c_1%29%5E2+min_%7Bc_2%7D%5Csum_%7Bx_j%5Cepsilon%20R_1%28j%2Cs%29%7D%28y_i-c_2%29%5E2%5D)
j为选的的划分特征,s为该特征的划分点,R为划分之后的集合,c为集合内样本输出均值。
(2)CART分类树
分类树采用基尼系数代替熵。
(3)流程
采用Bootstrap采样法随机有放回的抽取N个样本,作为生成树的训练集。
选择k个特征作为特征子集。k<<K
生成树。
重复上述步骤,直至生成T棵决策树。
import sklearn
import numpy as np
from sklearn import datasets, model_selection, ensemble
from matplotlib import pyplot as plt
"""
回归问题,加载糖尿病病人数据集
"""
def load_dataset_regression():
diabetes = datasets.load_diabetes()
return model_selection.train_test_split(diabetes.data, diabetes.target,
test_size=0.25, random_state=0)
"""
分类问题,加载鸢尾花数据集
"""
def load_dataset_classfication():
diabetes = datasets.load_digits()
return model_selection.train_test_split(diabetes.data, diabetes.target,
test_size=0.25, random_state=0)
"""
随机森林分类
__init__(self,
n_estimators='warn', # 随机森林中决策树的数量
criterion="gini", # 单个决策树的criterion参数
max_depth=None, # 单个决策树的深度,决策树最大深度增高,每个树的性能也提高;
决策树最大深度提高,决策树多样性也在增大
min_samples_split=2, # 生成树时每个节点划分的最小样本数
min_samples_leaf=1, # 叶子节点最少样本数
min_weight_fraction_leaf=0.,
max_features="auto",
max_leaf_nodes=None, # 叶子节点最大样本数
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=True, # 是否有放回采样
oob_score=False,
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None):
"""
def test_RandomForesrClassfier(*args):
X_train, X_test, y_train, y_test = args
clf = ensemble.RandomForestClassifier()
clf.fit(X_train, y_train)
print("training score:%f" %clf.score(X_train, y_train))
print("testing score: %f" %clf.score(X_test, y_test))
def test_RandomForestRegressor(*args):
X_train, X_test, y_train, y_test = args
regr = ensemble.RandomForestRegressor()
regr.fit(X_train, y_train)
print("training score:%f" %regr.score(X_train, y_train))
print("testing score: %f" %regr.score(X_test, y_test))
if __name__ == '__main__':
# X_train, X_test, y_train, y_test = load_dataset_classfication()
# test_RandomForesrClassfier(X_train, X_test, y_train, y_test)
X_train, X_test, y_train, y_test = load_dataset_regression()
test_RandomForestRegressor(X_train, X_test, y_train, y_test)
|