Scikit-Learn 随机森林分类器的使用

1. 原理

随机森林(RandomForest), 指的是利用多棵树对样本进行训练并预测的一种分类器。该分类器最早由Leo Breiman和Adele Cutler提出,并被注册成了商标。简单来说,随机森林就是由多棵CART(Classification And Regression Tree)构成的。对于每棵树,它们使用的训练集是从总的训练集中有放回采样出来的,这意味着,总的训练集中的有些样本可能多次出现在一棵树的训练集中,也可能从未出现在一棵树的训练集中。在训练每棵树的节点时,使用的特征是从所有特征中按照一定比例随机地无放回的抽取的,根据Leo Breiman的建议,假设总的特征数量为M,这个比例可以是sqrt(M),1/2sqrt(M),2sqrt(M)。

因此,随机森林的训练过程可以总结如下:

(1)给定训练集S,测试集T,特征维数F。确定参数:使用到的CART的数量t,每棵树的深度d,每个节点使用到的特征数量f,终止条件:节点上最少样本数s,节点上最少的信息增益m

对于第1-t棵树,i=1-t:

(2)从S中有放回的抽取大小和S一样的训练集S(i),作为根节点的样本,从根节点开始训练

(3)如果当前节点上达到终止条件,则设置当前节点为叶子节点,如果是分类问题,该叶子节点的预测输出为当前节点样本集合中数量最多的那一类c(j),概率p为c(j)占当前样本集的比例;如果是回归问题,预测输出为当前节点样本集各个样本值的平均值。然后继续训练其他节点。如果当前节点没有达到终止条件,则从F维特征中无放回的随机选取f维特征。利用这f维特征,寻找分类效果最好的一维特征k及其阈值th,当前节点上样本第k维特征小于th的样本被划分到左节点,其余的被划分到右节点。继续训练其他节点。有关分类效果的评判标准在后面会讲。

(4)重复(2)(3)直到所有节点都训练过了或者被标记为叶子节点。

(5)重复(2),(3),(4)直到所有CART都被训练过。

利用随机森林的预测过程如下:

对于第1-t棵树,i=1-t:

(1)从当前树的根节点开始,根据当前节点的阈值th,判断是进入左节点(=th),直到到达,某个叶子节点,并输出预测值。

(2)重复执行(1)直到所有t棵树都输出了预测值。如果是分类问题,则输出为所有树中预测概率总和最大的那一个类,即对每个c(j)的p进行累计;如果是回归问题,则输出为所有树的输出的平均值。

注:有关分类效果的评判标准,因为使用的是CART,因此使用的也是CART的评判标准,和C3.0,C4.5都不相同。

对于分类问题(将某个样本划分到某一类),也就是离散变量问题,CART使用Gini值作为评判标准。定义为Gini=1-∑(P(i)*P(i)),P(i)为当前节点上数据集中第i类样本的比例。例如:分为2类,当前节点上有100个样本,属于第一类的样本有70个,属于第二类的样本有30个,则Gini=1-0.7×07-0.3×03=0.42,可以看出,类别分布越平均,Gini值越大,类分布越不均匀,Gini值越小。在寻找最佳的分类特征和阈值时,评判标准为:argmax(Gini-GiniLeft-GiniRight),即寻找最佳的特征f和阈值th,使得当前节点的Gini值减去左子节点的Gini和右子节点的Gini值最大。

对于回归问题,相对更加简单,直接使用argmax(Var-VarLeft-VarRight)作为评判标准,即当前节点训练集的方差Var减去减去左子节点的方差VarLeft和右子节点的方差VarRight值最大。

2. Scikit-Learn函数调用

>>> from sklearn.ensemble import RandomForestClassifier
>>> data=[[0,0,0],[1,1,1],[2,2,2],[1,1,1],[2,2,2],[3,3,3],[1,1,1],[4,4,4]]
>>> arget=[0,1,2,1,2,3,1,4]
>>> rf = RandomForestClassifier()
>>> rf.fit(data,arget)
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
            max_depth=None, max_features='auto', max_leaf_nodes=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, n_estimators=10, n_jobs=1,
            oob_score=False, random_state=None, verbose=0,
            warm_start=False)
>>> print rf.predict_proba([[1,1,1]])
#[[ 0.  1.  0.  0.  0.]]
#输出是5个数,因为target有5个值

3..  如何设计一个自己的随机森林程序

首先,要有一个RandomForest类,里面保存整个树需要的一些参数,包括但不限于:训练样本数量、测试样本数量、特征维数、每个节点随机提取的特征维数、CART树的数量、树的最大深度、类别数量(如果是分类问题)、一些终止条件、指向所有树的指针,指向训练集和测试集的指针,指向训练集label的指针等。还要有一些函数,至少要有train和predict吧。train里面直接调用每棵树的train方法即可,predict同理,但要对每棵树的预测输出做处理,得到森林的预测输出。

 

其次,要有一个sample类,这个类可不是用来存储训练集和对应label的,这是因为,每棵树、每个节点都有自己的样本集和,如果你的存储每个样本集和的话,需要的内存实在是太过巨大了,假设样本数量为M,特征维数为N,则整个训练集大小为M×N,而每棵树的每层都有这么多样本,树的深度为D,共有S棵树的话,则需要存储M×N×D×S的存储空间。这实在是太大了。因此,每个节点训练时用到的训练样本和特征,我们都用序号数组来代替,sample类就是干这个的。sample的函数基本需要两个就行,第一个是从现有训练集有放回的随机抽取一个新的训练集,当然,只包含样本的序号。第二个函数是从现有的特征中无放回的随机抽取一定数量的特征,同理,也是特征序号即可。

然后,需要一个Tree类,代表每棵树,里面保存树的一些参数以及一个指向所有节点的指针。

最后,需要一个Node类,代表树的每个节点。

 

需要说明的是,保存树的方式可以是最普通的数组,也可是是vector。Node的保存方式同理,但是个人不建议用链表的方式,在程序设计以及函数处理上太麻烦,但是在省空间上并没有太多的体现。


最后,再次感谢http://www.cnblogs.com/hrlnw/p/3850459.html 的文字部分整理

你可能感兴趣的:(Python,python)