惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
S
Schneier on Security
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
U
Unit 42
Hacker News - Newest:
Hacker News - Newest: "LLM"
V2EX - 技术
V2EX - 技术
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
H
Heimdal Security Blog
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Cloudbric
Cloudbric
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
The Cloudflare Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
F
Fortinet All Blogs
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
D
DataBreaches.Net
N
News and Events Feed by Topic
Security Archives - TechRepublic
Security Archives - TechRepublic
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
F
Full Disclosure
The Register - Security
The Register - Security
L
LINUX DO - 热门话题
Webroot Blog
Webroot Blog
Google Online Security Blog
Google Online Security Blog
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
S
Security Affairs
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
T
Threatpost
Spread Privacy
Spread Privacy
小众软件
小众软件
AWS News Blog
AWS News Blog
S
Secure Thoughts
S
Security @ Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks

博客园 - Bean.Hsiang

评估和改进 ML.NET 分类器 ML.NET 和 Model Builder 2021年三月更新 ML.NET 推荐引擎中一类矩阵因子分解的缺陷 4倍速!ML.NET Model Builder GPU 与 CPU 对比测试 使用 ML.NET 识别乐高颜色块 ML.NET 十一月更新 借助AI激发组织创新活力 Virtual ML.NET Hackathon 2020 来啦 ML.NET 九月更新 ML.NET API 和工具八月更新 通过 ML.NET 使用预训练残差网络 ResNet 模型实现手势识别 通过 Continual Learning 提高 ML.NET 模型准确性并增强性能 在WSL2启用cuda进行深度学习尝鲜 基于 ONNX 在 ML.NET 中使用 Pytorch 训练的垃圾分类模型 在 Blazor WebAssembly 静态网站中部署ML.NET机器学习模型 使用 Scikit-learn 和 ML.NET 实现朴素贝叶斯(Naive Bayes)分类器 恢复已取消ML.NET训练中的模型 说说 ML.NET and AutoML 使用ML.NET进行自定义机器学习
使用 ML.NET 实现峰值检测来排查异常
Bean.Hsiang · 2021-01-04 · via 博客园 - Bean.Hsiang

机器学习中一类问题称为峰值检测,它旨在识别与大部分时序中明显不同但临时突发的数据值及时检测到这些可疑的个体、事件或观察值很重要,这样才能尽量减少其产生。异常情况检测是检测时序数据离群值的过程,在给定的输入时序上指向“怪异”或不是预期行为的峰值。

通常有两种类型的时序异常检测:

  • 峰值,指示系统中临时突发的异常行为。

  • 更改点,指示系统中一段时间内持续更改的开始。

在 ML.NET 中,IID 峰值检测或 IID 更改点检测算法适用于独立且均匀分布的数据集。峰值检测不需要任何训练,这一点不像其他的机器学习场景,代码也非常简单。

我们来看一个真实的例子,假设有这样一组日志数据:

如图所示有红色背景色的条形表明了发生异常。在 2019 年 10 月 19 日之前的错误计数,每天只发生了几例,而当天会突然达到峰值。当修复系统后系统正常运行了两天,不过由于引入了一个新的 Bug 在 2019 年 10 月 22 日又出现一个新的峰值。这个瞬间的峰值反映了系统肯定出现大规模异常。接下来我们就通过 ML.NET 来实现对峰值的识别。

首先安装以下 NuGet 包:

Install-Package Microsoft.ML
Install-Package Microsoft.ML.TimeSeries

Microsoft.MLMicrosoft.ML.TimeSeries 包含时间序列数据的相关对象。

var mlContext = new MLContext();

为了快速示例,我将模拟包含峰值的输入数据如下:

var counts = new[] { 0, 1, 1, 0, 2, 1, 0, 0, 1, 1, 50, 0, 1, 0, 2, 1, 0, 1 };

50这个值很突出的代表了峰值。接下来我们定义一个强类型对象作为输入模型:

class Input
{
    public float Count { get; set; }
}

与输入一样,定义一个强类型输出模型:

class Output
{
    [VectorType(3)]
    public double[] Prediction { get; set; }
}

用 VectorType 标注了预测数据为 3 个元素的双精度类型的数组。

接下来,我们定义评估器对象,可用于分析模型的效果:

var estimator = mlContext.Transforms.DetectIidSpike(
    nameof(Output.Prediction),
    nameof(Input.Count),
    confidence:99,
    pvalueHistoryLength:counts.Length / 4);

DetectIidSpike 方法有 4 个参数,输入属性的名称、输出属性的名称,置信度、峰值出现范围,一般会将范围设置为输入长度的四分之一。

最后,生成转换对象,创建预训练模型,只是这个模型不需要训练,所以传入空数组:

ITransformer transformer = estimator.Fit(mlContext.Data.LoadFromEnumerable(new List<Input>()));

有了模型,我们处理用于预测的输入数据:

var input = counts.Select(x => new Input { Count = x });
IDataView transformedData = transformer.Transform(mlContext.Data.LoadFromEnumerable(input));

最后一步获取预测结果:

var predictions = mlContext.Data.CreateEnumerable<Output>(transformedData, false);

在此步骤中,我们用循环输出每一个预测数据的结果:

foreach (var p in predictions)
{
    Console.WriteLine($"{p.Prediction[0]}\t{p.Prediction[1]}\t{p.Prediction[2]}");
}

在这里,你会看到输出预测中每行都是一个包含3个浮点数的数组:

第一列是一个bool值,指示该行是否为峰值。0 表示不是峰值,第二列是原始输入,第三列是逗号分隔的置信值。

以下是到目前为止的完整代码:

var counts = new[] { 0, 1, 1, 0, 2, 1, 0, 0, 1, 1, 50, 0, 1, 0, 2, 1, 0, 1 };

var mlContext = new MLContext();
var estimator = mlContext.Transforms.DetectIidSpike(nameof(Output.Prediction), nameof(Input.Count), confidence:99, pvalueHistoryLength:counts.Length / 4);
ITransformer transformer = estimator.Fit(mlContext.Data.LoadFromEnumerable(new List<Input>()));
var input = counts.Select(x => new Input { Count = x });
IDataView transformedData = transformer.Transform(mlContext.Data.LoadFromEnumerable(input));
var predictions = mlContext.Data.CreateEnumerable<Output>(transformedData, false);

foreach (var p in predictions)
{
    Console.WriteLine($"{p.Prediction[0]}\t{p.Prediction[1]}\t{p.Prediction[2]}");
}

乍一看,代码可能看起来有点啰嗦。主要是 ML.NET 无论训练模型与否,管道几乎相同的。

我们再试试改一下 confidence 设置。看看会发生什么:

var estimator = mlContext.Transforms.DetectIidSpike(
    nameof(Output.Prediction),
    nameof(Input.Count),
    confidence:95,
    pvalueHistoryLength:counts.Length / 4);

对于相同的输入,预测现在如下所示:

注意到区别了吗?第五行现在也标记为峰值。

我们将输入值更改为以下内容:

var counts = new[] { 1, 3, 0, 4, 5, 5, 4, 3, 3, 0, 13, 8, 1, 61, 21, 40, 7, 7, 5, 6, 8, 33, 11, 5,
    2, 10, 11, 18, 14, 23, 8, 17, 15, 13, 24, 29, 15, 20, 29, 19, 18, 17, 23, 47, 7, 14, 26, 28,
    5, 22, 47, 22, 20, 9, 40, 6, 8, 4, 10, 10, 1, 4, 27, 3, 3, 7, 6, 12, 8, 3, 1, 2, 0, 0, 2, 0,
    2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2 };

此时在没有 ML.NET 时就感觉到想要发现异常要困难得多了吧。运行程序后,下面是结果的一部分:

最后一行标记为峰值。但看看第14行绝对看起来像一个异常,ML.NET 似乎有点问题,置信值低于0.05。我们可以稍微处理一下:

if (p.Prediction[2] < (1 - 0.95))
{
    p.Prediction[0] = 1;
}

这虽然有点玩套路,但基本上真的峰值被预测出来,不过弄出了更多不正确的预测。实际上应该在置信度的基础上用额外的二次过滤机制来保证结果倾向于正确:

到目前为止,我们可以使用 ML.NET 来实现机器学习检测异常数据了,这会让我们监控一类的应用更加智能!