在工业设备预测性维护中,振动数据分析扮演着关键角色。异常振动可能预示着设备故障或性能下降,及时发现这些异常对于预防重大设备故障具有重要意义。本文详细介绍了一个基于ML.NET框架实现的振动数据异常检测系统。
C#Microsoft.ML.Data; Microsoft.ML.TimeSeries;

C#public class VibrationData
{
[LoadColumn(0)]
public DateTime Time { get; set; }
[LoadColumn(1)]
public float Value { get; set; }
}
public class VibrationDataWithIndex
{
public DateTime Time { get; set; }
public float Value { get; set; }
public int Index { get; set; }
}

C#var dataView = mlContext.Data.LoadFromTextFile<VibrationData>(
"振动数据.csv",
separatorChar: ',',
hasHeader: true
);
系统自动计算以下统计指标:
C#var pipeline = mlContext.Transforms.DetectAnomalyBySrCnn(
outputColumnName: nameof(VibrationDataPrediction.Prediction),
inputColumnName: nameof(VibrationDataWithIndex.Value),
windowSize: 64,
backAddWindowSize: 2,
threshold: 0.3f
);
参数说明:
C#mlContext.Model.Save(model, newDataView.Schema, "vibration_anomaly_model.zip");
C#using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.TimeSeries;
using Microsoft.ML.Transforms.TimeSeries;
class Program
{
static void Main(string[] args)
{
var mlContext = new MLContext();
// 加载数据
var dataView = mlContext.Data.LoadFromTextFile<VibrationData>("振动数据.csv", separatorChar: ',', hasHeader: true);
// 获取数据并添加索引
var rawData = mlContext.Data.CreateEnumerable<VibrationData>(dataView, reuseRowObject: false)
.Select(x => new VibrationDataWithIndex
{
Time = x.Time,
Value = x.Value
})
.ToList();
// 计算基本统计信息
var values = rawData.Select(x => x.Value).ToList();
double mean = values.Average();
double stdDev = Math.Sqrt(values.Select(x => Math.Pow(x - mean, 2)).Average());
double max = values.Max();
double min = values.Min();
Console.WriteLine("数据基本统计:");
Console.WriteLine($"平均值: {mean:F3}");
Console.WriteLine($"标准差: {stdDev:F3}");
Console.WriteLine($"最大值: {max:F3}");
Console.WriteLine($"最小值: {min:F3}");
Console.WriteLine($"数据点数量: {values.Count}");
Console.WriteLine();
// 添加索引
for (int i = 0; i < rawData.Count; i++)
{
rawData[i].Index = i;
}
// 将数据转换回IDataView
var newDataView = mlContext.Data.LoadFromEnumerable(rawData);
// 创建异常检测管道 - 使用更敏感的参数
var pipeline = mlContext.Transforms.DetectAnomalyBySrCnn(
outputColumnName: nameof(VibrationDataPrediction.Prediction),
inputColumnName: nameof(VibrationDataWithIndex.Value),
windowSize: 64, // 减小窗口大小以更容易检测到局部异常
backAddWindowSize: 2, // 减小后续窗口大小
threshold: 0.3f // 降低阈值以增加敏感度
);
// 训练模型
var model = pipeline.Fit(newDataView);
// 使用模型进行预测
IDataView transformedData = model.Transform(newDataView);
// 获取预测结果
var predictions = mlContext.Data.CreateEnumerable<VibrationDataPrediction>(
transformedData, reuseRowObject: false).ToList();
// 统计异常分数分布
var scores = predictions.Select(p => p.Prediction[0]).ToList();
Console.WriteLine("异常分数统计:");
Console.WriteLine($"最大异常分数: {scores.Max():F3}");
Console.WriteLine($"平均异常分数: {scores.Average():F3}");
Console.WriteLine($"最小异常分数: {scores.Min():F3}");
Console.WriteLine();
// 使用多级别阈值输出异常
Console.WriteLine("多级别异常检测结果:");
// 严重异常 (异常分数 > 0.7 或者值超过3个标准差)
Console.WriteLine("\n严重异常点:");
for (int i = 0; i < predictions.Count; i++)
{
if (predictions[i].Prediction[0] > 0.7 ||
Math.Abs(rawData[i].Value - mean) > 3 * stdDev)
{
Console.WriteLine($"时间: {rawData[i].Time}, " +
$"索引: {rawData[i].Index}, " +
$"值: {rawData[i].Value}, " +
$"异常分数: {predictions[i].Prediction[0]:F2}, " +
$"偏离标准差: {Math.Abs(rawData[i].Value - mean) / stdDev:F2}σ");
}
}
// 中度异常 (异常分数 > 0.5 或者值超过2个标准差)
Console.WriteLine("\n中度异常点:");
for (int i = 0; i < predictions.Count; i++)
{
if ((predictions[i].Prediction[0] > 0.5 && predictions[i].Prediction[0] <= 0.7) ||
(Math.Abs(rawData[i].Value - mean) > 2 * stdDev && Math.Abs(rawData[i].Value - mean) <= 3 * stdDev))
{
Console.WriteLine($"时间: {rawData[i].Time}, " +
$"索引: {rawData[i].Index}, " +
$"值: {rawData[i].Value}, " +
$"异常分数: {predictions[i].Prediction[0]:F2}, " +
$"偏离标准差: {Math.Abs(rawData[i].Value - mean) / stdDev:F2}σ");
}
}
// 将详细结果保存到CSV文件
using (var writer = new StreamWriter("详细异常检测结果.csv"))
{
writer.WriteLine("时间,值,异常分数,偏离均值标准差数,异常等级");
for (int i = 0; i < predictions.Count; i++)
{
double deviations = Math.Abs(rawData[i].Value - mean) / stdDev;
string anomalyLevel = "正常";
if (predictions[i].Prediction[0] > 0.7 || deviations > 3) anomalyLevel = "严重异常";
else if (predictions[i].Prediction[0] > 0.5 || deviations > 2) anomalyLevel = "中度异常";
writer.WriteLine($"{rawData[i].Time},{rawData[i].Value}," +
$"{predictions[i].Prediction[0]:F4},{deviations:F2},{anomalyLevel}");
}
}
// 保存模型
mlContext.Model.Save(model, newDataView.Schema, "vibration_anomaly_model.zip");
}
}
// 其他类定义保持不变
public class VibrationData
{
[LoadColumn(0)]
public DateTime Time { get; set; }
[LoadColumn(1)]
public float Value { get; set; }
}
public class VibrationDataWithIndex
{
public DateTime Time { get; set; }
public float Value { get; set; }
public int Index { get; set; }
}
public class VibrationDataPrediction
{
[VectorType(3)]
public double[] Prediction { get; set; }
}

C#windowSize: 64 // 可调整范围:32-256
C#backAddWindowSize: 2 // 可调整范围:1-5
C#threshold: 0.3f // 可调整范围:0.1-0.9
text0.1-0.3:超高敏感度(适用于精密设备) 0.3-0.5:高敏感度(适用于常规工业设备) 0.5-0.7:中等敏感度(适用于粗加工设备) 0.7-0.9:低敏感度(适用于高噪声环境)
该系统通过结合ML.NET的SR-CNN算法和传统统计方法,实现了高效的振动数据异常检测。系统的多级别异常分类机制为设备维护决策提供了更细致的参考依据。
未来改进方向:
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!