机器学习基础——RandomForest

随机森林(Random Forest):

    随机森林是一个最近比较火的算法,它有很多的优点:

  •     在数据集上表现良好
  •     在当前的很多数据集上,相对其他算法有着很大的优势
  •     它能够处理很高维度(feature很多)的数据,并且不用做特征选择
  •     在训练完后,它能够给出哪些feature比较重要
  •     在创建随机森林的时候,对generlization error使用的是无偏估计
  •     训练速度快
  •     在训练过程中,能够检测到feature间的互相影响
  •     容易做成并行化方法
  •     实现比较简单

    随机森林最早由Leo Breiman与Adele Cutler提出,

随机森林顾名思义,是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的(跟Adaboost相反,Adaboost的每个基学习器互相相关。)。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。

    在建立每一棵决策树的过程中,有两点需要注意 - 采样与完全分裂。首先是两个随机采样的过程,random forest对输入的数据要进行行的采样(即样本的采样)和列的采样(特征的采样)。对于行采样,采用有放回的方式,也就是在采样得到的样本集合中,可能有重复的样本。假设输入样本为N个,那么采样的样本也为N个。这样使得在训练的时候,每一棵树的输入样本都不是全部的样本,使得相对不容易出现over-fitting,这种方法也叫作re-sampling,通常情况下,随机抽取得到的N个样本中,只出现输入样本的60~70%的样本,剩下的样本不在re-sampling后的样本中出现。

然后进行列采样(特征采样),从M个feature中,选择m个(一般选择m=log2M)。之后就是对采样之后的数据根据CART进行分类。注意:在基学习器深度大于1的情况,要对每个结点都从该点的特征集合中重新选取k个特征,并且根据GINI系数进行判断,从而将决策树继续展开。这样决策树的某一个叶子节点要么是无法继续分裂的(更倾向于这种,这种方法就是设置基学习器CART的高度),要么里面的所有样本的都是指向的同一个分类(可能每个学习器都需要很多迭代,不推荐)。一般很多的决策树算法都一个重要的步骤 - 剪枝,但是这里不这样干,由于之前的两个随机采样的过程保证了随机性,所以就算不剪枝,也不会出现over-fitting。

    按这种算法得到的随机森林中的每一棵都是很弱的,但是大家组合起来就很厉害了。我觉得可以这样比喻随机森林算法:每一棵决策树就是一个精通于某一个窄领域的专家(因为我们从M个feature中选择m让每一棵决策树进行学习),这样在随机森林中就有了很多个精通不同领域的专家,对一个新的问题(新的输入数据),可以用不同的角度去看待它,最终由各个专家,投票得到结果。

下面是随机森林最简单实现的Python代码:

[python]  view plain  copy
  1. ''''' 
  2.     Samuel Gao 
  3.     2017.4.19 
  4.     随机森林 
  5.     离散属性 
  6.     1、基学习器深度取为1 ,因为我这里 
  7.        只随机取1个进行决策树分析, 
  8.        没有用到CART决策树,按gini系数比较。对特征多的可以加上。 
  9.        ps:要对每个基学习器的节点随机抽取一个特征进行分叉,除非像我一样 
  10.        ,将每棵树的高度设为1. 
  11.     2、基学习器可以并行生成,有兴趣的可以用Threading或multiprocessing模块 
  12.        来实现,还是不太难的。这里没有写出 
  13.  
  14. '''  
  15. # from sklearn.ensemble import RandomForestClassifier  
  16. import numpy as np  
  17. import pandas as pd  
  18. import random  
  19. from threading import Thread  
  20. from collections import Counter  
  21.   
  22.   
  23. def xunlian(data, number):  
  24.     featureChoice = int(np.random.randint(0, number-11))  
  25.     features = list(data[featureChoice].unique())  
  26.     # features为['清脆', '沉闷']的形式  
  27.   
  28.     categorys = list(data[featureChoice])  
  29.     dicts = {}  
  30.     cc = 0  
  31.   
  32.     for ll in features:  
  33.         dicts[ll] = []  
  34.   
  35.   
  36.     for m in categorys:  
  37.         for j in features:  
  38.             if m == j:  
  39.                 dicts[j].append(cc)  
  40.                 cc += 1  
  41.   
  42.     for i in features:  
  43.         lst = dicts.get(i)  
  44.         new_lst = []  
  45.         if len(lst) > 0:  
  46.             for k in lst:  
  47.                 new_lst.append(int(data[k:k+1][data.shape[1]-1]))  
  48.             jieguo = Counter(new_lst).most_common(1)[0][0]  
  49.             dicts[i] = jieguo  
  50.   
  51.     return dicts  
  52.     # dicts 为 {'清脆':1, '沉闷':0}的形式  
  53.   
  54.   
  55. class RandomForest():  
  56.   
  57.     def __init__(self, n_estimators = 3):  
  58.         self.estimators = n_estimators  
  59.  
  60.     @staticmethod  
  61.     def assemble(inputs, labels):  
  62.         n = len(labels)  
  63.         for i in range(n):  
  64.             inputs[i].append(labels[i])  
  65.   
  66.         data = np.vstack(inputs)  
  67.         return data  
  68.   
  69.     def train(self, inputs, labels):  
  70.         n = len(inputs[0])  # 特征个数  
  71.         data = RandomForest.assemble(inputs, labels)  
  72.         data = pd.DataFrame(data)  
  73.   
  74.         sum_dicts = {}  
  75.   
  76.         rows = int(data.shape[0])  
  77.         rcounts = rows - 1  
  78.   
  79.         for i in range(self.estimators):  
  80.             df = pd.DataFrame()  
  81.             for m in range(rows):  
  82.                 j = random.randint(0, int(rcounts))  
  83.                 df = df.append(data.loc[j, :])  
  84.             sum_dicts[i] = xunlian(df, n)  
  85.   
  86.         return sum_dicts  
  87.         # 多线程并行生成基学习器方式:以后有时间完善  
  88.         # threads = []  
  89.         # for i in range(self.estimators):  
  90.         #     ti = Thread(target=xunlian, args=(data, n,))  
  91.         #     threads.append(ti)  
  92.         #  
  93.         # for t in threads:  
  94.         #     t.setDeamon(True)  
  95.         #     t.start()  
  96.   
  97.   
  98.     def predict(self, input, model):  
  99.         n = len(model)  
  100.         # n为基学习器的个数  
  101.         predicts = list()  
  102.         for i in range(n):  
  103.             categoryes = model[i]  
  104.             for j in input:  
  105.                 if j in categoryes.keys():  
  106.                     predicts.append(categoryes[j])  
  107.         prediction = Counter(predicts).most_common(1)  
  108.         print(prediction)  
  109.         if prediction[0][0] == 0:  
  110.   
  111.             print("预测结果为:坏瓜")  
  112.         else:  
  113.   
  114.             print("预测结果为:好瓜")  
  115.   
  116.   
  117.   
  118.   
  119.   
  120. if __name__ == "__main__":  
  121.     ex = RandomForest()  # 默认为3个基学习器  
  122.     a0 = ['浅绿''清脆''中']  
  123.     a1 = ['深绿''沉闷''大']  
  124.     a2 = ['薄白''清脆''小']  
  125.     a3 = ['浅绿''清脆''小']  
  126.     a4 = ['深绿''沉闷''中']  
  127.     lst = [a0, a1, a2, a3, a4]  
  128.     y = [01011]  # 0坏 1好  
  129.   
  130.     model = ex.train(lst, y)  
  131.     ex.predict(['浅绿''清脆''小'], model)  


参考资料:

1、 http://www.cnblogs.com/LeftNotEasy/archive/2011/03/07/random-forest-and-gbdt.html

2 、http://blog.csdn.net/w28971023/article/details/8240756

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值