前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Easyensemble&LightGBM-应对气象样本不平衡问题的有效算法(支持各类基模型接入与新增优化参数)

Easyensemble&LightGBM-应对气象样本不平衡问题的有效算法(支持各类基模型接入与新增优化参数)

作者头像
郭好奇同学
发布2023-02-15 16:48:28
8791
发布2023-02-15 16:48:28
举报
文章被收录于专栏:好奇心Log好奇心Log

⚪在缓解气象强对流识别等样本不平衡问题中的效果

⚪总结论述

⚪样本不平衡问题概述

⚪本文Easyensemble的主要改进点

⚪代码

|| 在缓解气象强对流识别等样本不平衡问题中的效果

将Easyensemble应用到气象样本不平衡问题的缓解中,其中0(正样本):1(负样本) = 4723:84,仅调整了每个基模型的正负样本比例数,Easyensemble便可取得比SMOTE和原LightGBM方法更高的TS。相较其它方法而言,新增的几个参数的调整以达到较优的效果,虽是一项具有工作量的流程,但却新有了一条可优化的道路。当然具体问题具体分析,没有一种方法一定是通用的,假如特征与类别之间的关系较为明确,那么采用Easyensemble可能只会有不好的结果。

====================

验证集:

LGB:TS-0.0

Easyensemble:TS-0.058

smote:TS-0.046

测试集:

LGB:TS-0.0

Easyensemble:TS-0.079

SMOTE:TS-0.049

====================

||总结论述

Easyensemble是一种简单且有效的数据不均衡处理方法,其从全局来看能尽量避免有效信息的丢失以及过采样方法带来的异常值、模型训练难度加大等问题,目前已在相当领域取得了较传统样本不平衡处理方法更优的分类结果。现有的Easyensemble方法多基于Imbleace,其基模型为Adaboost,效果欠佳,并且缺乏其它必要的低层修改接口。为此,这里开源的Easyensemble已高度的精简化,适当修改可集成任意基模型,可按照自身需求修改。相对于imblearn提供的API接口,这里新增了子模型个数、分类权重分配、正负样本数之比这三个参数,能进一步通过调参来提升其分类效果。

|| 样本不平衡问题概述:

(https://blog.csdn.net/qq_41750911/article/details/124566619):

一般常见缓解方法分为数据层面和算法层面。

1 数据层面(采样、数据合成、数据增强)

数据增强:直接复制小类样本,对小类样本数据经过一定的处理,做一些小的改变等。

(1)采样(随机采样):

随机欠采样:从多数类样本集中随机选择较少的样本(有放回/无放回)。

缺点:欠采样中丢失了部分样本,可能损失有用的信息,造成模型对某些特征的欠拟合。

随机过采样:从少数类样本集中随机重复抽取样本(有放回)以得到更多的样本。

缺点:过采样对少数样本进行了复制多份,虽然扩大了数据规模,但是也容易造成过拟合。

(2)数据合成:

文本领域(离散空间):裁剪,翻转,旋转,加噪声,SMOTE方法。

图像领域(连续空间):去停用词,同义词替换,加噪声,回翻译。

2 算法层面(修改损失函数值、难例挖掘)

(1)带权值的损失函数

为小样本标签增加损失函数的权值,即一个小样本设置权值多次使用,类似于过采样。

(2) 新损失Focal loss

在原来带权值的loss函数的基础上进行了改进,继续改进损失函数的权值。

(3) 难例挖掘

挖掘出模型计算效果较差的样本,然后对这些样本再进行重新训练。

(4) 数据增强:

生成对抗网络(GAN)、自监督对比学习(SSL)等模型算法。

3 Easyensemble方法

2006年X.Y.Liu和J.Wu等人提出了一种基于欠采样技术与集成学习技术相结合的EasyEnsemble算法,该算法针对欠采样可能会损失重要信息的不足作了一定的改进,即按照少数类样本的数量将多数类样本分割成多个子集,然后分别与少数类样本进行组合,之后将各个组合样本分别使用Adaboost算法进行训练,再通过集成策略输出结果。

其流程图如下:

可以看出,该算法本质上还是一种欠采样技术,虽然欠采样后每个组合子集中多数类样本数量不及多数类样本总数量,但是在无放回的随机采样情况下将所有多数类样本子集组合起来仍然是多数类样本全集,从全局来看并没有丢失有效信息,所以这是一种简单且有效的数据不均衡处理方法。

|| 本文Easyensemble的主要改进点:

·精简化的源代码,可根据自身喜好,进行修改。

·可助于接入任意基模型,如LightGBM、Catboost、Xgboost、SVM等。

·新增子模型个数、分类权重分配、正负样本数之比这三个参数,通过调整这三个参数,来达到分类效果的优化。

|| 代码:

>> main.py

代码语言:javascript
复制
#%%
import pandas as pd
from Ensemble_model import easyensemble
import warnings
import os
import numpy as np 
import matplotlib.pyplot as plt
from collections import Counter
from sklearn.datasets import make_classification
import meteva.method as mem
import pickle
warnings.filterwarnings("ignore")
#%%
# 1.创建类别不平衡的数据集:
# 使用make_classification生成样本数据
X, Y = make_classification(n_samples=5000,
                           n_features=2,  # 特征个数 = n_informative() + n_redundant + n_repeated
                           n_informative=2,  # 多信息特征的个数
                           n_redundant=0,  # 冗余信息,informative特征的随机线性组合
                           n_repeated=0,  # 重复信息,随机提取n_informative和n_redundant 特征
                           n_classes=2,  # 分类类别
                           n_clusters_per_class=1,  # 某一个类别是有几个cluster构成的
                           weights=[0.99, 0.01],  # 列表类型,权重比
                           random_state=0
                           )

# 2.查看各个标签的样本:
counter = Counter(Y)

# 3.数据集可视化:
plt.scatter(X[:, 0], X[:, 1], c=Y)
plt.show()

path_model_save = 'Data/model/'  # 将easyensemble训练得到的模型保存,以便后续调用
path_importance_save = 'Data/importance/' # 获得单个基模型对应的特征重要性

cols_x = [str(i) for i in range(X.shape[1])]
num = 10
rate = 3

from sklearn.model_selection import train_test_split
xtrain,xvalid,ytrain,yvalid = train_test_split(X,Y,test_size=0.6,random_state=2021)
xvalid,xtest,yvalid,ytest = train_test_split(xvalid,yvalid,test_size=0.5,random_state=2021)

easyensemble(xtrain,
            ytrain,
            xvalid,
            yvalid,
            save_path=path_model_save,
            importance_save_path=path_importance_save,
            features_name = cols_x,
            rate = rate,num = num,weight = [1, 1])

###调用已经保存的模型
mds = os.listdir(path_model_save)
test_prob = np.empty((xtest.shape[0], len(mds)))  # 测试集
valid_prob = np.empty((xvalid.shape[0], len(mds)))  # 测试集
for idx,md in enumerate(mds):
    pic2 = open(path_model_save + md,'rb')
    md_load = pickle.load(pic2)
    test_prob[:, idx] = md_load.predict_proba(xtest)[:, -1]
    valid_prob[:, idx] = md_load.predict_proba(xvalid)[:, -1]
test_prob_result = np.average(test_prob, axis=1)
valid_prob_result = np.average(valid_prob, axis=1)

predtest_easyensemble = test_prob_result.copy()
predtest_easyensemble[test_prob_result >= 0.5] = 1
predtest_easyensemble[test_prob_result < 0.5] = 0

predvalid_easyensemble = valid_prob_result.copy()
predvalid_easyensemble[valid_prob_result >= 0.5] = 1
predvalid_easyensemble[valid_prob_result < 0.5] = 0

>> mkdir.py

代码语言:javascript
复制

def mkdir(path):
    # 引入模块
    import os
    # 去除首位空格
    path = path.strip()
    # 去除尾部 \ 符号
    path = path.rstrip("\\")
    # 判断路径是否存在
    # 存在     True
    # 不存在   False
    isExists = os.path.exists(path)
    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        # 创建目录操作函数
        os.makedirs(path)
        # print(path + ' 创建成功')
        return True
    else:
        # 如果目录存在则不创建,并提示目录已存在
        # print(path + ' 目录已存在')
        return False

获取全部代码请发送信息 “Easyensemble”到人工智能AI代码星球。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好奇心Log 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档