参考维基百科:

在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。 Leo Breiman和Adele Cutler发展出推论出随机森林的演算法。而"Random Forests"是他们的商标。这个术语是1995年由贝尔实验室的Tin Kam Ho所提出的随机决策森林(random decision forests)而来的。这个方法则是结合Breimans的"Bootstrap aggregating"想法和Ho的"random subspace method" 以建造决策树的集合。

算法过程:

  1. 用N来表示训练用例(样本)的个数,M表示特征数目。
  2. 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
  3. 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
  4. 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。
  5. 每棵树都会完整成长而不会剪枝(Pruning,这有可能在建完一棵正常树状分类器后会被采用)。

总结:

  Random Forest(随机森林)算法是通过训练多个决策树,生成模型,然后综合利用多个决策树进行分类。

1. 单棵决策树的构建:

  (1)令N为训练样例的个数,则单棵决策树的输入样例的个数为N个从训练集中有放回的随机抽取N个训练样例。

  (2)令训练样例的输入特征的个数为M,且m远远小于M,则我们在每颗决策树的每个节点上进行分裂时,从M个输入特征里随机选择m个输入特征,然后从这m个输入特征里选择一个最好的进行分裂。m在构建决策树的过程中不会改变。

  (3)每棵树都一直这样分裂下去,直到该节点的所有训练样例都属于同一类。不需要剪枝。

  2. 随机森林的分类结果

  按照1生成t个决策树之后,对于每个新的测试样例,综合多个决策树的分类结果来作为随机森林的分类结果。

  (1)目标特征为数字类型:取t个决策树的平均值作为分类结果。

  (2)目标特征为类别类型:少数服从多数,取单棵树分类结果最多的那个类别作为整个随机森林的分类结果。

  3. 分类效果的评价

  在随机森林中,无需交叉验证来评价其分类的准确性,随机森林自带OOB(out-of-bag)错误估计:

  OOB:在构造单棵决策树时我们只是随机有放回的抽取了N个样例,所以可以用没有抽取到的样例来测试这棵决策树的分类准确性,这些样例大概占总样例数目的三分之一(好心人评论给出的解释:n趋于无穷时,未选到的概率为(1-1/n)的n次方,极限为1/e=0.3678,约为三分之一)。所以对于每个样例j,都有大约三分之一的决策树(记为SetT(j))在构造时没用到该样例,我们就用这些决策树来对这个样例进行分类。我们对于所有的训练样例j,用SetT(j)中的树组成的森林对其分类,然后看其分类结果和实际的类别是否相等,不相等的样例所占的比例就是OOB错误估计。OOB错误估计被证明是无偏的。

tensorflow实现:

from __future__ import print_function

import tensorflow as tf
from tensorflow.python.ops import resources
from tensorflow.contrib.tensor_forest.python import tensor_forest

# Ignore all GPUs, tf random forest does not benefit from it.
import os
os.environ["CUDA_VISIBLE_DEVICES"] = ""

# Parameters
num_steps = 500 # Total steps to train
batch_size = 1024 # The number of samples per batch
num_classes = 10 # The 10 digits
num_features = 784 # Each image is 28x28 pixels
num_trees = 10
max_nodes = 1000

# Input and Target data
x = tf.placeholder(tf.float32, shape=[None, num_features])
# For random forest, labels must be integers (the class id)
y = tf.placeholder(tf.int32, shape=[None])

# Random Forest Parameters
hparams = tensor_forest.ForestHParams(num_classes=num_classes,
                                      num_features=num_features,
                                      num_trees=num_trees,
                                      max_nodes=max_nodes).fill()

# Build the Random Forest
forest_graph = tensor_forest.RandomForestGraphs(hparams)
# Get training graph and loss
train_op = forest_graph.training_graph(x, y)
loss_op = forest_graph.training_loss(x, y)

# Measure the accuracy
infer_op, _, _ = forest_graph.inference_graph(x)
correct_prediction = tf.equal(tf.argmax(infer_op, 1), tf.cast(y, tf.int64))
accuracy_op = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# Initialize the variables (i.e. assign their default value) and forest resources
init_vars = tf.group(tf.global_variables_initializer(),
    resources.initialize_resources(resources.shared_resources()))

# Start TensorFlow session
sess = tf.train.MonitoredSession()

# Run the initializer
sess.run(init_vars)

# Training
for i in range(1, num_steps + 1):
    # Prepare Data
    # Get the next batch of MNIST data (only images are needed, not labels)
    batch_x, batch_y = mnist.train.next_batch(batch_size)
    _, l = sess.run([train_op, loss_op], feed_dict={x: batch_x, y: batch_y})
    if i % 50 == 0 or i == 1:
        acc = sess.run(accuracy_op, feed_dict={x: batch_x, y: batch_y})
        print('Step %i, Loss: %f, Acc: %f' % (i, l, acc))

# Test Model
test_x, test_y = mnist.test.images, mnist.test.labels
print("Test Accuracy:", sess.run(accuracy_op, feed_dict={x: test_x, y: test_y}))

结果输出:

INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Step 1, Loss: -1.400000, Acc: 0.348633
Step 50, Loss: -257.600006, Acc: 0.902344
Step 100, Loss: -544.000000, Acc: 0.923828
Step 150, Loss: -828.000000, Acc: 0.915039
Step 200, Loss: -1001.000000, Acc: 0.907227
Step 250, Loss: -1001.000000, Acc: 0.918945
Step 300, Loss: -1001.000000, Acc: 0.928711
Step 350, Loss: -1001.000000, Acc: 0.918945
Step 400, Loss: -1001.000000, Acc: 0.925781
Step 450, Loss: -1001.000000, Acc: 0.919922
Step 500, Loss: -1001.000000, Acc: 0.914062
Test Accuracy: 0.923