本教程通过一个 C# 控制台应用示例,演示如何使用 ML.NET 对时序数据进行异常检测,帮助你在销售量等关键指标发生异常变化时及时捕捉峰值和更改点。
示例数据格式如下(仅节选):
| Date | Sales |
| 13-06-2010 | 5422 |
| 14-06-2010 | 7047 |
| 15-06-2010 | 1572 |
| 16-06-2010 | 5657 |
| 17-06-2010 | 3668 |
| 18-06-2010 | 2898 |
在 “解决方案资源管理器” 中,右键单击你的项目并选择 “管理 NuGet 包”,然后:
这些包包含本教程所需的核心功能和时序分析功能。
C#// 用于加载数据
public class ProductSalesData
{
[LoadColumn(0)]
public string? Dt;
[LoadColumn(1)]
public float Sales;
}
这里用 [LoadColumn] 特性来指定 CSV 文件中每列应映射到的 C# 属性。Sales解析为 float 类型,以便后续在 ML.NET 中使用。
C#// 用于接收预测结果
public class ProductSalesPrediction
{
[VectorType(3)]
public double[]? Prediction { get; set; }
}
打开 Program.cs 并添加以下代码,展示完整逻辑:
C#using Microsoft.ML;
namespace App13
{
internal class Program
{
// 数据集路径
private static string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "statsfinal.csv");
// 数据集中包含的行数数量,根据实际数据设置
private const int _docSize = 36;
static void Main(string[] args)
{
// 1. 创建新的 MLContext
MLContext mlContext = new MLContext();
// 2. 加载数据
IDataView dataView = mlContext.Data.LoadFromTextFile<ProductSalesData>(
path: _dataPath,
hasHeader: true,
separatorChar: ','
);
// 3. 执行“峰值”检测
DetectSpike(mlContext, _docSize, dataView);
// 4. 执行“更改点”检测
DetectChangepoint(mlContext, _docSize, dataView);
Console.WriteLine("========= 结束,按任意键退出 =========");
Console.ReadKey();
}
/// <summary>
/// 峰值异常检测
/// </summary>
private static void DetectSpike(MLContext mlContext, int docSize, IDataView productSales)
{
Console.WriteLine("=============== 峰值检测 ===============");
// 1. 创建一个 Spike 检测器(IIDSpikeEstimator)
var iidSpikeEstimator = mlContext.Transforms.DetectIidSpike(
outputColumnName: nameof(ProductSalesPrediction.Prediction),
inputColumnName: nameof(ProductSalesData.Sales),
confidence: 95d, // 表示 95% 的置信度
pvalueHistoryLength: docSize / 4
);
// 2. 模型训练
var iidSpikeTransform = iidSpikeEstimator.Fit(CreateEmptyDataView(mlContext));
// 3. 使用训练好的模型转换实际数据
IDataView transformedData = iidSpikeTransform.Transform(productSales);
// 4. 将结果投影到 IEnumerable 方便读取
var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(
transformedData,
reuseRowObject: false
);
Console.WriteLine("Alert\tScore\tP-Value");
int index = 0;
foreach (var p in predictions)
{
var prediction = p.Prediction;
// Prediction[0] 为警报(0 或 1),[1] 为原始分数,[2] 为 p-value
if (prediction != null)
{
Console.WriteLine($"{prediction[0]}\t{prediction[1]:F2}\t{prediction[2]:F2}");
}
index++;
}
Console.WriteLine("=============== 峰值检测完成 ===============\n");
}
/// <summary>
/// 更改点异常检测
/// </summary>
private static void DetectChangepoint(MLContext mlContext, int docSize, IDataView productSales)
{
Console.WriteLine("=============== 更改点检测 ===============");
// 1. 创建一个 Change Point 检测器(IIDChangePointEstimator)
var iidChangePointEstimator = mlContext.Transforms.DetectIidChangePoint(
outputColumnName: nameof(ProductSalesPrediction.Prediction),
inputColumnName: nameof(ProductSalesData.Sales),
confidence: 95d,
changeHistoryLength: docSize / 4
);
// 2. 模型训练
var iidChangePointTransform = iidChangePointEstimator.Fit(CreateEmptyDataView(mlContext));
// 3. 使用训练好的模型转换实际数据
IDataView transformedData = iidChangePointTransform.Transform(productSales);
// 4. 将结果投影到 IEnumerable 方便读取
var predictions = mlContext.Data.CreateEnumerable<ProductSalesPrediction>(
transformedData,
reuseRowObject: false
);
Console.WriteLine("Alert\tScore\tP-Value\tMartingale Value");
foreach (var p in predictions)
{
var prediction = p.Prediction;
// Prediction[0] 为警报(0 或 1),[1] 为原始分数, [2] 为 p-value, [3] 为 martingale value
if (prediction != null)
{
Console.WriteLine($"{prediction[0]}\t{prediction[1]:F2}\t{prediction[2]:F2}\t{prediction[3]:F2}");
}
}
Console.WriteLine("=============== 更改点检测完成 ===============\n");
}
/// <summary>
/// 创建一个空的 IDataView (仅用于“拟合”操作)
/// </summary>
private static IDataView CreateEmptyDataView(MLContext mlContext)
{
// 创建空列表
var enumerable = new List<ProductSalesData>();
return mlContext.Data.LoadFromEnumerable(enumerable);
}
}
}
DetectIidSpike 检测器是 Microsoft ML.NET 中用于检测时间序列数据中独立同分布(IID)异常的工具。以下是其主要参数的说明:
stringstringdoubleintdocSize / 4),确保检测器有足够的信息来进行准确的评估。
prediction 由 ProductSalesPrediction 类定义,包含了模型在检测过程中生成的预测结果。以下是 prediction 输出各参数的说明:
通过以上步骤,你可以快速地将 ML.NET 的异常检测功能集成到自己的 .NET 应用中,实现对时序销售数据(或者其他关键业务指标)的峰值和更改点监测。这样可在异常出现时及时通知相关人员并采取措施。
本示例只是基础流程,实际项目可在此基础上进行更多完善:
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!