Closed DuddyRosenberg closed 3 years ago
Hi @DuddyRosenberg
Thanks for raising this issue. Looking into it.
@DuddyRosenberg
I was not able to reproduce. I created the app from scratch and got the expected output without errors. Can you try starting again and taking a look at what I've pasted below to see if there's differences between your code and mine.
Evaluation Metrics
---------------------
Mean Absolute Error: 726.416
Root Mean Squared Error: 987.658
Rental Forecast
---------------------
Date: 1/1/2012
Actual Rentals: 2294
Lower Estimate: 1197.8424
Forecast: 2334.4434
Upper Estimate: 3471.0442
Date: 1/2/2012
Actual Rentals: 1951
Lower Estimate: 1148.4125
Forecast: 2360.8608
Upper Estimate: 3573.309
Date: 1/3/2012
Actual Rentals: 2236
Lower Estimate: 1068.5067
Forecast: 2373.2764
Upper Estimate: 3678.046
Date: 1/4/2012
Actual Rentals: 2368
Lower Estimate: 984.98376
Forecast: 2382.2546
Upper Estimate: 3779.5254
Date: 1/5/2012
Actual Rentals: 3272
Lower Estimate: 906.73895
Forecast: 2386.749
Upper Estimate: 3866.759
Date: 1/6/2012
Actual Rentals: 4098
Lower Estimate: 825.9437
Forecast: 2387.0024
Upper Estimate: 3948.0613
Date: 1/7/2012
Actual Rentals: 4521
Lower Estimate: 743.52264
Forecast: 2385.3787
Upper Estimate: 4027.2346
This is the code in my Program.cs
.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms.TimeSeries;
namespace BikeDemandForecasting
{
class Program
{
static void Main(string[] args)
{
string rootDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../"));
string dbFilePath = Path.Combine(rootDir, "Data", "DailyDemand.mdf");
string modelPath = Path.Combine(rootDir, "MLModel.zip");
var connectionString = $"Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename={dbFilePath};Integrated Security=True;Connect Timeout=30;";
MLContext mlContext = new MLContext();
DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<ModelInput>();
string query = "SELECT RentalDate, CAST(Year as REAL) as Year, CAST(TotalRentals as REAL) as TotalRentals FROM Rentals";
DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance,
connectionString,
query);
IDataView dataView = loader.Load(dbSource);
IDataView firstYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", upperBound: 1);
IDataView secondYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", lowerBound: 1);
var forecastingPipeline = mlContext.Forecasting.ForecastBySsa(
outputColumnName: "ForecastedRentals",
inputColumnName: "TotalRentals",
windowSize: 7,
seriesLength: 30,
trainSize: 365,
horizon: 7,
confidenceLevel: 0.95f,
confidenceLowerBoundColumn: "LowerBoundRentals",
confidenceUpperBoundColumn: "UpperBoundRentals");
SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYearData);
Evaluate(secondYearData, forecaster, mlContext);
var forecastEngine = forecaster.CreateTimeSeriesEngine<ModelInput, ModelOutput>(mlContext);
forecastEngine.CheckPoint(mlContext, modelPath);
Forecast(secondYearData, 7, forecastEngine, mlContext);
}
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.TotalRentals);
IEnumerable<float> forecast =
mlContext.Data.CreateEnumerable<ModelOutput>(predictions, true)
.Select(prediction => prediction.ForecastedRentals[0]);
var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);
var MAE = metrics.Average(error => Math.Abs(error)); // Mean Absolute Error
var RMSE = Math.Sqrt(metrics.Average(error => Math.Pow(error, 2))); // Root Mean Squared Error
Console.WriteLine("Evaluation Metrics");
Console.WriteLine("---------------------");
Console.WriteLine($"Mean Absolute Error: {MAE:F3}");
Console.WriteLine($"Root Mean Squared Error: {RMSE:F3}\n");
}
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.RentalDate.ToShortDateString();
float actualRentals = rental.TotalRentals;
float lowerEstimate = Math.Max(0, forecast.LowerBoundRentals[index]);
float estimate = forecast.ForecastedRentals[index];
float upperEstimate = forecast.UpperBoundRentals[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);
}
}
}
public class ModelInput
{
public DateTime RentalDate { get; set; }
public float Year { get; set; }
public float TotalRentals { get; set; }
}
public class ModelOutput
{
public float[] ForecastedRentals { get; set; }
public float[] LowerBoundRentals { get; set; }
public float[] UpperBoundRentals { get; set; }
}
}
Here is the project structure and package versions I'm using:
@DuddyRosenberg were you able to get your application running?
Closing this issue due to no response and being unable to reproduce the error. @DuddyRosenberg please feel free to open an issue if you run into other errors.
I’m trying to do this tutorial on forcasting with MLnet and it just blows up on Line 47
SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYearData);
in program.cs, error message just sayingException has been thrown by the target of an invocation.
. Am i the only one?Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.