通过 libsvm 对 n-gram 进行线性 One Class SVM 训练的参数估计

Parameter estimation for linear One Class SVM training via libsvm for n-grams

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

我将简化我的问题以使其更清楚。 假设我有一个英文文档中的多个句子,我想 class 使用一个 class 支持向量机(在 libsvm 中)对它们进行 class 验证,以便之后能够看到异常情况(例如德语句子)。

对于训练:我只有一个 class 的样本(假设其他 class 事先不存在)。我提取所有 3-grams(因此特征 space 最多包含 16777216 个不同的特征)并将它们保存为 libsvm 格式(标签=1,以防万一)

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

无论如何,最小的 c grid.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 没有为一个 class 训练过程做任何改变? - 我需要为 class 支持向量机更改哪些参数? - 线性内核是最好的方法吗? (+ 关于运行时)和 rbf 内核参数网格搜索需要很长时间才能处理如此大的数据集 - 没有使用 liblinear,因为我想进行异常检测 = one class svm

此致, 多重

性能影响是您的巨大特征 space 的 16777216 个元素的结果。这会导致德语句子等元素的向量非常稀疏。

Yang & Petersen 的一项研究 A Comparative Study on Feature Selection in Text Categorization 表明,激进 feature-selection 不一定会降低分类准确性。我在对(医学)德语文本文档进行文本分类时取得了类似的结果。

如评论中所述,LIBLINEAR 很快,因为它是为此类稀疏数据构建的。然而,您最终得到的是一个线性分类器,它有所有的缺陷和好处。

我建议采用以下策略:

  1. 使用 N

  2. 的剩余 feature-space 执行积极的特征选择(例如使用 InformationGain)
  3. 结合 cross-validation 逐步增加 N 并为您的数据找到 最佳 加工 N

  4. 使用 2.

  5. 中的 N 寻找 grid-search
  6. 使用 3. 中找到的最佳匹配参数和 2.

  7. 中找到的 N 训练您的分类器