run哥带你手撕决策树&随机森林&Xgboost

xgboost为比赛中的大杀器 今天又是机器学习课 于是复习一下决策树加学一下xgboost

决策树介绍

简单来说 就是依照一些特征进行分类

而对这些特征的评判标准

量化分类效果的方式有很多,比如信息增益(ID3)、信息增益率(C4.5)、基尼系数(CART)

ID3算法

ID3算法的核心是根据信息增益来选择进行划分的特征,然后递归地构建决策树。

熵表示事务不确定性的程度,也就是信息量的大小(一般说信息量大,就是指这个时候背后的不确定因素太多),熵的公式如下:

image-20220916141119480

p(xi) 为对应属性出现的概率 但是貌似这玩意只能算正反例 如果出现三种咋办

信息增益

image-20220916141652400

  1. 从根节点开始,计算所有可能的特征的信息增益,选择信息增益最大的特征作为节点的划分特征;
  2. 由该特征的不同取值建立子节点;
  3. 再对子节点递归1-2步,构建决策树;
  4. 直到没有特征可以选择或类别完全相同为止,得到最终的决策树。

image-20220916142127911

看来还是要写写。。。

这次我们选择一个隐形眼镜数据集

这个数据集只有24个样本 额 咋划分成了一个问题。。。

ID3算法实践

懒得解释了 直接贴代码

3 类
1:患者应安装硬性隐形眼镜,
2:患者应安装软性隐形眼镜,
3:患者不应佩戴隐形眼镜。

1 患者年龄:(1)年轻,(2)老花眼前,(3)老花眼
2 眼镜处方:(1)近视,(2)肥厚
3 散光: (1) 否, (2) 是
4 撕裂发生率:(1)降低,(2)正常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from collections import Counter
from math import log
import numpy as np


# 用一个二维数组来存?
# x_train , y_train
with open("F://机器学习/run-shousi/隐形眼镜/lenses.data","r") as lenses:
data = [i.strip().split() for i in lenses.readlines()]
# 然后分为 x_train , y_train
x_train = [j[1:5] for j in data]
y_train = [k[-1] for k in data]
dataset = [p[1:] for p in data]

x_train = np.array(x_train)
y_train = np.array(y_train)
dataset = np.array(dataset)

def calc_shannon(data):
l = len(data)
c = dict(Counter(data))
# 计算总体的熵
shang = [-c[t]/l*log((c[t]/l),2) for t in c ]
return sum(shang)

Y_Info = calc_shannon(y_train)

def calc_feature_shannon(x_train,y_train):

bastinfogain = 0
bestfeature = 0

for i in range(len(x_train[0])):
Info = 0
# print(x_train[:,i])
# print(dict(Counter(x_train[:,i])))
feature = x_train[:,i]
c = dict(Counter(x_train[:,i]))

# 现在知道了
for key in c:
# print(k)
l = []
for j in range(0,len(feature)):
if feature[j] == key:
l.append(y_train[j])
# 计算l的熵

Info += c[key]/len(feature) * calc_shannon(l)
infogain = Y_Info - Info
if infogain > bastinfogain:
bastinfogain = infogain
bestfeature = i
# 返回各特征的信息熵
return bastinfogain,bestfeature

def splitDataset(x_train,axis,value):
res = []
for i in x_train:
# print(type(i[0])) numpy.str_
if i[axis] == value:
res.append(i)

# print(np.array(res))
#
# print(np.delete(np.array(res),axis,axis=1))

return np.delete(np.array(res),axis,axis=1)

def majority(list):
my_dict = dict(Counter(list))
for key, value in my_dict.items():
return key

feature_list = ['患者年龄','眼镜处方','散光','撕裂发生率']
# labels = ['患者年龄','眼镜处方','散光','撕裂发生率']
def createTree(feature_list,dataset):
classlist = [example[-1] for example in dataset]
if classlist.count(classlist[0]) == len(classlist):#纯的叶子节点
return classlist[0]
elif len(dataset[0]) == 1: #叶子节点
return majority(classlist)
# 先选出最合适的特征作为第一个节点
else:
x_train = dataset[:,0:-1]
y_train = dataset[:,-1]
bestinfogain,bestfeature = calc_feature_shannon(x_train,y_train)

# print(bestinfogain,bestfeature)
# print(feature_list)
# 然后开始分类?
bestfeature_label = feature_list[bestfeature]
# print(bestfeature_label)
# # splitDataset(dataset,axis=bestfeature+1,value)
mytree = {bestfeature_label:{}}
del(feature_list[bestfeature])
# print(bestfeature_label)
featvalues = [example[bestfeature] for example in x_train]
# print(featvalues)
uniqueValues = set(featvalues)
# print(uniqueValues)
for val in uniqueValues:
sublabels = feature_list[:]
mytree[bestfeature_label][val] = createTree(sublabels,splitDataset(dataset,bestfeature,val))

return mytree

# calc_feature_shannon(x_train,y_train)
createTree(feature_list,dataset)

写了一下午 呜呜呜 我太菜惹

Xgboost

Xgboost就是由很多CART树集成

Xgboost就是由很多CART树集成

集成学习根据各个弱分类器之间有无依赖关系,分为Boosting和Bagging两大流派:

  1. Boosting流派,各分类器之间有依赖关系,必须串行,比如Adaboost、GBDT(Gradient Boosting Decision Tree)、Xgboost
  2. Bagging流派,各分类器之间没有依赖关系,可各自并行,比如随机森林(Random Forest)

https://www.kaggle.com/code/craerek/predict-malicious-websites-xgboost/notebook

https://blog.csdn.net/weixin_47723732/article/details/122870062

好像用这库 就挺简单的o.o

随机森林

学了很久突然发现自己连随机森林的概念都不懂 咳咳咳 尴尬