机器学习之随机森林(RF)及python实现

随机森林

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

1. 随机森林的介绍

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

下面主要讨论一下样本有放回的抽取:
设有 m m m个样本,有放回的抽取 m m m次,样本在 m m m次采样中始终不被踩到的概率是 ( 1 − 1 / m ) m (1-1/m)^m (11/m)m,取极限就可以得到:

lim ⁡ m → ∞ ( 1 − 1 / m ) m = 1 / e ≈ 0.368 \lim_{m \to \infty} (1-1/m)^m = 1/e \approx 0.368 mlim(11/m)m=1/e0.368

也可以画个图看看:

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()

在这里插入图片描述
即有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]

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

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
随机森林是一个强大的机器学习算法,在python中可以使用sklearn库来调参。调参的目标是找到最佳的参数组合,以提高模型的性能。以下是一种常用的调参方法: 1. 手动调参:可以通过循环遍历不同的参数组合并训练模型来找到最佳参数组合。对于随机森林,一些常用的参数包括树的数量(n_estimators)、每棵树的最大深度(max_depth)、特征选择的方式(max_features)等。通过尝试不同的参数值并评估模型的性能,可以确定最佳的参数组合。 2. 网格搜索调参:网格搜索是一种系统化的调参方法,它会遍历所有可能的参数组合,并选择在交叉验证中表现最好的参数组合。在sklearn中,可以使用GridSearchCV函数来进行网格搜索调参。你需要先定义一个参数网格,然后将它作为参数传递给GridSearchCV函数。在每个参数组合上进行交叉验证后,GridSearchCV会返回最佳参数组合和最佳得分。 下面是一个示例代码,演示了如何使用网格搜索调参来优化随机森林模型: ```python from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV param_grid = { 'n_estimators': [10, 50, 100], 'max_depth': [None, 5, 10], 'max_features': ['auto', 'sqrt', 'log2'] } rf = RandomForestClassifier(random_state=42) grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5) grid_search.fit(X_train, y_train) best_params = grid_search.best_params_ best_score = grid_search.best_score_ print("最佳参数组合:", best_params) print("最佳得分:", best_score) ``` 根据你的需求,你可以根据数据集的大小和特征选择的策略来调整n_estimators、max_depth和max_features等参数。通过网格搜索调参,你可以获得最佳参数组合以及对应的最佳得分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值