随机森林算法
1.1 题目的主要研究内容
(1)介绍随机森林算法的原理和算法流程,随机森林蕴含的思想,随机森林的应用场景,并且通过软件编程来实现此算法;
(2)查找随机森林算法原理、算法流程以及编写讲解随机森林类部分代码
1.2 题目研究的工作基础或实验条件
软件环境:通过Pycharm软件实现
1.3 随机森林算法原理
随机森林是从原始训练样本集N中有放回地重复随机抽取k个样本生成新的训练样本集合,然后根据自助样本集生成k个分类树组成随机森林,新数据的分类结果按分类树投票多少形成的分数而定。其实质是对决策树算法的一种改进,将多个决策树合并在一起,每棵树的建立依赖于一个独立抽取的样品,森林中的每棵树具有相同的分布,分类误差取决于每一棵树的分类能力和它们之间的相关性。特征选择采用随机的方法去分裂每一个节点,然后比较不同情况下产生的误差。能够检测到的内在估计误差、分类能力和相关性决定选择特征的数目。单棵树的分类能力可能很小,但在随机产生大量的决策树后,一个测试样品可以通过每一棵树的分类结果经统计后选择最可能的分类。
在建立每一棵决策树的过程中,有两点需要注意采样与完全分裂。首先是两个随机采样的过程,random forest对输入的数据要进行行、列的采样。对于行采样,采用有放回的方式,也就是在采样得到的样本集合中,可能有重复的样本。假设输入样本为N个,那么采样的样本也为N个。这样使得在训练的时候,每一棵树的输入样本都不是全部的样本,使得相对不容易出现over-fitting。然后进行列采样,从M个feature中,选择m个(m << M)。之后就是对采样之后的数据使用完全分裂的方式建立出决策树,这样决策树的某一个叶子节点要么是无法继续分裂的,要么里面的所有样本的都是指向的同一个分类。一般很多的决策树算法都一个重要的步骤——剪枝,但是这里不这样干,由于之前的两个随机采样的过程保证了随机性,所以就算不剪枝,也不会出现over-fitting。
1.4 建立随机森林流程图
图1 流程图
1.5 主要程序代码
############开始
# 随机森林类
class randomForest:
def __init__(self,trees_num, max_depth, leaf_min_size, sample_ratio, feature_ratio):
self.trees_num = trees_num # 森林的树的数目
self.max_depth = max_depth # 树的最大深度,超过最大深度的树枝会被剪掉
self.leaf_min_size = leaf_min_size # 建立树时,停止的分枝样本最小数目
self.samples_split_ratio = sample_ratio # 采样,创建子集的比例(行采样)
self.feature_ratio = feature_ratio # 特征比例(列采样)
self.trees = list() # 森林
'''有放回的采样,创建数据子集'''
def sample_split(self, dataset):
sample = list()
n_sample = round(len(dataset) * self.samples_split_ratio)
while len(sample) < n_sample:
index = randint(0, len(dataset) - 2)
sample.append(dataset[index])
return sample
'''建立随机森林'''
def build_randomforest(self, train):
max_depth = self.max_depth
min_size = self.leaf_min_size
n_trees = self.trees_num
n_features = int(self.feature_ratio * (len(train[0])-1))#列采样,从M个feature中,选择m个(m< for i in range(n_trees): sample = self.sample_split(train) tree = build_one_tree(sample, max_depth, min_size, n_features) self.trees.append(tree) return self.trees '''随机森林预测的多数表决''' def bagging_predict(self, onetestdata): predictions = [predict(tree, onetestdata) for tree in self.trees] return max(set(predictions), key=predictions.count) '''计算建立的森林的精确度''' def accuracy_metric(self, testdata): correct = 0 for i in range(len(testdata)): predicted = self.bagging_predict(testdata[i]) if testdata[i][-1] == predicted: correct += 1 return correct / float(len(testdata)) * 100.0 ############结束 1.6 运行结果及分析 图2 结果图