SVM中的样本不均衡问题

本文探讨了SVM在处理样本不均衡问题时,如何使用class_weight参数调整模型以捕获少数类。通过对比设置与未设置class_weight的模型,展示了该参数对决策边界的影响。此外,文章还介绍了多种评估模型性能的指标,如精确度、召回率、F1 measure、ROC曲线等,强调在样本不均衡情况下,准确率不再适用,而需关注对少数类的捕捉能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.重要参数class_weight

对于分类问题,永远都逃不过的一个痛点就是样本不均衡问题。样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有着捕捉出某种特定的分类的需求的状况。比如,我们现在要对潜在犯罪者和普通人进行分类,潜在犯罪者占总人口的比例是相当低的,也许只有2%左右,98%的人都是普通人,而我们的目标是要捕获出潜在犯罪者。这样的标签分布会带来许多问题。

首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更加依赖于从多数类中学到的信息来进行判断。如果我们希望捕获少数类,模型就会失败。其次,模型评估指标会失去意义。这种分类状况下,即便模型什么也不做,全把所有人都当成不会犯罪的人,准确率也能非常高,这使得模型评估指标 a c c u r a c y accuracy accuracy变得毫无意义,根本无法达到我们的“要识别出会犯罪的人”的建模目的。

所以现在,我们首先要让算法意识到数据的标签是不均衡的,通过施加一些惩罚或者改变样本本身,来让模型向着捕获少数类的方向建模。然后,我们要改进我们的模型评估指标,使用更加针对于少数类的指标来优化模型

要解决第一个问题,可以采用上采样或下采样的方法。但这些采样方法会增加样本的总数,对于支持向量机这个样本总是对计算速度影响巨大的算法来说,我们不想轻易地增加样本数量。况且,支持向量机中地决策仅仅受到决策边界的影响,而决策边界又仅仅受到参数C和支持向量的影响,单纯地增加样本数量不仅会增加计算时间,可能还会增加无数对决策边界无影响的样本点。因此在支持向量机中,我们要大力依赖调节样本均衡的参数:SVC类中的class_weight接口以及fit中可以设定的sample_weight参数。

在SVM中,分类判断是基于决策边界的,而最终决定究竟使用怎样的支持向量和决策边界的参数是参数C,所以所有的样本均衡都是通过参数C来调整的。

参数 描述
SVC的参数:
c l a s s _ w e i g h t class\_weight 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的参数:
s a m p l e _ w e i g h t sample\_weight sample_weight
数组,结构为 (n_samples, ),必须对应输入fit中的特征矩阵的每个样本每个样本在fit时的权重,让权重 * 每个样本对应的C值来迫使分类器强调设定的权重更大的样本。通常,较大的权重加在少数类的样本上,以迫使模型向着少数类的方向建模通常来说,这两个参数我们只选取一个来设置。如果我们同时设置了两个参数,则C会同时受到两个参数的影响,即 class_weight中设定的权重 * sample_weight中设定的权重 * C。

接下来就来看看如何使用这个参数。
首先,我们来自建一组样本不平衡的数据集。我们在这组数据集上建两个SVC模型,一个设置有class_weight参数,一个不设置class_weight参数。我们对两个模型分别进行评估并画出他们的决策边界,以此来观察class_weight带来的效果。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import make_blobs
from sklearn.svm import SVC

class_1 = 500
class_2 = 50
centers = [[0.0,0.0],[2.0,2.0]]
cluster_std = [1.5,0.5]
X,y = make_blobs(n_samples = [class_1,class_2]
                ,centers=centers
                ,cluster_std = cluster_std
                ,random_state=0
                ,shuffle=False
                )
plt.scatter(X[:,0],X[:,1],c=y,cmap='rainbow',s=10)

在这里插入图片描述
定义决策边界的绘制函数:

#决策边界绘制函数
def plot_svc_decision_function(model,ax=None):
    if ax == None:
        ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    
    axisx = np.linspace(xlim[0],xlim[1],30)
    axisy = np.linspace(y
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值