考虑一个数据集A
,它包含用于二元分类问题的训练样本。由于数据集高度不平衡,我使用了SVM并应用了加权方法(在MATLAB中)。我将权重设置为与每个类别中数据频率成反比。这是在训练过程中使用以下命令完成的:
fitcsvm(trainA, trainTarg , ... 'KernelFunction', 'RBF', 'KernelScale', 'auto', ... 'BoxConstraint', C,'Weight',weightTrain );
我使用了10折交叉验证进行训练,并学习了超参数。因此,在CV内部,数据集A
被分为训练集(trainA
)和验证集(valA
)。训练结束后,在CV循环之外,我在A
上得到了混淆矩阵:
80025 10 140
其中第一行为多数类,第二行为少数类。只有1个误报(FP),所有少数类样本都被正确分类,即真正例(TP)= 140。
问题:然后,我在新的未见过的测试数据集B
上运行训练好的模型,该数据集在训练期间从未见过。这是B
上的测试混淆矩阵:
50075 0100 0
可以看出,少数类根本没有被分类,因此权重的目的失败了。虽然没有误报,但SVM未能捕捉到少数类样本。我在B
上没有应用任何权重或平衡方法,如采样(SMOTE、RUSBoost等)。哪里出了问题,如何克服这个问题?
回答:
可以设置类误分类权重,而不是样本权重!
您可以根据以下示例设置类权重。
将类A(n条记录;主导类)误分类为类B(m条记录;少数类)的权重可以设置为n/m。将类B误分类为类A的权重可以根据您希望施加在学习上的严重性设置为1或m/n
c=[0 2.2;1 0];mod=fitcsvm(X,Y,'Cost',c)
根据文档:
对于两类学习,如果您指定了成本矩阵,则软件会通过纳入成本矩阵中描述的惩罚来更新先验概率。因此,成本矩阵会重置为默认值。有关BoxConstraint、Cost、Prior、Standardize和Weights的关系和算法行为的更多详细信息,请参见Algorithms。