Java支持向量机?

20

我希望用Java编写一个“智能监控器”,在检测到即将出现性能问题时发送警报。我的Java应用程序将数据以结构化格式写入日志文件:

<datetime> | <java-method> | <seconds-to-execute>

举个例子,如果我有一个Widget#doSomething(String)方法执行时间为812毫秒,它将被记录为:

所以,例如,如果我有一个Widget#doSomething(String)方法的执行时间为812ms,它将被记录为:

2013-03-24 11:39:21 | Widget#doSomething(String) | 812

当性能开始下降(例如在主要集合期间、在高峰负载期间或如果系统正在减速),方法执行时间开始变慢;因此,最右边的列开始看到巨大的数字(有时需要20-40秒才能执行一个方法)。

在大学时,我为了机器学习练习写了一个我的教授称之为“线性分割器”的程序,它使用简单的测试数据(人的身高、体重和性别)并“学习”如何根据他们的身高/体重将一个人分类为男性或女性。然后,一旦它获得了所有的训练数据,我们就会提供新的数据来查看它能够如何准确地确定性别。

我认为多元线性分割器的版本是被称为支持向量机(SVM)的东西。 如果我错了,请明确说明,我将更改我的问题标题为更合适的内容。 无论如何,我需要这个应用程序执行以下操作:

  • 在“测试模式”下运行,我将从我的主Java应用程序(我希望监视的那个应用程序)中提取结构化日志文件,并将每个日志条目(如上所示)用作测试数据
  • java-methodseconds-to-execute列对于输入/测试数据很重要; 我不关心日期时间
  • 在“监视模式”下运行,它正在积极地从日志文件中读取新的日志数据,并使用类似的“机器学习”技术来确定性能退化是否正在发生

需要注意的是,seconds-to-execute 列不是唯一重要的因素,在表现出色的时期我也曾经看到某些方法的执行时间非常糟糕,而在服务器似乎快要挂掉并推动风铃草时,其他方法的执行时间确实很好。 所以显然某些方法比其他方法更“加权”/更重要。

我的问题

  • 当我搜索“线性分割器”或“支持向量机”时,会出现一些令人惊恐、高度学术、超级理性的白皮书,我没有足够的精力(也没有时间)去消费它们——除非它们真的是我的唯一选择; 因此我问是否有一个通俗易懂的介绍这方面知识的网站/文章/教程,还有如何在Java中构建这样的系统
  • 是否有任何稳定的开源Java库? 我只找到了jlibsvmsvmlearn,但前者似乎处于纯测试状态,后者似乎只支持二进制决策(如我的旧线性分割器)。我知道有Mahout,但它依赖于Hadoop,我认为我没有足够的数据来证明自己设置自己的Hadoop集群的时间和精力。

8
这与你的问题没有直接关联,但是......对于这些领域来说,可怕的学术论文和相当数量的数学是很常见的,比如我长期以来一直对神经网络很感兴趣。在我的硕士课程中,我决定实现一个手写数字识别的神经网络作为最终项目。在我掌握这个主题之前,我花了三天时间浏览论文(阅读核心部分)、阅读代码和编写代码。我的建议是选择最基础的材料并从那里开始。基本上要有阅读的准备!祝好运! - Vivin Paliath
不错的观点@VivinPaliath (+1) - 我想我并不反对动手,只是我知道如果有任何开源项目存在,那么它肯定是由比我更聪明(和更有见识)的人编写的! - IAmYourFaja
1
我更喜欢使用Java进行开发,但是当我面临机器学习的挑战时,我会转向R。这些软件包通常非常成熟且文档齐全。这里有一个文档,其中包含了在R中使用SVM的示例。我使用一个称为JRI的桥接程序将R嵌入到我的Java代码中。 - Felix Dobslaw
我不确定 SVM 是否是最好的工具,但我喜欢 Andrew Ng 在这个视频中的讲解:https://www.youtube.com/watch?v=dzuuNPmGAVU - bendaizer
4个回答

7
您所描述的“智能监视器”正是时间序列分类。
有许多分类算法。它们基本上都采用矩阵,其中行是观测值,列是“特征”,这些特征以某种方式描述观测值,并且一个长度为行数的标签向量,其值为0或1。在您的问题中,一个观测值可能是一分钟的样本,您的标签向量将在经历性能问题的时间段内被赋值为1,否则为0。
在这个定义中,隐含着需要重新采样数据(必要时使用模式/中位数/平均值),使每个观测值均匀定义,例如秒、分钟或小时。
生成特征是至关重要的部分。我可能会从两个特征开始,即原始值和观测值x_i和x_i-1之间的(一次)差异值。我们将为滞后2定义这些。从技术上讲,这使得特征数量达到4个。每个特征都不能看到未来。每个特征必须为每个观测值表示相同的内容。
例如,考虑长度为10的时间序列:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果我们想使用过去两个时间间隔来生成一组特征,那么时间序列的前两个元素被认为是已烧入的样本。我们不能使用与它们相关的观察结果来训练算法。
8行2列的原始值将会是:
[[ 1.,  0.]
 [ 2.,  1.],
 [ 3.,  2.],
 [ 4.,  3.],
 [ 5.,  4.],
 [ 6.,  5.],
 [ 7.,  6.],
 [ 8.,  7.]]

差分值

[[ 1.,  1.],
 [ 1.,  1.],
 [ 1.,  1.],
 [ 1.,  1.],
 [ 1.,  1.],
 [ 1.,  1.],
 [ 1.,  1.]])

这些被列堆叠。您可以探索许多其他功能。滚动平均是我的下一个选择。
如果您想预测更远的未来,则您的训练数据应该比标签向量滞后更远。
如果性能不理想,请尝试通过选择较大窗口上的滚动平均或在未来进一步添加特征来添加更多特征。提高时间序列算法性能的一个巧妙技巧是将前一时间间隔的预测值包括在内。
在数据的早期部分上拟合分类器,然后观察其在数据的后期部分上的准确性。有许多可用于分类器的指标。如果您选择使用输出概率而不是硬1/0的分类器,则您的选择甚至会更广泛(您的分类器的用途也是如此)。 精度和召回率是分类器直观的性能指标。
在数据的前半部分(早期)进行训练,然后在后半部分(后期)进行测试。
就算是算法,我会推荐使用逻辑回归。除非性能不满意且已经尝试完特征提取方法,否则不需要考虑其他。
对于这个任务来说,Mallet 库似乎是一个好的选择。 查看文档的这一部分。 我最近发现了 JSAT ,它看起来很有前途。
有更具体的时间序列分类方法,明确考虑观测和标签的时序性。但这只是一种将分类应用于时间序列的通用方法。

在这种情况下提及逻辑回归是一个好的想法。 - afrischke
是的。除非有证据表明性能提高,否则应优先选择线性模型而不是非线性模型。逻辑回归还具有完全可解释性的额外优点。 - Jessica Collins

6

3

Weka是Java中一款流行的机器学习/数据挖掘软件包。这本书http://guidetodatamining.com/可能会有所帮助。它并没有涉及SVM,但它确实有很好的分类算法,并且它绝对不是晦涩难懂的。


1

也许Apache Spark MLlib能够帮助您:

线性SVM是大规模分类任务的标准方法。它是一种线性方法,如上面方程(1)所述,其公式中的损失函数由hinge loss给出:

L(w;x,y):=max{0,1−ywTx}。

默认情况下,线性SVM使用L2正则化进行训练。我们还支持替代的L1正则化。在这种情况下,问题变成了一个线性规划问题。

线性SVM算法输出一个SVM模型。给定一个新的数据点x,表示为wTx,该模型基于wTx的值进行预测。默认情况下,如果wTx≥0,则结果为正,否则为负。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接