dotnet / samples

Sample code referenced by the .NET documentation
https://docs.microsoft.com/samples/browse
Creative Commons Attribution 4.0 International
3.42k stars 5.09k forks source link

An executing problem about the ML_NET Code At [samples/machine-learning/tutorials /TaxiFarePrediction/] #6974

Open sky92archangel opened 4 months ago

sky92archangel commented 4 months ago

System information

STEP1

I created project [ TaxiFarePrediction.Console ] with net8.0 ; it has codefile GlobalUsings.cs

global using Microsoft.ML;
global using Microsoft.ML.Data;

created code file Program.cs

TaxiFarePrediction.CreateAndRunPrediction.Execute();

STEP2

Then I created a shared project [ TaxiFarePrediction.Shared ]
created code file CreateAndRunPrediction.cs which is almostly same as the codefile : https://github.com/dotnet/samples/tree/main/machine-learning/tutorials/TaxiFarePrediction/Program.cs

CreateAndRunPrediction.cs :

namespace TaxiFarePrediction
{
    public class CreateAndRunPrediction
    {
        // <Snippet2>
        static readonly string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-train.csv");
        static readonly string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-test.csv");
        static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
        // </Snippet2>

        public static void Execute( )
        {
            Console.WriteLine(Environment.CurrentDirectory);

            // <Snippet3>
            MLContext mlContext = new MLContext(seed: 0);
            // </Snippet3>

            // <Snippet5>
            var model = Train(mlContext, _trainDataPath);
            // </Snippet5>

            // <Snippet14>
            Evaluate(mlContext, model);
            // </Snippet14>

            // <Snippet20>
            TestSinglePrediction(mlContext, model);
            // </Snippet20>
        }

        public static ITransformer Train(MLContext mlContext, string dataPath)
        {
            // <Snippet6>
            IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(dataPath, hasHeader: true, separatorChar: ',');
            // </Snippet6>

            // <Snippet7>
            var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "FareAmount")
                    // </Snippet7>
                    // <Snippet8>
                    .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "VendorIdEncoded", inputColumnName: "VendorId"))
                    .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "RateCodeEncoded", inputColumnName: "RateCode"))
                    .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "PaymentTypeEncoded", inputColumnName: "PaymentType"))
                    // </Snippet8>
                    // <Snippet9>
                    .Append(mlContext.Transforms.Concatenate("Features", "VendorIdEncoded", "RateCodeEncoded", "PassengerCount", "TripDistance", "PaymentTypeEncoded"))
                    // </Snippet9>
                    // <Snippet10>
                    .Append(mlContext.Regression.Trainers.FastTree());
            // </Snippet10>

            Console.WriteLine("=============== Create and Train the Model ===============");

            // <Snippet11>
            var model = pipeline.Fit(dataView);
            // </Snippet11>

            Console.WriteLine("=============== End of training ===============");
            Console.WriteLine();
            // <Snippet12>
            return model;
            // </Snippet12>
        }

        private static void Evaluate(MLContext mlContext, ITransformer model)
        {
            // <Snippet15>
            IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(_testDataPath, hasHeader: true, separatorChar: ',');
            // </Snippet15>

            // <Snippet16>
            var predictions = model.Transform(dataView);
            // </Snippet16>
            // <Snippet17>
            var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");
            // </Snippet17>

            Console.WriteLine();
            Console.WriteLine($"*************************************************");
            Console.WriteLine($"*       Model quality metrics evaluation         ");
            Console.WriteLine($"*------------------------------------------------");
            // <Snippet18>
            Console.WriteLine($"*       RSquared Score:      {metrics.RSquared:0.##}");
            // </Snippet18>
            // <Snippet19>
            Console.WriteLine($"*       Root Mean Squared Error:      {metrics.RootMeanSquaredError:#.##}");
            // </Snippet19>
            Console.WriteLine($"*************************************************");
        }

        private static void TestSinglePrediction(MLContext mlContext, ITransformer model)
        {
            //Prediction test
            // Create prediction function and make prediction.
            // <Snippet22>
            var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(model);
            // </Snippet22>
            //Sample:
            //vendor_id,rate_code,passenger_count,trip_time_in_secs,trip_distance,payment_type,fare_amount
            //VTS,1,1,1140,3.75,CRD,15.5
            // <Snippet23>
            var taxiTripSample = new TaxiTrip()
            {
                VendorId = "VTS",
                RateCode = "1",
                PassengerCount = 1,
                TripTime = 1140,
                TripDistance = 3.75f,
                PaymentType = "CRD",
                FareAmount = 0 // To predict. Actual/Observed = 15.5
            };
            // </Snippet23>
            // <Snippet24>
            var prediction = predictionFunction.Predict(taxiTripSample);
            // </Snippet24>
            // <Snippet25>
            Console.WriteLine($"**********************************************************************");
            Console.WriteLine($"Predicted fare: {prediction.FareAmount:0.####}, actual fare: 15.5");
            Console.WriteLine($"**********************************************************************");
            // </Snippet25>
        }
    }
}

TaxiTrip.cs

namespace TaxiFarePrediction;
public class TaxiTrip
{
    [LoadColumn(0)]
    public string VendorId;

    [LoadColumn(1)]
    public string RateCode;

    [LoadColumn(2)]
    public float PassengerCount;

    [LoadColumn(3)]
    public float TripTime;

    [LoadColumn(4)]
    public float TripDistance;

    [LoadColumn(5)]
    public string PaymentType;

    [LoadColumn(6)]
    public float FareAmount;
}

public class TaxiTripFarePrediction
{
    [ColumnName("Score")]
    public float FareAmount;
}

STEP3

project TaxiFarePrediction.Console reference the project TaxiFarePrediction.Shared

STEP4 error happen

When I built and executed the project TaxiFarePrediction.Console , a problem happend at the code :

var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(model);

AND the error infomation shows:

System.Reflection.TargetInvocationException:“Exception has been thrown by the target of an invocation.”

PlatformNotSupportedException: Dynamic code generation is not supported on this platform.

    System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
    System.Reflection.Emit.AssemblyBuilder.EnsureDynamicCodeSupported()
    System.Reflection.Emit.DynamicMethod.Init(string, System.Reflection.MethodAttributes, System.Reflection.CallingConventions, System.Type, System.Type[], System.Type, System.Reflection.Module, bool, bool)
    System.Reflection.Emit.DynamicMethod.DynamicMethod(string, System.Type, System.Type[], System.Type, bool)
    Microsoft.ML.ApiUtils.GeneratePeek<TOwn, TRow, TValue>(System.Reflection.FieldInfo, System.Reflection.Emit.OpCode)
    System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(object, System.Span<object>, System.Reflection.BindingFlags)

otherwise, if I put all code files into the project TaxiFarePrediction.Console , the code would be smooth ; SO, what's the problem about PlatformNotSupportedException , maybe my project structrue would cause some problem ?

sky92archangel commented 4 months ago

FOUND!

Ah!! I found the problem , the AOT about NET8.0 ,my project TaxiFarePrediction.Console used AOT , which would cause problem at previous content ;

SOLVE!

Editing the .csproj file will solve the previous problem ; <PublishAot>false</PublishAot>

UPDATE

SO , NOW ,question update , when ML_NET could support the AOT ?