2 `6 j% W7 T# r. S$ {+ m- |+ Vnonce = 0 # 用来给节点一个全局ID , ?5 K( h j+ T: y. Kcolor_i = 0- ^9 ~' s2 x: w# p
# 绘图时节点可选的颜色, 非叶子节点是蓝色的, 叶子节点根据分类被赋予不同的颜色 M) J# f Q% P) t% o w9 c7 w Dcolor_set = ["#AAFFDD", "#DDAAFF", "#DDFFAA", "#FFAADD", "#FFDDAA"] ) m( @$ H+ b1 W' @* Q 4 ?8 e+ Y O% j; K" d# 载入汽车数据, 判断顾客要不要买 " x2 B0 S3 h/ `. L2 _1 Eclass load_car:. m6 d, B! [$ B! S
# 在表格中,最后一列是分类结果6 D/ y3 U2 r% l, ?5 ?+ x
# feature_names: 属性名列表 / z. S: t8 a8 m/ d. {! O # target_names: 标签(分类)名 ( q9 `% @) q( q: g' K: h- Y0 L( ^) F # data: 属性数据矩阵, 每行是一个数据, 每个数据是每个属性的对应值的列表( E r4 @* Q+ D
# target: 目标分类值列表7 p* q+ `2 }4 p$ O4 K/ z5 |
def __init__(self):2 }8 }. A# M6 h2 {9 T
df = pd.read_csv('../dataset/car/car_train.csv') * \; R1 `1 A, y labels = df.columns.values; Y0 k0 `4 K: S3 s
data_array = np.array(df[1:])& F' M- m# F! \' k, f& H9 \
self.feature_names = labels[0:-1]+ K6 \, \, \# o& M7 m x
self.target_names = labels[-1] & w6 I2 p- F' _7 v, b# [+ B self.data = data_array[0:,0:-1] ' ^; m" F& T' K' i4 `! ^ self.target = data_array[0:,-1] - o. ]+ [* r5 L( v) G7 i/ v* Y' H3 k0 {
# 载入蘑菇数据, 鉴别蘑菇是否有毒 ' n5 A/ g' r3 S; G4 J) u Q# I6 Kclass load_mushroom: 0 e- V4 E) l- s1 f8 Z- ` # 在表格中, 第一列是分类结果: e 可食用; p 有毒.) W4 M$ U- g9 Z2 M0 c/ k w' G
# feature_names: 属性名列表 2 a- X3 K* d2 S* c! C& _4 b # target_names: 标签(分类)名 ) v" B, n3 q7 k' l" a # data: 属性数据矩阵, 每行是一个数据, 每个数据是每个属性的对应值的列表$ a( }/ r: J( o
# target: 目标分类值列表 3 W5 ~7 r* J6 [1 { def __init__(self): 0 J% v: v5 B% g7 M df = pd.read_csv('../dataset/mushroom/agaricus-lepiota.data')5 V$ i6 M& I" P. a1 T/ I. b
data_array = np.array(df) r+ e( w( `6 h/ b: p, {
labels = ["edible/poisonous", "cap-shape", "cap-surface", "cap-color", "bruises", "odor", "gill-attachment", + z0 G d/ g7 g, w "gill-spacing", "gill-size", "gill-color", "stalk-shape", "stalk-root", "stalk-surface-above-ring", & g2 ]6 E) U- ~- ] "stalk-surface-below-ring", "stalk-color-above-ring", "stalk-color-below-ring",! f: `3 R# U9 |2 d/ k
"veil-type", "veil-color", "ring-number", "ring-type", "spore-print-color", "population", "habitat"] 7 i; @7 U, e- t | self.feature_names = labels[1:] 6 S. k4 }1 U* K! ` self.target_names = labels[0], b/ o0 r5 D! l5 W, f5 z
self.data = data_array[0:,1:] + x& r2 j `( v3 h self.target = data_array[0:,0] + G" Z. p3 x$ ^2 p, m0 X / X7 `% t5 V x; L# l% @( L# 创建一个临时的子数据集, 在划分测试集和训练集时使用9 e+ g6 F6 O- X; |# z+ P& z+ L& P, [! ^
class new_dataset: 8 Y5 }7 \6 \: _7 H( I # feature_names: 属性名列表 ' o# q. D, w3 h # target_names: 标签(分类)名4 K) J( q: o v" H$ e
# data: 属性数据矩阵, 每行是一个数据, 每个数据是每个属性的对应值的列表9 W7 h% P! H6 x' H! k7 _; C* M
# target: 目标分类值列表4 t8 A7 G) f# Z' n% l! f/ E
def __init__(self, f_n, t_n, d, t): 4 M3 a5 X# b; P S self.feature_names = f_n0 m$ E! Q+ V9 J2 q" \; g; E# o
self.target_names = t_n0 s2 [! `' O$ p
self.data = d. q) l$ W" Z2 c( h! F- O
self.target = t7 E# g5 o7 }0 P5 }# [
. X" Z+ l- h& x# x6 e* c
# 计算熵, 熵的数学公式为: $H(V) = - \sum_{k} P(v_k) \log_2 P(v_k)$ + X8 S( |7 V- O L: ?. Z0 X# 其中 P(v_k) 是随机变量 V 具有值 V_k 的概率 9 k# J( E; z& Y) h1 o# target: 分类结果的列表, return: 信息熵1 l+ S! |9 z- H( \- ~2 m
def get_h(target): + t) q0 e6 |# ^& \ target_count = {}# s# `: p z' i- L
for i in range(len(target)): ' l$ W$ b2 D) O3 f label = target 9 J0 n% e I( ]9 R: e if label not in target_count.keys():9 R! T* F# L) D
target_count[label] = 1.0+ h$ @) v" i( ^; _8 _
else:1 D3 Y. |* z `3 p' M1 }
target_count[label] += 1.01 X7 s/ Q# N; j+ J1 d+ V4 K
h = 0.0; f* `- i" u" {0 |: N# M& O7 I
for k in target_count: " _- r1 Q; ?7 s5 j) z p = target_count[k] / len(target)! w* B8 ~1 |# F9 ?# Z
h -= p * log(p, 2)4 x" D7 g5 U" s; C2 ?6 `) l
return h5 Q% e$ Q* }% _- B5 Z! [) ]$ Q
% P9 u, _) D- \1 t' @9 k4 p* @) p# 取数据子集, 选择条件是原数据集中的属性 feature_name 值是否等于 feature_value2 @) f$ g8 T! D) f$ d3 [
# 注: 选择后会从数据子集中删去 feature_name 属性对应的一列 0 @0 J0 ~! F9 k- s7 \) y7 Z$ cdef get_subset(dataset, feature_name, feature_value): / b2 D* ~) ]! T3 D1 p sub_data = [] . \6 T# \+ @6 d! S& W sub_target = [] 5 S& S4 M* a: E& {5 c f_index = -1 % g! x k9 m2 a3 w+ S: s( F0 Q for i in range(len(dataset.feature_names)): & c" S( V0 u1 F) D& q, w if dataset.feature_names == feature_name: 0 T' O4 p* R' ~6 V2 I: q f_index = i + p, s+ g* O' \9 b break 5 Y' A. R$ G1 h' S# z! w# k: P* _1 b$ h/ [) `$ y
for i in range(len(dataset.data)): ) ?# c. u. q" X. d! f P if dataset.data[f_index] == feature_value:* z2 T0 h! M. m1 R) t4 @3 Z5 u
l = list(dataset.data[:f_index]) 4 q: T8 v" K' P, X/ u- a6 a l.extend(dataset.data[f_index+1:])! A" G1 o% M) [3 b1 m: O: T7 O$ g
sub_data.append(l)/ p# o9 s5 a. `( f. K* C @2 w
sub_target.append(dataset.target) " ~. c! H0 v% }1 z8 ^9 X }- K \3 E$ Y" i( \2 H1 Z
sub_feature_names = list(dataset.feature_names[:f_index])' t3 E0 l% x, ]4 f6 \ Q+ q" [
sub_feature_names.extend(dataset.feature_names[f_index+1:])4 X, L, p. m5 C- T$ k
return new_dataset(sub_feature_names, dataset.target_names, sub_data, sub_target): o! Y, r2 B( F# S7 B1 G# H- h
% b) ?, `# i4 ~; M2 ]- o! W
# 寻找并返回信息收益最大的属性划分. M% J1 Z& ~ Z4 l/ f! a
# 信息收益值划分该数据集前后的熵减; |( z8 q9 ^$ ~+ I3 P( E/ h
# 计算公式为: Gain(A) = get_h(ori_target) - sum(|sub_target| / |ori_target| * get_h(sub_target))$ " w+ r: C( X) u7 `* s& `def best_spilt(dataset):5 ]0 F# l5 j5 X8 ]- }: u7 E
% s, i X9 K' t# v7 _) U% Y base_h = get_h(dataset.target) ; R5 |5 |- ^ M0 U$ T best_gain = 0.0 ) H- s8 [/ p& s, p3 R' R best_feature = None " }' G. Y' e7 \2 f4 D {5 r3 q' E for i in range(len(dataset.feature_names)):+ [& y. X% `6 ^! n
feature_range = [] ' W9 j% I( B6 l. p/ ~/ Q5 Q for j in range(len(dataset.data)):2 ?8 @" y6 R2 ?# j6 ^
if dataset.data[j] not in feature_range:- ?8 S/ T0 A& X* b9 j
feature_range.append(dataset.data[j]) 6 y: D; Q& N" N: Z8 r% a" O4 D8 C8 a/ \
spilt_h = 0.0 * P/ ]0 w/ j; Z( L for feature_value in feature_range: ( U) o7 e- x# r6 C subset = get_subset(dataset, dataset.feature_names, feature_value) * P6 {% u& D) h! s2 c' E; s spilt_h += len(subset.target) / len(dataset.target) * get_h(subset.target) " \( d. X4 z6 k6 ]& x& b6 ?+ p) k" P I" P" p9 |
if best_gain <= base_h - spilt_h: % f6 j& E$ z7 g# } best_gain = base_h - spilt_h; y& P% X4 X( C; o+ o3 i& T j
best_feature = dataset.feature_names ) p, I8 P+ U6 V4 V$ S( K+ F" G! F, [* v
return best_feature4 x4 O2 ?) V# D9 S- z7 f% L
: t; Q. U0 x' H) O9 I. k Q8 ^
# 返回数据集中一个数据最可能的标签 / e0 c; g. k. W& f/ qdef vote_most(dataset): 4 z7 j. x6 z$ x6 f+ Y target_range = {}% m& h( ^* m0 Y: M+ E J& @! O0 k
best_target = None $ Y: k9 P/ E( p* ^' Y* N best_vote = 0 : i) Y& R* |% D+ \3 z" v% o " T$ G; S% p T6 e% y" X for t in dataset.target:5 e, |3 h3 v3 K6 K/ Y8 d" c
if t not in target_range.keys():" ^; J/ T$ e( G. [8 w
target_range[t] = 1 3 Y6 o* a7 W- j5 t+ Q4 I1 J, ^ else: ( G9 \3 @+ S* s% z7 y/ G target_range[t] += 15 C2 s& d0 ~; I" E
4 ^: G ^2 a8 ^: x s6 [3 w for t in target_range.keys(): % y) k* S/ A- g; W" n% v3 e if target_range[t] > best_vote: - q2 {) |& q1 [0 ^# l/ Z best_vote = target_range[t]* r$ G) D- Y1 s% }" `7 G; \4 ?
best_target = t 3 b9 e' m. p, x8 [" j- h7 g7 I* @3 s
return best_target9 I y7 L" w" s! N6 Z( Z3 Z
2 ?: e8 R Z& W
# 返回测试的正确率3 p8 ~7 M% |( j1 J% L* o& Z8 \
# predict_result: 预测标签列表, target_result: 实际标签列表 + x* @; P3 U1 U7 k+ tdef accuracy_rate(predict_result, target_result):$ {( j v* X# Z* C2 L/ V, M$ L
# print("Predict Result: ", predict_result) 5 m6 P( R R7 u; T # print("Target Result: ", target_result)$ _( `1 s& g0 p4 Z s. z) y
accuracy_score = 0% K1 ^6 k( _* F- f% e* @) |
for i in range(len(predict_result)): ) Z) |' P5 B. ]8 P3 D/ W8 {! F if predict_result == target_result:6 n. R1 m$ |- K) y3 t8 v
accuracy_score += 1 I% j, Y& A( ~9 {0 J9 i. s
return accuracy_score / len(predict_result)5 ^+ }& _) A3 S& v, a% K
7 O. p, @: q8 p# 决策树的节点结构! E- \6 G% _. H# n: _7 T
class dt_node: ; |$ W# l5 P" ?* m/ Q* ~# O+ c1 O9 H f3 m8 Y" @5 V& `
def __init__(self, content, is_leaf=False, parent=None): 7 d( d! x' \, d" }1 e global nonce/ l2 ?% D# i$ {* x$ q, y1 Y
self.id = nonce # 为节点赋予一个全局ID, 目的是方便画图. J g6 |2 M5 Q# a6 F
nonce += 1 1 H9 Z% m8 K( I/ t+ x self.feature_name = None ( }/ S4 y: W2 t6 [" N- k self.target_value = None9 R$ j$ Q% Z- q4 m9 @, z+ y4 d
self.vote_most = None # 记录当前节点最可能的标签! q6 q! w! K; a' T
if not is_leaf:8 S @& u2 J% P8 a0 X
self.feature_name = content # 非叶子节点的属性名1 F7 j& Q) U. d. t' O o0 W
else: 1 i3 Y2 k/ x7 D) ]9 j: r7 ~! P self.target_value = content # 叶子节点的标签 9 }. N# [: R P. c( f1 | ( c4 u# J J! x) e9 b self.parent = parent / {+ B5 n$ O. V7 B self.child = {} # 以当前节点的属性对应的属性值作为键值- u# z- C. C0 z& R: o% I5 H
6 w+ A+ y& g$ |% P
# 决策树模型 : f; r4 x& ~' p. ]class dt_tree:3 q$ m- N- n8 E- H1 y
' ^, ~6 i/ t" ]; O+ c; e% E. q
def __init__(self):5 f8 _$ i' u# N6 e# y% H* C) t$ ^
self.tree = None # 决策树的根节点 5 g1 U* n# y6 R! O! a+ C# L self.map_str = """* Q$ C) A: U% E1 n* ~( s
digraph demo{& h& C1 \' \- N
node [shape=box, style="rounded", color="black", fontname="Microsoft YaHei"]; $ ]. p- a! r. I# b0 W Z edge [fontname="Microsoft YaHei"];4 G- N, r- x" i4 S& i+ c+ v7 o. j
""" # 用于作图: pydotplus 格式的树图生成代码结构# X0 ?- `3 h& U1 \5 |- o( s Y
self.color_dir = {} # 用于作图: 叶子节点可选颜色, 以标签值为键值 / x* ?) c( N6 r- {' P5 `9 @: K; [% L7 `
# 训练模型, train_set: 训练集 9 o4 K7 Q0 }. z) m! V, h0 ?* v/ a def fit(self, train_set):) Q$ Z7 A; B7 V
9 a8 H3 |( e" ^9 T
if len(train_set.target) <= 0: # 如果测试集数据为空, 则返回空节点, 结束递归 ! `# \* O& F! Q7 D% @2 R) X return None9 s' ]$ ]4 E. C4 M9 l% k, i
" E8 r s3 m# q8 f! e target_all_same = True2 U! U) @7 p! l& t! k8 p1 B/ `; U
for i in train_set.target: ' h+ n7 D+ [4 o; t1 i if i != train_set.target[0]: |, o3 T. U) o% H; y* V& |6 ?& y, C2 { target_all_same = False 2 W$ [; a1 T/ L, p) | Z$ T break( \5 H6 x2 m d. p+ g- o
& m4 T! s0 X4 Y+ F8 H d8 \. T- ?# r: q
if target_all_same: # 如果测试集数据中所有数据的标签相同, 则构造叶子节点, 结束递归. p6 g b- f" X+ o. T" r# z
node = dt_node(train_set.target[0], is_leaf=True) + B8 Y- k$ V$ T) ?( f if self.tree == None: # 如果根节点为空,则让该节点成为根节点5 }+ c' i$ M ~% ?+ t
self.tree = node 8 @% t8 s# ]9 e( W: G S- t) {+ _; P2 s* w5 c- G' @8 u( E
# 用于作图, 更新 map_str 内容, 为树图增加一个内容为标签值的叶子节点1 G7 Z& B# S$ S, w8 m
node_content = "标签:" + str(node.target_value)4 c. R( J, O4 v. C W- w$ s/ U/ u% X8 _
self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"" + self.color_dir[node.target_value] + "\", style=filled]\n"* U) j4 s$ i6 ?3 d! Q$ B0 r w
3 D7 ] L/ H1 R7 A return node + q. X0 O @7 L% i5 ~* H elif len(train_set.feature_names) == 0: # 如果测试集待考虑属性为空, 则构造叶子节点, 结束递归3 {& H/ n0 X, G @* Z: E
node = dt_node(vote_most(train_set), is_leaf=True) # 这里让叶子结点的标签为概率上最可能的标签 + f5 [' N/ `. V; Z. }* D if self.tree == None: # 如果根节点为空,则让该节点成为根节点 / F5 }, O( @9 V7 n% }8 v self.color_dir[vote_most(train_set)] = color_set[0] * u# R0 P2 O: e9 F self.tree = node; b! T I- Y Y6 F) q( I% u/ C
$ @3 r; _. d Z9 ~2 ` # 用于作图, 更新 map_str 内容, 为树图增加一个内容为标签值的叶子节点1 ?: C8 j: I2 |" e' d* C9 Q6 I
node_content = "标签:" + str(node.target_value)! }: H4 L, P. k% w$ q7 E6 t
self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"" + self.color_dir[node.target_value] + "\", style=filled]\n" * ]4 h) r) Y6 z, j0 E4 C; W# W/ d }: K: H) ]$ S, K9 O
return node) D( t% c0 E3 D
else: # 普通情况, 构建一个内容为属性的非叶子节点 & n1 c0 R7 @1 O h/ B' C/ d- r# P best_feature = best_spilt(train_set) # 寻找最优划分属性, 作为该结点的值 & { J, y9 w# L best_feature_index = -1 ' x, b* F% w; o for i in range(len(train_set.feature_names)):5 Z; _+ o4 x3 E) c6 u
if train_set.feature_names == best_feature: $ ]9 h8 a% s7 Q! P best_feature_index = i / ]- F0 F/ O/ t break- f4 ?8 E V0 k! I
: g6 Y* E2 |, ^9 |7 ` node = dt_node(best_feature) , A% I. F( _. G$ a( o$ [; w6 H node.vote_most = vote_most(train_set)' T! ?. v( C7 w1 V; I; `2 J
if self.tree == None: # 如果根节点为空,则让该节点成为根节点 3 R, |8 ^4 Z! v7 m self.tree = node 2 f0 M( z- y! f% x # 用于作图, 初始化叶子节点可选颜色 ' I4 h' Q; r6 ]/ d7 T; X( J for i in range(len(train_set.target)): o6 t/ t5 H: Y if train_set.target not in self.color_dir: 8 r& |+ c0 O$ A8 F( k global color_i) {8 j. a; b, X5 c
self.color_dir[train_set.target] = color_set[color_i]' Q1 W$ t' E$ b$ B% B
color_i += 1 # _- ?! Q6 r0 @4 s color_i %= len(color_set)/ ?1 v! ~% P# [: ^' E9 [
. H W( F7 u2 J- p) C S/ u feature_range = [] # 获取该属性出现在数据集中的可选属性值 4 o5 S! D" `0 e1 Z for t in train_set.data: 9 l) n4 G- \+ w9 |" I if t[best_feature_index] not in feature_range: 9 h! s2 a% a- l9 Q' i feature_range.append(t[best_feature_index]) b4 a4 ?1 l. X) y* O1 M
/ H7 F4 d" D3 T! B. q4 h # 用于做图, 创建一个内容为属性的非叶子节点 + `! `% q0 c) q" _ node_content = "属性:" + node.feature_name % o0 \! e3 r8 k+ ?+ `" t# K1 F self.map_str += "id" + str(node.id) + "[label=\"" + node_content + "\", fillcolor=\"#AADDFF\", style=filled]\n" 2 D* E0 k7 J/ ]/ a- k. U* N. U* v( }
for feature_value in feature_range: j/ u1 s* h3 M i' @1 T subset = get_subset(train_set, best_feature, feature_value) # 获取每一个子集 , H; p$ p, B+ s s- R node.child[feature_value] = self.fit(subset) # 递归调用 fit 函数生成子节点 : t ~! i8 o. I; K5 U) ` if node.child[feature_value] == None:, G7 ~0 u9 W. A8 `; E( \
# 如果创建的子节点为空, 则创建一个叶子节点作为其子节点, 其中标签值为概率上最可能的标签 $ t7 q3 L& }# _3 h4 P4 q node.child[feature_value] = dt_node(vote_most(train_set), is_leaf=True)4 @; V" d% I4 ?, Z
node.child[feature_value].parent = node N3 _. l& D9 u$ Y& ?
; e3 Q! K- g# T8 n5 q) L3 A # 用于做图, 创建当前节点到所有子节点的连线 w. e8 K) I: p* A4 p9 }) \" r$ a+ P t self.map_str += "id" + str(node.id) + " -> " + "id" + str(node.child[feature_value].id) + "[label=\"" + str(feature_value) + "\"]\n" 9 K" w6 B4 z2 P( C: G " e" L+ E9 n& l U1 ^& o # print("Rest Festure: ", train_set.feature_names)' U. x! V/ D( b( W. g9 D$ `2 P
# print("Best Feature: ", best_feature_index, best_feature, "Feature Range: ", feature_range) " u% @; L3 |7 \ # for feature_value in feature_range: # n& r# `& d! n9 Z" [7 r8 C1 _# [ # print("Child[", feature_value, "]: ", node.child[feature_value].feature_name, node.child[feature_value].target_value) 1 p( s( Y, \" r8 u# A2 I1 L; _0 i return node) w8 q2 f, p' b, r+ z0 P$ L
" C$ q) x5 G( ]8 `- [ # 测试模型, 对测试集 test_set 进行预测# ~4 \: }& E+ |& O
def predict(self, test_set):7 l6 H( k3 c( A2 ^3 c! U
test_result = []: X9 E+ p$ \) T, |* f% x5 S
for test in test_set.data: 8 S: x W0 E) E& ` node = self.tree # 从根节点一只往下找, 知道到达叶子节点 6 j/ y5 L* e9 j while node.target_value == None: 1 e9 g# F9 A0 U* O `! J feature_name_index = -1 3 ]( O* H! G7 C* x$ G8 G& O for i in range(len(test_set.feature_names)): 1 K' C J* v- g: ^ if test_set.feature_names == node.feature_name: 1 E6 D5 J, l [3 |5 M feature_name_index = i 7 w7 J6 M' G7 t break 5 R/ D) H7 e9 f if test[feature_name_index] not in node.child.keys(): 4 N) S2 b! ^3 g" s7 W+ s* I" a9 U% u4 r break2 w' B& m4 E' r7 L0 P4 O8 [
else:: Y' I) K$ p) ?7 c1 k. R, b
node = node.child[test[feature_name_index]] 2 w$ f9 n2 V7 \ ) D6 ^# A8 x2 f+ ` if node.target_value == None:2 B$ p5 d' d4 H" x
test_result.append(node.vote_most) 8 C7 o7 q0 V5 B* r, R else: # 如果没有到达叶子节点, 则取最后到达节点概率上最可能的标签为目标值& v# d0 v% b% J7 r) N7 Z
test_result.append(node.target_value)) L$ N! G" {* y* g/ n% m- P; A4 d
7 C) c6 U2 J# h% L return test_result" R, `6 v6 A) r; H
+ K) w: k" C! i6 R( m9 I5 y# N
# 输出树, 生成图片, path: 图片的位置 6 z. d7 J6 @: s7 ]: B8 y def show_tree(self, path="demo.png"):# L8 _3 x6 J i/ ]
map = self.map_str + "}"$ V, \) c0 a2 n: f' B, |! Y
print(map). {8 V1 F" J) M
graph = pdp.graph_from_dot_data(map)4 W! j! u) P I, F
graph.write_png(path)5 e+ V9 W3 D+ g# o& L+ Y8 z
2 t" F+ ^! {" v# @! m2 e
# 学习曲线评估算法精度 dataset: 数据练集, label: 纵轴的标签, interval: 测试规模递增的间隔6 P) ~! ]( w( l# U
def incremental_train_scale_test(dataset, label, interval=1): 8 r/ V, A9 q: R7 B( B c = dataset T& |& l* l5 L, v8 J
r = range(5, len(c.data) - 1, interval) 3 |. e" Z/ r; [ rates = []# v( p! ^2 M7 W0 l, [0 B; `
for train_num in r:3 Q8 o8 c5 a, d7 R! N7 l1 J
print(train_num) ! u$ [ N1 t6 M1 k& N$ v train_set = new_dataset(c.feature_names, c.target_names, c.data[:train_num], c.target[:train_num])) O* V' T$ [( H s$ q& ^& `6 j0 @. s
test_set = new_dataset(c.feature_names, c.target_names, c.data[train_num:], c.target[train_num:])1 V" Z3 p3 l! A2 Q" l. H
dt = dt_tree() 8 q2 M% W, J& e3 C6 E* M% g- r dt.fit(train_set). ~( ]/ u# M6 K/ o! _: {% r
rates.append(accuracy_rate(dt.predict(test_set), list(test_set.target)))) w) x6 k; Z1 _
9 U, Z4 E$ L; Z/ f7 u
print(rates) - Z6 \; Q( H9 K4 H& V. i plt.plot(r, rates) % b9 C J7 W3 h% U( [3 \6 @ plt.ylabel(label)8 Y& I$ D: L- V6 ?9 Y
plt.show() ( U; i- e2 D+ x ! y/ q" }4 B8 v4 g0 ?$ R mif __name__ == '__main__':5 q) x2 f1 {4 r
0 |( M) G. g+ u m c = load_car() # 载入汽车数据集 . S# r0 S/ J* [& \6 x4 O* | # c = load_mushroom() # 载入蘑菇数据集 2 m5 y' t$ k, H6 D, { train_num = 1000 # 训练集规模(剩下的数据就放到测试集) ' A* s' F% E1 A train_set = new_dataset(c.feature_names, c.target_names, c.data[:train_num], c.target[:train_num]) & S0 `, I9 q* V' Z+ l0 x5 S test_set = new_dataset(c.feature_names, c.target_names, c.data[train_num:], c.target[train_num:]) : f5 u1 I f; y% {7 | % ]. [& X8 x' ~ dt = dt_tree() # 初始化决策树模型 , r, q. ]) O0 ^ dt.fit(train_set) # 训练 8 ?: Z5 W/ n }0 G dt.show_tree("../image/demo.png") # 输出决策树图片) E$ z1 Z0 O% ?) W0 n4 z* f8 N
print(accuracy_rate(dt.predict(test_set), list(test_set.target))) # 进行测试, 并计算准确率吧0 Y9 k/ \3 s& Z! H9 P* h e% F
$ S& g- ~ {) H, m # incremental_train_scale_test(load_car(), "car")& P0 ]* s2 r% Q- G {" K* p5 Q, w
# incremental_train_scale_test(load_mushroom(), "mushroom", interval=20) M+ h- t& n+ C
H2 ^: I. j/ i+ `$ t( P8 R& f N6 H$ A+ b/ r
5 L9 [) v4 Z# `: [1) M" Y* Q% T" h! a N# G
2( h$ o) S {+ j- D
3* Y+ c2 S$ V' G
48 b, x* Z/ e: y& B: q$ H W
5# c4 @$ [" `* b) |9 Z! I8 @
6 7 x6 h, z' p+ @7 * \, a; \0 Q7 X Y4 X' L: o X8 . T! N& V* b! y( f! L4 I9) ^+ c0 E& H: W F& N8 r
10 % \, p9 y$ J. M# z- h11 ' u# [- a& D1 j" g" c$ l* W12* G b: H" p4 y) S4 ~
13& `- r% t7 s4 X/ S, }$ E L0 J
14% e y: i' C0 a
15 2 L5 N7 P+ E" b- A164 s* C4 j" \) |/ c* {, C
173 _9 N" ~8 s6 }+ Z" I$ r3 r
18 $ L" R& H! R! l5 `7 w2 s193 K& h5 u. X8 }* `& N
20 * T6 L( `0 d6 V21 ( k1 C2 ` Y$ v% U8 Y5 Z% `! x22$ V# B4 K# t; M Q: V
23 + r. \0 L: O" Y4 j/ ]24" a0 R7 r! _/ f! e4 n
256 F, [" w& a* G" C1 T# y4 |% n$ ^& W
26 1 Z6 p- |6 C% y: H27 / Z/ b# F c5 ~) }2 P28: S9 s6 [' b" I; v& @& }" M
29 1 O* \7 A+ r$ w0 ~" E# ]9 U30 / n& n9 ~; E% I: o31 ' o/ s8 J, f+ n1 N' ?5 [" R32- U6 i% P5 D3 G5 S$ ?1 c
33' r2 L1 Z1 h. U: e5 t0 k
34 / R& M& u2 g9 I35 & J& B. E2 S# ?2 w- f363 s# g* I9 d) l# |* F& Y
373 y2 W4 o6 G( l4 a% k( R
38 $ {1 ~2 R) j9 B3 D, F4 y39, Z$ ]- W Y/ Y; p8 q2 ?4 w, }! E1 ]* k
40 9 E* o Z- D, M, X419 A. s9 u, E3 Q
42- n8 G9 ]( N, ?# J( J1 h `4 `
43 $ f! A) U1 L x$ c; T3 |( y446 l# B9 F# J3 ~% K& W7 f; {
450 b2 Z/ m8 x! t2 J1 H
46 4 w" e( e' t/ p$ R. Z4 t& U- ^9 n47 $ N. I. P2 J5 T& p/ t' v48, K/ N. ^4 G0 i8 f& q
49 " ~$ \ C5 F; h( s9 h, Z- J509 x/ k! S5 b7 h, y4 o
51 6 h# s* ?* a% c. u6 r52: X' I7 n, x9 N& x- D/ [
53$ ~# [4 i7 I6 S( p4 d1 M
54 7 U! A7 a! ]( W# u" ]5 Z558 e- ]$ O1 x! `, {9 ?
56* g1 O, |7 I6 @" f( s R
57 8 O- `4 Y; f7 b8 L58 9 ?* L o7 {9 K+ A59 / K+ i3 c- {* j9 g! D60 ! y* ?1 O$ e6 e9 b. _- n. h$ J K9 r* n61, F6 F! F d3 l7 u! z
62" K! u, M: z& h9 X: Y4 @
63 4 T2 C1 O5 ^ I! K647 S8 _8 J% s* G7 x0 J7 ?: ]* y
65- a2 m, ^3 [$ |' }. c% i$ D
669 Z6 s. Z, j& R2 n; W) k( R' d
67 4 `# H* K! T! g6 U685 U( C6 W- i3 g, L: g9 q4 f0 x' @: ~
69 $ G! ?' [5 X) \6 Z' m70 E3 s7 g( D% z9 f& e8 D* q; b
71 . E) ?1 H, j/ E9 |72 2 A; M" I7 o: m73( { C5 w5 {1 A' j4 d% {* B3 p
74 8 F4 h6 f. W/ ~" U5 X75 2 ~* L1 x8 z" l4 h1 j2 V5 e76) X9 m( e, @. z' i8 T
77; f" ?* m- d3 p5 s5 m2 a) K4 ^! v; N' `
78 ) Z1 R% h% i" X6 z# t79 8 B6 F7 u8 y: s8 Z% f& R/ [. L80 5 _5 G: n2 D: O! A# C0 F81. e9 y" h/ z* f' Z. h+ ` L' O6 M
822 \3 a( m5 y9 p/ \! q
839 F/ _; o2 e5 F! x
846 \8 b- ~( `2 u2 g/ n( C# `0 W. t
856 j+ g) g) O4 [7 q* S' r6 M
86$ s, P- k3 _8 b g5 C/ f* X% P
87. u% G6 @6 P6 C, K
88: p3 Q+ T6 E! X
898 J: i S) G, i4 H
90. b1 R3 T9 T- `& w' ?3 p: J. F0 j7 L
91 ; V2 Y( A+ H8 L+ k1 R92+ [ ^. m3 r# w/ g) y$ i
93+ U/ _" f! L7 ^% Q
94 3 b- Y6 b# ~9 C0 P, R* ^) z954 I( w( @% ?2 U. |/ g0 p5 |
96' A0 P& [: d8 N$ o; N' g4 ~
971 m2 M7 ]* S, y3 r
981 {: [* {/ ?# O+ E
995 k* Y& o) e! T2 a' _: M
100 ) V( N2 U% C" K3 z8 ]" ^1019 M/ b# S) j1 M6 C
1029 i ]6 P! {. x3 q2 b" ^1 D z
103 : ], q8 ], _: I4 q4 P1042 O2 C0 I# M( V$ Z
105 ( S7 G3 d: S' C7 M1068 _, S. o' S: s# K
107 . d1 R7 V- A/ C+ b$ D108# c+ m( A6 S- `& P
109 4 G e4 C' g( x; d1109 V+ V _; p5 E- A! P* {
111 6 F9 T2 t5 `$ [9 H( z( _112! f4 ]& \: X7 p z
113& P$ l7 W; n5 X) o
114# T. W Q+ M& m0 }& r3 l9 \. s
115 1 U; e; B/ a' C; q116# i: |5 v5 Z5 F1 F! D6 }- Z
117& c4 O0 A, s/ D. B
118 , p4 `; n+ b$ K n& C H5 z# l119 I3 V! n$ P5 V& y* C120; ]/ e: t( n, g: @) U! J3 l
121 + O4 a0 e9 \7 L1 W122+ ~: b7 ~; c( D" x K/ I( w8 U6 b8 @+ }
123 7 `% E" D3 W- s4 N& @124 ( T9 d. v# y5 k" ^125# j8 H; X. {- ]* _
1263 s8 R* a! {, y7 [
127 0 _# i6 d# Q* J7 |128$ l$ j' N. o( | q' P
129" L; @$ F' ?( g v
130 ) U( V, B S: \' V+ p$ Q131 9 o0 D/ \4 N" f$ V3 E132+ o5 G( |+ Q" }+ r
133! M; z- U: l! b7 @
134 * f* V; A& i: U+ }) @# Y135 8 w; c, Y5 @3 Y8 r9 Z5 q7 a136 . D: k. H% ]) l, U- ]& E137 # d: L9 D( s& u; h5 G. ^( |1381 V+ b! V; m% Y: {
139- e3 z% B% c! S7 A
140) g* o5 r1 X6 P- O; h8 s
1417 v$ k0 M, L# g5 `' e
142 1 v6 p/ t7 B% F/ j; H/ l+ [3 N0 m143 ) K' ?2 G" R# y d1445 G, m0 y c6 R" `# M
145- ]6 }& n5 {/ x y: j0 s
146 2 n' N- [; w$ ]5 d$ \% j147. r2 \- h* \& \# ?
148& x) Y+ A- u1 n* ~: ~- t
149 1 S+ U, y5 C& b. u150 + s7 X4 y# }$ A8 C G1 I9 W0 o151$ R- C7 i8 B8 N2 S+ ?' a2 {
152 4 c) N) M) |% k153 - N1 x4 |% c1 W2 ]" b154, f: _3 K" {2 d" ?+ C" q" Y
155$ R# Y& g0 X% G% {3 k7 O
156 Y1 ~: @% U5 T* B
157 & S' _- Y- j' g) D5 n2 a- q/ K5 C1580 X$ C" A1 Z; s0 @+ P( v
159 3 V$ s; g! y' h/ G& N5 }160 5 T: q/ ]7 I, X2 }/ |161 ; E9 V9 ?) O9 C' R& e162 % Q0 R5 N2 Q7 j163; j0 L5 ?. ^0 N" U/ w6 k* s& m% L
164 , C, u. Z% _9 a( E* k4 b" D7 x165 & n) m7 o9 {1 K$ V9 _166 0 S) D; q/ ~3 P: K1676 i! o" P. F+ }) G8 Q
168$ }# }) @$ l) x
169& D$ n, ?1 ~& e9 l* x
1700 H7 g. `2 K+ k$ M# h0 j U
171" @% I4 g, p: k* e7 ]; x+ @% s
172 7 a6 z+ V5 y2 h, P$ o1 i1 l- r173 : X2 C5 F3 x' M! W6 T( Z; Y' ]174 * D5 Q7 Y$ k" A5 ]175 " } ]4 r$ |% \1761 }0 ?. j" d8 c# _; E1 S& G
177$ j) ]- q! L# d. B$ c) s9 n
178 6 C' O/ S5 h1 v/ ~0 T0 y4 E5 D179 8 B' l' x6 a$ t180" n6 i% l0 J9 S! I8 M) E
1813 {% _/ l: C$ o
182 . B% Z5 N3 W1 g! X183' K$ o4 U1 a* B: J: j8 d4 P5 ^( |5 y
184 / b* i+ n: w: T4 G2 b: v8 P; H( O185" k; g& d2 c5 O7 `, b- J! W1 i- q
186, b: [/ Z1 z1 G6 P5 p
187+ W' t# [0 B# |) I4 i
188 8 s& P0 x* q# _4 B8 u189$ ^3 c5 c) b5 Q- B
190 : I- s! S1 i" @191 ; V/ p, Q8 U6 I$ r6 O1 C- T8 d" Q! C192 : s4 Y4 t" b4 Z5 L4 G# D [1 o193/ ]" @, l( A/ F$ g l, O x
194 3 T: n ~% @, d! c* |$ }195 4 x9 x- @3 ?" T: d- D& X& ^196 3 c) n" [- E2 C5 S197" m2 r, K. \: y! s3 j
198 * q2 g G+ Q8 J4 C199 , ^3 _) f# u& x7 }4 n8 y2003 H* C- j3 Z- J8 z$ \$ \
201 % T2 S) B& x( i4 p202- r3 o% y( { j* l7 p( |: p* T9 X4 j
203 ' Z3 s2 O+ y% x' K' [- \204 0 O0 B; K+ N6 p' `205 & |, i6 V" A8 H% k" C* [# w; M" k* o206 2 Y# V" d2 n- V+ l' L207 0 t4 a3 i% W3 y) b0 J# f" R- H3 l1 X208 * m6 c9 Z, e7 c# v/ U209( F9 t- k3 ~# R- r2 Y+ I9 `
210 0 `& ~3 j5 X3 u8 C6 R211' t( g5 l: D1 S" R% ^
212 / t3 `% t% }5 @& q213 4 d" Y8 [9 O3 F7 f214" c. T% V# ]. ~3 n2 \
2154 z# C [$ T* o, \2 G
216 5 W! N( V, f. A% `* N6 j N2179 v+ I& O8 P& |8 V0 A
218* o1 o i9 S) [9 o$ Z
219 ) {2 L5 }" T `( \- c220# J% B8 f% v- T' G# F C- `6 ?
221' Q h! z) ]" Z. N" k' t+ Q
222 % R& J2 @! c7 u2 a223 W& {- F% o& t9 g1 S5 }0 |$ c0 X
224 5 N& A @4 T# f225 . L! m# \0 S3 Y4 l4 G A7 l! T0 _226 + M7 [$ `) m5 ^% t227 # s8 } ]- `' c: M0 ^228 + ? m8 h4 R; o5 d229 $ k$ z7 R5 l7 T230- {' ?6 ^1 N% w- {" P( i
231 9 m- Z0 ^ e9 ~; ?8 D# O232 # @/ F4 o P7 P P7 ~2339 ^$ j% P4 u6 o
234 5 B' {7 n: q) u% N235& S% l- n2 y( r' V) Y
2365 w9 n8 @, F8 c+ ?
2374 l& P3 J5 w3 _0 _. J
238 $ p3 R- c7 Q& v( ]239 ( _' f' X- N x240 % K# z- i9 V% ?" i0 l4 N241! x% b2 n" y2 l2 {! i
2421 N8 r# Y3 M( m9 U. @- R$ h3 E
243 : q- ?2 A5 T! k# i3 q! @" b( ^/ y2441 [! i- _8 [, c8 W% o) k
2450 Z( ^ H' D( ]2 \0 m; X0 p( a/ O. h
246/ G2 D. C8 D/ U9 K* q
247 * k2 q3 U) p B2 q* ?$ j- O% z- w6 [( j248 4 A* `0 I$ h* I; ^249 0 }1 d$ Q' y+ j' E3 C250 . ^1 B: o: c' k1 ?, A* j251& ~" v* i8 U5 L1 C# X. R8 m6 c
252 , Y3 ^7 H" m' w, S) E2534 c o% V! z2 u
254 4 L3 F3 v0 U# W3 I255- k, A2 Q4 n# H X1 H) o- T/ J/ @( n
256. \+ u9 U& U& q$ g9 e6 ]$ `) z; r
257 ) a* X3 Q6 p, G) l- j- F# z258 ) q: @! d4 s- g5 y. ^. g259/ L- E! \" e% Q9 L* r" Q) t
260 3 a5 X/ F! O ^! J: r0 i0 z2 G261 0 t- J o) @0 B5 n2625 i8 V% ?6 T( A- g8 \( c2 O
263 7 N7 U6 {$ i! v: s; a* L, G264 " ^2 s4 q! \- V& D( n! `265( S |% I0 ?' F
266 + n1 ~6 ]8 B4 g+ h# g1 Q2 R, I9 _0 |0 @267 " u: w: O* O3 B# X. S268 0 |6 Q( S j6 p; Q- f269 ( V( g; |6 g6 h$ Y/ M" `+ P270$ ?1 U( k( \# f1 _1 O' S0 x
271! B$ U, i2 p# \0 }5 f6 B, \
272 9 z* f/ n( L$ Z$ X# Y: i) l273* a$ i! W2 h* A* `; R' w
2743 x! p. z( t" y! d7 V: w( a7 A
275 ) E- d B3 A( [' E276" ^; O. s- g+ x
277 q, U' ]7 T5 [* I
278 : K/ {: ^# T! t% A. `5 R% O279) J1 F* |3 [+ _8 u0 K; Y4 \
2800 O! a$ x& H T) S0 W+ \+ e
2811 v: d4 Z( r# V% l/ s l1 z2 Q. F
2820 R2 r. }! I( W0 P0 f1 A0 g8 D5 ?
283 2 [4 K O" j4 R: r! u: z284 : ^% V( Z. F& `. v6 c285 9 u6 f, X0 U# t6 s286: F3 O- c0 q! ?" o" G* ?
287 ; l y( a- L( u0 V) D288% {+ G% Y w7 |% M
289" _* y3 U3 n9 k" l; Q n& `( H
290 * @ h) v, ?+ p8 b: m2917 K# ^2 l+ _4 Q, B6 d5 e" R" O
292 * Q* j# D$ W- f293 3 t! d! w# [1 O t. r294 E; \+ V1 K( J! F$ Y295& u( V4 y$ Y" p5 f) G
2960 L- w$ X! @+ C8 P( K1 k" M
297 5 R/ V. U1 A2 d' H& h/ M: L/ _2983 S* O7 S! E) u/ i; X5 o: X
299* H: z7 a1 ?: S3 c0 F
300 6 ]$ V+ D% ~6 Q5 y9 z301' u* ~; U% d2 p1 A
3020 n! s1 X2 |% g! `$ y
303 |! T6 x) s3 P% K( q9 [, h304" P. J3 O; O3 c) Q& _7 r1 d
3059 H! Z! w& G5 V2 f/ a
306& u" h+ I. I ]7 g/ v
307. {& z! J; v3 i
308 * y) f; }7 V$ [309" Y5 i* T) y3 j6 O1 r
3103 R8 B$ K& N$ H% Q3 J, {- c
311 1 E2 ?! Y% V$ N) X1 i3 O) T3128 j: O$ v+ a4 ~' c. D2 C
313: b5 A+ Y( @ Y' M7 p! _& P
314! s, X1 j1 O, j% v) ~1 p; k. S+ q
315 2 S- U8 G* E: `2 z3167 u2 O$ m( q$ j: ^
3176 X& z* P# a# d: H0 Z# l1 q
318 @; Z: X: `. e. p" p
3192 o* K: V5 d( Y1 E `! k) c; d Y
3202 w/ v6 X! G0 x( M; ?
321 ; ]: A/ @& B" K8 j" @322 ' {% s S/ }, p1 S323 # V0 Y" W$ s) z; z324 ) [- L0 ?3 z! D, F, {# ^7 M3254 ~7 T9 h+ i2 K+ R. k
326 - D h( m8 X2 c$ n; R* P! e; W327 0 y6 s9 p/ N- S7 Q# {' E: x328- f1 E0 P2 N1 t9 e( }5 K
329% n {7 g( r7 A
330 4 c1 @# D) B" Y) R% @: O( h331& _! x% L# u) v, S" r
9 C5 R4 Y5 r; ^. u3 U7 U* ^" G
- h, B* d- A7 c3 T1 z& {% H7 s
( J8 t" |0 z% d7 R3 H ( n5 K6 n! I7 q( y# k 6 r. P% o* @6 |0 I, b/ T ! |4 b: C8 R" l; V( r0 N7 @' t E0 x' S
, f& O) _2 `+ c% e1 g; A* G
+ h9 `1 k, @/ i# v' b8 e) Q$ X% B6 f A* f9 @! C. V
! E2 B$ M/ `7 m6 n& J& {6 X
————————————————: E- ^7 B& h% W6 N* [: j: T. Z
版权声明:本文为CSDN博主「biyezuopin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# w( ~6 @# l5 D$ y5 F: i
原文链接:https://blog.csdn.net/sheziqiong/article/details/126803242, d6 [; u; [( E3 M( M
' K- C2 T9 l6 P6 l- C, Z
) t9 P3 t6 o0 G; t3 N