随机森林算法
1.1 题目的主要研究内容
查找相关资料并介绍随机森林的基本原理,查找相关例程及数据,使用Python和MATLAB软件对随机森林的算法进行演示并分析结果,总结随机森林算法的优缺点及适用性。
查找数据集及随机森林算法例程,通过Python软件导入数据集对随机森林算法进行演示和讲解,对运行结果进行分析及评判。
1.2 题目研究的工作基础或实验条件
(1)硬件环境(PC机)
(2)软件环境(Python)
1.3 设计思想
从原始训练集中随机有放回采样取出m个样本,共进行n次采样。生成n个训练集。对n个训练集,我们分别训练n个决策树模型,对于单个决策树模型,每次分裂时根据信息增益/信息增益比/基尼指数,选择最好的特征进行分裂。每棵树都已知这样分裂下去,知道该节点的所有训练样例都属于同一类。在决策树的分裂过程中不需要剪枝。将生成的多颗决策树组成随机森林。对于分类问题,按照多棵树分类器投票决定最终分类结果;对于回归问题,由多颗树预测值的均值决定最终预测结果。
1.4 基本思路
(1)导入文件并将所有特征转换为float形式。
(2)将数据集分成n份,方便交叉验证,构造数据子集(随机采样),并在指定特征个数(假设m个,手动调参)下选取最优特征。
(3)构造决策树,创建随机森林(多个决策树的结合)。
(4)输入测试集并进行测试,输出预测结果。
1.5 构造步骤
(1)一个样本容量为N的样本,有放回的抽取N次,每次抽取1个,最终形成了N个样本。这选择好了的N个样本用来训练一个决策树,作为决策树根节点处的样本。
(2)当每个样本有M个属性时,在决策树的每个节点需要分裂时,随机从这M个属性中选取出m个属性,满足条件m< (3)决策树形成过程中每个节点都要按照步骤2来分裂(很容易理解,如果下一次该节点选出来的那一个属性是刚刚其父节点分裂时用过的属性,则该节点已经达到了叶子节点,无须继续分裂了)。一直到不能够再分裂为止。注意整个决策树形成过程中没有进行剪枝。 (4)按照步骤1-3建立大量的决策树,这样就构成了随机森林了。 1.6 主要程序代码(要求必须有注释) #创建随机森林 def random_forest(train,test,ratio,n_feature,max_depth,min_size,n_trees): trees=[] for i in range(n_trees): train=get_subsample(train,ratio) tree=build_tree(train,n_features,max_depth,min_size) #print 'tree %d: '%i,tree trees.append(tree) #predict_values = [predict(trees,row) for row in test] predict_values = [bagging_predict(trees, row) for row in test] return predict_values #计算准确率 def accuracy(predict_values,actual): correct=0 for i in range(len(actual)): if actual[i]==predict_values[i]: correct+=1 return correct/float(len(actual)) if __name__=='__main__': seed(1) dataSet=loadCSV('sonar-all-data.csv') column_to_float(dataSet) n_folds=5 max_depth=15 min_size=1 ratio=1.0 #n_features=sqrt(len(dataSet)-1) n_features=15 n_trees=10 folds=spiltDataSet(dataSet,n_folds) scores=[] for fold in folds: train_set=folds[:] #此处不能简单地用train_set=folds,这样用属于引用,那么当train_set的值改变的时候,folds的值也会改变,所以要用复制的形式。(L[:])能够复制序列,D.copy() 能够复制字典,list能够生成拷贝 list(L) train_set.remove(fold) #print len(folds) train_set=sum(train_set,[]) #将多个fold列表组合成一个train_set列表 #print len(train_set) test_set=[] for row in fold: row_copy=list(row) row_copy[-1]=None test_set.append(row_copy) #for row in test_set: # print row[-1] actual=[row[-1] for row in fold] predict_values=random_forest(train_set,test_set,ratio,n_features,max_depth,min_size,n_trees) accur=accuracy(predict_values,actual) scores.append(accur) print ('Trees is %d'% n_trees) print ('scores:%s'% scores) print ('mean score:%s'% (sum(scores)/float(len(scores)))) 1.7 运行结果及分析 结果分析: (1)数据集为1500个数据,测试集为500个数据,每棵树的深度为10。 (2)对500个测试集数据进行随机森林算法分类,分类的平均准确率达到了62.4%#创建随机森林
def random_forest(train,test,ratio,n_feature,max_depth,min_size,n_trees):
trees=[]
for i in range(n_trees):
train=get_subsample(train,ratio)
tree=build_tree(train,n_features,max_depth,min_size)
#print 'tree %d: '%i,tree
trees.append(tree)
#predict_values = [predict(trees,row) for row in test]
predict_values = [bagging_predict(trees, row) for row in test]
return predict_values
#计算准确率
def accuracy(predict_values,actual):
correct=0
for i in range(len(actual)):
if actual[i]==predict_values[i]:
correct+=1
return correct/float(len(actual))
if __name__=='__main__':
seed(1)
dataSet=loadCSV('sonar-all-data.csv')
column_to_float(dataSet)
n_folds=5
max_depth=15
min_size=1
ratio=1.0
#n_features=sqrt(len(dataSet)-1)
n_features=15
n_trees=10
folds=spiltDataSet(dataSet,n_folds)
scores=[]
for fold in folds:
train_set=folds[:] #此处不能简单地用train_set=folds,这样用属于引用,那么当train_set的值改变的时候,folds的值也会改变,所以要用复制的形式。(L[:])能够复制序列,D.copy() 能够复制字典,list能够生成拷贝 list(L)
train_set.remove(fold)
#print len(folds)
train_set=sum(train_set,[]) #将多个fold列表组合成一个train_set列表
#print len(train_set)
test_set=[]
for row in fold:
row_copy=list(row)
row_copy[-1]=None
test_set.append(row_copy)
#for row in test_set:
# print row[-1]
actual=[row[-1] for row in fold]
predict_values=random_forest(train_set,test_set,ratio,n_features,max_depth,min_size,n_trees)
accur=accuracy(predict_values,actual)
scores.append(accur)
print ('Trees is %d'% n_trees)
print ('scores:%s'% scores)
print ('mean score:%s'% (sum(scores)/float(len(scores))))