我正在尝试使用看到横幅的人的点击和转换数据来教授我的 SVM 算法。主要问题是点击量约占所有数据的 0.2%,因此其中存在很大的不均衡性。当我在测试阶段使用简单的 SVM 时,它总是只预测“查看”类,而不是“点击”或“转换”。平均而言,它给出了 99.8% 的正确答案(因为不成比例),但如果您检查“点击”或“转化”答案,它给出的正确预测为 0%。您如何调整 SVM 算法(或选择另一种算法)以考虑不成比例?
问问题
3508 次
2 回答
25
这里最基本的方法是使用所谓的“类加权方案”——在经典的 SVM 公式中,有一个C
用于控制错误分类计数的参数。可分别更改为1 类C1
和C2
2 类使用的参数。C1
对于给定的和C2
对于给定的最常见的选择C
是
C1 = C / n1
C2 = C / n2
其中n1
和n2
分别是第 1 类和第 2 类的大小。因此,您“惩罚” SVM 对频率较低的类别进行错误分类要比对最常见类别的错误分类更难。
许多现有的库(如libSVM)通过 class_weight 参数支持这种机制。
使用 python 和 sklearn 的示例
print __doc__
import numpy as np
import pylab as pl
from sklearn import svm
# we create 40 separable points
rng = np.random.RandomState(0)
n_samples_1 = 1000
n_samples_2 = 100
X = np.r_[1.5 * rng.randn(n_samples_1, 2),
0.5 * rng.randn(n_samples_2, 2) + [2, 2]]
y = [0] * (n_samples_1) + [1] * (n_samples_2)
# fit the model and get the separating hyperplane
clf = svm.SVC(kernel='linear', C=1.0)
clf.fit(X, y)
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - clf.intercept_[0] / w[1]
# get the separating hyperplane using weighted classes
wclf = svm.SVC(kernel='linear', class_weight={1: 10})
wclf.fit(X, y)
ww = wclf.coef_[0]
wa = -ww[0] / ww[1]
wyy = wa * xx - wclf.intercept_[0] / ww[1]
# plot separating hyperplanes and samples
h0 = pl.plot(xx, yy, 'k-', label='no weights')
h1 = pl.plot(xx, wyy, 'k--', label='with weights')
pl.scatter(X[:, 0], X[:, 1], c=y, cmap=pl.cm.Paired)
pl.legend()
pl.axis('tight')
pl.show()
特别是,在sklearn中,您可以通过设置简单地打开自动加权class_weight='auto'
。
于 2013-08-06T18:47:47.820 回答
1
本文介绍了多种技术。一种简单(但对 SVM 来说非常糟糕的方法)就是复制少数类,直到达到平衡:
http://www.ele.uri.edu/faculty/he/PDFfiles/ImbalancedLearning.pdf
于 2015-06-12T21:31:13.843 回答