机器学习——样本不均衡学习

1、样本不均衡定义

一般在分类机器学习中,每种类别的样本是均衡的,也就是不同目标值的样本总量是接近的,但是在很多场景下的样本没有办法做到理想情况,甚至部分情况本身就是不均衡情况:
(1)很多场景下,数据集本身不平和,部分类别的数据多于其他数据;
(2)固定场景下,例如风控的场景,负样本的比例远远小于正样本的占比;
(3)梯度下降过程中,不同类别的样本量比较大时,模型本身很难做到收敛最优解。

2、解决方案

不同场景下,对样本不均衡的解决方案侧重点不同,下面以金融风控举例:
(1)下探法:将被拒绝的用户放进来,充当负样本。缺点也很明显,容易风险高,成本也较高;
(2)代价敏感:对少数样本进行加权处理,让模型进行均衡训练;
(3)采样法:通过多正样本进行欠采样,或者负样本进行过采样的方式平衡样本;
(4)半监督学习

2.1 代价敏感

通过改变少数样本的权重,从而让模型得到一定的均衡训练。但是代价敏感加权增大了负样本在模型中的贡献度,但本身并没有为模型增加额外的信息,这就没有办法解决选择偏误的问题,也没办法带来负面影响。
在逻辑回归中就可以通过参数class_weight='balanced’来调整正负样本的权重,我们以逻辑回归评分卡为例,调整逻辑回归的class_weight的参数,看看结果,该例子链接:逻辑回归评分卡

# 导入模块
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score,roc_curve,auc

data = pd.read_csv('Bcard.txt')
feature_lst = ['person_info','finance_info','credit_info','act_info']
# 划分数据
train = data[data.obs_mth != '2018-11-30'].reset_index().copy()
val = data[data.obs_mth == '2018-11-30'].reset_index().copy()
x = train[feature_lst]
y = train['bad_ind']
val_x = val[feature_lst]
val_y = val['bad_ind']

# 查看正负样本的数量
print('训练集:\n',y.value_counts())
print('跨时间验证集:\n',val_y.value_counts())

# 训练模型
lr_model = LogisticRegression(C=0.1)
lr_model.fit(x,y)

# 训练集
print('参数调整前的ks值')
y_pred = lr_model.predict_proba(x)[:,1] #取出训练集预测值
fpr_lr_train,tpr_lr_train,_ = roc_curve(y,y_pred) #计算TPR和FPR
train_ks = abs(fpr_lr_train - tpr_lr_train).max() #计算训练集KS
print('train_ks : ',train_ks)

#验证集
y_pred = lr_model.predict_proba(val_x)[:,1] #计算验证集预测值
fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred) #计算验证集预测值
val_ks = abs(fpr_lr - tpr_lr).max() #计算验证集KS值
print('val_ks : ',val_ks)


# 调整逻辑回归中的class_weight参数
print('参数调整后的ks值')
lr_model = LogisticRegression(C=0.1,class_weight = 'balanced')
lr_model.fit(x,y)
y_pred = lr_model.predict_proba(x)[:,1] #取出训练集预测值
fpr_lr_train,tpr_lr_train,_ = roc_curve(y,y_pred) #计算TPR和FPR
train_ks = abs(fpr_lr_train - tpr_lr_train).max() #计算训练集KS
print('train_ks : ',train_ks)
y_pred = lr_model.predict_proba(val_x)[:,1] #计算验证集预测值
fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred) #计算验证集预测值
val_ks = abs(fpr_lr - tpr_lr).max() #计算验证集KS值
print('val_ks : ',val_ks)

在这里插入图片描述
从上面可以看出,调整参数后的训练集合验证集的ks值都有了一定的提升。

2.2 过采样

代价敏感有用,但效果不一定,通过对负样本进行过采样能够达到更好的效果,即为模型引入更多的负样本。一般过采样的方法如下:

  • 随机过采样:直接复制负样本,模型的泛化能力较差。
  • SMOTE算法:少数类别过采样技术(Synthetic Minority Oversampling Technique)

SMOTE过采样

SMOTE是通过合成少数样本的过采样技术,它是通过对少数样本进行分析,然后在现有少数样本之间进行插值,人工合成新样本,合并样本到模型中训练。基本步骤如下:
(1)采用knn算法,计算出每个少数样本的k个近邻;
(2)从k个近邻中随机挑选N个样本进行随机线性插值;
(3)构造新的少数样本;
(4)将新样本和原本数据合并,产生新的训练集。
在这里插入图片描述

SMOTETomek综合采样

先使用过采样,扩大样本后再对处在胶着状态的点用 Tomek Link 法进行删除,有时候甚至连 Tomek Link 都不用,直接把离得近的对全部删除,因为在进行过采样后,0 和 1 的样本量已经达到了 1:1。
在这里插入图片描述

随机过采样、SMOTE采样和综合采样的示例代码

以上面的评分卡数据为例,读取数据的代码省略。
导入模块

from imblearn.over_sampling import RandomOverSampler,SMOTE
from imblearn.combine import SMOTETomek

使用三种过采样方法进行采样

# 随机过采样
ros = RandomOverSampler(random_state=0, sampling_strategy='auto')
x_ros, y_ros = ros.fit_resample(x,y)
print('随机过采样后分类情况:',y_ros.value_counts())

# SMOTE过采样
sot = SMOTE(random_state=0)
x_sot,y_sot = sot.fit_resample(x,y)
print('smote过采样后情况:',y_sot.value_counts())

# SMOTETomek综合采样
sttk = SMOTETomek(random_state=0)
x_sttk,y_sttk = sttk.fit_resample(x,y)
print('综合采样后情况:',y_sttk.value_counts())

在这里插入图片描述
比较三种采样后的ks值、recall值和auc值

data = [['原始数据',x,y],['随机过采样',x_ros,y_ros],['SMOTE过采样',x_sot,y_sot],['综合过采样',x_sttk,y_sttk]]

# 使用逻辑回归分别对过采样后的数据进行训练,看看情况
lr = LogisticRegression(C=0.1)
for text,train_X, train_y in data:
    lr.fit(train_X, train_y)
    y_pred = lr.predict_proba(val_x)[:,1] #计算验证集预测值
    pred_y = lr.predict(val_x)
    rc_score = recall_score(val_y,pred_y)
    fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred) #计算验证集预测值
    val_ks = abs(fpr_lr - tpr_lr).max() #计算验证集KS值
    auc_score = auc(fpr_lr,tpr_lr)
    print(text,'ks',val_ks,'auc',auc_score,'recall',rc_score)

在这里插入图片描述
以上可以看出三种方法过采样可以提升模型的评分,但没有一定要采用哪种过采样方法,不同的数据会有不同的情况。

机器学习与过采样

我们还能使用机器学习先对训练集的数据进行拟合,将预测结果较差的样本排除,不参与过采样,具体代码如下:
这里我们使用lightGBM算法,数据还是使用上面数据

 # 使用lightGBM进行数据拟合,去掉预测结果较差的数据,再进行smote过采样
import lightgbm as lgb
import numpy as np
lgb_clf = lgb.LGBMClassifier(learning_rate=0.05,n_estimators=100)
lgb_clf.fit(x, y, eval_set=[(x, y), (val_x, val_y)], eval_metric='auc')
temp = x.copy()
temp['bad_ind'] = y
temp['pred'] = lgb_clf.predict_proba(x)[:,1]
temp=temp.sort_values(by=['pred'], ascending=False).reset_index()
temp['rank'] = np.array(temp.index)/len(temp)
temp

在这里插入图片描述
我们定义一个weight函数,将预测不准的前后各20%数据排除

def weight(x,y):
    if x==0 and y<0.2:
        return 0.1
    elif x==1 and y>0.8:
        return 0.1
    else:
        return 1
    
temp['weight'] = temp.apply(lambda x:weight(x.bad_ind,x['rank']), axis=1)
smote_sample = temp[temp.weight==1]
print(smote_sample.shape)
train_X_smote = smote_sample[feature_lst]
train_y_smote = smote_sample['bad_ind']

在这里插入图片描述
同样进行三种采样,跟没有采样数据进行对比

# 随机过采样
ros = RandomOverSampler(random_state=0, sampling_strategy='auto')
x_ros, y_ros = ros.fit_resample(train_X_smote,train_y_smote)
print('随机过采样后分类情况:',y_ros.value_counts())

# SMOTE过采样
sot = SMOTE(random_state=0)
x_sot,y_sot = sot.fit_resample(train_X_smote,train_y_smote)
print('smote过采样后情况:',y_sot.value_counts())

# SMOTETomek综合采样
sttk = SMOTETomek(random_state=0)
x_sttk,y_sttk = sttk.fit_resample(train_X_smote,train_y_smote)
print('综合采样后情况:',y_sttk.value_counts())

data = [['原始数据',x,y],['随机过采样',x_ros,y_ros],['SMOTE过采样',x_sot,y_sot],['综合过采样',x_sttk,y_sttk]]

# 使用逻辑回归分别对过采样后的数据进行训练,看看情况
lr = LogisticRegression(C=0.1)
for text,train_X, train_y in data:
    lr.fit(train_X, train_y)
    y_pred = lr.predict_proba(val_x)[:,1] #计算验证集预测值
    pred_y = lr.predict(val_x)
    rc_score = recall_score(val_y,pred_y)
    fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred) #计算验证集预测值
    val_ks = abs(fpr_lr - tpr_lr).max() #计算验证集KS值
    auc_score = auc(fpr_lr,tpr_lr)
    print(text,'ks',val_ks,'auc',auc_score,'recall',rc_score)

在这里插入图片描述
可以看到将预测结果较差的样本排除,再进行过采样,得到的模型会比更好一些。

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

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

相关文章

SSL 证书过期巡检脚本

哈喽大家好&#xff0c;我是咸鱼 我们知道 SSL 证书是会过期的&#xff0c;一旦过期之后需要重新申请。如果没有及时更换证书的话&#xff0c;就有可能导致网站出问题&#xff0c;给公司业务带来一定的影响 所以说我们要每隔一定时间去检查网站上的 SSL 证书是否过期 如果公…

StackOverFlow刚刚宣布推出自己的AI产品!

StackOverFlow刚刚宣布要推出自己的AI产品&#xff01; OverflowAI是StackOverFlow即将推出自己AI产品的名字&#xff0c;据称也是以VSCode插件的形式&#xff0c;计划在8月发布。我们来看看都有些什么功能&#xff0c;通过目前的信息看&#xff0c;OverflowAI的主要功能就是&…

中断控制器的驱动解析

这里主要分析 linux kernel 中 GIC v3 中断控制器的代码(drivers/irqchip/irq-gic-v3.c)。 设备树 先来看下一个中断控制器的设备树信息&#xff1a; gic: interrupt-controller51a00000 {compatible "arm,gic-v3";reg <0x0 0x51a00000 0 0x10000>, /* GI…

机器学习笔记之优化算法(二)线搜索方法(方向角度)

机器学习笔记之优化算法——线搜索方法[方向角度] 引言回顾&#xff1a;线搜索方法从方向角度观察线搜索方法场景构建假设1&#xff1a;目标函数结果的单调性假设2&#xff1a;屏蔽步长 α k \alpha_k αk​对线搜索方法过程的影响假设3&#xff1a;限定向量 P k \mathcal P_k …

Transformer模型简单介绍

Transformer是一个深度学习模型。主要功能通俗的来说就是翻译。输入&#xff0c;处理&#xff0c;输出。 https://zhuanlan.zhihu.com/p/338817680 大牛写的很完整 目录 总框架Encoder输入部分注意力机制前馈神经网络 Decoder 总框架 Encoders: 编码器Decoders: 解码器 Encoder…

【node.js】01-fs读写文件内容

目录 一、fs.readFile() 读取文件内容 二、fs.writeFile() 向指定的文件中写入内容 案例&#xff1a;整理txt 需求&#xff1a; 代码&#xff1a; 一、fs.readFile() 读取文件内容 代码&#xff1a; //导入fs模块&#xff0c;从来操作文件 const fs require(fs)// 2.调…

Vue+ElementUI操作确认框及提示框的使用

在进行数据增删改查操作中为保证用户的使用体验&#xff0c;通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现&#xff0c;点击下载以及删除按钮&#xff0c;会出现对相关信息的提示&#xff0c;操作结果如下所示。 点击…

第十章:重新审视扩张卷积:一种用于弱监督和半监督语义分割的简单方法

0.摘要 尽管取得了显著的进展&#xff0c;弱监督分割方法仍然不如完全监督方法。我们观察到性能差距主要来自于它们在从图像级别监督中学习生成高质量的密集目标定位图的能力有限。为了缓解这样的差距&#xff0c;我们重新审视了扩张卷积[1]并揭示了它如何以一种新颖的方式被用…

【云原生】Docker容器资源限制(CPU/内存/磁盘)

目录 ​编辑 1.限制容器对内存的使用 2.限制容器对CPU的使用 3.block IO权重 4.实现容器的底层技术 1.cgroup 1.查看容器的ID 2.在文件中查找 2.namespace 1.Mount 2.UTS 3.IPC 4.PID 5.Network 6.User 1.限制容器对内存的使用 ⼀个 docker host 上会运⾏若⼲容…

【Python入门系列】第十八篇:Python自然语言处理和文本挖掘

文章目录 前言一、Python常用的NLP和文本挖掘库二、Python自然语言处理和文本挖掘1、文本预处理和词频统计2、文本分类3、命名实体识别4、情感分析5、词性标注6、文本相似度计算 总结 前言 Python自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&…

PLC学习的步骤与重点:

熟悉基础元器件的原理和使用方法&#xff1a;了解按钮、断路器、继电器、接触器、24V开关电源等基础元器件的原理和使用方法&#xff0c;并能够应用它们来实现简单的逻辑电路&#xff0c;例如电机的正反转和单按钮的启停控制。 掌握PLC的接线方法&#xff1a;了解PLC的输入输出…

【微服务架构设计】微服务不是魔术:处理超时

微服务很重要。它们可以为我们的架构和团队带来一些相当大的胜利&#xff0c;但微服务也有很多成本。随着微服务、无服务器和其他分布式系统架构在行业中变得更加普遍&#xff0c;我们将它们的问题和解决它们的策略内化是至关重要的。在本文中&#xff0c;我们将研究网络边界可…

element-ui form表单的动态rules校验

在vue 项目中&#xff0c;有时候可能会用到element-ui form表单的动态rules校验&#xff0c;比如说选择了哪个选项&#xff0c;然后动态显示或者禁用等等。 我们可以巧妙的运用element-ui form表单里面form-item想的校验规则来处理&#xff08;每一个form-item项都可以单独校验…

uiautomatorViewer无法获取Android8.0手机屏幕截图的解决方案

问题描述&#xff1a; 做APP UI自动化的时候&#xff0c;会碰到用uiautomatorViewer在Android 8.0及以上版本的手机上&#xff0c;无法获取到手机屏幕截图&#xff0c;无法获取元素定位信息的问题&#xff0c;会有以下的报 在低版本的Android手机上&#xff0c;则没有这个问题…

数字化新时代,VR全景拍摄与制作

导语&#xff1a; 随着科技的飞速发展&#xff0c;数字化图片正在引领新的时代潮流。在这个数字化图片的新时代&#xff0c;VR全景拍摄与制作技术正以其独特的特点和无限的优势&#xff0c;成为数字影像领域的一颗璀璨明星。让我们深入了解VR全景拍摄与制作的特点和优势&#…

selenium浏览器驱动下载

Chrome谷歌浏览器 下载地址&#xff1a;http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的chromedriver.exe 版本也不一样&#xff0c;下载时不要搞错了。 如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。 Firefox火狐浏览器 驱…

vue中Cascader 级联选择器实现-修改实现

vue 的cascader研究了好长时间&#xff0c;看了官网给的示例&#xff0c;上网查找了好多信息&#xff0c;才解决修改时回显的问题&#xff0c;现将方法总结如下&#xff1a; vue代码&#xff1a; <el-form-item label"芯片" prop"firmware"> <…

C++-----stack和queue

本期我们来学习stack和queue 目录 stack介绍 栈的使用 栈的模拟实现 queue介绍 队列的使用 队列的模拟实现 deque 优先级队列 模拟实现 仿函数 全部代码 stack介绍 1. stack 是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除…

3D工厂模拟仿真 FACTORY I/O 2.55 Crack

FACTORY I/O 提供超过20个典型的工业应用场景让您如身临其境般地练习控制任务。选择一种场景直接使用或以其作为一个新项目的开端。学生可以利用内嵌的可编辑的典型工业系统模板&#xff0c;也可以自由搭建并编辑工业系统。同时该系统具有全方位3D视觉漫游&#xff0c;可随意放…

在Vue-Element中引入jQuery的方法

一、在终端窗口执行安装命令 npm install jquery --save执行完后&#xff0c;npm会自动在package.json中加上jquery 二、在main.js中引入&#xff08;或者在需要使用的页面中引入即可&#xff09; import $ from jquery三、使用jquery