Почему производительность моей SVM падает после масштабирования обучающих и тестовых данных?

Я использую 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, но здесь оно, похоже, снижает производительность. Почему это происходит? Как я могу сделать это правильно?


person P.C.    schedule 02.10.2014    source источник


Ответы (2)


Масштабирование по среднему и дисперсии не является хорошей стратегией для частоты терминов. Предположим, у вас есть две гистограммы с тремя терминами (назовем их просто 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 не встречается в X[1], больше не различим.

Конечно, это очень экстремальный пример, но подобные эффекты возникают и в больших наборах. Вместо этого вы должны нормализовать гистограммы:

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

Это сохраняет относительную частоту терминов, что вас и интересует; больше положительных терминов, чем отрицательных, — это то, о чем заботится линейный классификатор настроений, а не о фактической частоте или ее масштабированном варианте.

(Масштабирование рекомендуется для доменов, где масштаб отдельных объектов фактически не имеет значение, как правило, потому, что объекты измеряются в разных единицах.)

person Fred Foo    schedule 04.10.2014

Есть, по крайней мере, несколько вещей, которые следует учитывать:

  • масштабирование данных может снизить точность. Не должно, а может
  • точность - это неправильная мера для несбалансированных задач, вы используете "class_weight='auto'", так что это ваш случай. Вместо этого используйте сбалансированную меру, такую ​​как усредненная точность или MCC.
  • похоже, вы используете гиперпараметр по умолчанию линейного SVM, что означает C=1 и; это может привести к любым, почти случайным результатам, вам нужно подобрать лучшие гиперпараметры с помощью некоторого метода оптимизации (по крайней мере, поиска по сетке), чтобы сравнить две разные обработки данных (например, ваше масштабирование).
person lejlot    schedule 02.10.2014
comment
- Я использую усредненную F-меру для сравнения двух методов. - Я использую LinearSVC с параметрами по умолчанию. Я рассмотрю поиск по сетке, но не могли бы вы сказать мне, почему параметры по умолчанию дают случайные результаты? - person P.C.; 03.10.2014
comment
LinearSVC не использует ядра. - person Fred Foo; 04.10.2014