123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Hosting;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.ML;
- using Microsoft.ML.Data;
- using InfluxData.Net.Common.Enums;
- using InfluxData.Net.InfluxDb;
- using System.CodeDom.Compiler;
- using AdysTech.InfluxDB.Client.Net;
- using System.Drawing;
- using InfluxData.Net.InfluxDb.Models;
- namespace Ropin.IOT.MLService
- {
- public class Program
- {
- //public static void Main(string[] args)
- //{
- // CreateHostBuilder(args).Build().Run();
- //}
- // 定义文件路径
- private static string _dataPath = "./accident_data.csv";
- private static string _modelPath = "./AccidentPredictionModel.zip";
- public static void Main(string[] args)
- {
- //try
- //{
- // GetData(args);
- //}
- //catch (Exception ex) { Console.WriteLine(ex.InnerException.Message); }
-
- Console.OutputEncoding = System.Text.Encoding.UTF8;
- Console.WriteLine("工厂事故预测系统启动...");
- // 创建ML.NET上下文
- MLContext mlContext = new MLContext(seed: 0);
- // 加载数据
- Console.WriteLine("正在加载数据...");
- IDataView dataView = mlContext.Data.LoadFromTextFile<AccidentData>(
- path: _dataPath,
- hasHeader: true,
- separatorChar: ',',
- allowQuoting: true
- );
- // 分割训练集和测试集
- var dataSplit = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
- var trainingData = dataSplit.TrainSet;
- var testData = dataSplit.TestSet;
- // 数据处理和特征工程
- Console.WriteLine("正在处理数据和提取特征...");
- var dataProcessPipeline = mlContext.Transforms.Conversion.MapValueToKey(
- outputColumnName: "Label", // 这将创建一个新列作为Key类型标签
- inputColumnName: "AccidentLevel" // 原始字符串标签
- )
- .Append(mlContext.Transforms.Categorical.OneHotEncoding(
- new[] {
- new InputOutputColumnPair("CountryEncoded", "Country"),
- new InputOutputColumnPair("IndustrySectorEncoded", "IndustrySector"),
- new InputOutputColumnPair("CriticalRiskEncoded", "CriticalRisk"),
- new InputOutputColumnPair("GenreEncoded", "Genre"),
- new InputOutputColumnPair("EmployeeTypeEncoded", "EmployeeOrThirdParty")
- }))
- // 文本特征提取(从描述中提取特征)
- .Append(mlContext.Transforms.Text.FeaturizeText("DescriptionFeaturized", "Description"))
- // 合并所有特征到一个向量
- .Append(mlContext.Transforms.Concatenate("Features",
- "CountryEncoded", "IndustrySectorEncoded", "CriticalRiskEncoded",
- "GenreEncoded", "EmployeeTypeEncoded", "DescriptionFeaturized"));
- // 选择训练算法 - 使用多类分类器
- Console.WriteLine("构建和训练模型...");
- var trainer = mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy();
- // 构建完整训练管道
- var trainingPipeline = dataProcessPipeline.Append(trainer)
- // 将预测结果映射回原始标签值
- .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
- // 训练模型
- var trainedModel = trainingPipeline.Fit(trainingData);
- Console.WriteLine("模型训练完成!");
- // 保存模型
- mlContext.Model.Save(trainedModel, trainingData.Schema, _modelPath);
- Console.WriteLine($"模型已保存到: {_modelPath}");
- // 评估模型
- Console.WriteLine("评估模型性能...");
- var predictions = trainedModel.Transform(testData);
- var metrics = mlContext.MulticlassClassification.Evaluate(predictions);
- // 输出评估指标
- Console.WriteLine($"宏平均精确度: {metrics.MacroAccuracy:F2}");
- Console.WriteLine($"微平均精确度: {metrics.MicroAccuracy:F2}");
- Console.WriteLine($"对数损失: {metrics.LogLoss:F2}");
- Console.WriteLine($"混淆矩阵: \n{metrics.ConfusionMatrix.GetFormattedConfusionTable()}");
- // 使用模型进行预测示例
- PredictSample(mlContext, trainedModel);
- CreateHostBuilder(args).Build().Run();
- }
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup<Startup>();
- });
- #region 从Influxdb读取数据创建模型预测
- private static readonly IInfluxDBClient client = new InfluxDBClient("http://60.204.212.71:8085/", "admin", "123456");
- public static async Task GetData(string[] args)
- {
- //// 查询最近 10 条 CPU 使用率数据
- // var query1 = "SELECT * FROM fanyidev ORDER BY time DESC LIMIT 10";
- // var results = await client.QueryMultiSeriesAsync("fanyidb", query1);
- // if (results != null && results.Count > 0)
- // {
- // }
- // if (results != null && results.Count > 0)
- // {
- // // 处理查询结果
- // foreach (var series in results)
- // {
- // Console.WriteLine($"查询结果集: {series.Name}");
- // foreach (var point in series.Entries)
- // {
- // // 根据字段名获取值
- // var time = point.GetTimeAsDateTime();
- // var host = point.GetTagAsString("host");
- // var value = point.GetFieldAsDouble("value");
- // Console.WriteLine($"时间: {time}, 主机: {host}, CPU 使用率: {value}");
- // }
- //}
- // }
- //传入查询命令,支持多条
- var queries = new[]
- {
- " SELECT * FROM fanyidev WHERE time> now() - 1h "
- };
- var dbName = "fanyidb";
- InfluxDbClient influxDbClient = new InfluxDbClient("http://60.204.212.71:8085/", "admin", "123456", InfluxDbVersion.Latest);
- //从指定库中查询数据
- var response = await influxDbClient.Client.QueryAsync(queries, dbName);
- if (response.Any())
- {
- var series = response.ToList();
- foreach (var value in series[0].Values)
- {
- //var TimeStamp = DateTime.Parse((string)value[0]);
- var Pressure = Convert.ToDouble(value[2]);
- }
- var dataPoints = series[0].Values.Select(value =>
- new DeviceStatusDataPoint
- {
- //TimeStamp = DateTime.Parse((string)value[0]),
- //Temperature = Convert.ToDouble(value[1]),
- Pressure = Convert.ToDouble(value[2])//,
- //IsFaulty = (bool)value[3]
- }).ToList();
- dataPoints = new List<DeviceStatusDataPoint>();
- var v1 = new DeviceStatusDataPoint
- {
- TimeStamp = DateTime.Now.AddMilliseconds(-1),
- Temperature = 70,
- Pressure = 150,
- IsFaulty = true
- };
- var v2 = new DeviceStatusDataPoint
- {
- TimeStamp = DateTime.Now,
- Temperature = 60,
- Pressure = 140,
- IsFaulty = false
- };
- dataPoints.Add(v1);
- dataPoints.Add(v2);
- // 使用 ML.NET 训练模型
- var mlContext = new MLContext();
- // 将数据加载到 IDataView
- var dataView = mlContext.Data.LoadFromEnumerable(dataPoints);
- // 分割数据集为训练集和测试集
- var trainTestSplit = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
- var trainingData = trainTestSplit.TrainSet;
- var testData = trainTestSplit.TestSet;
- // 定义管道
- var pipeline = mlContext.Transforms.Concatenate("Features", nameof(DeviceStatusDataPoint.Temperature), nameof(DeviceStatusDataPoint.Pressure))
- .Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: nameof(DeviceStatusDataPoint.IsFaulty)));
- // 训练模型
- var model = pipeline.Fit(trainingData);
- // 创建预测引擎
- var predictionEngine = mlContext.Model.CreatePredictionEngine<DeviceStatusDataPoint, FaultPrediction>(model);
- // 预测新样本
- var sampleData = new DeviceStatusDataPoint { Temperature = 75.0, Pressure = 150.0 };
- var prediction = predictionEngine.Predict(sampleData);
- Console.WriteLine($"Predicted IsFaulty: {prediction.PredictedLabel}, Probability: {prediction.Probability}");
- // 评估模型
- var predictions = model.Transform(testData);
- var metrics = mlContext.BinaryClassification.Evaluate(predictions);
- Console.WriteLine($"Accuracy: {metrics.Accuracy}");
- }
- else
- {
- Console.WriteLine("Failed to retrieve data from InfluxDB.");
- }
- //var response = await influxDbClient.Client.QueryAsync(query);
- ////得到Serie集合对象(返回执行多个查询的结果)
- //var series = response.ToList();
- ////取出第一条命令的查询结果,是一个集合
- //var list = series[0].Values;
- ////从集合中取出第一条数据
- //var info_model = list.FirstOrDefault();
- }
- #endregion
- private static void PredictSample(MLContext mlContext, ITransformer model)
- {
- // 创建预测引擎
- var predictionEngine = mlContext.Model.CreatePredictionEngine<AccidentData, AccidentPrediction>(model);
- // 创建测试样本
- var sampleAccident = new AccidentData
- {
- Country = "Country_01",
- IndustrySector = "Mining",
- Genre = "Male",
- EmployeeOrThirdParty = "Third Party",
- CriticalRisk = "Pressed",
- Description = "Worker operating drilling equipment without proper safety procedures, potential for hand injury."
- };
- // 进行预测
- var prediction = predictionEngine.Predict(sampleAccident);
- Console.WriteLine("\n预测示例:");
- Console.WriteLine($"行业: {sampleAccident.IndustrySector}");
- Console.WriteLine($"风险类型: {sampleAccident.CriticalRisk}");
- Console.WriteLine($"事故描述: {sampleAccident.Description}");
- Console.WriteLine($"预测事故等级: {prediction.PredictedAccidentLevel}");
- // 输出各类别的概率
- Console.WriteLine("各等级的概率分布:");
- var labels = new[] { "I", "II", "III", "IV" };
- for (int i = 0; i < prediction.Score.Length; i++)
- {
- if (i < prediction.Score.Length)
- Console.WriteLine($"等级 {i}: {prediction.Score[i]:P2}");
- }
- Console.ReadKey();
- }
- }
- public class AccidentData
- {
- [LoadColumn(0)]
- public float SeqNo { get; set; }
- [LoadColumn(1)]
- public string Date { get; set; }
- [LoadColumn(2)]
- public string Country { get; set; }
- [LoadColumn(3)]
- public string Local { get; set; }
- [LoadColumn(4)]
- public string IndustrySector { get; set; }
- [LoadColumn(5)]
- public string AccidentLevel { get; set; } // 原始字符串标签
- [LoadColumn(6)]
- public string PotentialAccidentLevel { get; set; }
- [LoadColumn(7)]
- public string Genre { get; set; }
- [LoadColumn(8)]
- public string EmployeeOrThirdParty { get; set; }
- [LoadColumn(9)]
- public string CriticalRisk { get; set; }
- [LoadColumn(10)]
- public string Description { get; set; }
- }
- public class AccidentPrediction
- {
- [ColumnName("PredictedLabel")]
- public string PredictedAccidentLevel { get; set; }
- public float[] Score { get; set; }
- }
-
- public class DeviceStatusDataPoint
- {
- [LoadColumn(0)]
- public DateTime TimeStamp { get; set; }
- [LoadColumn(1)]
- public double Temperature { get; set; }
- [LoadColumn(2)]
- public double Pressure { get; set; }
- [LoadColumn(3)]
- public bool IsFaulty { get; set; }
- }
- public class FaultPrediction
- {
- [ColumnName("PredictedLabel")]
- public bool PredictedLabel { get; set; }
- [ColumnName("Probability")]
- public float Probability { get; set; }
- }
- }
|