检测数据的异常类别
Elastic Stack Serverless
分类是一种机器学习过程,它对文本字段进行分词,将相似的数据聚类在一起,并将其分类到类别中。它最适用于机器编写的消息和应用程序输出,这些消息和应用程序输出通常由重复的元素组成。分类作业使您能够找到分类数据中的异常行为。分类不是自然语言处理 (NLP)。当您创建分类异常检测作业时,机器学习模型会学习每个类别在一段时间内的正常数量和模式。然后,您可以使用 count 或 rare 函数来检测异常并显示罕见事件或不寻常类型的消息。 分类适用于有限的可能消息集,例如
{"@timestamp":1549596476000,
"message":"org.jdbi.v2.exceptions.UnableToExecuteStatementException: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request [statement:\"SELECT id, customer_id, name, force_disabled, enabled FROM customers\"]",
"type":"logs"}
- 分类经过调整,可以通过考虑标记顺序(包括停用词)而不考虑其分析中的同义词来最好地处理日志消息之类的数据。将机器编写的消息用于分类分析。
- 人类交流或文学文本中的完整句子(例如,电子邮件、维基页面、散文或其他人类生成的内容)在结构上可能非常多样化。由于分类是针对机器数据进行调整的,因此它会为人类生成的数据提供较差的结果。它会创建太多的类别,以至于无法有效地处理它们。避免将人工生成的数据用于分类分析。
在 Kibana 中,导航到 作业。要打开 作业,请在主菜单中找到 Machine Learning > 异常检测,或使用全局搜索字段。
单击 创建作业,选择要分析的数据视图。
从列表中选择 分类 向导。
选择一个分类检测器 - 在此示例中为
count
函数 - 以及您要分类的字段 - 在此示例中为message
字段。单击 下一步。
提供作业 ID 并单击 下一步。
如果验证成功,请单击 下一步 以查看作业创建摘要。
单击 创建作业。
此示例作业从 message
字段的内容生成类别,并使用 count
函数来确定某些类别何时以异常速率发生。
API 示例
PUT _ml/anomaly_detectors/it_ops_app_logs
{
"description" : "IT ops application logs",
"analysis_config" : {
"categorization_field_name": "message",<1>
"bucket_span":"30m",
"detectors" :[{
"function":"count",
"by_field_name": "mlcategory"<2>
}]
},
"data_description" : {
"time_field":"@timestamp"
}
}
- 此字段用于派生类别。
- 这些类别通过将
by_field_name
、over_field_name
或partition_field_name
设置为关键字mlcategory
在检测器中使用。如果您未在其中一个属性中指定此关键字,则 API 请求将失败。
使用 Kibana 中的 异常资源管理器 查看分析结果

对于此类作业,结果包含每个异常的额外信息:类别的名称(例如,mlcategory 2
)以及该类别中消息的示例。您可以使用这些详细信息来调查异常高的消息计数的情况。
如果您在 Kibana 中使用高级异常检测作业向导或创建异常检测作业 API,则有其他配置选项。例如,可选的 categorization_examples_limit
属性指定为每个类别存储在内存和结果数据存储中的最大示例数。默认值为 4
。请注意,此设置不影响分类;它仅影响可见示例的列表。如果您增加此值,则会有更多示例可用,但您必须有更多可用存储空间。如果您将此值设置为 0
,则不会存储任何示例。
另一个高级选项是 categorization_filters
属性,该属性可以包含正则表达式数组。如果分类字段值与正则表达式匹配,则在定义类别时,不会考虑字段的匹配部分。分类过滤器按照它们在作业配置中列出的顺序应用,这使您可以忽略分类字段值的多个部分。在此示例中,您可以创建一个类似于 [ "\\[statement:.*\\]"]
的过滤器,以从分类算法中删除 SQL 语句。
如果您启用按分区分类,则将为每个分区独立确定类别。例如,如果您的数据包含来自不同应用程序的多种类型的日志的消息,则可以使用诸如 ECS event.dataset
字段之类的字段作为 partition_field_name
并单独对每种类型的日志的消息进行分类。
如果您的作业有多个检测器,则使用 mlcategory
关键字的每个检测器还必须定义一个 partition_field_name
。您必须在所有这些检测器中使用相同的 partition_field_name
值。否则,当您创建或更新作业并启用按分区分类时,它将失败。
启用按分区分类后,您还可以利用 stop_on_warn
配置选项。如果分区的分类状态更改为 warn
,则它不会很好地进行分类,并且可能导致不必要的资源使用。当您将 stop_on_warn
设置为 true
时,该作业会停止分析这些有问题的分区。因此,您可以避免不适合分类的分区产生持续的性能成本。
分类使用英语词典单词来标识日志消息类别。默认情况下,它还使用英语分词规则。因此,如果您使用默认的分类分析器,则仅支持英语日志消息,如 限制中所述。
如果您使用 Kibana 中的分类向导,则可以查看它使用的分类分析器以及它标识的标记的突出显示示例。您还可以通过自定义分类字段值的解释方式来更改分词规则

分类分析器可以引用内置的 Elasticsearch 分析器或零个或多个字符过滤器、分词器和零个或多个标记过滤器的组合。在此示例中,添加 pattern_replace
字符过滤器可实现与前面描述的 categorization_filters
作业配置选项相同的行为。有关这些属性的更多详细信息,请参阅 categorization_analyzer
API 对象。
如果您在 Kibana 中使用默认的分类分析器或从 API 中省略 categorization_analyzer
属性,则使用以下默认值
POST _ml/anomaly_detectors/_validate
{
"analysis_config" : {
"categorization_analyzer" : {
"char_filter" : [
"first_line_with_letters"
],
"tokenizer" : "ml_standard",
"filter" : [
{ "type" : "stop", "stopwords": [
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"GMT", "UTC"
] }
]
},
"categorization_field_name": "message",
"detectors" :[{
"function":"count",
"by_field_name": "mlcategory"
}]
},
"data_description" : {
}
}
但是,如果您指定 categorization_analyzer
的任何部分,则任何省略的子属性不会设置为默认值。
ml_standard
分词器以及日和月停用词过滤器几乎等效于以下分析器,该分析器仅使用内置的 Elasticsearch 分词器和 标记过滤器定义
PUT _ml/anomaly_detectors/it_ops_new_logs
{
"description" : "IT Ops Application Logs",
"analysis_config" : {
"categorization_field_name": "message",
"bucket_span":"30m",
"detectors" :[{
"function":"count",
"by_field_name": "mlcategory",
"detector_description": "Unusual message counts"
}],
"categorization_analyzer":{
"char_filter" : [
"first_line_with_letters"
],
"tokenizer": {
"type" : "simple_pattern_split",
"pattern" : "[^-0-9A-Za-z_./]+"
},
"filter": [
{ "type" : "pattern_replace", "pattern": "^[0-9].*" },
{ "type" : "pattern_replace", "pattern": "^[-0-9A-Fa-f.]+$" },
{ "type" : "pattern_replace", "pattern": "^[^0-9A-Za-z]+" },
{ "type" : "pattern_replace", "pattern": "[^0-9A-Za-z]+$" },
{ "type" : "stop", "stopwords": [
"",
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"GMT", "UTC"
] }
]
}
},
"analysis_limits":{
"categorization_examples_limit": 5
},
"data_description" : {
"time_field":"time",
"time_format": "epoch_ms"
}
}
- 仅出于分类目的考虑带有字母的消息的第一行。
- 标记由连字符、数字、字母、下划线、点和斜杠组成。
- 默认情况下,分类会忽略以数字开头的标记。
- 默认情况下,分类会忽略十六进制数。
- 下划线、连字符和点会从标记的开头删除。
- 下划线、连字符和点也会从标记的末尾删除。
默认 categorization_analyzer
和本示例分析器之间的主要区别在于使用 ml_standard
分词器速度更快,可提速数倍。 ml_standard
分词器还会尝试将 URL、Windows 路径和电子邮件地址保留为单个词条。 另一个行为差异是,自定义分析器不包含词条中的重音字母,而 ml_standard
分词器包含。 这可以通过使用更复杂的正则表达式来解决。
如果您要对非英语消息进行分类,且该语言中单词之间用空格分隔,则如果将停止词过滤器中的日期或月份词更改为该语言中的相应词语,您可能会获得更好的结果。 如果您要对单词之间没有空格分隔的语言的消息进行分类,您还必须使用不同的分词器才能获得合理分类结果。
重要的是要意识到,为机器生成的日志消息进行分类分析与为搜索进行分词略有不同。 适用于搜索的功能(例如词干提取、同义词替换和转换为小写)可能会使分类结果更糟。 但是,为了从机器学习结果中向下钻取以正确工作,分类分析器生成的词条必须与搜索分析器生成的词条相似。 如果它们足够相似,当您搜索分类分析器生成的词条时,您会找到分类字段值来自的原始文档。