检测异常数据类别

编辑

分类是一个机器学习过程,它对文本字段进行标记化,将相似的数据聚类在一起,并将其分类到不同的类别中。它最适用于机器生成的邮件和应用程序输出,这些输出通常包含重复的元素。 分类作业 使您能够在已分类数据中查找异常行为。分类不是自然语言处理 (NLP)。当您创建分类异常检测作业时,机器学习模型会随着时间的推移学习每个类别的正常数量和模式。然后,您可以使用 计数罕见 函数检测异常并显示罕见事件或异常类型的消息。分类适用于有限的可能消息集,例如

{"@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"}

建议

编辑
  • 分类经过调整,可以最佳地处理日志消息等数据,方法是考虑标记顺序,包括停用词,并且在分析中不考虑同义词。将机器生成的邮件用于分类分析。
  • 人类交流或文学文本中的完整句子(例如电子邮件、维基页面、散文或其他人类生成的内容)在结构上可能极其多样。由于分类针对机器数据进行了调整,因此它对人类生成的数据效果不佳。它会创建如此多的类别,以至于无法有效地处理它们。避免将人类生成的数据用于分类分析。

创建分类作业

编辑
  1. 在 Kibana 中,导航到 机器学习 > 异常检测 > 作业
  2. 点击 创建异常检测作业,选择您要分析的 {data-view}。
  3. 从列表中选择 分类 向导。
  4. 选择一个分类检测器 - 在此示例中为 count 函数 - 以及您要分类的字段 - 在此示例中为 message 字段。

    Creating a categorization job in Kibana
  5. 点击 下一步
  6. 提供作业 ID 并点击 下一步
  7. 如果验证成功,请点击 下一步 以查看作业创建的摘要。
  8. 点击 创建作业

此示例作业从 message 字段的内容生成类别,并使用 count 函数来确定某些类别何时以异常速率出现。

API 示例
PUT _ml/anomaly_detectors/it_ops_app_logs
{
  "description" : "IT ops application logs",
  "analysis_config" : {
    "categorization_field_name": "message",
    "bucket_span":"30m",
    "detectors" :[{
      "function":"count",
      "by_field_name": "mlcategory"
    }]
  },
  "data_description" : {
    "time_field":"@timestamp"
  }
}

此字段用于派生类别。

通过将 by_field_nameover_field_namepartition_field_name 设置为关键字 mlcategory,在检测器中使用类别。如果您未在其中一个属性中指定此关键字,则 API 请求将失败。

查看作业结果
编辑

使用 Kibana 中的 异常资源管理器 查看分析结果

Categorization results in the Anomaly Explorer

对于此类型的作业,结果包含每个异常的其他信息:类别的名称(例如,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 中使用分类向导,则可以看到它使用了哪个分类分析器以及它识别的标记的突出显示示例。您还可以通过自定义解释分类字段值的方式来更改标记化规则

Editing the categorization analyzer in 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 标记器则包含。这可以通过使用更复杂的正则表达式来解决。

如果您正在对以空格分隔单词的非英语消息进行分类,则如果将停用词过滤器中的日期或月份单词更改为您语言中的相应单词,则可能会获得更好的结果。如果您正在对单词没有用空格分隔的语言的消息进行分类,则还必须使用不同的标记器才能获得合理的分类结果。

务必注意,分析机器生成的日志消息的分类与标记搜索略有不同。对搜索效果良好的功能,例如词干提取、同义词替换和小写,可能会使分类结果变差。但是,为了从机器学习结果中正确向下钻取,分类分析器生成的标记必须与搜索分析器生成的标记类似。如果它们足够相似,当您搜索分类分析器生成的标记时,则会找到分类字段值来自的原始文档。