c# - 带有 ML.NET 的 SSA 预测返回奇怪的结果
问题描述
我刚开始使用 ML.NET,所以我尝试在我的代码上调整Microsoft的教程,这应该可以预测未来的预订:
static void Main(string[] args)
{
MLContext mlContext = new MLContext();
ModelInput[] modelInputFirstYear = Database.Instance.GetBookingsOfYear(2018).ToArray();
ModelInput[] modelInputSecondYear = Database.Instance.GetBookingsOfYear(2019).ToArray();
modelInputFirstYear = FillDates(modelInputFirstYear); //FillDates fills the array on days where no bookings were made with a date and the TotalBookings = 0, so it has 365 items
modelInputSecondYear = FillDates(modelInputSecondYear);
IDataView firstYear = mlContext.Data.LoadFromEnumerable<ModelInput>(modelInputFirstYear);
IDataView secondYear = mlContext.Data.LoadFromEnumerable<ModelInput>(modelInputSecondYear);
var forecastingPipeline = mlContext.Forecasting.ForecastBySsa(
outputColumnName: "ForecastedBookings",
inputColumnName: "TotalBookings",
windowSize: 7,
seriesLength: 30,
trainSize: 365,
horizon: 7,
confidenceLevel: 0.95f,
confidenceLowerBoundColumn: "LowerBoundBookings",
confidenceUpperBoundColumn: "UpperBoundBookings");
SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYear);
Evaluate(secondYear, forecaster, mlContext);
var forecastEngine = forecaster.CreateTimeSeriesEngine<ModelInput, ModelOutput>(mlContext);
Forecast(secondYear, 7, forecastEngine, mlContext);
}
private static void Evaluate(IDataView testData, ITransformer model, MLContext mlContext)
{
IDataView predictions = model.Transform(testData);
IEnumerable<float> actual = mlContext.Data.CreateEnumerable<ModelInput>(testData, true).Select(observed => observed.TotalBookings);
IEnumerable<float> forecast = mlContext.Data.CreateEnumerable<ModelOutput>(predictions, true).Select(prediction => prediction.ForecastedBookings[0]);
var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);
var MAE = metrics.Average(error => Math.Abs(error));
var RMSE = Math.Sqrt(metrics.Average(error => Math.Pow(error, 2)));
Console.WriteLine(" > Evaluation Metrics");
Console.WriteLine($" > Mean Absolute Error: {MAE:F3}");
Console.WriteLine($" > Root Mean Squared Error: {RMSE:F3}\n");
}
private static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine<ModelInput, ModelOutput> forecaster, MLContext mlContext)
{
ModelOutput forecast = forecaster.Predict();
IEnumerable<string> forecastOutput = mlContext.Data.CreateEnumerable<ModelInput>(testData, reuseRowObject: false)
.Take(horizon)
.Select((ModelInput rental, int index) =>
{
string rentalDate = rental.BookingDate.ToShortDateString();
float actualRentals = rental.TotalBookings;
float lowerEstimate = Math.Max(0, forecast.LowerBoundBookings[index]);
float estimate = forecast.ForecastedBookings[index];
float upperEstimate = forecast.UpperBoundBookings[index];
return $"Date: {rentalDate}\n" +
$"Actual Rentals: {actualRentals}\n" +
$"Lower Estimate: {lowerEstimate}\n" +
$"Forecast: {estimate}\n" +
$"Upper Estimate: {upperEstimate}\n";
});
Console.WriteLine(" > Rental Forecast");
Console.WriteLine("");
foreach (var prediction in forecastOutput)
{
Console.WriteLine(prediction);
}
}
ModelInput
和ModelOutput
类:
public class ModelInput
{
public DateTime BookingDate { get; set; }
public float Year { get; set; }
public float TotalBookings { get; set; }
}
public class ModelOutput
{
public float[] ForecastedBookings { get; set; }
public float[] LowerBoundBookings { get; set; }
public float[] UpperBoundBookings { get; set; }
}
但预测值返回奇怪的结果:
解决方案
两个想法:
- 我们在国际化方面遇到了一些问题,我注意到您似乎使用逗号来表示小数点。您可以尝试使用美国格式的数据,看看这是否能解决您的问题?
- 负值可能不是不准确的。我注意到您在代码中取了下限和 0 的最大值,但我敢打赌,如果您返回实际的下限,它也将是负数。您的数据实际上可能暗示了负面趋势。
推荐阅读
- angularjs - Bootstrap 下拉子菜单未在 Angularjs 中显示?
- python - 生成 xlsx 报告时出现 Odoo 10 错误
- r - 具有先验未知级别的 dplyr::recode_factor
- vba - 使用过程将 Sheet1 导出为 CSV 时出现运行时错误“438”
- r - 以编程方式为变量的每个可能值创建一个虚拟变量,并将这些虚拟变量传递给公式
- image-processing - 使用 imagemagick 获取 jpg 的原始像素
- python - AttributeError:模块'PyQt5.QtCore'没有属性'Slot'
- javascript - 在 React 中使用 Axios getData 中的道具时历史推送未定义
- ruby-on-rails - 在 ruby 助手中需要 javascript 位置对象数据
- android - Statement.executeInsert() 返回值