2023年华数杯建模思路 - 案例:随机森林

## 0 赛题思路

(赛题出来以后第一时间在CSDN分享)

https://blog.csdn.net/dc_sinor?type=blog

1 什么是随机森林?

随机森林属于 集成学习 中的 Bagging(Bootstrap AGgregation 的简称) 方法。如果用图来表示他们之间的关系如下:

在这里插入图片描述
决策树 – Decision Tree

在这里插入图片描述
在解释随机森林前,需要先提一下决策树。决策树是一种很简单的算法,他的解释性强,也符合人类的直观思维。这是一种基于if-then-else规则的有监督学习算法,上面的图片可以直观的表达决策树的逻辑。

随机森林 – Random Forest | RF

在这里插入图片描述
随机森林是由很多决策树构成的,不同决策树之间没有关联。

当我们进行分类任务时,新的输入样本进入,就让森林中的每一棵决策树分别进行判断和分类,每个决策树会得到一个自己的分类结果,决策树的分类结果中哪一个分类最多,那么随机森林就会把这个结果当做最终的结果。

2 随机深林构造流程

在这里插入图片描述

    1. 一个样本容量为N的样本,有放回的抽取N次,每次抽取1个,最终形成了N个样本。这选择好了的N个样本用来训练一个决策树,作为决策树根节点处的样本。
    1. 当每个样本有M个属性时,在决策树的每个节点需要分裂时,随机从这M个属性中选取出m个属性,满足条件m << M。然后从这m个属性中采用某种策略(比如说信息增益)来选择1个属性作为该节点的分裂属性。
    1. 决策树形成过程中每个节点都要按照步骤2来分裂(很容易理解,如果下一次该节点选出来的那一个属性是刚刚其父节点分裂时用过的属性,则该节点已经达到了叶子节点,无须继续分裂了)。一直到不能够再分裂为止。注意整个决策树形成过程中没有进行剪枝。
    1. 按照步骤1~3建立大量的决策树,这样就构成了随机森林了。

3 随机森林的优缺点

3.1 优点

  • 它可以出来很高维度(特征很多)的数据,并且不用降维,无需做特征选择
  • 它可以判断特征的重要程度
  • 可以判断出不同特征之间的相互影响
  • 不容易过拟合
  • 训练速度比较快,容易做成并行方法
  • 实现起来比较简单
  • 对于不平衡的数据集来说,它可以平衡误差。
  • 如果有很大一部分的特征遗失,仍可以维持准确度。

3.2 缺点

  • 随机森林已经被证明在某些噪音较大的分类或回归问题上会过拟合。
  • 对于有不同取值的属性的数据,取值划分较多的属性会对随机森林产生更大的影响,所以随机森林在这种数据上产出的属性权值是不可信的

4 随机深林算法实现

数据集:https://archive.ics.uci.edu/ml/machine-learning-databases/undocumented/connectionist-bench/sonar/

import csv
from random import seed
from random import randrange
from math import sqrt


def loadCSV(filename):#加载数据,一行行的存入列表
    dataSet = []
    with open(filename, 'r') as file:
        csvReader = csv.reader(file)
        for line in csvReader:
            dataSet.append(line)
    return dataSet

# 除了标签列,其他列都转换为float类型
def column_to_float(dataSet):
    featLen = len(dataSet[0]) - 1
    for data in dataSet:
        for column in range(featLen):
            data[column] = float(data[column].strip())

# 将数据集随机分成N块,方便交叉验证,其中一块是测试集,其他四块是训练集
def spiltDataSet(dataSet, n_folds):
    fold_size = int(len(dataSet) / n_folds)
    dataSet_copy = list(dataSet)
    dataSet_spilt = []
    for i in range(n_folds):
        fold = []
        while len(fold) < fold_size:  # 这里不能用if,if只是在第一次判断时起作用,while执行循环,直到条件不成立
            index = randrange(len(dataSet_copy))
            fold.append(dataSet_copy.pop(index))  # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
        dataSet_spilt.append(fold)
    return dataSet_spilt

# 构造数据子集
def get_subsample(dataSet, ratio):
    subdataSet = []
    lenSubdata = round(len(dataSet) * ratio)#返回浮点数
    while len(subdataSet) < lenSubdata:
        index = randrange(len(dataSet) - 1)
        subdataSet.append(dataSet[index])
    # print len(subdataSet)
    return subdataSet

# 分割数据集
def data_spilt(dataSet, index, value):
    left = []
    right = []
    for row in dataSet:
        if row[index] < value:
            left.append(row)
        else:
            right.append(row)
    return left, right

# 计算分割代价
def spilt_loss(left, right, class_values):
    loss = 0.0
    for class_value in class_values:
        left_size = len(left)
        if left_size != 0:  # 防止除数为零
            prop = [row[-1] for row in left].count(class_value) / float(left_size)
            loss += (prop * (1.0 - prop))
        right_size = len(right)
        if right_size != 0:
            prop = [row[-1] for row in right].count(class_value) / float(right_size)
            loss += (prop * (1.0 - prop))
    return loss

# 选取任意的n个特征,在这n个特征中,选取分割时的最优特征
def get_best_spilt(dataSet, n_features):
    features = []
    class_values = list(set(row[-1] for row in dataSet))
    b_index, b_value, b_loss, b_left, b_right = 999, 999, 999, None, None
    while len(features) < n_features:
        index = randrange(len(dataSet[0]) - 1)
        if index not in features:
            features.append(index)
    # print 'features:',features
    for index in features:#找到列的最适合做节点的索引,(损失最小)
        for row in dataSet:
            left, right = data_spilt(dataSet, index, row[index])#以它为节点的,左右分支
            loss = spilt_loss(left, right, class_values)
            if loss < b_loss:#寻找最小分割代价
                b_index, b_value, b_loss, b_left, b_right = index, row[index], loss, left, right
    # print b_loss
    # print type(b_index)
    return {'index': b_index, 'value': b_value, 'left': b_left, 'right': b_right}

# 决定输出标签
def decide_label(data):
    output = [row[-1] for row in data]
    return max(set(output), key=output.count)


# 子分割,不断地构建叶节点的过程对对对
def sub_spilt(root, n_features, max_depth, min_size, depth):
    left = root['left']
    # print left
    right = root['right']
    del (root['left'])
    del (root['right'])
    # print depth
    if not left or not right:
        root['left'] = root['right'] = decide_label(left + right)
        # print 'testing'
        return
    if depth > max_depth:
        root['left'] = decide_label(left)
        root['right'] = decide_label(right)
        return
    if len(left) < min_size:
        root['left'] = decide_label(left)
    else:
        root['left'] = get_best_spilt(left, n_features)
        # print 'testing_left'
        sub_spilt(root['left'], n_features, max_depth, min_size, depth + 1)
    if len(right) < min_size:
        root['right'] = decide_label(right)
    else:
        root['right'] = get_best_spilt(right, n_features)
        # print 'testing_right'
        sub_spilt(root['right'], n_features, max_depth, min_size, depth + 1)

        # 构造决策树
def build_tree(dataSet, n_features, max_depth, min_size):
    root = get_best_spilt(dataSet, n_features)
    sub_spilt(root, n_features, max_depth, min_size, 1)
    return root
# 预测测试集结果
def predict(tree, row):
    predictions = []
    if row[tree['index']] < tree['value']:
        if isinstance(tree['left'], dict):
            return predict(tree['left'], row)
        else:
            return tree['left']
    else:
        if isinstance(tree['right'], dict):
            return predict(tree['right'], row)
        else:
            return tree['right']
            # predictions=set(predictions)
def bagging_predict(trees, row):
    predictions = [predict(tree, row) for tree in trees]
    return max(set(predictions), key=predictions.count)
# 创建随机森林
def random_forest(train, test, ratio, n_feature, max_depth, min_size, n_trees):
    trees = []
    for i in range(n_trees):
        train = get_subsample(train, ratio)#从切割的数据集中选取子集
        tree = build_tree(train, n_features, max_depth, min_size)
        # print 'tree %d: '%i,tree
        trees.append(tree)
    # predict_values = [predict(trees,row) for row in test]
    predict_values = [bagging_predict(trees, row) for row in test]
    return predict_values
# 计算准确率
def accuracy(predict_values, actual):
    correct = 0
    for i in range(len(actual)):
        if actual[i] == predict_values[i]:
            correct += 1
    return correct / float(len(actual))


if __name__ == '__main__':
    seed(1) 
    dataSet = loadCSV('sonar-all-data.csv')
    column_to_float(dataSet)#dataSet
    n_folds = 5
    max_depth = 15
    min_size = 1
    ratio = 1.0
    # n_features=sqrt(len(dataSet)-1)
    n_features = 15
    n_trees = 10
    folds = spiltDataSet(dataSet, n_folds)#先是切割数据集
    scores = []
    for fold in folds:
        train_set = folds[
                    :]  # 此处不能简单地用train_set=folds,这样用属于引用,那么当train_set的值改变的时候,folds的值也会改变,所以要用复制的形式。(L[:])能够复制序列,D.copy() 能够复制字典,list能够生成拷贝 list(L)
        train_set.remove(fold)#选好训练集
        # print len(folds)
        train_set = sum(train_set, [])  # 将多个fold列表组合成一个train_set列表
        # print len(train_set)
        test_set = []
        for row in fold:
            row_copy = list(row)
            row_copy[-1] = None
            test_set.append(row_copy)
            # for row in test_set:
            # print row[-1]
        actual = [row[-1] for row in fold]
        predict_values = random_forest(train_set, test_set, ratio, n_features, max_depth, min_size, n_trees)
        accur = accuracy(predict_values, actual)
        scores.append(accur)
    print ('Trees is %d' % n_trees)
    print ('scores:%s' % scores)
    print ('mean score:%s' % (sum(scores) / float(len(scores))))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/55823.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

51单片机学习--蜂鸣器播放音乐

由原理图可知&#xff0c;蜂鸣器BEEP与P1_5 相关&#xff0c;但其实这个原理图有错&#xff0c;实测接的是P2_5 下面这个代码就是以500HZ的频率响500ms的例子 sbit Buzzer P2^5;unsigned char KeyNum; unsigned int i;void main() {while(1){KeyNum Key();if(KeyNum){for(i …

亚马逊买家账号ip关联怎么处理

对于亚马逊买家账号&#xff0c;同样需要注意IP关联问题。在亚马逊的眼中&#xff0c;如果多个买家账号共享相同的IP地址&#xff0c;可能会被视为潜在的操纵、违规或滥用行为。这种情况可能导致账号受到限制或处罚。 处理亚马逊买家账号IP关联问题&#xff0c;建议采取以下步骤…

实用干货!一文读懂Salesforce中6种数据关系类型!

Salesforce中对象之间的数据关系可能是一个棘手的话题。对于创建自定义对象的业务场景&#xff0c;需要决定使用哪些关系类型来扩展Salesforce数据模型。 01 查找关系 查找关系&#xff08;Lookup Relationships&#xff09;是一种松散耦合&#xff08;loosely coupled&…

[React]生命周期

前言 学习React&#xff0c;生命周期很重要&#xff0c;我们了解完生命周期的各个组件&#xff0c;对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1、getDefaultProps() 设置默认的props&#xff0c;也可以用duf…

【Quartus FPGA】EMIF DDR3 读写带宽测试

在通信原理中&#xff0c;通信系统的有效性用带宽来衡量&#xff0c;带宽定义为每秒传输的比特数&#xff0c;单位 b/s&#xff0c;或 bps。在 DDR3 接口的产品设计中&#xff0c;DDR3 读/写带宽是设计者必须考虑的指标。本文主要介绍了 Quartus FPGA 平台 EMIF 参数配置&#…

Tomcat 创建https

打开CMD,按下列输入 keytool -genkeypair -alias www.bo.org -keyalg RSA -keystore d:\ambition.keystore -storetype pkcs12 输入密钥库口令:123456 再次输入新口令:123456 您的名字与姓氏是什么? [Unknown]: www.ambition.com 您的组织单位名称是什么? [Unknown…

cc2652在使用过程中的一些注意事项

可能不只是cc2652有这些坑&#xff0c;估计cc26xx系列都存在。 CCS的预编译宏配置位置 时钟获取 时钟获取__STATIC_INLINE uint32_t SysCtrlClockGet( void )在sys_ctrl.h中&#xff0c;sys_ctrl.h没有在工程路径下面&#xff0c;在其sdk中 节拍时间获取 ICall_getTicks(); …

IPv6 over IPv4隧道配置举例

配置IPv6 over IPv4手动隧道示例 组网需求 如图1所示&#xff0c;两台IPv6主机分别通过SwitchA和SwitchC与IPv4骨干网络连接&#xff0c;客户希望两台IPv6主机能通过IPv4骨干网互通。 图1 配置IPv6 over IPv4手动隧道组网图 配置思路 配置IPv6 over IPv4手动隧道的思路如下&…

roop 视频换脸

roop: one click face swap. 只用一张人脸图片&#xff0c;就能完成视频换脸。 项目地址&#xff1a; https://github.com/s0md3v/roopColab 部署&#xff1a; https://github.com/dream80/roop_colab 本文是本地部署的实践记录。 环境基础 OS: Ubuntu 22.04.2 LTSKernel: 5…

Redis实战(4)——Redisson分布式锁

1 基于互斥命令实现分布式锁的弊端 根据上篇文章基于redis互斥命令实现的分布式锁任然存在一定的弊端 1无法重入: 同一个线程无法重新获得同一把锁2超时删除 &#xff1a;会因为超时、任务阻塞而自动释放锁&#xff0c;出现其他线程抢占锁出现并行导致线程不安全的问题3 不可…

unity行为决策树实战详解

一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型&#xff0c;它将游戏AI的行为分解为一系列的决策节点&#xff0c;并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中&#xff0c;每个节点都代表一个行为或决策&#xff0c;例如移动、攻击、逃跑等…

LInux的安装(VMware,网卡设置,SSH连接工具)

Linux的安装 1、安装方式介绍 1.安装方式: 物理机安装:直接将操作系统安装到服务器硬件上 虚拟机安装:通过虚拟机软件安装 **虚拟机( Virtual Machine&#xff09;**指通过软件模拟的具有完整硬件系统功能、运行在完全隔离环境中的完整计算机系统。 2、安装Linux 在官网将…

20款奔驰S350升级原厂HUD抬头显示系统,提升您的行车安全

HUD是平视显示器的简称&#xff0c;它原先是运用在航空器上的飞行辅助仪器。指飞行员不需要低头&#xff0c;就能够看到他需要的重要资讯。由于HUD的方便性以及能够提高飞行安全&#xff0c;这项技术后来也发展到汽车行业。汽车搭载的HUD抬头数字显示功能&#xff0c;是利用光学…

Toolformer :让AI学会使用工具

paper: 《Toolformer: Language Models Can Teach Themselves to Use Tools 》 核心思想&#xff0c; 1. Sampling API Calls &#xff1a;设计设计prompt,让模型生成含API调用的文本&#xff08;如图3&#xff09;&#xff0c;只保留K个概率最高的API调用 2. Executing API …

MySql006——基本的SELECT查询语句

在《MySql003——结构化查询语言SQL基础知识》中&#xff0c;我们学习了有关SQL的基础知识&#xff0c;也知道SQL中查询语句SELECT使用最为频繁 接下来我们将学习一些基本的SELECT查询语句 一、SELECT语句的通用语法 在MySQL数据库中&#xff0c;使用SELECT语句可以查询数据…

Android Studio多渠道打包

使用环境&#xff1a; Android studio 多渠道打包 使用方法&#xff1a; 1 APP下build.gradle文件 flavorDimensions "default"productFlavors {huawei {dimension "default"manifestPlaceholders [ channel:"huawei" ]}xiaomi {dimension &…

Nginx学习教程(基础篇)

目录 一、Nginx安装 二、Nginx基本使用 2.1、目录结构 conf html logs sbin 2.2、基本运行原理 2.3、nginx.conf最小配置解析 worker_processes worker_connections include mime.types default_type application/octet-stream sendfile on keepalive_timeout…

Python实现GA遗传算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;最早是由美国的 John holland于20世…

lc1074.元素和为目标值的子矩阵数量

创建二维前缀和数组 两个for循环&#xff0c;外循环表示子矩阵的左上角&#xff08;x1,y1&#xff09;&#xff0c;内循环表示子矩阵的右下角&#xff08;x2,y2&#xff09; 两个for循环遍历&#xff0c;计算子矩阵的元素总和 四个变量&#xff0c;暴力破解的时间复杂度为O(…

驱动开发(中断)

头文件&#xff1a; #ifndef __LED_H__ #define __LED_H__#define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_LED1_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014 #define PHY_LED2_RCC 0X50000A28#def…