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; }
}*/
}
}