dotnet / dotnet/machinelearning-samples
System.InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Single'.
- Dominant language
- PowerShell
- Stars
- 4.7k
- Forks
- 2.7k
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 1
Description
Looking to convert this example (https://github.com/dotnet/machinelearning-samples/tree/master/samples/csharp/getting-started/AnomalyDetection_Sales) to read from a local SqlServer database. The problem seems to be in the lazy loading of the data from the database. I'm reading two integers from a table (an ID and Status), and trying to figure out when a change in Status occurs. The example code works when reading from a CSV file.
Do I need to do something to convert the integer being read from the db table to a float? I didn't need to do that when reading from the CSV file.
Using ML.Net 1.5.2
Exception:
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Single'.
at System.Data.SqlClient.SqlBuffer.get_Single()
at System.Data.SqlClient.SqlDataReader.GetFloat(Int32 i)
at Microsoft.ML.Data.DatabaseLoader.Cursor.<>c__DisplayClass37_0.b__0(Single& value)
at Microsoft.ML.Data.TypedCursorable`1.TypedRowBase.<>c__DisplayClass10_0`1.b__0(TRow row)
at Microsoft.ML.Data.TypedCursorable`1.TypedRowBase.FillValues(TRow row)
at Microsoft.ML.Data.TypedCursorable`1.TypedCursor.FillValues(TRow row)
at Microsoft.ML.Data.TypedCursorable`1.RowCursorImplementation.FillValues(TRow row)
at Microsoft.ML.Transforms.StatefulFilterTransform`3.Cursor.RunLambda(Boolean& isRowAccepted)
at Microsoft.ML.Transforms.StatefulFilterTransform`3.Cursor.MoveNextCore()
at Microsoft.ML.Data.RootCursorBase.MoveNext()
at Microsoft.ML.Data.SynchronizedCursorBase.MoveNext()
at Microsoft.ML.Data.TypedCursorable`1.TypedCursor.MoveNext()
at Microsoft.ML.Data.TypedCursorable`1.RowCursorImplementation.MoveNext()
at Microsoft.ML.PipeEngine`1.RunPipe(Boolean reuseRowObject)+MoveNext()
at MLNetDemo.Program.Main(String[] args) in C:\MLNetDemo\Program.cs:line 58
Code:
` public class ConnectionStatus
{
public long ConnectionId;
public float Status;
}
public class ConnectionStatusPrediction
{
[VectorType(3)]
public double[] Prediction { get; set; }
}
public class Program
{
static void Main(string[] args)
{
int size = 36;
MLContext mlContext = new MLContext();
IDataView dataView = GetDatabaseDataView(mlContext);
IidChangePointEstimator estimator = mlContext.Transforms.DetectIidChangePoint(nameof(ConnectionStatusPrediction.Prediction), nameof(ConnectionStatus.Status), 95, size / 5);
ITransformer tansformedModel = estimator.Fit(CreateEmptyDataView(mlContext));
IDataView transformedData = tansformedModel.Transform(dataView);
IEnumerable predictions = mlContext.Data.CreateEnumerable(transformedData, reuseRowObject: false);
Console.WriteLine("Alert\tScore\tP-Value");
// code throws exception here, when iterating through the list of predictions
foreach(ConnectionStatusPrediction p in predictions)
{
Console.WriteLine("{0}\t{1:0.00}\t{2:0.00}", p.Prediction[0], p.Prediction[1], p.Prediction[2]);
Console.ResetColor();
}
Console.WriteLine("");
}
private static IDataView CreateEmptyDataView(MLContext mlContext)
{
//Create empty DataView. We just need the schema to call fit()
IEnumerable enumerableData = new List();
IDataView dv = mlContext.Data.LoadFromEnumerable(enumerableData);
return dv;
}
private static IDataView GetDatabaseDataView(MLContext mlContext)
{
string connectionStr = "Data Source=localhost; Initial Catalog=connectionstatus;Integrated Security=SSPI;";
string query = "select ConnectionId, cast([Status] as float) as [Status] from connectionstatus";
DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader();
DatabaseSource source = new DatabaseSource(SqlClientFactory.Instance, connectionStr, query);
IDataView dataView = loader.Load(source);
return source.ProviderFactory.CreateDataAdapter();
}
}`
Contributor guide
Assessment
This issue has not been assessed yet.