编程点滴 您所在的位置:网站首页 randomint 编程点滴

编程点滴

2022-05-29 14:47| 来源: 网络整理| 查看: 265

决策树算法实现:RandomForest是由RandomTree组成的,而RandomTree的基础就是决策树,weka中决策树实现的核心代码如下:

protected void buildTree(Instances data, double[] classProbs, Instances header,                           double minNum, boolean debug, int[] attIndicesWindow,                           Random random, int depth, boolean allow) throws Exception {..........................................................................................................................      m_SplitPoint = splits[m_Attribute];      m_Prop = props[m_Attribute];      Instances[] subsets = splitData(data);      m_Successors = new RandomTree[distribution.length];      for (int i = 0; i < distribution.length; i++) {        m_Successors[i] = new RandomTree();        m_Successors[i].setKValue(m_KValue);        m_Successors[i].setMaxDepth(getMaxDepth());        m_Successors[i].buildTree(subsets[i], distribution[i], header, m_MinNum, m_Debug,                                  attIndicesWindow, random, depth + 1, allow);..........................................................................................................................    }..........................................................................................................................}其中subsets就是分裂后每个节点的样本,把这个数据递归传入buildTree中进行下次分裂。在转换成C代码时,我首先想到的是用vector来保存这些样本,但是因为是递归函数,占用内存过大了(java中的垃圾回收机制起到了作用?反正weka占用的内存要少很多)。一种很自然的改进产生了,即每次只是传入样本的id,因为样本总量是一定的,所以总的样本只保留了一份,大大节省了内存。然而这样每次还是需要传入一个数组,感觉还是有冗余啊,看了LH的代码后才发现原来内存可以这么省...比如我有十个样本,id为[0,1,2,3,4,5,6,7,8,9]分裂的时候属于左节点的样本为[0,2,4,6,8]分裂的时候属于右节点的样本为[1,3,5,7,9]这样我每次传入的是其中一个数组,需要复制五个字节(假设这里用的是char型数组)LH的做法是:将[0,1,2,3,4,5,6,7,8,9]看成是一个链表,用两个字节记录下左右节点的初始id,用-1表示链表结束,这样每次只需传入链表的起始位置一个字节即可

从上图你会发现,数组内存的数据既是样本id,也是指针指向下个元素在数组中的位置!

例如,当你获得0这个链表起点时,不但知道该节点包含了样本0,还知道该节点包含的下一个样本id在数组的第0个位置,当遍历到2时,又知道下个节点在位置2,即4



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有