本站分享:AI、大数据、数据分析师培训认证考试,包括:Python培训Excel培训Matlab培训SPSS培训SAS培训R语言培训Hadoop培训Amos培训Stata培训Eviews培训

随机森林算法实现_随机森林算法 python

python培训 cdadata 4382℃

随机森林算法实现

关键词:随机森林算法原理随机森林算法 python随机森林算法

随机森林是一个包含多个决策树的分类器,该分类器的输出结果是由所有决策树输出结果的众数而定,每个决策树都生长于一个被称为bootstrap样本的训练数据集之上,所谓“bootstrap样本”的构造原理为:对于容量为n原始训练数据,采取重复抽样的方式抽样n次,形成一组新的训练数据,被称为原始数据的一个bootstrap样本。在bootstrap样本上构造决策树的原理与传统的构造决策树的方法大致相同,但也存在一些差别,不同之处在于:在对非叶节点分裂时,需要从所有的m个属性中随机地选取p个属性(一般建议取p的值为m的平方根),再从这p个属性中选取最佳分裂属性以及相应的最佳分裂阀值,在该bootstrap样本上最终生成的决策树不需要剪枝。在原始训练数据上生成多个bootstrap样本,利用上述方法就会得到多颗完全生长的决策树,因为取样过程以及变量选取过程都是随机的,因此被形象地称为随机森林。

算法的为代码如下:

随机森林算法实现_随机森林算法 python

本文利用Python语言实现随机森林算法,构建的每颗决策树都基于CART算法,所有代码都位于一个文件

randomforests.py中,

[python]

  1. from __future__ import division
  2. import numpy as np
  3. import math
  4. class node:
  5.     def __init__(self, col=-1, value=None, results=None, trueBranch=None, falseBranch=None):
  6.         self.col = col
  7.         self.value = value
  8.         self.results = results
  9.         self.trueBranch = trueBranch
  10.         self.falseBranch = falseBranch
  11.     def getLabel(self):
  12.         if self.results == None:
  13.             return None
  14.         else:
  15.             max_counts = 0
  16.             for key in self.results.keys():
  17.                 if self.results[key] > max_counts:
  18.                     label = key
  19.                     max_counts = self.results[key]
  20.         return label
  21. class RandomForestsClassifier:
  22.     def __init__(self, n_bootstrapSamples=20):
  23.         self.n_bootstrapSamples = n_bootstrapSamples
  24.         self.list_tree = []
  25.     def divideSet(self, samples, column, value):
  26.         splitFunction = None
  27.         if isinstance(value,int) or isinstance(value,float):
  28.             splitFunction = lambda row: row[column] >= value
  29.         else:
  30.             splitFunction = lambda row: row[column] == value
  31.         set1 = [row for row in samples if splitFunction(row)]
  32.         set2 = [row for row in samples if not splitFunction(row)]
  33.         return (set1,set2)
  34.     def uniqueCounts(self, samples):
  35.         results = {}
  36.         for row in samples:
  37.             r = row[len(row)-1]
  38.             if r not in results:
  39.                 results[r] = 0
  40.             results[r] = results[r]+1
  41.         return results
  42.     def giniEstimate(self, samples):
  43.         if len(samples)==0return 0
  44.         total = len(samples)
  45.         counts = self.uniqueCounts(samples)
  46.         gini = 0
  47.         for target in counts:
  48.             gini = gini + pow(counts[target],2)
  49.         gini = 1 – gini / pow(total,2)
  50.         return gini
  51.     def buildTree(self, samples):#构造CART决策树
  52.         if len(samples) == 0:
  53.             return node()
  54.         currentGini = self.giniEstimate(samples)
  55.         bestGain = 0
  56.         bestCriteria = None
  57.         bestSets = None
  58.         colCount = len(samples[0]) – 1
  59.         colRange = range(0,colCount)
  60.         np.random.shuffle(colRange)
  61.         for col in colRange[0:int(math.ceil(math.sqrt(colCount)))]:
  62.             colValues = {}
  63.             for row in samples:
  64.                 colValues[row[col]] = 1
  65.             for value in colValues.keys():
  66.                 (set1,set2) = self.divideSet(samples,col,value)
  67.                 gain = currentGini – (len(set1)*self.giniEstimate(set1) + len(set2)*self.giniEstimate(set2)) / len(samples)
  68.                 if gain > bestGain and len(set1) > 0 and len(set2) > 0:
  69.                     bestGain = gain
  70.                     bestCriteria = (col,value)
  71.                     bestSets = (set1,set2)
  72.         if bestGain > 0:
  73.             trueBranch = self.buildTree(bestSets[0])
  74.             falseBranch = self.buildTree(bestSets[1])
  75.             return node(col=bestCriteria[0],value=bestCriteria[1],trueBranch=trueBranch,falseBranch=falseBranch)
  76.         else:
  77.             return node(results=self.uniqueCounts(samples))
  78.     def printTree(self, tree,indent=‘  ‘):#以文本形式显示决策树
  79.         if tree.results != None:
  80.             print str(tree.results)
  81.         else:
  82.             print str(tree.col)+‘:’+str(tree.value)+‘?’
  83.             print indent+‘T->’,
  84.             self.printTree(tree.trueBranch,indent+‘  ‘)
  85.             print indent+‘F->’,
  86.             self.printTree(tree.falseBranch,indent+‘  ‘)
  87.     def predict_tree(self, observation, tree):#利用决策树进行分类
  88.         if tree.results != None:
  89.             return tree.getLabel()
  90.         else:
  91.             v = observation[tree.col]
  92.             branch = None
  93.             if isinstance(v,int) or isinstance(v,float):
  94.                 if v >= tree.value: branch = tree.trueBranch
  95.                 else: branch = tree.falseBranch
  96.             else:
  97.                 if v == tree.value: branch = tree.trueBranch
  98.                 else: branch = tree.falseBranch
  99.             return self.predict_tree(observation,branch)
  100.     def generateBootstrapSamples(self, data):#构造bootstrap样本
  101.         samples = []
  102.         for i in range(len(data)):
  103.             samples.append(data[np.random.randint(len(data))])
  104.         return samples
  105.     def fit(self, data):#构造随机森林
  106.         for i in range(self.n_bootstrapSamples):
  107.             samples = self.generateBootstrapSamples(data)
  108.             currentTree = self.buildTree(samples)
  109.             self.list_tree.append(currentTree)
  110.     def predict_randomForests(self, observation):#利用随机森林对给定观测数据进行分类
  111.         results = {}
  112.         for i in range(len(self.list_tree)):
  113.             currentResult = self.predict_tree(observation, self.list_tree[i])
  114.             if currentResult not in results:
  115.                 results[currentResult] = 0
  116.             results[currentResult] = results[currentResult] + 1
  117.         max_counts = 0
  118.         for key in results.keys():
  119.             if results[key] > max_counts:
  120.                 finalResult = key
  121.                 max_counts = results[key]
  122.         return finalResult

接下来使用经典的鸢尾花数据集来检验随机森林的分类效果,代码如下:

  1. from sklearn.datasets import load_iris
  2. iris = load_iris()
  3. X = iris.data
  4. y = iris.target
  5. temp_data = np.concatenate([X, y.reshape((150,1))], axis=1)
  6. #由于上述代码要求输入的观测数据存储在二维列表中,需将numpy二维数组转换成列表
  7. data = []
  8. for i in range(temp_data.shape[0]):
  9.     temp = []
  10.     for j in range(temp_data.shape[1]):
  11.         temp.append(temp_data[i][j])
  12.     data.append(temp)
  13. rowRange = range(150)
  14. np.random.shuffle(rowRange)
  15. #从鸢尾花数据集(容量为150)按照随机均匀抽样的原则选取70%的数据作为训练数据
  16. training_data = [data[i] for i in rowRange[0:105]]
  17. #按照随机均匀抽样的原则选取30%的数据作为检验数据
  18. testing_data = [data[i] for i in rowRange[105:150]]
  19. classifier = randomforest.RandomForestsClassifier(n_bootstrapSamples=10)#初始化随机森林
  20. classifier.fit(training_data)#利用训练数据进行拟合
  21. finalResults = []
  22. for row in testing_data:
  23.     finalResult = classifier3.predict_randomForests(row[0:4])#对检验数据集进行分类
  24.     finalResults.append(finalResult)
  25. errorVector = np.zeros((45,1))
  26. errorVector[np.array(finalResults) != (np.array(testing_data))[:,4]] =1
  27. errorVector.sum()/45#计算错判率

运行上述代码,可以计算出随机森林分类器classifier在检验数据集上的错判率为11.11%,取得不错的分类效果,实际上如果将随机森林中决策树的个数设置为20(n_bootstrapSamples=10),再重复运行上述代码,会发现错判率几乎接近0,这些都表明随机森林作为分类器的效果是非常好的。

转载请注明:数据分析 » 随机森林算法实现_随机森林算法 python

喜欢 (0)or分享 (0)