ptyhon 随机森林算法及其优化 RandomForest

本文探讨如何在已有90%以上正确率的基础上优化随机森林算法,通过调整树的数量和深度,筛选高AUC的树,排除相似度高的低效树,进一步提高模型准确率,避免过拟合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优化随机森林算法,正确率提高1%~5%(已经有90%+的正确率,再调高会导致过拟合)

论文当然是参考的,毕竟出现早的算法都被人研究烂了,什么优化基本都做过。而人类最高明之处就是懂得利用前人总结的经验和制造的工具(说了这么多就是为偷懒找借口。hhhh)

优化思路

1. 计算传统模型准确率
2. 计算设定树木颗数时最佳树深度,以最佳深度重新生成随机森林
3. 计算新生成森林中每棵树的AUC,选取AUC靠前的一定百分比的树
4. 通过计算各个树的数据相似度,排除相似度超过设定值且AUC较小的树
5. 计算最终的准确率

主要代码粘贴如下(注释比较详细,就不介绍代码了)

#-*- coding: utf-8 -*-
import time
from csv import reader
from random import randint
from random import seed

import numpy as np
from numpy import mat

from group_11 import caculateAUC_1, plotTree

# 建立一棵CART树
'''试探分枝'''
def data_split(index, value, dataset):
    left, right = list(), list()
    for row in dataset:
        if row[index] < value:
            left.append(row)
        else:
            right.append(row)
    return left, right

'''计算基尼指数'''
def calc_gini(groups, class_values):
    gini = 0.0
    total_size = 0
    for group in groups:
        total_size += len(group)
    for group in groups:
        size = len(group)
        if size == 0:
            continue
        for class_value in class_values:
            proportion = [row[-1] for row in group].count(class_value) / float(size)
            gini += (size / float(total_size)) * (proportion * (1.0 - proportion))# 二分类执行两次,相当于*2
    return gini

'''找最佳分叉点'''
def get_split(dataset, n_features):
    class_values = list(set(row[-1] for row in dataset))# 类别标签集合
    b_index, b_value, b_score, b_groups = 999, 999, 999, None

    # 随机选取特征子集,包含n_features个特征
    features = list()
    while len(features) < n_features:
        # 随机选取特征
        # 特征索引
        index = randint(0, len(dataset[0]) - 2)  # 往features添加n_features个特征(n_feature等于特征数的根号),特征索引从dataset中随机取
        if index not in features:
            features.append(index)
    for index in features:      # 对每一个特征
        # 计算Gini指数
        for row in dataset:   # 按照每个记录的该特征的取值划分成两个子集,计算对于的Gini(D,A),取最小的
            groups = data_split(index, row[index], dataset)
            gini = calc_gini(groups, class_values)
            if gini < b_score:
                b_index, b_value, b_score, b_groups = index, row[index], gini, groups
    return {'index': b_index, 'value': b_value, 'groups': b_groups}  # 每个节点由字典组成

'''多数表决'''
def to_terminal(group):
    outcomes = [row[-1] for row in group]
    return max(set(outcomes), key=outcomes.count)

'''分枝'''
def split(node, max_depth, min_size, n_features, depth):
    left, right = node['groups']  # 自动分包/切片
    del (node['groups'])
    if not left or not right:    # left或者right为空时
        node['left'] = node['right'] = to_terminal(left + right)  # 叶节点不好理解
        return

    if depth >= max_depth:
        node['left'], node['right'] = to_terminal(left), to_terminal(right)
        return
    # 左子树
    if len(left) <= min_size:
        node['left'] = to_terminal(left)
    else:
        node['left'] = get_split(left, n_features)
        split(node['left'], max_depth, min_size, n_features, depth + 1)
    # 右子树
    if len(right) <= min_size:   # min_size最小的的分枝样本数
        node['right'] = to_terminal(ri
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值