我想用Java编写一个“智能监控器”,它会在检测到即将到来的性能问题时发出警报。我的Java应用程序会以结构化的格式将数据写入日志文件:
<datetime> | <java-method> | <seconds-to-execute>
例如,如果我有一个Widget#doSomething(String)
方法,执行时间为812毫秒,它会被记录为:
2013-03-24 11:39:21 | Widget#doSomething(String) | 812
当性能开始下降时(例如在进行大规模收集时,在高峰负载期间,或者系统只是逐渐变慢),方法执行时间开始变长;因此,最右边的列开始出现巨大的数字(有时单个方法的执行时间为20到40秒)。
在大学期间,为了一个机器学习练习,我编写了一个我的教授称之为线性二分器的程序,它使用简单的测试数据(一个人的身高、体重和性别)并“学习”如何根据他们的身高/体重将一个人分类为男性或女性。然后,一旦它有了所有的训练数据,我们就输入新的数据来测试它能多准确地确定性别。
我认为,线性二分器的多变量版本被称为支持向量机 (SVM)。如果我错了,请澄清,我会更改问题的标题为更合适的内容。无论如何,我需要这个应用程序执行以下操作:
- 在“测试模式”下运行,我将从我的主Java应用程序(我希望监控的那个)中输入结构化的日志文件,它会将每个日志条目(如上所示)用作测试数据
- 只有
java-method
和seconds-to-execute
列作为输入/测试数据重要;我对datetime不关心 - 在“监控模式”下运行,它会主动从日志文件中读取新的日志数据,并使用类似的“机器学习”技术来判断是否即将出现性能下降
需要注意的是,seconds-to-execute
列并不是这里唯一重要的因素,因为我在某些方法在性能极佳的时期也看到了可怕的执行时间,而在其他方法在服务器似乎即将崩溃的时刻却有非常好的执行时间。所以显然,某些方法对性能的“权重”/重要性比其他方法更高。
我的问题
- 在谷歌上搜索“线性二分器”或“支持向量机”会出现一些非常可怕的、高度学术的、超级复杂的白皮书,我实在没有精力(也没有时间)去阅读——除非它们真的是我唯一的选择;所以我问是否有适合外行人的介绍,或者关于在Java中构建这样一个系统的优秀网站/文章/教程?
- 是否有任何稳定的开源Java库?我只找到了
jlibsvm
和svmlearn
,但前者看起来处于纯测试状态,后者似乎只支持二元决策(就像我以前的线性二分器)。我知道有Mahout,但它建立在Hadoop之上,我认为我的数据量不足以让我花时间和精力去搭建自己的Hadoop集群。
回答:
你描述的“智能监控器”正是时间序列分类。
有许多分类算法。它们基本上都接受一个矩阵,其中行是观察值,列是“特征”,这些特征以某种方式描述观察值,以及一个长度为行的标签向量,其值为0或1。在你的问题中,一个观察值可能是一分钟的样本,你的标签向量将在经历性能问题的时间段内值为1,否则为0。
这个定义中隐含的是需要重新采样你的数据(如果必要的话,使用众数/中位数/平均数),以便每个观察值被定义为均匀的,例如秒、分钟或小时。
生成特征是关键部分。我可能会从2个特征开始,原始值和(一次)差分值,即观察值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,看起来很有前景。
有更多专门针对时间序列分类的特定方法,这些方法明确考虑了观察值和标签的顺序性。这是对时间序列的通用分类适应。