支持向量机(SVM)的一些实现细节

时间:2010-08-10 06:41:22

标签: machine-learning libsvm svm

在特定的应用程序中,我需要机器学习(我知道我在本科课程中学到的东西)。我使用支持向量机并解决了问题。工作正常。

现在我需要改进系统。这里的问题是

  1. 我每周都会收到额外的培训示例。现在,系统开始使用更新的示例(旧示例+新示例)进行新的培训。我想让它增量学习。使用以前的知识(而不是之前的例子)和新的例子来获得新的模型(知识)

  2. 我的训练样本有3个班级。因此,每个训练样例都适合这三个类中的一个。我想要“未知”类的功能。任何不适合这3个类的东西都必须标记为“未知”。但我不能将“未知”视为一个新类,并为此提供示例。

  3. 假设实现了“未知”类。当类是“未知”时,应用程序的用户输入他认为该类可能的内容。现在,我需要将用户输入合并到学习中。我也不知道怎么做。如果用户输入一个新类(即一个尚未在训练集中的类),它会有什么不同吗?

  4. 我是否需要选择新算法或支持向量机可以执行此操作?

    PS:我正在使用libsvm实现SVM。

4 个答案:

答案 0 :(得分:8)

我刚使用与您的问题相同的组织编写了我的答案(1.,2.,3)。

  1. SVM可以这样做 - 即增量学习吗?多层感知器当然可以 - 因为后续的训练实例不会影响基本的网络架构,它们只会调整权重矩阵的值。但SVM?在我看来(理论上)一个额外的训练实例可以改变支持向量的选择。但是,我不知道。

  2. 我认为您可以通过将LIBSVM配置为一对多来轻松解决此问题 - 即,作为一类分类器。 SVM 一类分类器;将SVM应用于多类意味着它已被编码为执行多个逐步的一对多分类,但同样,该算法一次被训练(和测试)一个类。如果你这样做,那么在对测试集逐步执行之后剩下的是“未知” - 换句话说,在执行多个顺序一类分类之后没有对任何数据进行分类,根据定义是'未知'上课。

  3. 为什么不让用户猜测一个特征(即只是另一个因变量)?唯一的另一个选择是使它成为类标签本身,你不希望这样。例如,您可以在数据矩阵“用户类猜测”中添加一个列,然后只使用某些值填充它,这些值最有可能对那些不在“未知”类别中的数据点产生影响,因此对用户而言不会提供猜测 - 此值可能为“0”或“1”,但实际上这取决于您的数据如何缩放和标准化。

答案 1 :(得分:5)

您的第一个项目可能是最困难的,因为现有基本上没有好的增量SVM实现。

几个月前,我还研究了在线增量 SVM算法。不幸的是,当前的实现状态非常稀少。我发现的只有一个Matlab exampleOnlineSVR(一个只实现回归支持的论文项目)和SVMHeavy(只有二进制类支持)。

我个人没有使用过任何一个。他们似乎都处于“研究玩具”阶段。我甚至无法让SVMHeavy进行编译。

目前,您可以通过定期批量培训来结合更新。我也使用LibSVM,而且速度非常快,所以在实现适当的增量版本之前,它应该是一个很好的替代品。

我也不认为SVM可以默认模拟“未知”样本的概念。它们通常作为一系列布尔分类器工作,因此样本最终会被归类为某种东西,即使该样本与之前看到的任何内容完全不同。可能的解决方法是对要素范围进行建模,并随机生成这些范围之外的样本,然后将这些样本添加到训练集中。

例如,如果您有一个名为“color”的属性,其最小值为4,最大值为123,那么您可以将这些属性添加到训练集

[({'color':3},'unknown'),({'color':125},'unknown')]

让您的SVM了解“未知”颜色的含义。

答案 2 :(得分:3)

  1. 有逐步训练SVM的算法,但我认为libSVM不会实现这一点。我想你应该考虑一下你是否真的需要这个功能。除非训练过程太慢,否则我认为您当前的方法没有问题。如果是,你可以批量重新训练(即每100个新例子之后)吗?
  2. 您可以使libSVM生成类成员资格的概率。我认为这可以用于多类分类,但我不完全确定。您需要确定分类不够确定的阈值,然后输出“未知”。我想在最有可能和最可能的第二类之间设置一个阈值就可以达到这个目的。
  3. 我认为libSVM可以扩展到任意数量的新类。但是,通过添加新类,您的模型的准确性可能会受到影响。

答案 3 :(得分:2)

即使这个问题可能已经过时,我也不得不提出一些额外的想法。

  1. 由于您的第一个问题已被其他人回答(没有生产就绪的SVM实现增量学习,即使有可能),我将跳过它。 ;)

  2. 将“未知”添加为类并不是一个好主意。根据它的用途,原因是不同的。

    • 如果您使用“未知”类作为“此实例尚未归类,但属于其中一个已知类”的标记,那么您的SVM就会陷入困境。原因是,libsvm构建了几个二元分类器并将它们组合在一起。因此,如果你有三个类 - 让我们说A,B和C - SVM通过将训练样例分为“分类为A”和“任何其他类”来构建第一个二元分类器。后者显然将包含“未知”类中的所有示例。在尝试构建超平面时,“未知”(实际上属于“A”类)中的示例可能会导致SVM构建一个边距非常小的超平面,并且很难识别A的未来实例,即它的泛化性能会减少。这是因为SVM将尝试构建一个超平面,它将大多数A(正式标记为'A')的实例分隔到超平面的一侧和某些实例(官方标记为'未知')的实例上。另一边。

    • 如果您使用“未知”类来存储所有示例(SVM尚不知道其类),则会出现另一个问题。例如,SVM知道类A,B和C,但是您最近获得了两个新类D和E的示例数据。由于这些示例未被分类且SVM不知道新类,您可能希望临时存储他们在'未知'。在这种情况下,“未知”类可能会引起麻烦,因为它可能包含其特征值的巨大变化的示例。这将使得创建良好的分离超平面变得非常困难,因此得到的分类器很难将D或E的新实例识别为“未知”。可能对属于A,B或C的新实例的分类也会受到阻碍。

    总结:引入一个'Unknown'类,其中包含已知类的示例或几个新类的示例,将导致分类器较差。我认为在训练分类器时最好忽略所有未分类的实例。

  3. 我建议你在分类算法之外解决这个问题。我自己被要求提供此功能并实现了一个网页,该网页显示了相关对象的图像以及每个已知类的按钮。如果有问题的对象属于尚未知的类,则用户可以填写另一个表单来添加新类。如果他回到分类页面,该类的另一个按钮将会神奇地出现。在对实例进行分类后,可以将它们用于训练分类器。 (我使用数据库来存储已知类和引用哪个示例属于哪个类。我实现了一个导出函数来使数据支持SVM。)