随机森林

随机森林是集成学习分(Ensemble Learning)中的一种。随机森林主要体现在‘随机’和‘森林’上。

1. 随机森林的介绍

随机森林是一种实现简单但是又很有效的方法,其随机性体现在样本选取的随机性上和特征选取的随机性上。

下面主要讨论一下样本有放回的抽取: 设有python 随机森林 目标数据分类_数据挖掘个样本,有放回的抽取python 随机森林 目标数据分类_数据挖掘次,样本在python 随机森林 目标数据分类_数据挖掘次采样中始终不被踩到的概率是python 随机森林 目标数据分类_数据挖掘_04,取极限就可以得到:

python 随机森林 目标数据分类_数据挖掘_05

也可以画个图看看:

def plot_sample():
    import matplotlib.pyplot as plt
    m = [i for i in range(10, 1000)]
    y = [pow(1 - 1 / i, i) for i in m]
    plt.plot(m, y)
    plt.show()

python 随机森林 目标数据分类_python 随机森林 目标数据分类_06

即有36.8%的样本没有放入训练中,这些样本可以抽取出来再作为‘包外估计’。

2.随机森林的python实现2.1 模型实现

决策树部分的实现见:机器学习之决策树原理及python实现.

import numpy as np
import pandas as pd
from ml.decision_tree.basic_tree import MyDecisionTree


class MyRF(object):
    def __init__(self, max_depth=3, criterion="entropy", n_estimator=5):
        """
        随机森林的实现
        :param max_depth: 每棵决策树的最大深度
        :param criterion: 筛选特征用的策略:
            'mse': 均方误差计算,用来实现回归树
            'entropy': 用信息增益来筛选特征
            'gini':用gini系数来筛选特征
        :param n_estimator: 评估器个数,这儿也就是决策树的个数
        """
        self.max_depth = max_depth
        self.n_estimator = n_estimator
        self.criterion = criterion

        self.trees = []

    def _sample(self, data_set, columns):
        """
        随机森林的随机性在这儿体现,这儿仅仅是对样本做了随机性,也可以对特征进行随机抽取
        :param data_set: 输入数据:待采样的数据
        :param columns: 特征名称
        :return: 采样后的结果
        """
        n = len(data_set)
        indexs = np.random.choice(n, n)
        return data_set[indexs], columns

    def fit(self, data_set, columns):
        """
        训练模型
        :param data_set: 输入的训练数据 
        :param columns: 特征名称
        :return: 
        """
        # 随机森林的'森林'就在这儿体现,也就是由多棵决策树构成
        for _ in range(self.n_estimator):
            data_sample, columns_sample = self._sample(data_set, columns)
            tree = MyDecisionTree(max_depth=self.max_depth, criterion=self.criterion)
            tree.fit(data_sample, columns_sample)
            self.trees.append(tree)

    def predict(self, data_set, columns):
        """
        通过投票机制选择出最优的结果
        :param data_set: 输入数据
        :param columns: 特征名称
        :return: 结果列表
        """
        # 对所有样本预测
        result_list = []
        # 随机森林中的每棵决策树都输出结果
        for tree in self.trees:
            result_list.append(tree.predict(data_set, columns))
        
        # 下面的逻辑就是投票选择出最优的结果
        # 如果是'mse'作为特征选择,即是回归树,输出结果为所有树结果的均值
        final_result = []
        result_list = np.array(result_list)
        for i in range(len(result_list[0])):
            single = result_list[:, i]
            if self.criterion == 'mse':
                final_result.append(np.mean(single))
            else:
                result_dict = {}
                for s in single:
                    if s not in result_dict.keys():
                        result_dict[s] = 1
                    else:
                        result_dict[s] += 1
                max_ = 0
                r = None
                for key, value in result_dict.items():
                    if value > max_:
                        r = key
                final_result.append(r)
        return final_result
2.2 模型验证
def run_my_model():
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    iris_data = load_iris()

    my = MyRF()
    df = pd.DataFrame(iris_data['data'], columns=['f1', 'f2', 'f3', 'f4'])
    df['label'] = iris_data['target']

    train_data, test_data = train_test_split(df)

    print('train:')
    my.fit(train_data.values, train_data.columns)
    print(my.trees)

    test_result = my.predict(test_data.values, test_data.columns)
    test = [int(y) for y in test_data['label'].values]
    pred = [int(y) for y in test_result]
    print('result:')
    print('test: ', test)
    print('pred: ', pred)

运行结果:

result:
 test: [2, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 2, 0, 0, 1, 1, 2, 0, 0, 0, 2, 2, 1, 0, 1, 2, 2, 2, 0, 0, 1, 0, 2, 0, 0, 1, 1, 0]
 pred: [2, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 2, 2, 1, 0, 1, 2, 2, 2, 0, 0, 1, 0, 2, 0, 0, 1, 1, 0]

参考资料: 《机器学习》 周志华著