using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Trainers.LightGbm; namespace Game1.Sources.ML_Joel { class Model { private static MLContext mlContext = new MLContext(seed: 1); private static string path_base = FindPath(); private static string path = System.IO.Path.Combine(path_base, "Content/ML/Rainfall.csv"); private static string modelpath = System.IO.Path.Combine(path_base, "Content/ML/MLmodel_Joel"); private static string report = System.IO.Path.Combine(path_base, "Content/ML/report_Joel"); private static string path_area = System.IO.Path.Combine(path_base, "Content/ML/Rainfall_area.csv"); private static string modelpath_area = System.IO.Path.Combine(path_base, "Content/ML/MLmodel_Joel_area"); private static string report_area = System.IO.Path.Combine(path_base, "Content/ML/report_Joel_area"); // Loading data, creatin and saving ML model for smaller dataset (100) public static void CreateModel() { IDataView trainingDataView = mlContext.Data.LoadFromTextFile( path: path, hasHeader: true, separatorChar: ',', allowQuoting: true, allowSparse: false); var splitData = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.2); trainingDataView = splitData.TrainSet; IDataView testDataView = splitData.TestSet; Input sample = mlContext.Data.CreateEnumerable(trainingDataView, false).ElementAt(0); ITransformer MLModel = BuildAndTrain(mlContext, trainingDataView, testDataView, sample, report); SaveModel(mlContext, MLModel, modelpath, trainingDataView.Schema); } // Building and training ML model public static ITransformer BuildAndTrain(MLContext mLContext, IDataView trainingDataView, IDataView testDataView, Input sample, string reportPath) { var options = new LightGbmRegressionTrainer.Options { MaximumBinCountPerFeature = 40, LearningRate = 0.00020, NumberOfIterations = 20000, NumberOfLeaves = 55, LabelColumnName = "Production", FeatureColumnName = "Features", Booster = new DartBooster.Options() { MaximumTreeDepth = 10 } }; var pipeline = mlContext.Transforms .Text.FeaturizeText("SeasonF", "Season") .Append(mlContext.Transforms.Text.FeaturizeText("CropF", "Crop")) .Append(mlContext.Transforms.Concatenate("Features", "SeasonF", "CropF", "Rainfall")) .AppendCacheCheckpoint(mLContext) .Append(mLContext.Regression.Trainers.LightGbm(options)); ITransformer MLModel = pipeline.Fit(trainingDataView); var testEval = MLModel.Transform(testDataView); Evaluate(mlContext, testEval, pipeline, 10, reportPath, "Production"); return MLModel; } public static void CreateModelArea() { IDataView trainingDataView = mlContext.Data.LoadFromTextFile( path: path_area, hasHeader: true, separatorChar: ',', allowQuoting: true, allowSparse: false); var splitData = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.2); trainingDataView = splitData.TrainSet; IDataView testDataView = splitData.TestSet; ITransformer MLModel = BuildAndTrainArea(mlContext, trainingDataView, testDataView, report_area); SaveModel(mlContext, MLModel, modelpath_area, trainingDataView.Schema); } // Building and training ML model public static ITransformer BuildAndTrainArea(MLContext mLContext, IDataView trainingDataView, IDataView testDataView, string reportPath) { var options = new LightGbmRegressionTrainer.Options { MaximumBinCountPerFeature = 40, LearningRate = 0.00020, NumberOfIterations = 20000, NumberOfLeaves = 55, LabelColumnName = "Production", FeatureColumnName = "Features", Booster = new DartBooster.Options() { MaximumTreeDepth = 10 } }; var pipeline = mlContext.Transforms .Text.FeaturizeText("SeasonF", "Season") .Append(mlContext.Transforms.Text.FeaturizeText("CropF", "Crop")) .Append(mlContext.Transforms.Concatenate("Features", "SeasonF", "CropF", "Area", "Rainfall")) .AppendCacheCheckpoint(mLContext) .Append(mLContext.Regression.Trainers.LightGbm(options)); ITransformer MLModel = pipeline.Fit(trainingDataView); var testEval = MLModel.Transform(testDataView); Evaluate(mlContext, testEval, pipeline, 10, reportPath, "Production"); return MLModel; } public static ITransformer TrainModel(MLContext mlContext, IDataView trainingDataView, IEstimator trainingPipeline) { ITransformer model = trainingPipeline.Fit(trainingDataView); return model; } // Evaluate and save results to a text file public static void Evaluate(MLContext mlContext, IDataView trainingDataView, IEstimator trainingPipeline, int folds, string reportPath, string labelColumnName) { var eval = mlContext.Regression.Evaluate(trainingDataView, labelColumnName: labelColumnName); var report = File.CreateText(reportPath); report.Write("Mean Absolute Error: " + eval.MeanAbsoluteError + '\n' + "R Squared: " + eval.RSquared, 0, 0); report.Flush(); report.Close(); } public static void SaveModel(MLContext mlContext, ITransformer Model, string modelPath, DataViewSchema modelInputSchema) { mlContext.Model.Save(Model, modelInputSchema, modelPath); } public static ITransformer LoadModel() { return mlContext.Model.Load(modelpath, out DataViewSchema inputSchema); } public static PredictionEngine CreateEngine() { ITransformer mlModel = LoadModel(); return mlContext.Model.CreatePredictionEngine(mlModel); } public static ITransformer LoadModelArea() { return mlContext.Model.Load(modelpath_area, out DataViewSchema inputSchema); } public static PredictionEngine CreateEngineArea() { ITransformer mlModel = LoadModelArea(); return mlContext.Model.CreatePredictionEngine(mlModel); } private static string FindPath() { string path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).ToString(); while(true) { path = Directory.GetParent(path).ToString(); if (path.EndsWith("\\Game1")) { return path; } } } } }