通过 libsvm 对 n 元语法进行线性单类 SVM 训练的参数估计



我知道,这有很多问题,但没有一个问题针对我的特定问题。

我将简化我的问题,以使其更清晰。 假设我有一个来自英语文档的多个句子,我想使用一个类 svm(在 libsvm 中)对它们进行分类,以便之后能够看到异常(例如德语句子)。

对于训练:我只有一个类的样本(让我们假设其他类事先不存在)。我提取所有 3 克(因此功能空间最多包括16777216个不同的功能)并将它们保存为 libsvm 格式(label=1,以防万一)

现在我想估计我的参数。我尝试使用其他参数来使用该grid.py,但是,运行时对于 rbf 内核来说太大了。所以我尝试使用线性核(因此,可以更改grid.py以仅使用一个 gamma 值,因为它对线性核无关紧要)。

无论如何,最小的cgrid.py 测试将显示为最佳解决方案(-c 对线性内核重要吗?

此外,无论我改变多少-n(nu) 值,每次分数之间都会实现相同的关系(即使支持向量的数量发生变化)。分数是使用 python 实现收集的。(分数之间的关系意味着,例如,起初它们是 -1 和 -2,我更改nu之后它们是例如 -0.5 和 -1,所以如果我对它们进行排序,总是会出现相同的顺序,如本例所示):

# python2
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
from svmutil import *
y,x = svm_read_problem("/tmp/english-3-grams.libsvm") # 5000 sentence samples
ym,xm = svm_read_problem("/tmp/german-3-grams.libsvm") # 50 sentence samples
m = svm_train(y,x,"-s 2 -t 2 -n 0.5");
# do the prediction in one or two steps, here is one step:
p_l, p_a, p_v = svm_predict(y[:100]+ym[:100],x[:100]+xm[:100],m)
# p_v are our scores.
# let's plot a roc curve
roc_ret = roc_curve([1]*100+[-1]*100,p_v)
plt.plot(roc_ret[0],roc_ret[1])
plt.show()

在这里,每次实现完全相同的 roc 曲线(即使-n是变化的)。即使只有 1 个支持向量,也会显示相同的曲线。

因此,我的问题(假设每次训练最多 50000 个样本): - 为什么-n没有改变一堂课的培训过程? - 对于单类 SVM,我需要更改哪些参数? - 线性核是最好的方法吗?(+ 关于运行时)和 RBF 内核参数网格搜索需要很长时间才能找到如此大的数据集 - liblinear没有被使用,因为我想做异常检测=一个类svm

此致敬意 茜草属

性能影响是16777216元素的巨大功能空间的结果。这导致德语句子等元素的向量非常稀疏。

Yang&Petersen的一项研究《文本分类中特征选择的比较研究》表明,积极的特征选择并不一定会降低分类准确性。我在对(医学)德语文本文档进行文本分类时也取得了类似的结果。

如评论中所述,LIBLINEAR很快,因为它是为这种稀疏数据构建的。但是,您最终会得到一个线性分类器及其所有陷阱和好处。

我建议以下策略:

  1. 执行积极的功能选择(例如,使用 InformationGain),剩余功能空间为N

  2. 结合交叉验证逐步增加N,并为数据找到最佳处理N

  3. 使用在 2 中找到的N进行网格搜索。

  4. 使用在 3. 中找到的最佳匹配参数和在 2. 中找到N来训练分类器。

最新更新