正文
)
==
0
:
return
get_majority
(
classes
)
# 分裂创建新的子树
tree
=
{}
best_feat_idx
=
self
.
choose_best_split_feature
(
dataset
,
classes
)
feature
=
feat_names
[
best_feat_idx
]
tree
[
feature
]
=
{}
# 创建用于递归创建子树的子数据集
sub_feat_names
=
feat_names
[
:
]
sub_feat_names
.
pop
(
best_feat_idx
)
splited_dict
=
self
.
split_dataset
(
dataset
,
classes
,
best_feat_idx
)
for
feat_val
,
(
sub_dataset
,
sub_classes
)
in
splited_dict
.
items
()
:
tree
[
feature
][
feat_val
]
=
self
.
create_tree
(
sub_dataset
,
sub_classes
,
sub_feat_names
)
self
.
tree
=
tree
self
.
feat_names
=
feat_names
return
tree
树分裂的终止条件有两个
-
一个是遍历完所有的属性
可以看到,在进行树分裂的时候,我们的数据集中的数据向量的长度是不断缩短的,当缩短到0时,说明数据集已经将所有的属性用尽,便也分裂不下去了, 这时我们选取最终子数据集中的众数作为最终的分类结果放到叶子节点上.
-
另一个是新划分的数据集中只有一个类型。
若某个节点所指向的数据集都是同一种类型,那自然没有必要在分裂下去了即使属性还没有遍历完.
构建一棵决策树
这我用了一下MLiA书上附带的隐形眼镜的数据来生成一棵决策树,数据中包含了患者眼部状况以及医生推荐的隐形眼镜类型.
首先先导入数据并将数据特征同类型分开作为训练数据用于生成决策树
from
trees
import
DecisionTreeClassifier
lense_labels
=
[
'age'
,
'prescript'
,
'astigmatic'
,
'tearRate'
]
X
=
[]
Y
=
[]
with
open
(
'lenses.txt'
,
'r'
)
as
f
:
for
line
in
f
:
comps
=
line
.
strip
().
split
(
'\t'
)
X
.
append
(
comps
[
: -
1
])
Y
.
append
(
comps
[
-
1
])
生成决策树:
clf
=
DecisionTreeClassifier
()
clf
.
create_tree
(
X
,
Y
,
lense_labels
)
查看生成的决策树:
In
[
2
]
:
clf
.
tree
Out
[
2
]
:
{
'tearRate'
:
{
'normal'
:
{
'astigmatic'
:
{
'no'
:
{
'age'
:
{
'pre'
:
'soft'
,
'presbyopic'
:
{
'prescript'
:
{
'hyper'
:
'soft'
,
'myope'
:
'no lenses'
}},
'young'
:
'soft'
}},
'yes'
:
{
'prescript'
:
{
'hyper'
:
{
'age'
:
{
'pre'
:
'no lenses'
,
'presbyopic'
:
'no lenses'
,
'young'