机器学习之随机森林

前两篇博客我分别介绍了决策树ID3和CRAT回归树,这次我打算说说随机森林。顾名思义,森林就是多个树,而随机就是随机选择特征建立决策树,还是从上次女人相亲记那个例子开始。
经过近一年的相亲,还是没有找到合适的,她的爸妈着急了,这可咋办?闺女嫁不出去了,于是找了亲戚,朋友来帮忙。由于亲戚,朋友都有自己喜欢的类型,因此关注男人的特征也不相同,比如:大姐,大姐命苦,嫁了一个”小白脸“,小白脸除了打游戏还是打游戏,大姐说:”俺妹找对象可别找你姐夫那样的软蛋,要找能撑起一个家的“;大哥,大哥是一个”海龟“博士,大哥说:”俺妹找对象要找有学问的,本科以上文凭,985,211或者学校专业全国前20“(那些奇葩的公司都是这样子的。。。无奈);小妹,小妹是个花痴,”俺未来的姐夫,是要身材苗条,皮肤白嫩,最好是带个眼睛,家境优越“(尼玛。。。看韩剧看多了);爸爸,老爸说:”女婿,人品好就行,女儿愿意就好“(典型在家受气的料),七大姑,八大姨等等。。。。。由上面可以看出,没一个人的关注点是不想同的(比如小妹看中长相,大哥看中学问等等。。),因此所关注的特征也就不想同,并且每一个人都能够找出所在领域的”优秀男人“ ,随机森林也就是这个意思。每一个决策树都能从所在领域找出相对较优的类别(包括分类与回归),通过所有决策数的判别,得出最终预测的结果。对于分类问题,要计算森林中类别最多的作为结果,对于回归问题,计算最终的均值作为最终结果。
机器学习之随机森林_第1张图片
综上所述,相亲基本不靠谱。在实现任何机器学习算法前,最终要的就是特征的选择,特征的选择直接影响的最终的预测结果。对于一些无用的特征甚至会降低算法的性能,因此许许多多的算法也就出现了(SVD,PCA,稀疏编码,L1,L2正则化等等),而随机森林属于集成算法,采用的是随机选择特征建立决策树。随机选择一共包含两个方面:
1) 行数据的采集(允许出现重复选择,可以避免过拟合)
2) 列数据的采集(不允许出现重复选择,降维处理,可以避免过拟合)
有了上一篇文章中的代码构建随机森林就简单的多了(这里实现的比较简单,没有深入的研究过,仅仅看了最最原始的论文),数据集从UCI下载,housing.data,代码如下:

import numpy as np
import random
import regTrees as regTrees
''' Created on Feb 1, 2016 random forests @author: Zhang luoyang '''
def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().replace(" "," ").replace(" "," ").split(' ')
        fltLine = map(float,curLine)
        dataMat.append(fltLine)
    return np.mat(dataMat)
def randomRec(dataMat, numtrees=10):
    N,M = np.shape(dataMat)
    datas = []
    for j in range(0,numtrees):
        index = []
        for i in range(0,N):
            index.append(random.choice( range(0,N) ))
        datas.append(dataMat[index,:])
    return datas
def randomAtt(data, numAtts):
    N,M = np.shape(data)
    sub_data = []
    index = random.sample(range(M-1), numAtts)
    index.append(M-1)
    sub_data = data[:,index]
    return index,sub_data
def createRandomForest(data,numtrees,numAtts):
    print 'create...'
    trees = []
    sub_datas = randomRec(data,numtrees)
    sub_datas=[randomAtt(sub_data,numAtts) for sub_data in sub_datas]
    indexs = [index[0] for index in sub_datas]
    for i in range(numtrees):
        trees.append(regTrees.createTree(sub_datas[i][1]))
    print 'create end .....'
    return indexs,trees
def treesPrune(trees, indexs,testData,numtrees):
    print 'start'
    treesprune = [regTrees.prune(trees[i],testData[:,indexs[i]]) for i in range(numtrees)]
    print 'end'
    return treesprune
def treesForeCast(trees,indexs,testData,numtrees):
    result = [regTrees.treeForeCast(trees[i],testData[indexs[i]]) for i in range(numtrees)]
    return np.mean(result)
numtrees = 5
numAtts = 9
dataMat = loadDataSet("housing.data")
train = dataMat[0:300,:]
test = dataMat[301:,:]
indexs,trees = createRandomForest(dataMat,numtrees,numAtts)
treesprune = treesPrune(trees,indexs,dataMat,numtrees)
t = np.array([0.04741,0.00,11.930,0,0.5730,6.0300,80.80,2.5050,1,273.0,21.00,396.90,7.88,11.90])
print treesForeCast(treesprune,indexs,t,numtrees)

随机森林要比单个CRAT树的性能要好很多,感兴趣的可以对代码进行补充,这里我就不在继续写代码了,实现起来也很简单。(代码需要进行优化,这个样子肯定是无法直接进行工程上的使用的。。)

你可能感兴趣的:(python,机器学习,随机森林)