支持Java的矢量机?

时间:2013-03-25 21:43:11

标签: java machine-learning artificial-intelligence svm mahout

我想在Java中编写一个“智能监视器”,它会在检测到即将发生的性能问题时发出警报。我的Java应用程序正在以结构化格式将数据写入日志文件:

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

因此,例如,如果我有一个Widget#doSomething(String)方法执行了812毫秒,它将记录为:

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

随着性能开始下降(例如在主要收集期间,峰值负载期间,或者系统正在慢慢爬行),方法执行时间开始减慢;所以最右边的列开始看到很大的数字(有时候执行单个方法需要20到40秒)。

在大学里 - 为了机器学习练习 - 我写了我的教授所谓的线性二分法,它采用简单的测试数据(一个人的身高,体重和性别)和“学会”如何根据身高/体重将某人分类为男性或女性。然后,一旦它掌握了所有的训练数据,我们就会向它提供新的数据,以确定它可以准确地确定性别。

认为 线性二分法的多变量版本称为support vector machine (SVM)。如果我错了,那么请澄清,我会将问题的标题更改为更合适的名称。 无论如何,我需要这个应用程序来执行以下操作:

  • 以“测试模式”运行,我从我的主Java应用程序(我希望监视的那个)提供结构化日志文件,并获取每个日志条目(如上所示)并将其用于测试数据
    • 只有java-methodseconds-to-execute列作为输入/测试数据非常重要;我不关心日期时间
  • 在“监控模式”下运行,它正在从日志文件中主动读取新的日志数据,并使用类似的“机器学习”技术来确定性能下降是否迫在眉睫

重要的是要注意seconds-to-execute列并不是唯一重要的因素,因为我看到某些方法在令人敬畏的表现期间的可怕时间,以及其他方法的时间非常好服务器似乎就要死了,推着雏菊。因此,某些方法显然比其他方法“加权”/对性能更重要。

我的问题

  • 谷歌搜索“线性二分法”或“支持向量机”出现了一些非常可怕,高度学术,超脑白皮书,我只是没有精神能量(也没有时间)消费 - 除非他们真的是我唯一的选择;所以我问是否有外行人对这些内容的介绍,或者是用Java构建这样一个系统的优秀网站/文章/教程
  • 是否有任何可靠/稳定的开源Java库?我只能找到jlibsvmsvmlearn,但前者看起来处于纯beta状态,而后者似乎只支持二元决策(就像我的旧线性二分法)。我知道有Mahout但是它位于Hadoop之上,我认为我没有足够的数据来保证建立我自己的Hadoop集群所需的时间和精力。

提前致谢!

4 个答案:

答案 0 :(得分:8)

您描述的“智能监视器”正是时间序列分类。

有许多分类算法。它们基本上都是一个矩阵,其中行是观察,列是以某种方式描述观察的“特征”,以及长度为0或1的长度行的标签向量。在您的问题中,观察可能是一小部分样本,对于遇到性能问题的时间段,您的标签向量的值为1,否则为0。

此定义隐含需要重新采样您的数据(必要时使用模式/中位数/平均值),以便均匀定义每个观察点,例如秒或分钟或小时。

生成功能是至关重要的部分。我可能从观察x_i和x_i-1之间的2个特征开始,原始值和(一次)差异值。我们将这些定义为滞后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.]])

这些得到的列堆叠。您可以探索许多其他功能。 Rolling mean将是我的下一个选择。

如果您希望将来进一步预测,那么您的训练数据应该远远超出您的标签矢量。

如果性能不理想,请尝试通过在更大的窗口上选择滚动平均值来添加更多功能,或者在将来再添加更多功能。提高时间序列算法性能的一个聪明技巧是包含前一时间间隔的预测值。

将分类器安装在数据的某些早期部分,然后在后续部分数据中观察其准确性。您可以使用许多分类器指标。如果您选择使用输出概率而不是硬1/0的分类器,那么您的选项甚至会扩大。 (与分类器的用法一样。)

Precision and recall是分类器的直观性能指标。

训练第一(早)一半的数据并在下半年(稍后)进行测试。

就算法而言,我会研究逻辑回归。如果性能不令人满意并且您已经用尽了功能提取选项,我只会查看其他地方。

Mallet似乎是一个很好的任务库。 See this bit of the docs.

我最近发现了JSAT,看起来很有希望。

有更具体的时间序列分类方法明确考虑了观察和标签的连续性。这是对时间序列的分类的通用修改。

答案 1 :(得分:6)

如果您对使用支持向量机感兴趣,那么有一个非常适合初学者的指南,您可能会觉得有用(http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

该指南来自libsvm的同一个人,这是一个非常成熟的支持向量机库(http://www.csie.ntu.edu.tw/~cjlin/libsvm/),他们确实有Java的绑定(http://www.csie.ntu.edu.tw/~cjlin/libsvm/#java

答案 2 :(得分:2)

Weka是Java中流行的机器学习/数据挖掘包。这本书http://guidetodatamining.com/可能有用。它并没有真正解决SVM的问题,但它确实具有良好的分类算法,而且它当然不是很深奥。

答案 3 :(得分:1)

也许Apache Spark MLlib会帮助你:

  

线性SVM是大规模分类的标准方法   任务。它是如上面等式(1)中所述的线性方法,具有   由铰链损失给出的配方中的损失函数:

     

L(瓦特; X,Y):= MAX {0,1-ywTx}

     

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

     

线性SVM算法输出SVM模型。给出一个新数据   点,由x表示,模型根据的值进行预测   WTX。默认情况下,如果wTx≥0则结果为正,并且   否则就是否定。