我在使用LinearSVM对文档进行分类。然而,我的数据集是不平衡的,有些类别下有48,000个文档,而有些类别只有100个。当我训练模型时,即使使用了分层K折交叉验证,我发现有48,000个文档的类别在训练集中占了更大的比例(3300个文档),这显然会导致预测结果出现偏差。我如何确保这种选择不带有偏见?
kf=StratifiedKFold(labels, n_folds=10, shuffle=True)for train_index, test_index in kf: X_train, X_test = docs[train_index],docs[test_index] Y_train, Y_test = labels[train_index],labels[test_index]
然后,我将这些(X_train, Y_train)写入文件,计算特征矩阵,并按照以下方式传递给分类器:
model1 = LinearSVC()model1 = model1.fit(matrix, label_tmp)pred = model1.predict(matrix_test)print("Accuracy is:")print(metrics.accuracy_score(label_test, pred))print(metrics.classification_report(label_test, pred))
回答:
StratifiedKFold
方法默认会考虑所有类别中标签的比例,这意味着每个折叠中每个标签的比例将是完全相同(或接近相同)的。你是否要对此进行调整取决于你自己——你可以让分类器学习对样本更多的标签产生某种偏见(就像你现在所做的),或者你可以做以下两件事之一:
-
构建一个独立的训练/测试集,其中训练集中的每个标签具有相同数量的样本(因此在你的情况下,训练集中的每个类别标签可能只有50个示例,这并不理想)。然后你可以在训练集上进行训练,并在剩余部分上进行测试。如果你多次这样做并使用不同的样本,你实际上是在进行k折交叉验证,只是以不同的方式选择样本大小。
-
你可以更改你的损失函数(即你初始化
LinearSVC()
的方式,以考虑类别不平衡。例如:model = LinearSVC(class_weight='balanced')
。这将使模型学习一个考虑类别不平衡的损失函数。