• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
导航菜单
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx
您的位置:首页 > 服务器 >云计算 > 谈谈自己对随机森林(Random Forest)的一点理解以及代码注释~,randomforest

谈谈自己对随机森林(Random Forest)的一点理解以及代码注释~,randomforest

作者:网友 字体:[增加 减小] 来源:互联网

本文主要包含谈谈自己对随机森林(Random Forest)的一点理解以及代码注释~,randomforest等服务器相关知识,网友希望可以进行参考

谈谈自己对随机森林(Random Forest)的一点理解以及代码注释~,randomforest


之前因为做过随机森林方面的项目,对随机森林有过研究,但理论这块还不是很深入,代码倒是看了不少,这里写下这篇博客,说说对随机森林的一些理解,以及附上了一份代码注释。

1. 随机森林

随机森林属于非传统式的机器学习算法,由多颗决策树组成,每棵决策树处理的是一个训练样本子集。训练阶段,通过决策树的节点分裂来筛选特征,层层对样本进行细分,直至将每个训练样本子集分类正确,测试阶段,直接基于训练出的特征进行样本分类,所以测试速度较快(但训练速度较慢)。属于“傻瓜式”的策略(这点和adaboost很像很像),以下部分是标准随机森林训练阶段的大致流程。

  1. 假如有N个样本,则有放回的随机选择N个样本(每次随机选择一个样本,然后返回继续选择)。这选择好了的N个样本用来训练一个决策树,作为决策树根节点处的样本。

  2. 当每个样本有M个属性时,在决策树的每个节点需要分裂时,随机从这M个属性中选取出m个属性,满足条件m << M。然后从这m个属性中采用某种策略(比如说信息增益)来选择1个属性作为该节点的分裂属性。

  3. 决策树形成过程中每个节点都要按照步骤2来分裂,一直到不能够再分裂为止(就是收敛)。所谓不能再分裂,就是全部到达叶子节点,如果下一次该节点选出来的那一个属性是刚刚其父节点分裂时用过的属性,则该节点就是叶子节点。

  4. 按照步骤1~3建立大量的决策树,便构成了随机森林。

从上面的步骤可以看出,随机森林的随机性体现在每颗数的训练样本是随机的,树中每个节点的分类属性也是随机选择的。有了这2个随机的保证,随机森林就不会产生过拟合的现象了。

值得注意的是,随机森林的基本思想都一样,但是在细节上却有所不同,尤其是在节点分裂所采用规则,叶子节点确定那里,有着很多种变种,也就具有不同的效果。说一个我自己遇到的,在确定叶子节点那块,它不是采用属性和父节点一致来确定,而是属性为空来确定,因为它在每一个节点选择一个属性之后,都会将该属性从候选属性集中删除,这样就会造成叶子节点候选属性集为空的情况。

给出一份某位朋友在论坛中提问的代码,关于文本分类的,刚好符合我上面描述的情况,我新添加了注释,与朋友们分享,里面肯定有很多问题,请不吝赐教啊!!!

2. 代码

</pre><pre name="code" class="cpp">#include <iostream>
#include <fstream>
#include <sstream>
#include "random_forest.h"

using namespace std;

vector<decision_tree*>  alltrees;               // 森林(决策树集合)
vector<TupleData>       trainAll,train,test;	// 样本集
vector<int>	            attributes;	        // 属性集(元素为属性序号)

int                     trainAllNum = 0;	
int                     testAllNum  = 0;	
int                     MaxAttr;	        // 属性总数
int                     *ArrtNum;               // 属性个数集(元素为属性最大值)
unsigned int            F;
int                     tree_num    = 100;      // 决策树个数
const int               leafattrnum = -1;       // 叶子节点的属性序号
int                     TP          = 0,
                        FN          = 0,
                        FP          = 0,
                        TN          = 0,
                        TestP       = 0,
                        TestN       = 0;

// 读入数据
void init(char * trainname, char * testname)
{
    trainAllNum     = readData(trainAll, trainname);
    testAllNum      = readData(test, testname);
    calculate_attributes();
    double temp     = (double)trainAllNum;
    temp            = log(temp)/log(2.0);
    F               = (unsigned int)floor(temp+0.5)+1;
    if(F>MaxAttr) F = MaxAttr;
}

// 初始化训练样本子集
void sub_init()
{
    // 选取决策树的训练样本集合
    RandomSelectData(trainAll, train);

    // 计算样本属性个数
    calculate_ArrtNum();
}

// 读数据
int readData(vector<TupleData> &data, const char* fileName)
{
    ifstream fin;
    fin.open(fileName);
    string line;

    int datanum=0;

    // 每行数据作为一个样本
    while(getline(fin,line))
    {
        TupleData d;
        istringstream stream(line);
        string str;

        // 设置每个样本的标签和内容
        while(stream>>str)
        {
            if(str.find('+')==0)
            {
                d.label='+';
            }
            else if(str.find('-')==0)
            {
                d.label='-';
            }
            else
            {
                int j=stringtoint(str);
                d.A.push_back(j);
            }
        }

        data.push_back(d);	
        datanum++;
    }

    fin.close();
    return datanum;
}

// 生成根节点的训练样本子集
void RandomSelectData(vector<TupleData> &data, vector<TupleData> &subdata)
{
    int index;
    subdata.clear();
    int d = 0;
    while (d < trainAllNum)
    {
        index = rand() % trainAllNum;
        subdata.push_back(data.at(index));
        d++;
    }
}

// 计算属性序列
void calculate_attributes()
{
    // 每个样本必须具有相同的属性个数
    TupleData d = trainAll.at(0);
    MaxAttr = d.A.size();
    attributes.clear();

    // 建立属性集合attributes,元素为属性序号
    for (int i = 0; i < MaxAttr; i++)
    {
        attributes.push_back(i);
    }

    // 初始化属性最大值序列,元素为属性最大值
    ArrtNum = new int[MaxAttr];
}

// 字符串转化为int
int stringtoint(string s)
{
    int sum=0;
    for(int i=0; s[i]!='\0';i++)
    {
        int j=int(s[i])-48;
        sum=sum*10+j;
    }
    return sum;
}

// 计算ArrtNum元素值
void calculate_ArrtNum()
{
    for(int i = 0; i < MaxAttr; i++) ArrtNum[i] = 0;

    // ArrtNum元素值为属性最大值
    for (vector<TupleData>::const_iterator it = train.begin(); it != train.end(); it++)	
    {
        int i = 0;

        for (vector<int>::const_iterator intt=(*it).A.begin(); intt!=(*it).A.end();intt++)
        {
            int valuemax=(*intt)+1;
            if(valuemax>ArrtNum[i]) ArrtNum[i]=valuemax;
            i++;
        }
    }
}

// 计算熵
double Entropy(double p, double s)
{
    double n = s - p;
    double result = 0;
    if (n != 0)
        result += - double(n) / s * log(double(n) / s) / log(2.0);
    if (p != 0)
        result += double(-p) / s * log(double(p) / s) / log(2.0);
    return result;
}

// 训练一棵决策树
int creat_classifier(decision_tree *&p, const vector<TupleData> &samples, vector<int> &attributes)
{
    if (p == NULL)
        p = new decision_tree();

    // 根据样本真实类别,输出叶子节点类别
    if (Allthesame(samples, '+'))
    {
        p->node.label = '+';
        p->node.attrNum = leafattrnum;
        p->childs.clear();
        return 1;
    }
    if (Allthesame(samples, '-'))
    {
        p->node.label = '-';
        p->node.attrNum = leafattrnum;
        p->childs.clear();
        return 1;
    }
    // 如果属性序列为空,当前节点就为叶子节点
    if (attributes.size() == 0)
    {
        p->node.label = Majorityclass(samples);
        p->node.attrNum = leafattrnum;
        p->childs.clear();
        return 1;
    }

    // 计算当前节点的最优属性
    p->node.attrNum = BestGainArrt(samples, attributes);

    // 中间节点无标签
    p->node.label = ' ';

    // 计算子节点候选属性集合,候选集合元素越来越少
    vector<int> newAttributes;
    for (vector<int>::iterator it = attributes.begin(); it != attributes.end(); it++)
        if ((*it) != p->node.attrNum)
            newAttributes.push_back((*it));

    // 初始化样本子集,建立maxvalue个样本子集,也就说明该节点有maxvalue个子节点
    // 为什么不建立一个阈值,进行二分类?
    int maxvalue = ArrtNum[p->node.attrNum];
    vector<TupleData>* subSamples = new vector<TupleData>[maxvalue];
    for (int i = 0; i < maxvalue; i++)
        subSamples[i].clear();

    // 将样本集合分为样本子集
    for (vector<TupleData>::const_iterator it = samples.begin(); it != samples.end(); it++)
    {
        // 对样
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 谈谈自己对随机森林(Random Forest)的一点理解以及代码注释~,randomforest

相关文章

  • redis主从同步,redis主从
  • hadoop做HA后,hbase修改,hadoophahbase修改
  • hive:Access denied for user &#39;root&#39;@&#39;%&#39;,hivedenied
  • (Kilo)Devstack Kilo版本localrc推荐,devstacklocalrc
  • hive复杂类型访问操作,hive访问
  • kafka集群搭建,kafka集群
  • HDFS学习笔记(2)hdfs_shell &amp; JavaAPI,hdfshdfs_shell
  • Azure云平台学习之路(一)——Azure简介,azure之路
  • &lt;转&gt;云主机配置OpenStack使用spice的方法,openstackspice
  • Hadoop DistributedCache使用案例,hadoopcache

文章分类

  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx

最近更新的内容

    • kafka 安装步骤,kafka安装步骤
    • hadoop-2.6.0运行woudcount报错,hadoop运行wordcount
    • 详说大数据计算的可类化Classable,类化classable
    • HBase基本数据操作详解,HBase数据操作详解
    • Java 调用Hive 自定义UDF,java调用hiveudf
    • java保留两位小数,java两位小数
    • Nodejs课堂笔记-第六课 在DynamoDB中如何创建表,nodejsdynamodb
    • hive创建分区,hive创建
    • Andrew Ng Machine Learning,andrewlearning
    • R.net简介(原创翻译),r.net简介原创翻译

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有