决策树

决策树算法

一、特征选取

特征选择在于选取对训练数据具有分类能力的特征。这样可以提高决策树学习的效率。如果利用一个特征进行分类的结果与随机分类的结果没有很大差别,则称这个特征是没有分类能力的。经验上扔掉这样的特征对决策树学习的精度影响不大。通常特征选择的准则是信息增益、信息增益比、基尼指数。

1.信息增益

(1)信息熵

信息的度量方式:信息熵

假设X是一个离散型随机变量,其概率分布为:
P(X=xi) = pi, i=1, 2, 3, 4, ......, n
则其熵为:


0 ≤ H(p) ≤ log n
熵就是对所有可能性带来的信息量求平均值。
熵越大,随机变量的不确定性就越大。

示例:
当随机变量X的取值只有两个:0和1
P(x=1) = p(0 ≤ p ≤ 1)
P(x=0)= 1 - p(0 ≤ p ≤ 1)
熵为:H(p) = -p log p - (1-p) log (1-p) ,图像如下:



当p=0或p=1时,H(p)=0,随机变量完全没有不确定性。
当p=0.5时,H(p)=1,熵取值最大,随机变量不确定性最大。

(2)条件熵

设随机变量(X,Y),其联合概率分布为:
P(X = xi,Y = yj) = pi(i = 1,2,3,…,n;j = 1,2,…,m)

条件熵H(Y|X) 表示在已知随机变量X的条件下随机变量Y的不确定性。随机变量X给定的条件下随机变量Y的条件熵(conditionalentropy)H(Y|X),定义为X给定条件下Y的条件概率分布的熵对X的数学期望:


(3)信息增益

信息增益(information gain)表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。

特征A对训练数据集D的信息增益g(D,A),定义为集合D的熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差:
g(D,A) = H(D) – H(D|A)

一般地,熵H(Y)与条件熵H(Y|X)之差称为互信息(mutual information)

根据信息增益准则的特征选择方法是:对训练数据集(或子集)D,计算其每个特征的信息增益,并比较它们的大小,选择信息增益最大的特征。

2.信息增益比

信息增益值的大小是相对于训练数据集而言的,并没有绝对意义。使用信息增益比可以对这一问题进行校正。这是特征选择的另一准则。

特征A对训练数据集D的信息增益比gR(D,A)定义为其信息增益g(D,A)与训练数据集D的经验熵H(D)之比:


3.基尼系数

分类问题中,假设有K个类,样本点属于第k类的概率为pk,则概率分布的基尼指数定义为:



基尼指数越大,样本集合的不确定性就越大,这一点与熵相似。

下图显示了(横坐标表示概率,纵坐标表示损失):熵之半、分类误差率和基尼指数的关系,由此可见,熵之半和基尼指数都可以近似的代表分类误差率:


二、决策树生成算法

1.ID3算法

ID3算法的核心是在决策树各个结点上应用信息增益准则选择特征,递归地构建决策树。
具体方法是:从根结点(rootnode)开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子结点;再对子结点递归地调用以上方法,构建决策树;直到所有特征的信息增益均很小或没有特征可以选择为止。最后得到一个决策树。

算法
输入:训练数据集D,特征集A,阈值ε(Epsilon)
输出:决策树T。

2.C4.5生成算法

C4.5生成算法与ID3生成算法相似,只是在选取分类特征时使用信息增益比。

算法
输入:训练数据集D,特征集A,阈值ε(Epsilon)
输出:决策树T。

三、决策树剪枝算法

剪枝是决策树算法应对过拟合的主要手段,因为决策树在生成的过程中,为了尽可能的正确分类样本数据,节点的划分过程将不断重复,这样导致的结果就是过拟合。

决策树的剪枝算法大体包含两种:预剪枝后剪枝

  • 预剪枝:在决策树生成的过程中,对每个节点在划分前先进行估计,如果节点的划分不能带来决策树性能的提升,则停止划分,并将当前的节点标识为叶节点。
  • 后剪枝:先从训练集生成一棵完整的决策树,然后自底向上的对非叶节点进行考察,若将该节点对应的子树替换为叶节点能带来决策树泛化性能的提升,则将该子树替换为叶节点。
  • 预剪枝的优缺点:
    预剪枝使决策树的很多分支都没有展开,因此不仅能显著降低过拟合的风险,并且显著减少了决策树的训练时间和测试时间。
    但另一方面,有些分支的当前划分虽然不能提升决策树的泛化性能,但是在其基础熵的后继划分却能显著提高决策树的性能,预剪枝算法会禁止这样的分支展开,因此给决策树带来了欠拟合的风险。
  • 后剪枝的优缺点:
    一般情况下,后剪枝决策树欠拟合的风险很小,泛化性能往往优于预剪枝决策树。但后剪枝决策树需要展开整棵树,并且要自底向上对所有子树进行考察,因此训练时间的开销更大。

四、sckit-learn决策树

所用数据集

1.数据准备

(1)导入数据

def read_dataset(filename):
    # 读取数据,并且把第一列设为索引列
    data = pd.read_csv('./{}.csv'.format(filename), index_col=0)
    
    # 去除无用数据列
    data.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)
    
    # 处理性别数据
    data["Sex"] = (data['Sex'] == 'male').astype("int")
    
    # 将文字编码转换为数字编码
    labels = data['Embarked'].unique().tolist()
    data['Embarked'] = data['Embarked'].apply(lambda n:labels.index(n))
    
    # 处理缺失值
    data = data.fillna(0)
    
    return data

train = read_dataset("train")

(2)分割数据集

# 分割训练集测试集的特征值和标签
from sklearn.model_selection import train_test_split

def feature_label_split(dataset):
    y = dataset['Survived'].values
    X = dataset.drop(['Survived'], axis=1).values
    return X, y

X, y = feature_label_split(train)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

2.初步训练

数据拟合

# 使用树对数据拟合
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(criterion='entropy')
clf.fit(X_train, y_train)
train_score = clf.score(X_train, y_train)
test_score = clf.score(X_test, y_test)

print("train score:{0}; test_score:{1}".format(train_score,test_score))
运行结果

3.优化模型

(1)超参数优化

①最大深度

def cv_score(depth):
    clf = DecisionTreeClassifier(max_depth=depth)
    clf.fit(X_train, y_train)
    tr_score = clf.score(X_train, y_train)
    cv_score = clf.score(X_test, y_test)
    
    return tr_score, cv_score

depths = range(2, 15)
scores = [cv_score(depth) for depth in depths]
tr_scores = [s[0] for s in scores]
cv_scores = [s[1] for s in scores]

# 找出交叉验证评分最高的索引
best_score_index = np.argmax(cv_scores)
best_score = cv_scores[best_score_index]

best_param = depths[best_score_index]

%matplotlib inline
import matplotlib.pyplot as plt

plt.figure(figsize=(6, 4), dpi=96)
plt.grid()
plt.xlabel("decision tree max depth")
plt.ylabel("score")

plt.plot(depths, cv_scores, 'g-', label='test score')
plt.plot(depths, tr_scores, 'r--', label='train score')

plt.legend()
plt.show()

print("最好的参数:{0},最好的分数:{1}".format(best_param, best_score))

运行结果

②基尼系数

# 指定min_impurity_decrease,决定分支条件
def cv_score_gini(val):
    clf = DecisionTreeClassifier(criterion='gini', min_impurity_decrease=val)
    clf.fit(X_train, y_train)
    tr_score = clf.score(X_train, y_train)
    cv_score = clf.score(X_test, y_test)
    
    return tr_score, cv_score

values = np.linspace(0,0.5, 1000)
scores = [cv_score_gini(val) for val in values]
tr_scores = [s[0] for s in scores]
cv_scores = [s[1] for s in scores]

# 找出交叉验证评分最高的索引
best_score_index = np.argmax(cv_scores)
best_score = cv_scores[best_score_index]

best_param = values[best_score_index]

%matplotlib inline
import matplotlib.pyplot as plt

plt.figure(figsize=(6, 4), dpi=96)
plt.grid()
plt.xlabel("threshold of entropy")
plt.ylabel("score")

plt.plot(values, cv_scores, 'g-', label='test score')
plt.plot(values, tr_scores, 'r--', label='train score')

plt.legend()
plt.show()

print("最好的参数:{0},最好的分数:{1}".format(best_param, best_score))

运行结果

(2)网格搜索

from sklearn.model_selection import GridSearchCV
entropy_thresholds = np.linspace(0, 1, 50)
gini_thresholds = np.linspace(0, 0.5, 50)

# 设置参数矩阵
param_grid = [
    {"criterion":['entropy'], 'min_impurity_decrease': entropy_thresholds},
    {"criterion":['gini'], 'min_impurity_decrease': entropy_thresholds},
    {"max_depth": range(2, 15)},
    # 每个节点最小样本数量
    {"min_samples_leaf":range(2, 30, 2)}
]

clf = GridSearchCV(DecisionTreeClassifier(), param_grid, cv=5)
clf.fit(X, y)

print("最好的参数:{0}\n最好的分数:{1}".format(clf.best_params_, clf.best_score_))
运行结果

(3)使用最优超参数重新训练模型

clf = DecisionTreeClassifier(criterion='entropy', max_depth=5, min_samples_leaf=8)
clf.fit(X_train, y_train)
运行结果

4.保存模型

  • 1.首先将决策树模型保存为dot文件:
import sklearn.tree as tree
tree.export_graphviz(decision_tree=clf, out_file="tree.dot")
  • 2.然后用以下方法将dot文件转化为png、pdf等可视化文件:

(1)命令行

.../> dot -Tpng tree.dot -o tree.png
tree.png

(2)Graphviz库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ graphviz
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 决策树理论在决策树理论中,有这样一句话,“用较少的东西,照样可以做很好的事情。越是小的决策树,越优于大的决策树”。...
    制杖灶灶阅读 5,819评论 0 25
  • Decision Trees (DTs) 是一种用来classification和regression的无参监督学...
    婉妃阅读 6,060评论 0 8
  • 决策树是一种基本分类与回归方法。其不要优点是模型具有可读性,分类速度快。学习时,利用训练数据,根据损失函数最小化的...
    rosyxiao阅读 1,064评论 0 0
  • 前言: 通过第前面的学习介绍了机器学习回归模型创建的流程,并且知道了机器学习要做的事情是找到目标函数,优化它,通过...
    飘涯阅读 6,363评论 4 83
  • 1 前言 在了解树模型之前,自然想到树模型和线性模型,他们有什么区别呢? 树形模型是一个一个特征进行处理,之前线性...
    高永峰_GYF阅读 1,370评论 0 1