为什么在扩展训练和测试数据后我的SVM性能下降?

时间:2014-10-02 23:45:31

标签: python machine-learning scikit-learn svm text-classification

我正在使用scikit-learn来执行文本的情感分析。我现在的功能只是字频数。

当我执行以下操作时,平均F值约为59%:

from sklearn import svm
clf = svm.LinearSVC(class_weight='auto');
clf.fit(Xfeatures, YLabels);
......
predictedLabels = clf.predict(XTestFeatures);

但是当我使用StandardScalar()来扩展我的特征向量时,平均F测量值下降到49%:

from sklearn import svm
clf = svm.LinearSVC(class_weight='auto');
Xfeatures = scaler.fit_transform(Xfeatures);
clf.fit(Xfeatures, YLabels);
......
XTestFeatures = scaler.transform(XTestFeatures);
predictedLabels = clf.predict(XTestFeatures);

缩放应该可以提高我的SVM的性能,但在这里,它似乎会降低性能。为什么会这样?我怎样才能做对吗?

2 个答案:

答案 0 :(得分:4)

通过均值和方差进行缩放对于术语频率来说不是一个好策略。假设您有两个术语直方图和三个术语(让我们称之为0, 1, 2):

>>> X = array([[100, 10, 50], [1, 0, 2]], dtype=np.float64)

你缩放它们;那你得到了

>>> from sklearn.preprocessing import scale
>>> scale(X)
array([[ 1.,  1.,  1.],
       [-1., -1., -1.]])

缩放只是让我无法确定术语2在X[1]中比术语0更频繁地发生。事实上,第1项 not X[1]中发生的事实已不再可以区分。

当然,这是一个非常极端的例子,但在较大的集合中会出现类似的效果。你应该做的是标准化直方图:

>>> from sklearn.preprocessing import normalize
>>> normalize(X)
array([[ 0.89087081,  0.08908708,  0.4454354 ],
       [ 0.4472136 ,  0.        ,  0.89442719]])

这保留了条款的相对频率,这是您感兴趣的; 更多正面条款而不是负面条款是线性情绪分类器所关心的,而不是实际频率或它的缩放变体。

(对于各个功能的规模实际上重要的域,建议使用缩放,通常是因为功能以不同的单位进行测量。)

答案 1 :(得分:2)

Tnere至少需要考虑的事情很少:

  • 缩放数据可以降低准确性。它不应该,但可以
  • 对于不平衡的问题,
  • 准确性是错误的衡量标准,您使用" class_weight =' auto'",所以这是您的情况。使用一些平衡测量,而不是平均准确度或MCC。
  • 您似乎使用线性SVM的默认超参数,这意味着C=1和;它可能带来任意,几乎随机的结果,你必须通过一些优化技术(至少是网格搜索)来拟合最好的超参数,以便比较两种不同的数据处理(例如你的缩放)