关闭

随机森林的原理分析及Python代码实现

标签: python机器学习随机森林
11234人阅读 评论(22) 收藏 举报
分类:

在讲随机森林前,我先讲一下什么是集成学习。集成学习通过构建并结合多个分类器来完成学习任务。集成学习通过将多个学习器进行结合,常可获得比单一学习器更好的泛化性能。

考虑一个简单例子:在二分类任务中,假定三个分类器在三个测试样本上的表现如下图,其中√表示分类正确,×表示分类错误,集成学习的结果通过投票法产生,即“少数服从多数”。如下图,在(a)中,每个分类器都只有66.6%的精度,但集成学习却达到了100%;在(b)中,三个分类器没有差别,集成之后性能没有提高;在(c)中,每个分类器的精度都只有33.3%,集成学习的结果变得更糟。这个简单地例子显示出:要获得好的集成,个体学习器应“好而不同”,即个体学习器要有一定的“准确性”,即学习器不能太差,并且要有“多样性”,即学习器间具有差异。

 

根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即个体学习器之间存在强依赖关系,必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系,可同时生成的并行化方法;前者的代表是Boosting,后者的代表是Bagging和“随机森林”(Random Forest)

Bagging与随机森林

要得到泛化性能强的集成,集成中的个体学习器应尽可能相互独立,虽然这在现实任务中很难做到,但我们可以设法使基学习器尽可能具有较大的差异。

在我的实验中,使用“自助采样法”:给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m次随机操作,我们得到含m个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现。

按照这种方法,我们可以采样出T个含m个训练样本的采样集,然后基于每个采样集训练处一个基学习器,再将这些基学习器进行结合,这就是Bagging的基本流程。在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法。


随机森林是Bagging的一个扩展。随机森林在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择(即引入随机特征选择)。传统决策树在选择划分属性时时在当前节点的属性集合(假定有d个属性)中选择一个最优属性;而在随机森林中,对基决策树的每个节点,先从该节点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分。这里的参数k控制了随机性的引入程度:若令k=d,则基决策树的构建与传统决策树相同;若令k=1,则是随机选择一个属性进行划分。

在这篇文章中,我们只讲随机森林的分类部分。随机森林用于分类时,即采用n个决策树分类,将分类结果用简单投票法得到最终分类,提高分类准确率。

对于决策树不太了解的童鞋,可以看我的上一篇博客:决策树原理及Python代码实现

简单来说,随机森林就是对决策树的集成,但有两点不同:

(1)采样的差异性:从含m个样本的数据集中有放回的采样,得到含m个样本的采样集,用于训练。这样能保证每个决策树的训练样本不完全一样。

(2)特征选取的差异性:每个决策树的n个分类特征是在所有特征中随机选择的(n是一个需要我们自己调整的参数)

随机森林需要调整的参数有:

(1)    决策树的个数

(2)    特征属性的个数

(3)    递归次数(即决策树的深度)

 

下面,讲一下如何用代码实现随机森林。

代码实现流程:

(1)    导入文件并将所有特征转换为float形式

(2)    将数据集分成n份,方便交叉验证

(3)    构造数据子集(随机采样),并在指定特征个数(假设m个,手动调参)下选取最优特征

(4)    构造决策树

(5)    创建随机森林(多个决策树的结合)

(6)    输入测试集并进行测试,输出预测结果

 

(1)    导入文件并将所有特征转换为float形式

#加载数据
def loadCSV(filename):
    dataSet=[]
    with open(filename,'r') as file:
        csvReader=csv.reader(file)
        for line in csvReader:
            dataSet.append(line)
    return dataSet

#除了判别列,其他列都转换为float类型
def column_to_float(dataSet):
    featLen=len(dataSet[0])-1
    for data in dataSet:
        for column in range(featLen):
            data[column]=float(data[column].strip())
(2)    将数据集分成n份,方便交叉验证

#将数据集分成N块,方便交叉验证
def spiltDataSet(dataSet,n_folds):
    fold_size=int(len(dataSet)/n_folds)
    dataSet_copy=list(dataSet)
    dataSet_spilt=[]
    for i in range(n_folds):
        fold=[]
        while len(fold) < fold_size:   #这里不能用if,if只是在第一次判断时起作用,while执行循环,直到条件不成立
            index=randrange(len(dataSet_copy))
            fold.append(dataSet_copy.pop(index))  #pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
        dataSet_spilt.append(fold)
    return dataSet_spilt

(3)    构造数据子集(随机采样),并在指定特征个数(假设m个,手动调参)下选取最优特征
#构造数据子集
def get_subsample(dataSet,ratio):
    subdataSet=[]
    lenSubdata=round(len(dataSet)*ratio)
    while len(subdataSet) < lenSubdata:
        index=randrange(len(dataSet)-1)
        subdataSet.append(dataSet[index])
    #print len(subdataSet)
    return subdataSet

#选取任意的n个特征,在这n个特征中,选取分割时的最优特征
def get_best_spilt(dataSet,n_features):
    features=[]
    class_values=list(set(row[-1] for row in dataSet))
    b_index,b_value,b_loss,b_left,b_right=999,999,999,None,None
    while len(features) < n_features:
        index=randrange(len(dataSet[0])-1)
        if index not in features:
            features.append(index)
    #print 'features:',features
    for index in features:
        for row in dataSet:
            left,right=data_spilt(dataSet,index,row[index])
            loss=spilt_loss(left,right,class_values)
            if loss < b_loss:
                b_index,b_value,b_loss,b_left,b_right=index,row[index],loss,left,right
    #print b_loss
    #print type(b_index)
    return {'index':b_index,'value':b_value,'left':b_left,'right':b_right}

(4)    构造决策树

#构造决策树
def build_tree(dataSet,n_features,max_depth,min_size):
    root=get_best_spilt(dataSet,n_features)
    sub_spilt(root,n_features,max_depth,min_size,1) 
    return root

(5)    创建随机森林(多个决策树的结合)

#创建随机森林
def random_forest(train,test,ratio,n_feature,max_depth,min_size,n_trees):
    trees=[]
    for i in range(n_trees):
        subTrain=get_subsample(train,ratio)
        tree=build_tree(subTrain,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

(6)    输入测试集并进行测试,输出预测结果
#预测测试集结果
def predict(tree,row):
    predictions=[]
    if row[tree['index']] < tree['value']:
        if isinstance(tree['left'],dict):
            return predict(tree['left'],row)
        else:
            return tree['left']
    else:
        if isinstance(tree['right'],dict):
            return predict(tree['right'],row)
        else:
            return tree['right']
   # predictions=set(predictions)

对以上代码的一点总结:

训练部分:假设我们取dataset中的m个feature来构造决策树,首先,我们遍历m个feature中的每一个feature,再遍历每一行,通过spilt_loss函数(计算分割代价)来选取最优的特征及特征值,根据是否大于这个特征值进行分类(分成left,right两类),循环执行上述步骤,直至不可分或者达到递归限值(用来防止过拟合),最后得到一个决策树tree。

测试部分:对测试集的每一行进行判断,决策树tree是一个多层字典,每一层为一个二分类,将每一行按照决策树tree中的分类索引index一步一步向里层探索,直至不出现字典时探索结束,得到的值即为我们的预测值。

附上:随机森林完整代码 

编程环境:Python2.7

参考:

《机器学习》作者:周志华

从头开始:用Python实现随机森林算法

10
1
查看评论
发表评论
* 以上用户言论只代表其个人钱柜娱乐开户,不代表CSDN网站的钱柜娱乐开户或立场

随机森林算法的简单总结及python实现

python实现的随机森林算法
  • lo_cima
  • lo_cima
  • 2016-01-17 18:46
  • 15590

python实现机器学习之随机森林

这几天一直在看随机森林。可以说遇到任何一个有关预测的问题。都可以首先随机森林来进行预测,同时得到的结果也不会太差。在这篇文章里我首先会向大家推荐几篇写的比较好的博客。接着会将我觉得比较好的例子使用py...
  • LULEI1217
  • LULEI1217
  • 2015-11-02 10:17
  • 24216

python包sk-learn中的随机森林

最近在学习机器学习,学习到了随机森林算法,想做一个demo,阅读了python的sk-learn包中随机森林的代码实现,做了一些笔记。 sk-learn中的随机森林是基于RandomForestCl...
  • xiaonannanxn
  • xiaonannanxn
  • 2016-05-11 16:00
  • 4912

决策树与随机森林相关概念及其Python实现

决策树所谓的决策树, 就是一种树形结构。其内部每个节点代表一个特征的测试,每个一个分支代表测试的输出,而每个叶子节点则代表一种类别。 而随机森林,就是指的一群决策树所组成的一个森林。当一个新的样本需...
  • wy250229163
  • wy250229163
  • 2016-07-20 11:24
  • 1211

随机森林 python

转自:/lulei1217/article/details/49583287 这几天一直在看随机森林。可以说遇到任何一个有关预测的问题。都可以首先随机森林来进...
  • u013066730
  • u013066730
  • 2017-01-10 10:40
  • 753

随机森林(python)

什么是随机森林 随机 森林 是 几乎 任何 预测 问题 (甚至 非直线 部分) 的固有 选择 。 它是 一个 相对较 新 的&...
  • guang_mang
  • guang_mang
  • 2017-09-01 19:53
  • 250

python机器学习库scikit-learn简明教程之:随机森林

机器学习算法系列
  • hanss2
  • hanss2
  • 2016-12-08 22:55
  • 5885

再谈随机森林---python实现

好用的randomforest
  • u010882121
  • u010882121
  • 2017-06-25 14:36
  • 304

python实现机器学习之随机森林

转载自/lulei1217/article/details/49583287。仅用作个人学习。 这几天一直在看随机森林。可以说遇到任何一个有关预测的问题。都可...
  • qq_27245709
  • qq_27245709
  • 2017-06-28 23:32
  • 604

随机森林---python实现

随机森林---python实现
  • u010882121
  • u010882121
  • 2017-06-16 15:06
  • 546
    个人资料
    • 访问:89831次
    • 积分:1195
    • 等级:
    • 排名:千里之外
    • 原创:29篇
    • 转载:0篇
    • 译文:0篇
    • 评论:65条
    最新评论