二分类决策树中的样本不均衡问题

本文探讨了二分类问题中的样本不均衡问题,指出模型倾向于多数类而牺牲少数类。通过调整决策树的class_weight参数,可以引导模型关注少数类。示例比较了设置与未设置class_weight的模型,显示后者能更有效地识别少数类,但可能降低整体准确率。在某些场景下,捕捉少数类的重要性远大于整体准确率,因此适合使用调整后的模型。
摘要由CSDN通过智能技术生成

对于分类问题,永远都逃不过的一个痛点就是样本不均衡问题。
样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有着捕捉出某种特定的分类的需求的状况。
比如,我们现在要对潜在犯罪者和普通人进行分类,潜在犯罪者占总人口的比例是相当低的,也许只有2%左右,98%的人都是普通人,而我们的目标是要捕获出潜在犯罪者。这样的标签分布会带来许多问题。
首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更加依赖于从多数类中学到的信息来进行判断。如果我们希望捕获少数类,模型就会失败。
其次,模型评估指标会失去意义。这种分类状况下,即便模型什么也不做,全把所有人都当成不会犯罪的人,准确率也能非常高,这使得模型评估指标accuracy变得毫无意义,根本无法达到我们的“要识别出会犯罪的人”的建模目的。
所以,首先要让算法意识到数据的标签是不均衡的,通过施加一些惩罚或者改变样本本身,来让模型向着捕获少数类的方向建模。我们可以使用上采样和下采样来达成这个目的,所用的方法叫做SMOTE,这种方法通过将少数类的特征重新组合,创造出更多的少数类样本。但这些采样方法会增加样本的总数,对于决策树这个样本总数对计算速度影响巨大的算法来说,完全不想轻易地增加样本数量,所以要寻求另一条路:改进模型评估指标,使用更加针对于少数类的指标来优化模型。
在决策树中,存在着调节样本均衡的参数:class_weight和接口fit中可以设定的sample_weight。
在决策树中,参数class_weight默认None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签的比例是1:1。所以当样本不均衡的时候,可以使用形如{“标签的值1”:权重1,“标签的值2”:权重2}的字典来输入真实的样本标签比例,让算法意识到样本是不平衡的。或者使用”balanced“模式,直接使n_samples/(n_classes * np.bincount(y))作为权重,可以比较好地修正样本不均衡情况。
有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_ weight_fraction_leaf这个基于权重的剪枝参数来使用。另请注意,基于权重的剪枝参数(例如min_weight_ fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,确保叶节点至少包含样本权重的总和的一小部分。
示例如下:
首先,自建一组样本不平衡的数据集。在这组数据集上建两个模型,一个设置有class_weight参数,一个不设置class_weight参数。对两个模型分别进行评估并画出他们的决策边界,以此来观察class_weight带来的效果。

#样本不均衡问题
#导⼊入需要的库和模块
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
#创建样本不不均衡的数据集
class_1 = 1000 #类别1有1000个样本
class_2 = 100 #类别2只有100个
centers = [[0,0], [2.0, 2.0]] #设定两个类别的中心
clusters_std = [2.5, 0.5] #设定两个类别的方差,通常来说,样本量比较大的类别会更加松散
X, y = make_blobs(n_samples=[class_1, class_2],
                  centers=centers,
                  cluster_std=clusters_std,
                  random_state=420,shuffle=False)

#看看数据集长什么样
plt.scatter(X[:, 0], X[:, 1], c=y, cmap="rainbow",s=10);
#其中红⾊色点是少数类,紫⾊色点是多数类

运行结果
在这里插入图片描述

# 划分数据集
Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.2,random_state=420)
#在数据集上分别建模
#不设定class_weight
clf = DecisionTreeClassifier()
clf.fit(Xtrain, Ytrain)
clf.predict(Xtest)

运行结果

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值