样本不均衡问题
对于分类问题,永远都逃不过的一个痛点就是样本不均衡问题。样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有着捕捉出某种特定的分类的需求的状况。比如,我们现在要对潜在犯罪者和普通人进行分类,潜在犯罪者占总人口的比例是相当低的,也许只有2%左右,98%的人都是普通人,而我们的目标是要捕获出潜在犯罪者。这样的标签分布会带来许多问题。
首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更加依赖于从多数类中学到的信息来进行判断。如果我们希望捕获少数类,模型就会失败。其次,模型评估指标会失去意义。这种分类状况下,即便模型什么也不做,全把所有人都当成不会犯罪的人,准确率也能非常高,这使得模型评估指标accuracy变得毫无意义,根本无法达到我们的“要识别出会犯罪的人”的建模目的。
所以现在,我们首先要让算法意识到数据的标签是不均衡的,通过施加一些惩罚或者改变样本本身,来让模型向着捕获少数类的方向建模。然后,我们要改进我们的模型评估指标,使用更加针对于少数类的指标来优化模型。
要解决第一个问题,可以采用上采样下采样的方法。但这些采样方法会增加样本的总数,对于支持向量机这个样本总是对计算速度影响巨大的算法来说,我们完全不想轻易地增加样本数量。况且,支持向量机中的决策仅仅受决策边界的影响,而决策边界又仅仅受到参数C和支持向量的影响,单纯地增加样本数量不仅会增加计算时间,可能还会增加无数对决策边界无影响的样本点。因此在支持向量机中,我们要大力依赖我们调节样本均衡的参数:SVC类中的class_weight和接口fit中可以设定的sample_weight。
在逻辑回归中,参数class_weight默认None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签的比例是1:1。所以当样本不均衡的时候,我们可以使用形如{“标签的值1”:权重1,“标签的值2”:权重2}的字典来输入真实的样本标签比例,来让算法意识到样本是不平衡的。或者使
用”balanced“模式,直接使用n_samples/(n_classes * np.bincount(y))作为权重,可以比较好地修正我们的样本不均衡情况。
但在SVM中,我们的分类判断是基于决策边界的,而最终决定究竟使用怎样的支持向量和决策边界的参数是参数C,所以所有的样本均衡都是通过参数C来调整的。
SVC的参数:class_weight
可输入字典或者"balanced”,可不填,默认None
对SVC,将类i的参数C设置为class_weight [i] * C。如果没有给出具体的class_weight,则所有类都被假设为占有相同的权重1,模型会根据数据原本的状况去训练。如果希望改善样本不均衡状况,请输入形如{“标签的值1”:权重1,“标签的值2”:权重2}的字典,则参数C将会自动被设为:
标签的值1的C:权重1 * C,标签的值2的C:权重2*C
或者,可以使用“balanced”模式,这个模式使用y的值自动调整与输入数据中的类频率成反比的权重为n_samples/(n_classes * np.bincount(y))
SVC的接口fit的参数:sample_weight
数组,结构为 (n_samples, ),必须对应输入fit中的特征矩阵的每个样本。
每个样本在fit时的权重,让权重 * 每个样本对应的C值来迫使分类器强调设定的权重更大的样本。通常,较大的权重加