7 o) n$ B. D0 X6 i! Q# 载入蘑菇数据, 鉴别蘑菇是否有毒$ @4 B- w& r7 s* W
class load_mushroom:* G2 X U, F) V3 R8 X6 ~8 P
# 在表格中, 第一列是分类结果: e 可食用; p 有毒.7 F: q! q: A7 C
# feature_names: 属性名列表8 [& o; W1 h9 m8 v0 {
# target_names: 标签(分类)名4 g* |( v& F! Z( S
# data: 属性数据矩阵, 每行是一个数据, 每个数据是每个属性的对应值的列表 3 ?) f: T: m5 e # target: 目标分类值列表: ~# k$ a4 v+ A) c$ P5 l$ B
def __init__(self): & [. _2 i, R2 O. @# h. E) a5 A# q df = pd.read_csv('../dataset/mushroom/agaricus-lepiota.data'); w. N0 D8 }3 G" G% X5 B
data_array = np.array(df) 2 Q* n0 c/ ^1 d+ V- e$ u labels = ["edible/poisonous", "cap-shape", "cap-surface", "cap-color", "bruises", "odor", "gill-attachment",+ p# x! ^4 t# g1 n" f& c
"gill-spacing", "gill-size", "gill-color", "stalk-shape", "stalk-root", "stalk-surface-above-ring",7 O* B& @7 d$ U- x
"stalk-surface-below-ring", "stalk-color-above-ring", "stalk-color-below-ring",0 Q9 \+ F1 @3 l5 j% N4 C6 `7 k1 Q C
"veil-type", "veil-color", "ring-number", "ring-type", "spore-print-color", "population", "habitat"] ' h7 F8 L8 k8 J, i4 N7 [3 u. _ self.feature_names = labels[1:]3 A7 p L$ y, p& n Z6 D# R
self.target_names = labels[0] + `) I1 `! ^2 i+ R2 P X1 ~9 b self.data = data_array[0:,1:]/ a/ P7 M! K Z' N0 P
self.target = data_array[0:,0], ]/ R$ B; B; K% b2 }! ^
+ B) A' \6 j$ v" K* ~2 P. m% m9 X( l5 F
# 创建一个临时的子数据集, 在划分测试集和训练集时使用 k% D0 s, ~3 t" Bclass new_dataset:+ |' X5 l7 j% t" _5 ~2 g7 m
# feature_names: 属性名列表" |1 U% i; S; C+ |- S9 V+ e
# target_names: 标签(分类)名1 x$ Y, X! b$ ^. `* |" f
# data: 属性数据矩阵, 每行是一个数据, 每个数据是每个属性的对应值的列表 4 D, A% C! U1 L9 d- r0 l2 ?5 L # target: 目标分类值列表 ; V U( z, o; Q" d- S- C* N def __init__(self, f_n, t_n, d, t): 7 K/ {; h) ?( r P2 A% d! Z7 j self.feature_names = f_n8 g1 m: y4 V+ L u. V9 d. [
self.target_names = t_n ] }; ^: H \% T' |
self.data = d: O7 ]2 I" o* m( W1 Y
self.target = t1 z6 ~4 I+ a) `% y
( D. k/ T# y3 Q
# 计算熵, 熵的数学公式为: $H(V) = - \sum_{k} P(v_k) \log_2 P(v_k)$ % }3 x3 W( E: t0 P1 H3 f% }! r# 其中 P(v_k) 是随机变量 V 具有值 V_k 的概率. n+ [/ }" M+ e% q* L1 D: w; L- p
# target: 分类结果的列表, return: 信息熵 7 Y! D {# n" \& f: Jdef get_h(target): : L) `0 R- [# k& B/ e target_count = {}& k5 f; D, B c/ y$ ]
for i in range(len(target)):& M5 q0 G& ^5 t/ o( E
label = target 6 }6 R# ]! n) ?! F if label not in target_count.keys():3 i, T& _* Y$ @: A, Y
target_count[label] = 1.01 `( A! C# A2 e
else: + |1 E( i% {0 m/ h' g# M' J$ \3 g! K target_count[label] += 1.0' c) W* P" o0 ]6 j' {
h = 0.0 " w( R% K) Q( O for k in target_count: , K g$ P3 a& M p = target_count[k] / len(target) ( \8 O# F& a5 H- u; s% z; p# Q/ q h -= p * log(p, 2) ) a a/ w5 G. e/ [ return h9 O8 ?# B( x3 ~ Z! s3 W3 h3 D c' `
3 M Z4 a: P" R% C! ^7 ]- t# 取数据子集, 选择条件是原数据集中的属性 feature_name 值是否等于 feature_value 2 J7 R9 J* h% m# z* W# 注: 选择后会从数据子集中删去 feature_name 属性对应的一列8 m: b* I3 r: e( r! p! {. m
def get_subset(dataset, feature_name, feature_value): % [4 f+ A+ \. V sub_data = []: F. s" m: }1 _' e
sub_target = []6 C# }! `0 ]. e& L
f_index = -1 1 `: \. H" b2 g* N8 n3 d6 F* a for i in range(len(dataset.feature_names)):3 w- Y( z8 v- I7 ^; h5 U! e/ h
if dataset.feature_names == feature_name:# X$ @7 D) s2 o5 ]2 c3 N0 D# o
f_index = i , I, v3 ?9 n/ m6 W! F8 t break& \1 H: A+ u! {. G+ p2 ^) f% {
1 b' S' ]0 C( i9 W* O# I0 L+ |3 Y6 J for i in range(len(dataset.data)): * U$ r! m# e5 s if dataset.data[f_index] == feature_value:# Z) ~* I6 w( H4 v
l = list(dataset.data[:f_index]) 4 [( b: T7 O3 I. v4 `: O l.extend(dataset.data[f_index+1:])8 O: V. Z- r. L# S5 y
sub_data.append(l) , d7 U# V$ T3 ?8 a$ Q- w- p; c sub_target.append(dataset.target) % s9 b. A0 h( W; k0 R1 g1 D( K
sub_feature_names = list(dataset.feature_names[:f_index]) 8 q; j+ g$ A) v sub_feature_names.extend(dataset.feature_names[f_index+1:]) 9 t" r, Z2 E, {4 J9 f' i. A return new_dataset(sub_feature_names, dataset.target_names, sub_data, sub_target) / y. g8 @" x0 O: X. B7 u2 Q& u: O- [5 A2 t& r! [
# 寻找并返回信息收益最大的属性划分 # ?' ?) E5 ?# d& ]. T/ `$ s7 U# 信息收益值划分该数据集前后的熵减 ( f/ g* t$ A: `$ y4 ]1 F: Y# 计算公式为: Gain(A) = get_h(ori_target) - sum(|sub_target| / |ori_target| * get_h(sub_target))$$ ?2 r( c' V( T; F/ \3 Y
def best_spilt(dataset):5 F+ s" \4 ]# g2 [# R) E" o
! D2 ^/ K! \1 I# Z4 P3 W7 _& P base_h = get_h(dataset.target) ! N. \8 L2 A( Q4 J4 z best_gain = 0.06 c8 M& m* s9 t$ R
best_feature = None: o5 X. f; { R
for i in range(len(dataset.feature_names)):4 u9 M5 D# g8 A- W+ y+ \ g- i
feature_range = [] 7 Q! r! j( @. i9 Q/ U for j in range(len(dataset.data)): 1 s0 Q% ?, h; `- Y, A, _, H if dataset.data[j] not in feature_range:; T1 q8 P1 w' K, q! |2 [! K
feature_range.append(dataset.data[j])$ w8 X% ]& a) L& Z# b& d
* g% y/ f5 C# T. C! y spilt_h = 0.0 ) {5 ^# H* H! a for feature_value in feature_range: ; V' v* L3 D, k subset = get_subset(dataset, dataset.feature_names, feature_value) / ?2 q% F3 S( W k6 m spilt_h += len(subset.target) / len(dataset.target) * get_h(subset.target)) O$ b, E' G8 T' e
& \/ F( ` v# A. {/ S
if best_gain <= base_h - spilt_h: A U8 p5 y3 L. |0 U4 a, E best_gain = base_h - spilt_h: h# t5 f4 T- x' [% R% R A
best_feature = dataset.feature_names* w+ S# j% ?5 E& j+ P
4 S0 t; q3 Z/ ^1 | return best_feature " N# P' k& g7 f/ b, V2 X5 A9 c% t, C: }. u0 k% D+ o
# 返回数据集中一个数据最可能的标签) S& A) J0 a# m+ }% \
def vote_most(dataset): : X1 m7 x) D1 y) V3 C' Q& D. m target_range = {}- [) L# a7 t; x6 @# C/ \1 Y% M
best_target = None 1 Q/ h4 U! j* c' L best_vote = 0* U3 y0 {( ^0 l8 h+ Y. N+ O
. q% K k' u# t- K. g
for t in dataset.target:% h/ M, ]! G; D$ r9 t7 b
if t not in target_range.keys(): c3 E" H- ^8 D+ {& ?: w" H1 O
target_range[t] = 12 i1 o/ K) R4 R+ q* g9 u
else:3 f0 m6 v& b- r4 `; e) |" V+ ~
target_range[t] += 1$ P& |5 g5 n% x0 K1 W6 b
* ^* d3 |0 e+ E for t in target_range.keys():( ]2 F8 Z- _7 G$ _7 r8 o
if target_range[t] > best_vote: $ [1 V" P5 j& Q5 q3 O( p ? best_vote = target_range[t] 3 X! x5 C5 e8 Z5 @5 t% U! t best_target = t ; L2 f, |# q1 O% A: h: U0 B$ m. ^4 g9 n7 s+ J- a" b# k# K
return best_target& A/ X# `, C0 |: {
6 D- b, S0 b# ]% Y! S( v, k/ K1 ^' D# 返回测试的正确率' E' K! k5 L: U& L2 v" R
# predict_result: 预测标签列表, target_result: 实际标签列表2 Y1 w# W0 Z' \
def accuracy_rate(predict_result, target_result):9 y3 {( v3 v0 Q$ r- p" G
# print("Predict Result: ", predict_result) 6 d0 d; p8 E/ U T # print("Target Result: ", target_result) ( @4 C- d2 s$ x: o accuracy_score = 0" e0 f2 ~# R0 Q9 `+ B4 J# k) G
for i in range(len(predict_result)): 8 \$ N! @# ]4 W: v( l* f" I if predict_result == target_result:3 P! F8 ^" Z/ W
accuracy_score += 1 , q O! x" o. D: b return accuracy_score / len(predict_result)+ o" W4 g$ t; l6 N
( W2 q- I( y \
# 决策树的节点结构 : J$ K: T7 E8 ^class dt_node: ! S6 i! N3 {& \, P" x+ }9 ^( q! F8 u; c) d5 u# o: \
def __init__(self, content, is_leaf=False, parent=None):: ^* ?- g. ~- z. j8 G
global nonce- ^; F' G6 f/ Y7 N) p1 j
self.id = nonce # 为节点赋予一个全局ID, 目的是方便画图' c4 n) G0 A0 F) A
nonce += 12 B' ?7 |: B. R: o: U: q3 t
self.feature_name = None, s+ \- u, c* D/ j7 B
self.target_value = None6 X. P+ l' ?( I7 N8 Z
self.vote_most = None # 记录当前节点最可能的标签/ R; x* U, H& V) ^% C" U
if not is_leaf:: v/ P7 R% s l/ M2 b% v
self.feature_name = content # 非叶子节点的属性名! F0 w! A6 @8 Z0 t8 l
else: 9 D5 ~+ z; I- h% Q' w; \ self.target_value = content # 叶子节点的标签9 z% z+ E, t% y8 {. C5 u
6 ?+ E- z. q4 b9 d4 j
self.parent = parent + V$ c# Y+ o' |; D self.child = {} # 以当前节点的属性对应的属性值作为键值 2 m, `8 G6 w$ y3 \- T/ ]' m( j2 F u! N0 X3 u: h$ w- i p9 J
# 决策树模型% B% O" X5 y) {
class dt_tree: 7 r+ R; T& ~8 a. i3 Q4 d 4 `( D- {! g. h0 o def __init__(self): 6 B. b& K+ H, l% p* p9 X self.tree = None # 决策树的根节点 7 ?# F; W/ `; N/ B/ R self.map_str = """ p3 T/ k; S9 ?8 W' g( h! F1 r
digraph demo{3 u& n# [6 J9 N+ q. k6 x
node [shape=box, style="rounded", color="black", fontname="Microsoft YaHei"]; 8 k4 T \6 n- y% e& h1 O7 d edge [fontname="Microsoft YaHei"]; " n+ R; X& ~9 V$ y% H# w1 A """ # 用于作图: pydotplus 格式的树图生成代码结构 j* R3 m w6 `4 r self.color_dir = {} # 用于作图: 叶子节点可选颜色, 以标签值为键值( a& t$ f( V& C X% X' I
0 z. u g" R2 c2 }5 w# E # 训练模型, train_set: 训练集 , W, w* B: c5 E" a3 F def fit(self, train_set):7 s5 P* G( z2 X" u
) G# y0 w& J9 f1 w7 r) I# ]% W if len(train_set.target) <= 0: # 如果测试集数据为空, 则返回空节点, 结束递归 : i+ g1 E9 N5 P0 f) ^3 }9 i return None # j4 c! e3 A% R c, P / {3 F+ [' x1 g! j target_all_same = True ' a8 Y. M3 H) K; Q( o" J8 H E for i in train_set.target:& v+ B6 _) P% X' `( v. a0 x8 c
if i != train_set.target[0]: - V9 M: n+ b5 @7 S* x3 p& v target_all_same = False g+ P$ E! ^! g: L1 p, `! e break , k' V* I. k2 \ H# z ' U1 W4 m5 T" t& W% A if target_all_same: # 如果测试集数据中所有数据的标签相同, 则构造叶子节点, 结束递归 1 k( [3 y2 [4 }: }( `7 ? node = dt_node(train_set.target[0], is_leaf=True)6 T' a( F+ @, u3 L
if self.tree == None: # 如果根节点为空,则让该节点成为根节点 K0 W% F$ C4 w8 f- t
self.tree = node . P7 z$ q4 d1 l$ d: N5 p4 p" X4 t# P/ c1 q' m" U4 O! c
# 用于作图, 更新 map_str 内容, 为树图增加一个内容为标签值的叶子节点: t; S4 x: f5 V% f: K9 Y8 O
node_content = "标签:" + str(node.target_value)* v4 w9 v; I' Y" W; r: t/ B
self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"" + self.color_dir[node.target_value] + "\", style=filled]\n" , [7 S; Y/ {8 Q# r" T$ o* A/ k1 K1 x4 R" h9 ?7 P$ d! x2 l+ I/ Q
return node $ p8 T2 G" e% z1 C! z; |* M$ p! ^ elif len(train_set.feature_names) == 0: # 如果测试集待考虑属性为空, 则构造叶子节点, 结束递归 a. z* H5 r! S7 Y, ? node = dt_node(vote_most(train_set), is_leaf=True) # 这里让叶子结点的标签为概率上最可能的标签 9 T4 {9 Q9 [1 @1 j' X2 p: O if self.tree == None: # 如果根节点为空,则让该节点成为根节点: G; T1 p9 z' i( n7 i
self.color_dir[vote_most(train_set)] = color_set[0] 9 y$ S9 k* N* p4 S/ R self.tree = node 8 B% D$ y# o( q3 z ; x; L% V6 d4 r # 用于作图, 更新 map_str 内容, 为树图增加一个内容为标签值的叶子节点 0 O F- l. \3 o6 H- L% o9 X9 B; ^ node_content = "标签:" + str(node.target_value) " w. P% D: |7 v1 } self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"" + self.color_dir[node.target_value] + "\", style=filled]\n" . a' n1 O5 j0 V8 v7 F1 y7 t + P. U* ?8 ?8 E2 w, w& N2 H return node # e7 x$ R7 j1 U- r/ K- C/ o else: # 普通情况, 构建一个内容为属性的非叶子节点- y9 h) U Y7 \% K- A. p
best_feature = best_spilt(train_set) # 寻找最优划分属性, 作为该结点的值# Q2 g- ~. s; u2 A+ L) S
best_feature_index = -17 T5 a3 [% T6 u
for i in range(len(train_set.feature_names)): 5 q, k$ `' Z3 ~2 f/ U/ F- S/ ? if train_set.feature_names == best_feature:6 V% g0 p' E+ \; M. y( L/ q- H
best_feature_index = i+ j) e$ F) ]0 E! ]) P( E& O
break % @: u* k8 M, U$ A+ j$ w ! V7 j2 n7 H3 F+ W6 I: f& L! X/ v* M node = dt_node(best_feature) 4 j+ I5 X9 M+ ?# o( U node.vote_most = vote_most(train_set)3 I! k; S1 O, L9 B
if self.tree == None: # 如果根节点为空,则让该节点成为根节点# n' l* M9 y2 K9 e+ ` @
self.tree = node - {3 p: r# P' u! V( K" N- l # 用于作图, 初始化叶子节点可选颜色 % e; M! q; m# Y2 V/ L for i in range(len(train_set.target)):& o$ p, a- ]) R! _
if train_set.target not in self.color_dir:' h8 J; E& [6 `3 v
global color_i4 r8 x" |9 T4 a6 r* F; \! t% ^$ y
self.color_dir[train_set.target] = color_set[color_i] ) w; ~/ ]& s0 a% u6 J7 J color_i += 1+ ]5 W" Y6 Q9 F7 a
color_i %= len(color_set) / s$ a$ x; |& g! _' k ; Q# B8 G: |) O feature_range = [] # 获取该属性出现在数据集中的可选属性值 7 S- h+ U9 L9 O9 x for t in train_set.data: 0 P, l' ~3 n7 M: a; Z: D- S if t[best_feature_index] not in feature_range: ' M' J. Q. w; R, h5 D feature_range.append(t[best_feature_index]): r5 R7 D7 p2 R- z# T8 n ] N
+ l( t$ h- ^7 v5 O6 T! m/ p # 用于做图, 创建一个内容为属性的非叶子节点+ _$ x7 [) z9 F
node_content = "属性:" + node.feature_name W" @' S# V$ |' V: [ self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"#AADDFF\", style=filled]\n" + t0 u+ J) X8 W9 j4 g2 v 8 ^, S6 Y; e% n$ y' R8 c for feature_value in feature_range: 9 C9 t$ O3 \/ @, m) A subset = get_subset(train_set, best_feature, feature_value) # 获取每一个子集 # ~ Q# }& j" \$ `9 Y node.child[feature_value] = self.fit(subset) # 递归调用 fit 函数生成子节点! S# t. |7 k) T6 P; e; z' ]+ ^
if node.child[feature_value] == None: 7 L4 e7 J& K/ U" s+ p/ a # 如果创建的子节点为空, 则创建一个叶子节点作为其子节点, 其中标签值为概率上最可能的标签$ G5 Z5 o" O$ c! K$ C- _& x; E
node.child[feature_value] = dt_node(vote_most(train_set), is_leaf=True) l) w9 p; H6 e/ l node.child[feature_value].parent = node* p# }# j) Q( V5 h% [' K- G! L
4 S3 S6 H% O+ O: R/ w # 用于做图, 创建当前节点到所有子节点的连线 ! q- [( ]* E! }) L. I0 P self.map_str += "id" + str(node.id) + " -> " + "id" + str(node.child[feature_value].id) + "[label=\"" + str(feature_value) + "\"]\n" ' x/ y% a3 I& e4 L4 ]. i 6 I3 y, ^1 \9 S* @8 O+ R% o8 z # print("Rest Festure: ", train_set.feature_names)7 l& z7 `! {" \7 R3 p: [
# print("Best Feature: ", best_feature_index, best_feature, "Feature Range: ", feature_range)! i7 p6 v6 H/ q7 Q3 z# v
# for feature_value in feature_range:9 V3 Q) Z {+ m' T9 }$ d
# print("Child[", feature_value, "]: ", node.child[feature_value].feature_name, node.child[feature_value].target_value) : c1 O0 C: B' d/ o P c& M return node) I% z% Y! L- e8 u, G, ]
; O/ p( i* Y0 P) t' z
# 测试模型, 对测试集 test_set 进行预测 : O; k! X+ r: g" w: h% J% z* t def predict(self, test_set):4 L. B! v. g. F# W6 N7 w
test_result = [] . _, _' b6 F; s/ e( M2 X for test in test_set.data:; B4 ~; e7 O5 @- g9 W4 P# ?. h
node = self.tree # 从根节点一只往下找, 知道到达叶子节点 0 ?: t% J: g# p6 i# `8 v0 M* o3 r while node.target_value == None: & ~- Q) b5 a* M feature_name_index = -16 v% H$ @5 n2 H8 T
for i in range(len(test_set.feature_names)):2 z: m8 ^# S m8 P9 a
if test_set.feature_names == node.feature_name: ' A+ Z3 f. b/ x1 P( L& s feature_name_index = i 9 E* \! X3 c& G4 O- h6 Z break - a- {* j; O) U$ M3 A1 ^ if test[feature_name_index] not in node.child.keys():8 T. b9 n9 t7 U9 A$ ?
break % h4 t, f$ o) G x% O9 i else:4 r9 j" R& \& q1 f6 D
node = node.child[test[feature_name_index]] $ u( Q- c' ?* O3 s# E: c# g: _5 t( P8 E3 I6 v
if node.target_value == None: ( M/ y* F' |9 B/ _3 u test_result.append(node.vote_most) - u3 Z% J5 r0 q' Q a else: # 如果没有到达叶子节点, 则取最后到达节点概率上最可能的标签为目标值& a W4 r V' p( Z( I, i4 R
test_result.append(node.target_value) 9 Q3 v4 f0 {" M' F+ b9 l, \2 ~- ?7 y" r X+ f3 \2 b
return test_result . i7 U1 ~$ ^' t i5 t+ m+ d: [5 e4 L9 c! b, ]
# 输出树, 生成图片, path: 图片的位置 7 F6 @4 n/ f# m3 v9 k. C* d9 @ Z def show_tree(self, path="demo.png"):/ m4 T. o q. w2 K- I+ S
map = self.map_str + "}" " _8 B7 u3 a/ c, M: o* W/ q print(map) 8 p* K/ |1 f- a graph = pdp.graph_from_dot_data(map)& X v- u3 k4 h+ N) e0 I7 G% f
graph.write_png(path) 1 p5 f0 ?) U. ]# l7 ]& `" h' ~/ h: W+ ]
# 学习曲线评估算法精度 dataset: 数据练集, label: 纵轴的标签, interval: 测试规模递增的间隔 $ M# X E6 A* p0 L6 R( M" Rdef incremental_train_scale_test(dataset, label, interval=1):1 w" k* ~" Q6 i) X, \8 ?/ N0 G
c = dataset 9 f G' D4 m) c1 U* p4 W6 u# S) ` r = range(5, len(c.data) - 1, interval)9 M& r' w; o+ v) R3 t
rates = []) s, g, G+ O3 s/ b. Z1 h$ j
for train_num in r:0 ^, W* [8 f8 j4 `$ x
print(train_num) S5 W! `$ A" w( A
train_set = new_dataset(c.feature_names, c.target_names, c.data[:train_num], c.target[:train_num]) 2 u) ?+ L; a2 Y test_set = new_dataset(c.feature_names, c.target_names, c.data[train_num:], c.target[train_num:]) ; I. C7 O9 z! o# C dt = dt_tree() - t4 T }7 T# {8 ~7 Z4 r O dt.fit(train_set) 9 _. e Q; g* O, A, x5 Y5 |. t, l rates.append(accuracy_rate(dt.predict(test_set), list(test_set.target)))7 f" P; |' V% f3 `
9 `3 r) P& U( ^$ | print(rates) 6 n6 G ~5 A8 d+ `7 X/ _' K plt.plot(r, rates) 0 F% O* k7 D! q1 q! W& Y plt.ylabel(label) ( G% ?" p7 v% y1 T8 O plt.show() 6 d. i; u; J+ W. j# \; M& ], ]% e8 Q
if __name__ == '__main__':3 w( J6 j3 g" `! G2 U
2 T# R5 Z- ^5 H9 t, f9 j
c = load_car() # 载入汽车数据集 H( g/ R3 p+ G
# c = load_mushroom() # 载入蘑菇数据集 / N) I! N { e4 {! x train_num = 1000 # 训练集规模(剩下的数据就放到测试集)% [" e6 O6 J* D& @4 J7 b
train_set = new_dataset(c.feature_names, c.target_names, c.data[:train_num], c.target[:train_num])3 I# n/ H) \& p7 ]. ?. O3 O& |
test_set = new_dataset(c.feature_names, c.target_names, c.data[train_num:], c.target[train_num:]) 5 F# O6 ?+ |- x# W( Z6 o) j2 P+ U% n2 x& z
dt = dt_tree() # 初始化决策树模型 1 W; w0 Y4 z9 l( s) x dt.fit(train_set) # 训练 6 h( K( f6 u# l3 i8 q dt.show_tree("../image/demo.png") # 输出决策树图片 / C9 q6 v! Q' D. @, A- |4 f/ ^5 A print(accuracy_rate(dt.predict(test_set), list(test_set.target))) # 进行测试, 并计算准确率吧 E' o+ ?" v- R- c }/ K5 J& F
" Q3 ?3 N8 u! w& w
# incremental_train_scale_test(load_car(), "car")4 O7 P0 k! ^3 B' T; X! t' r
# incremental_train_scale_test(load_mushroom(), "mushroom", interval=20): x* P- R, o) B b4 F7 [
; L. m# [* p M( I/ ^% B* _ 5 G0 K7 i1 o- B3 Y) `1 [' {5 c! {" s3 X& o" j Q5 t r( p6 S, Q
18 B: a! W) \2 J) I1 U
2* } t7 B& G( G" u! l5 }
37 j' @: d7 Y& h) |
4 $ w: J5 c: ?4 ?; { X& l. V8 f5' h+ o0 L. i/ j
6 1 Z' A4 g) u& E* R0 |: @7 ) U. Y6 g# N- [, _$ v: x5 X# r2 [8. Y3 G% l/ | T
9( I |# @7 G3 A2 O \
10/ v& P% t" q5 c5 Y5 n, d
11 - b; O3 ~, T: N& i( |7 R; T12* ?. Q5 g6 a6 n5 A0 Q1 t
13! h1 _0 r2 \+ ~, e* O
14 / w. ?. d) @6 K15( r, I' W# U C R- `; F
164 `' ^" ~$ L2 K
17! l; l( t& P& S6 _/ G" I: b
18 8 Q( Q; [* O) T! i19# \" W" v2 F$ |) M
20 8 j4 J! @) l/ x21$ z% A, o4 {; d$ e
22 0 h3 S [( }2 y: {/ I% p( S" G: t235 ]% ~% K5 n5 n
24 6 p- h* L1 O B2 I% a25: G2 R* K! X8 e; V$ g
262 F% c2 s: o/ H! Y# s' ^
27) I" k2 ^. _6 Q" ` t5 J$ x. e( M
280 I4 J( D [* f; C2 Y
293 j7 Z: D. i3 H( q7 Q2 r6 s; }
30 ; d% f1 R' }: u2 b31% e8 e) b: w$ P# ~+ q9 Q9 _
324 d2 d8 I$ I1 L+ F# q
33 ' V b A. a% B" _4 a* O34& f- Z5 F# G& G2 b* Z
35 6 d7 ?7 M. \$ `' V0 l5 S363 C: h4 f/ q* _, W
37" _7 k3 C* C; `. s( N
38 & e: X, a- H3 e6 R! W3 X6 d' R8 e39, a; z* q- `& w% g4 {* [8 Y
40 : u" H' ^- J& T; s41 % w* ^2 y7 Z% `42! z" O; X& W: _1 U' S8 F
43 0 x) F% H$ t% E44& T4 e. \8 C- @9 x3 @9 l
45 2 n! |6 b' E! a7 b9 W46: z2 Z" f2 W6 e# m' w6 @! J- T
47) Z% @% s8 g4 v1 Q+ D2 A% d7 N
48 1 n# F6 H4 L5 l0 \# a4 z, D- c49 , i/ L- S% B3 R. F50, g K5 c0 W3 ]! i5 H2 q; M
518 U$ e) A j" Z; R2 b, x9 I
52" X; n" y8 ?$ L. Z) S* T" | Y
53* k- N* ~0 e4 }9 I
54; a. ~% k) O/ S: N/ |0 P) H- r
55! i9 w& x- E8 {- c! k" D
56 4 V `+ g6 j I$ d+ e+ J3 v0 _5 ?574 q$ y% H" b# c& [4 i
585 d! A7 ?. H3 [# i
59 2 {2 b; ^* S% t u/ U2 y605 ?* b8 Q3 ]& L& _
61 8 L+ x' `: X( s9 O( ]& A622 A. a' L; j9 x9 i( M. {# r
63# @: n6 q! J, q4 z K* c3 O5 ], A
64 9 r* w% {* _. p) |& `0 F+ t; h& u65: H7 U( P" M* R: A1 j" p
66. R" X& [! r- d8 B! q+ b
671 | U+ R7 |: R9 U0 m
68( U1 C+ M. A6 W% {' n% S' |
69 ! A" X8 [% Q9 _3 g {70) D2 {8 z8 T1 C% G
71 , ?; E9 v! x* l72 6 I: m- a. Q, ~, t+ S C' a732 d8 X6 P: _4 C6 X; M5 o6 M0 V
74: X! D L5 a5 X
75 ' g/ J! Q4 U* b a76 , U# c+ v6 A0 |8 x77 2 V8 \: f7 E5 Z7 E8 M. J) A" a78+ A& ~" D1 V+ J1 r3 ~
79% o& `+ M" N+ n# q
80# J5 b9 }' }) z- ?
814 ]" r8 I, s! ^' G
82 ' |4 t& d( z! X8 L83 _8 j, I6 U, P# _& P
84 + i2 v/ C- M" u, H( ]4 u3 T85 ; S5 O6 C2 H' K2 s# J& p86 f1 ]" m) Q( Y0 s1 H87+ ~; k3 z/ `$ i7 H2 }, T0 ~
888 w/ t8 R; U: W
89! ~2 N9 k8 r& d2 }! h
90+ Y* b1 n! _* C* |% y
91* @: W) y/ T. {# P; ?
92* `. m3 _: g, H. j- I: }
93 g# {. {4 X5 T# h8 I$ R4 r( y1 R
94 " V6 @4 ^3 C$ s" U2 U7 _" F95 : C6 N. D1 s9 m$ [& x: ]( u961 ?' d. G K1 i6 @
97 . G, E& M1 M# k1 c2 \98 ; |+ @3 ] L9 b. x0 z. ~99 ! S/ u5 T4 t4 i; w7 A! I+ u100 / j$ M' ~' K# w+ Z0 F3 g0 C' U+ i101 v- ^6 N" L1 T5 j$ j* o
102 1 i* O" N0 ~4 g( L3 L1 g, T' j103 5 \2 ]" N8 D- }: j0 j9 v& Z104& w5 ]) |0 P6 Z6 M% N7 Z
105 - U/ m0 ^/ A2 }5 p$ D \3 U106 - s5 b+ U* _2 z" A" v107 8 v+ v: ?! j! Z# c+ ^1084 a1 {) T7 T* ]9 \4 m: R: T
109 ; ?9 L# W% U' s110" d5 i: p8 r; L0 U
111 * t6 S2 R6 s$ U0 `6 V9 W: \112 8 ]) r; T( `- u" A$ I$ ]( @/ b113, ]& N$ l! e! c* O
114 & B$ ~3 L# \2 `9 N2 Y115 . j+ Y/ T# \% y1161 E# Y! x' z4 K" g- T
1173 o) O2 `* ~; G# m
118 5 U% Y+ g/ N$ i9 z) d" y119 ' C" s* h! ~! d- b/ T) G0 ?. Z' E120 : Q; K- e# J9 C- r. J" j121 ' E. w! v& U5 ~" v122 3 [0 f5 M9 C! P8 f" t123* c; e& W2 \1 _' Z
124: C# Z3 f) u: Z" I- l
1254 h& t$ D! t% c
126+ r1 D O* r' N4 S0 w
127( w n3 [9 L2 x/ Z/ D
128/ U0 a- A$ ^0 w5 S* q
129 0 J- b" C% R0 a1307 u( ^9 h0 E8 O6 I
131 8 C' c' z A i. N132 2 {6 m$ t/ p) ]% o) N4 h133 8 N- e: J9 c. ]% M- `134 % R& f) S& Q5 F0 H% o! p( @135 - P9 Z+ H( f. F9 c9 o+ n1362 k) t: z3 ]; x# `* n- r, A
137+ i$ p2 i- J7 k
138 % p% t' _3 S, i- ?% O139 6 x8 n+ g! g# u4 T2 t( H140 : Q; w5 w; d4 h4 z& {141 # y! h) k# u; S2 t- z0 f: N1426 H8 h2 `- p9 c- [/ X
1436 a5 ?! @; A/ [) b6 ^9 n
144+ J$ m/ u' ~3 P- L7 `2 R# z2 x
145% I m# C! u' L/ T" E o
146% S8 S. Z. L# t
147 $ z+ \% \9 b" x* e" k: r148 ( J1 l% |! k; o; [9 W' { s149# i6 ]1 E7 {( b G
1504 e# ^) H+ n# j) p) r# J2 c* }
151 V$ i& Z" F1 e: z0 F4 M152( l T4 ?0 Z7 [# m7 V4 d
153 1 i3 I6 ~, B L& k154 V" M/ H/ _) L2 A. f: @
155 # [4 P! \5 O; _* E2 Z: `" L156 8 n) G$ q+ i$ c+ j% f157: ~& J& p' v: ^. Z- O
158( I# [ l* h- k6 E1 i2 m
159 & @5 g% @0 {: g* e' v$ R, P160$ v) t6 Y( s O
161 2 }7 E% s0 R- o; C' j# c" d162 1 S/ o) K1 u" n3 P x7 G163& Y6 y) s' w9 g& J( f
164* Z3 L) u4 T' f- L( L) Q
165' d7 G% t/ y! j) F1 }: k3 i
166 ! h4 Q! p& J! Q! {9 z- x5 O167 , E0 A" f- E9 Q4 l/ [( L4 G$ g1688 \ O1 I/ R0 J# I s7 _
169 3 }+ |# n n; j, f% y, I170 ' Z* z& o, y3 C3 ~" u$ d( }! M- G1714 q6 J0 p$ F b$ q
172 ' t) m3 C8 P$ L9 l) G- B* N173 9 D% F* V: s4 f6 G" T& j" c174 ( m. y0 h C- A# D* F175( A' q: y& d6 ]/ V( Y
176 3 ^& [/ m ]3 g( P: t' @& R: `177 J. |9 J1 D/ [* S7 j* d
178$ ` z# t* V7 Y* D6 v
179 4 n! N8 ?0 W. V8 `) {6 r1 P% m180 . ]* `5 I- Y. g( F181 ! K. _* l. L; x3 t P G9 z6 j2 H182; s( Z( H6 Z9 _) P
183 H" z+ z8 v' k& k5 o* p$ ~184; L6 I/ D# Z. v- f7 [
185 * r; ^$ g" a) U' f( P; Z: L186. t' p- d. Y# i* |3 {: Z6 b
187 2 N& d# H" N+ e$ c% g+ w1 x188 . I& P0 Z1 k ]. T189; ^1 v! r Y, a0 z$ F& O+ m
190 2 ]% E) C" q$ |% N4 n, [191& i- ?. Y; b4 ]7 t \$ q
192 $ ~% Y w% a2 ?1 K. u: g) ~, S c. ]193 ( k- H/ {( c) `2 X8 Q1949 m7 `6 n8 ?1 |) p( L( W
195! t" p4 F3 |5 A
196 & A( w; K: A' C+ d% \- z* `. U197 % T( n0 q% L$ ]: A, c$ v# z198" S: |. t1 I) F& \/ J! @/ w K
199 ) W" o: |; C3 |5 f0 ~200 ! h$ M% L& A" K9 R. Q2013 v1 a+ L; O3 P0 ]5 O
202+ e4 P# X! p6 L: m9 n j6 M2 K) D
2033 @6 s' e& U$ i9 }8 z
2043 {0 P6 I( S, s. s) N: ?% @* t
205 . H2 K: ]8 r$ C+ L206 * ]- @5 ^% L8 X& O207 " A' k+ b7 } |* T! S- t& v* }208 - x v1 C) A% a1 x209 5 d4 S/ e i' `' f210+ F* `% @; N2 _ g: {+ O. x
211 * v/ |- {* v) ]212 6 X- ]% r" D) E+ D213! L6 m6 i0 o8 \ x m
214# V( L% \+ r/ H4 k4 O
215) i: d7 d, f/ V, X3 i
216' i$ G9 G) S/ F. ^- c+ a& b- `: c
217- {9 D6 y7 L ^9 P* f2 z( `3 j
218 & M8 ?) ^$ a6 L2 n1 q2 }219/ ?( `! r, Q6 W% b7 v/ o0 n1 x
220+ p, n6 u: B& r a
221# p2 m$ s( ~( D, j5 k# X9 e) l& t
222 9 s1 l& m7 ?7 p& `. I223 1 n! Z" s' |) C0 F1 b) M5 u224 ! b) R$ H8 |$ c/ J2259 B7 |0 J. i. Q/ B4 m
226' l: J9 `4 T) v% S- _) |
227 , V ~! H- p' R228 + @! }% H2 x/ V229 ' n8 s' m/ f* B) N, {2304 f" k/ }9 O+ V, E6 x
231 , \) s2 E8 b6 X: b- t' B/ A232 # d9 q+ P2 y( m! z2333 H) R4 m- O! S
2343 M- _8 w3 d: ^' }4 J3 [: {
235 ; \" v4 U, l x' j236 ; \% C% q# Y6 u2 A$ Z6 D# z# f9 R. |3 L237 ; S- ?: P/ v* Z1 Y3 a- {2383 s7 W$ a5 B2 u1 x4 l
2394 ?1 q' Z# b e& A" U' x7 x
2404 J# U) G" a' [
241' E8 h! K3 h6 ]& l& P) h' A( N
242" }9 k. }7 @& q- T
243 : B: S6 n- z U9 E244% o: g4 `& n# B' a. t" O6 X
2455 I N# f5 c {% N7 O" K- j* n
2465 G% K" k1 M; M P4 J- O
247 * D4 Z, H& O& u3 O248 4 z% w* K+ z+ C7 V P" ?/ g Z249 2 U. i8 v n+ D4 e4 f7 \5 {& N, R250" k; x+ r; R+ j" t l
251( a3 i/ P" p0 ~+ k
252 1 ^; U/ P2 c( ~) V7 `253 }" f* e$ j/ T
254; G6 P$ k" K- v- D3 F+ a. D4 z6 m
2554 ?4 j( Q; j3 {/ F% a. s
256 - h; B. I! h: S* J1 Z/ v257 & w$ w3 R; E" e g s! }4 U7 {258! }0 i. s* ?! B; w
2590 G: C) m( t+ X# k, o. l
260 ( X6 P* I1 K, X1 \# L261 6 L3 d/ o/ M+ B* w9 k1 _2620 R& `( J: E5 Y# D. W* _6 a* E
263 $ N1 P5 g" N; _+ [ d* o* B264 : F8 o) e) K/ x( `265. M0 a$ T3 d) P9 m; R, ^$ Z. r
266' Y, a0 Y) @& `9 x
267; S0 I: Q: ~5 ^( o& x
268 y7 D$ M9 Q! J9 V" a269 ! @: V1 a5 b& n! l/ X% e* q# d; x7 P270' t- J$ M* |) \& F, y
271 - @, W( b6 b5 u# Q. e! f8 _2 l272 - F' |# M g7 j1 d$ t I7 S, w273 . ^" s$ S) K# ~* S, u2 g1 _274 ; O9 D! `# [1 A, J0 }# v. e275 : B1 ?% |" D( J( m( P276/ e# z! ?3 y$ M9 I' ]0 M
277 4 t9 O5 }0 L/ e3 Q! h2 ?278# J0 d$ ?$ Y' v/ b0 P2 e ?5 T2 G
2795 o1 ]0 y, t5 v: B3 m/ ?) ?( f
280 b6 O+ D! }$ |# D6 V2 s
281 . J7 ~4 o1 y0 B. D/ Q282% r, N' @5 u6 S
283; `- y' A# @, h% ?" K1 g
284 , n, ^$ L) b, \; `/ g285 6 e/ z0 U1 f& f7 X286 $ a, T3 J0 b* N287 ) n2 k c q% a2 K4 Q, U( c: `; N k2885 }3 L' N- b4 j1 T9 L( F. `8 g, m1 k
289 / k# O+ h5 [1 {/ {6 U. N$ G* K290 3 m$ b+ X7 i' W' i291 + M: ~$ o* c4 N: H/ p, X2 @292 $ A2 p L0 j% |1 ?2933 r6 v( |% ?8 ?7 J2 H" A
294: n4 l( ~1 ?# W2 d g. N
295 ! C8 I) _, e# J296& E4 s) I$ s$ n0 Y
297 ) |0 {' k8 l2 }2 ~& C/ C8 Z7 K298 6 _( c0 b, S" t# ?) ^299 5 o, ^* N* r9 y0 O' _( f4 s300, }) v# N5 F/ H+ F- m/ O$ ?
3015 ]% W" F, ^% c
302" }* L+ F- F% T7 Z. {, Z# |1 C; @
303* r! Y( ^5 Z( X" i
3043 X- p7 C# X3 `8 ~, N
305 2 @3 ]5 ]1 B4 A: a% C306 , r$ Q" ^2 { f9 ]4 Q( U8 ^307 0 B* B) U0 k- ^- E- s308: ^! b5 P# e4 n, W+ b* Q
309 ) e6 o) D1 p4 K/ U$ a8 F2 `310& y @/ s# e$ C; e2 D
311- Q7 b' V! }7 g! g! a% O
312 ; _# y( W+ F+ l& B9 A( d& g313 ; T4 t7 w! _) A! F3141 u! C# B8 D# ?' k8 n
315) u6 ?& S7 }/ {: { i5 [0 K ]
316. G0 g7 k1 |- \# K
317 - `* u; w" I$ T4 Q" V' k. ~6 \318/ i& y# Z: t q% o" w) [
319 9 ~5 u' L) I0 m" n+ c% t3207 a T' |5 |2 q: U
3212 @5 D$ J& R3 g
322 ; z+ i- `& h3 n: j323 9 h" ]6 F+ O" w$ W" }324 % u5 Z' L8 q$ w9 C C% k3256 ^2 r+ n5 b4 C! f# a$ _
3266 w( H0 l# |( y9 O7 O
327 4 C: z6 _" r& _ I328$ g) C m) Y) m! _. J
329 & Z" u( i4 {+ E# G8 r" V330 3 o, z$ `0 _. |331) x8 `/ m/ f- S" K
# |; B- o: I* K( r0 ]! g' I
3 f0 ?& G( J) \! Z1 n$ l
' t4 {" |; W% U. x
5 c$ S4 U p# ]5 Q9 i4 h
* @3 ]- }$ M2 D% T 9 ]. U1 C( c0 R( G" f1 p - r2 u& m2 y5 P% q3 S' T ' a$ i6 J; ?. r7 m/ Q4 O) @# `& ]
. Z, f0 N: u, X2 [2 Z& n: N