帮助——LibSVM 100% 的准确度?
Posted
技术标签:
【中文标题】帮助——LibSVM 100% 的准确度?【英文标题】:Help--100% accuracy with LibSVM? 【发布时间】:2011-11-01 13:46:28 【问题描述】:名义上是一个很好的问题,但我很确定这是因为发生了一些有趣的事情......
作为上下文,我正在研究面部表情/识别领域的一个问题,因此获得 100% 的准确率似乎令人难以置信(并不是说它在大多数应用程序中都是合理的......)。我猜要么数据集中存在一些一致的偏差,这使得 SVM 很容易得出答案,=或者=,更有可能的是,我在 SVM 方面做错了。
我正在寻找帮助了解正在发生的事情的建议——是我吗(=我对 LibSVM 的使用)?还是数据?
详情:
大约 2500 个标记数据向量/实例(个人的转换视频帧 - 总共 运行 subset.py 将数据分成测试(500 个实例)和训练(剩余)。 运行“svm-train -t 0”。 (注意:显然不需要'-w1 1 -w-1 4'...) 在测试文件上运行 svm-predict。准确度 = 100%!尝试过的事情:
通过一些无意的命令行参数错误检查了大约 10 次我没有对相同的数据文件进行训练和测试 多次重新运行 subset.py(即使使用 -s 1)并且只训练/测试多个不同的数据集(以防我随机选择最神奇的训练/测试 pa 运行一个简单的类似差异的检查,以确认测试文件不是训练数据的子集 数据上的 svm-scale 对准确度没有影响(准确度 = 100%)。 (虽然支持向量的数量确实从 nSV=127, bSV=64 下降到 nBSV=72, bSV=0。) ((weird)) 使用默认的 RBF 内核(副线性 - 即删除 '-t 0')会导致准确性变为垃圾(?!) (健全性检查)使用针对未缩放数据集在缩放数据集上训练的模型运行 svm-predict 会导致准确率 = 80%(即,它总是猜测主导类)。这严格来说是一个健全性检查,以确保 svm-predict 以某种方式名义上在我的机器上正常运行。初步结论?
数据中的某些东西很奇怪——不知何故,在数据集中,SVM 正在接受一种微妙的、由实验者驱动的效果。
(然而,这并不能解释为什么 RBF 内核会给出垃圾结果。)
非常感谢以下方面的任何建议
【问题讨论】:
嗯,数据和模型分析一臂之力。可行,但真的,真的很慢。这可能相当具有挑战性。你有机会发布数据吗?几乎可以肯定是数据,但让其他人重现它可能会有所帮助。此外,如果您精通 R,那可能会更容易提供建议。 最有可能 -) 是您已将测试数据包含在训练集中。我知道你已经检查过了,但请检查更多。 @carlosdc 有一个很好的观点:这些是独立样本,还是您选择随机、训练/测试分割,图像在时间上可能非常接近? @severian:如果您将数据集处理到最低限度,它应该会小得多 - 2500 * 900 * 15(假设每个特征大约 15 个字符)约为 33mb,未压缩。我的预感是它确实存在于数据中——也许正样本和负样本的预处理有所不同,导致分类器拾取的特征中出现伪影——其他数据集也发生了。至于“RBF 内核返回垃圾” - 这可能是过度拟合。改变 C 和 sigma 应该会有所帮助(但如果线性内核完美分离,为什么还要使用 RBF ;)) @Sid:见上面的线程——这是一个问题(我的错),没有将数据集很好地划分为测试和训练。例如,考虑一种将所有帧 50-50 划分为测试和训练的幼稚类型。框架 n+1(以及在较小程度上,n+2、n+3 等)看起来很像框架 n,并且通常(在我的情况下)标记为与框架 n 相同。分类器在第 n 帧上接受训练,然后在“测试”集中看到 n+1,然后神奇地让它“正确”……一遍又一遍。需要对测试和训练进行更离散的分区(例如,多秒/分钟/任何子集)。 【参考方案1】:另外两个想法:
确保您没有在相同的数据上进行训练和测试。这听起来有点愚蠢,但在计算机视觉应用程序中你应该注意:确保你没有重复数据(比如同一视频的两帧落在不同的折叠上),你不是在同一个人上训练和测试等等。它比听起来更微妙。
确保搜索 RBF 内核的 gamma 和 C 参数。有很好的理论(渐近)结果证明线性分类器只是一个退化的 RBF 分类器。所以你应该寻找一个好的 (C, gamma) 对。
【讨论】:
对于 RBF,感谢您说明(应该是什么!)显而易见的——我忘了搜索好的参数。一旦 100% 的准确率开始恢复,就会变得过于急切(因此,我很可能知道我正在做的事情或数据的设置方式有问题)。【参考方案2】:尽管魔鬼在细节中,但您可以尝试以下三个简单的测试:
-
Quickie(约 2 分钟):通过决策树算法运行数据。这可以通过
clas-s-regtree
在 Matlab 中使用,或者您可以加载到 R 中并使用rpart
。这可以告诉您是否有一个或几个特征恰好提供了完美的分离。
不那么快(约 10-60 分钟,具体取决于您的基础架构):迭代地拆分特征(即从 900 到 2 组 450)、训练和测试。如果其中一个子集为您提供了完美的分类,请再次拆分它。只需不到 10 次这样的拆分就可以找出问题变量的位置。如果它碰巧在剩余许多变量的情况下“中断”(甚至在第一次拆分中),请选择不同的随机特征子集,一次削减更少的变量等。它不可能需要全部 900 个来拆分数据.
更深入的分析(几分钟到几小时):尝试标签排列。如果您可以置换所有这些并仍然获得完美的分离,那么您的训练/测试设置就会出现问题。如果您选择越来越大的子集进行置换(或者,如果朝另一个方向前进,则保持静态),您可以看到您开始失去可分性的地方。或者,考虑减小训练集的大小,如果即使训练集非常小也能获得可分离性,那就有点奇怪了。
方法#1 速度很快,应该很有洞察力。还有一些我可以推荐的其他方法,但 #1 和 #2 很简单,如果它们不提供任何见解,那就太奇怪了。
【讨论】:
我不确定你所说的置换标签是什么意思,但如果你的意思是置换向量变量的顺序,这应该永远不会影响 SVM 结果! @Ite:你能澄清一下“permute”声明(#3)吗?您的意思是在每个数据实例/点中随机排列一些变量吗? (所以不同的实例的排列方式略有不同?) Re:#1 & #2,很快就会开始讨论它们......真的很感激这些建议。 标签是响应变量。换句话说,您正在引入噪音。在二元分类中,这本身不会引入错误分类,因为它会从响应分布中重新采样。关键是在某些时候会出现故障。您可以故意错误标记,但从响应分布重新采样或排列标签是数据和模型探索的有用方法。 @ldog:你的说法是正确的,这不是建议。事实上,大多数建模方法都是如此,而不仅仅是 SVM,因为大多数建模方法都是排列不变的,除了那些有意构建在序列上的方法,比如时间序列模型。以上是关于帮助——LibSVM 100% 的准确度?的主要内容,如果未能解决你的问题,请参考以下文章