关于sklearn下class_weight参数

一直没有很在意过sklearn的class_weight的这个参数的具体作用细节,只大致了解是是用于处理样本不均衡。后来在简书上阅读svm松弛变量的一些推导的时候,看到样本不均衡的带来的问题时候,想更深层次的看一下class_weight的具体作用方式,

svm松弛变量的简书链接:https://www.jianshu.com/p/8a499171baa9

该文中的样本不均衡的描述:

“样本偏斜是指数据集中正负类样本数量不均,比如正类样本有10000个,负类样本只有100个,这就可能使得超平面被“推向”负类(因为负类数量少,分布得不够广),影响结果的准确性。” 

随后翻开sklearn LR的源码:

我们以分类作为说明重点

在输入参数class_weight=‘balanced’的时候:
 

# compute the class weights for the entire dataset y
    if class_weight == "balanced":
        class_weight = compute_class_weight(class_weight,
                                            np.arange(len(self.classes_)),
                                                y)
        class_weight = dict(enumerate(class_weight))

进一步阅读 compute_class_weight这个函数:

elif class_weight == 'balanced':
    # Find the weight of each class as present in y.
    le = LabelEncoder()
    y_ind = le.fit_transform(y)
    if not all(np.in1d(classes, le.classes_)):
            raise ValueError("classes should have valid labels that are in y")
 
    recip_freq = len(y) / (len(le.classes_) *
                           np.bincount(y_ind).astype(np.float64))
    weight = recip_freq[le.transform(classes)]

compute_class_weight这个函数的作用是对于输入的样本,平衡类别之间的权重,下面写段测试代码测试这个函数:

# coding:utf-8
 
from sklearn.utils.class_weight import compute_class_weight
 
class_weight = 'balanced'
label = [0] * 9 + [1]*1 + [2, 2]
print(label) # [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2]
classes=[0, 1, 2]
weight = compute_class_weight(class_weight, classes, label)
print(weight) #[ 0.44444444 4.         2.        ]
print(.44444444 * 9) # 3.99999996
print(4 * 1) # 4
print(2 * 2) # 4

如上图所示,可以看到这个函数把样本的平衡后的权重乘积为4,每个类别均如此。banlanced的计算公式为:n_samples/n_classes/np.bincount(y)。n_samples表示样本总数,n_classes表示总类别数量,np.bincount(y)输出所有类别的每个类别的样本数量,y是所有样本的标签。一个标签代表一个类别。采用balanced模型时,每种类别的权重为n_samples/n_classes,即12/3=4;然后根据每种类别中的样本数量对每个样本进行平均分配权重,即4/9=0.444, 4/1=4, 4/2=2。0类别有9个样本,1类别有1个样本,2类别有2个样本。

关于class_weight与sample_weight在损失函数上的具体计算方式:

sample_weight *= class_weight_[le.fit_transform(y_bin)] # sample_weight 与 class_weight相乘
 
# Logistic loss is the negative of the log of the logistic function.
out = -np.sum(sample_weight * log_logistic(yz)) + .5 * alpha * np.dot(w, w)

上述可以看出对于每个样本,计算的损失函数乘上对应的sample_weight来计算最终的损失。这样计算而来的损失函数不会因为样本不平衡而被“推向”样本量偏少的类别中。

class_weight以及sample_weight并没有进行不平衡数据的处理,比如,上下采样。详细参见SMOTE EasyEnsemble等。
————————————————
原文链接:https://blog.csdn.net/go_og/article/details/81281387

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

keras  中fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0,

validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0,

steps_per_epoch=None, validation_steps=None)

官方文档中:

class_weight:字典,将不同的类别映射为不同的权值,该参数用来在训练过程中调整损失函数(只能用于训练)。该参数在处理非平衡的训练数据(某些类的训练样本数很少)时,可以使得损失函数对样本数不足的数据更加关注。

sample_weight:权值的numpy array,用于在训练时调整损失函数(仅用于训练)。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权,或者在面对时序数据时,传递一个的形式为(samples,sequence_length)的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample_weight_mode='temporal'。

class_weight---主要针对的上数据不均衡问题,比如:异常检测的二项分类问题,异常数据仅占1%,正常数据占99%; 此时就要设置不同类对loss的影响。

sample_weigh---主要解决的是样本质量不同的问题,比如前1000个样本的可信度,那么它的权重就要高,后1000个样本可能有错、不可信,那么权重就要调低。
————————————————
原文链接:https://blog.csdn.net/weixin_40755306/article/details/82290033

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


链接:https://www.zhihu.com/question/265420166/answer/293896934
 

  • 14
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值