using IStation.ChEr.Application; using Microsoft.ML; using Microsoft.ML.Transforms.TimeSeries; namespace IStation.Service { /// /// 单谱分析(.Net) /// public class SSAPredictHelper { /// /// 样本周期数量 /// public const int Win_Size = 12; /// /// 数据样本间隔 /// public const int Series_Length = 288; /// /// 上下限的可信度.预测属于合理猜测,不总是完全准确 /// public const float Confidence_Level = 0.95f; /// /// 输入 /// public class SSAInput { /// /// 时间 /// public DateTime Time { get; set; } /// /// 值 /// public float Value { get; set; } } /// /// 输出 /// public class SSAOutput { /// /// /// public float[] Predict { get; set; } /// /// /// public float[] Lower { get; set; } /// /// /// public float[] Upper { get; set; } } /// /// 预测 /// /// 样本数据 /// 数据步长(秒) /// 样本周期数量 /// 数据样本间隔 /// 上下限的可信度 /// 预测条数 /// public List Predict(List> data, int time_step, int win_size, int series_length, float confidence_level, int fulture) { #region 基础验证 if (data == null || data.Count < win_size) { return null; } if (time_step < 1) { return null; } if (win_size < 1) { return null; } if (series_length < 1 || series_length <= win_size) { return null; } if (confidence_level < 0) { confidence_level = 0; } if (confidence_level > 1) { confidence_level = 1; } if (fulture < 1) { return null; } #endregion 基础验证 var sampleData = data.Select(x => new SSAInput() { Time = x.Item1, Value = (float)x.Item2 }).ToList();//样本数据 var mlContext = new MLContext();//创建 IDataView dataView = mlContext.Data.LoadFromEnumerable(sampleData);//加载数据 var forecastingPipeline = mlContext.Forecasting.ForecastBySsa(//定义训练通道 outputColumnName: "Predict", inputColumnName: "Value", windowSize: win_size, seriesLength: series_length, trainSize: sampleData.Count, horizon: fulture, confidenceLevel: confidence_level, confidenceLowerBoundColumn: "Lower", confidenceUpperBoundColumn: "Upper"); SsaForecastingTransformer forecaster = forecastingPipeline.Fit(dataView); //训练 var forecastEngine = forecaster.CreateTimeSeriesEngine(mlContext);//预测 var forecast = forecastEngine.Predict(); if (forecast.Predict == null || forecast.Predict.Length < 1) { return null; } //构造预测记录 var beginTime = sampleData.Last().Time; var vmList = new List(); for (int i = 0; i < forecast.Predict.Length; i++) { var vm = new SSAData() { DateTime = beginTime.AddSeconds((i + 1) * time_step), Total = forecast.Predict[i] }; vmList.Add(vm); } return vmList; } /* public class TotalOneDay { public DateTime DateTime { get; set; } public double Total { get; set; } }*/ } }