我正在使用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的性能,但在这里,它似乎会降低性能。为什么会这样?我怎样才能做对吗?
答案 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至少需要考虑的事情很少:
C=1
和;它可能带来任意,几乎随机的结果,你必须通过一些优化技术(至少是网格搜索)来拟合最好的超参数,以便比较两种不同的数据处理(例如你的缩放)