첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestSolution.zip
5.32MB

[TestLibrary 프로젝트]

 

▶ ModelInput.cs

using Microsoft.ML.Data;

namespace TestLibrary
{
    /// <summary>
    /// 모델 입력
    /// </summary>
    public class ModelInput
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 공급자 ID - VendorID

        /// <summary>
        /// 공급자 ID
        /// </summary>
        [ColumnName("vendor_id"), LoadColumn(0)]
        public string VendorID { get; set; }

        #endregion
        #region 요금 코드 - RateCode

        /// <summary>
        /// 요금 코드
        /// </summary>
        [ColumnName("rate_code"), LoadColumn(1)]
        public float RateCode { get; set; }

        #endregion
        #region 승객 수 - PassengerCount

        /// <summary>
        /// 승객 수
        /// </summary>
        [ColumnName("passenger_count"), LoadColumn(2)]
        public float PassengerCount { get; set; }

        #endregion
        #region 이동 시간 (단위 : 초) - TripTimeInSeconds

        /// <summary>
        /// 이동 시간 (단위 : 초)
        /// </summary>
        [ColumnName("trip_time_in_secs"), LoadColumn(3)]
        public float TripTimeInSeconds { get; set; }

        #endregion
        #region 이동 거리 - TripDistance

        /// <summary>
        /// 이동 거리
        /// </summary>
        [ColumnName("trip_distance"), LoadColumn(4)]
        public float TripDistance { get; set; }

        #endregion
        #region 지불 타입 - PaymentType

        /// <summary>
        /// 지불 타입
        /// </summary>
        [ColumnName("payment_type"), LoadColumn(5)]
        public string PaymentType { get; set; }

        #endregion
        #region 요금 - FareAmount

        /// <summary>
        /// 요금
        /// </summary>
        [ColumnName("fare_amount"), LoadColumn(6)]
        public float FareAmount { get; set; }

        #endregion
    }
}

 

728x90

 

▶ ModelOutput.cs

namespace TestLibrary
{
    /// <summary>
    /// 모델 입력
    /// </summary>
    public class ModelOutput
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 점수 - Score

        /// <summary>
        /// 점수
        /// </summary>
        public float Score { get; set; }

        #endregion
    }
}

 

300x250

 

▶ ConsumeModel.cs

using Microsoft.ML;
using System;

namespace TestLibrary
{
    /// <summary>
    /// 모델 소비
    /// </summary>
    public class ConsumeModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 예측 엔진 LAZY
        /// </summary>
        private static Lazy<PredictionEngine<ModelInput, ModelOutput>> _predictionEngineLazy = new Lazy<PredictionEngine<ModelInput, ModelOutput>>(CreatePredictionEngine);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 예측 엔진 생성하기 - CreatePredictionEngine()

        /// <summary>
        /// 예측 엔진 생성하기
        /// </summary>
        /// <returns>예측 엔진</returns>
        public static PredictionEngine<ModelInput, ModelOutput> CreatePredictionEngine()
        {
            MLContext context = new MLContext();

            string filePath = @"WEIGHT\MLModel.zip";

            ITransformer mlModel = context.Model.Load(filePath, out var modelInputSchema);

            PredictionEngine<ModelInput, ModelOutput> predictionEngine = context.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);

            return predictionEngine;
        }

        #endregion
        #region 예측하기 - Predict(input)

        /// <summary>
        /// 예측하기
        /// </summary>
        /// <param name="input">모델 입력</param>
        /// <returns>모델 출력</returns>
        public static ModelOutput Predict(ModelInput input)
        {
            ModelOutput result = _predictionEngineLazy.Value.Predict(input);

            return result;
        }

        #endregion
    }
}

 

반응형

 

[TestProtect 프로젝트]

 

▶ ModelBuilder.cs

using Microsoft.ML;
using Microsoft.ML.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using TestLibrary;

namespace TestProject
{
    /// <summary>
    /// 모델 빌더
    /// </summary>
    public static class ModelBuilder
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 훈련 데이터 파일 경로
        /// </summary>
        private static string TRAINING_DATA_FILE_PATH = @"DATA\taxi-fare-train.csv";

        /// <summary>
        /// 가중치 모델 파일 경로
        /// </summary>
        private static string WEIGHT_MODEL_FILE_PATH = @"WEIGHT\MLModel.zip";

        /// <summary>
        /// ML 컨텍스트
        /// </summary>
        private static MLContext _mlContext = new MLContext(seed : 1);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 모델 생성하기 - CreateModel()

        /// <summary>
        /// 모델 생성하기
        /// </summary>
        public static void CreateModel()
        {
            IDataView trainingDataView = _mlContext.Data.LoadFromTextFile<ModelInput>
            (
                path          : TRAINING_DATA_FILE_PATH,
                hasHeader     : true,
                separatorChar : ',',
                allowQuoting  : true,
                allowSparse   : false
            );

            IEstimator<ITransformer> trainingPipeline = BuildTrainingPipeline(_mlContext);

            ITransformer mlModel = TrainModel(_mlContext, trainingDataView, trainingPipeline);

            Evaluate(_mlContext, trainingDataView, trainingPipeline);

            SaveModel(_mlContext, mlModel, WEIGHT_MODEL_FILE_PATH, trainingDataView.Schema);
        }

        #endregion
        #region 훈련 파이프라인 만들기 - BuildTrainingPipeline(mlContext)

        /// <summary>
        /// 훈련 파이프라인 만들기
        /// </summary>
        /// <param name="mlContext">ML 컨텍스트</param>
        /// <returns>훈련 파이프라인</returns>
        public static IEstimator<ITransformer> BuildTrainingPipeline(MLContext mlContext)
        {
            var dataProcessPipeline = mlContext.Transforms.Categorical.OneHotEncoding
            (
                new[]
                {
                    new InputOutputColumnPair("vendor_id"   , "vendor_id"   ),
                    new InputOutputColumnPair("payment_type", "payment_type")
                }
            )
            .Append
            (
                mlContext.Transforms.Concatenate
                (
                    "Features",
                    new[] { "vendor_id", "payment_type", "rate_code", "passenger_count", "trip_distance" }
                )
            );

            var trainer = mlContext.Regression.Trainers.LightGbm(labelColumnName : "fare_amount", featureColumnName : "Features");

            var trainingPipeline = dataProcessPipeline.Append(trainer);

            return trainingPipeline;
        }

        #endregion
        #region 모델 훈련하기 - TrainModel(mlContext, trainingDataView, trainingPipeline)

        /// <summary>
        /// 모델 훈련하기
        /// </summary>
        /// <param name="mlContext">ML 컨텍스트</param>
        /// <param name="trainingDataView">훈련 데이터 뷰</param>
        /// <param name="trainingPipeline">훈련 파이프라인</param>
        /// <returns>모델</returns>
        public static ITransformer TrainModel(MLContext mlContext, IDataView trainingDataView, IEstimator<ITransformer> trainingPipeline)
        {
            Console.WriteLine("모델 훈련을 시작합니다.");

            ITransformer model = trainingPipeline.Fit(trainingDataView);

            Console.WriteLine("훈련 프로세스를 종료합니다.");

            return model;
        }

        #endregion

        #region 회귀 메트릭 출력하기 - PrintRegressionMetrics(metrics)

        /// <summary>
        /// 회귀 메트릭 출력하기
        /// </summary>
        /// <param name="metrics">메트릭</param>
        public static void PrintRegressionMetrics(RegressionMetrics metrics)
        {
            Console.WriteLine($"회귀 모델 메트릭");
            Console.WriteLine($"    LossFn        : {metrics.LossFunction        :0.##}");
            Console.WriteLine($"    R2 Score      : {metrics.RSquared            :0.##}");
            Console.WriteLine($"    Absolute loss : {metrics.MeanAbsoluteError   :#.##}");
            Console.WriteLine($"    Squared loss  : {metrics.MeanSquaredError    :#.##}");
            Console.WriteLine($"    RMS loss      : {metrics.RootMeanSquaredError:#.##}");
        }

        #endregion
        #region 회귀 폴드 평균 메트릭 출력하기 - PrintRegressionFoldsAverageMetrics(crossValidationResults)

        /// <summary>
        /// 회귀 폴드 평균 메트릭 출력하기
        /// </summary>
        /// <param name="crossValidationResults">교차 검증 결과</param>
        public static void PrintRegressionFoldsAverageMetrics(IEnumerable<TrainCatalogBase.CrossValidationResult<RegressionMetrics>> crossValidationResults)
        {
            IEnumerable<double> l1LossEnumerable       = crossValidationResults.Select(r => r.Metrics.MeanAbsoluteError   );
            IEnumerable<double> l2LossEnumerable       = crossValidationResults.Select(r => r.Metrics.MeanSquaredError    );
            IEnumerable<double> rmsEnumerable          = crossValidationResults.Select(r => r.Metrics.RootMeanSquaredError);
            IEnumerable<double> lossFunctionEnumerable = crossValidationResults.Select(r => r.Metrics.LossFunction        );
            IEnumerable<double> rSquaredEnumerable     = crossValidationResults.Select(r => r.Metrics.RSquared            );

            Console.WriteLine($"회귀 모델 메트릭");
            Console.WriteLine($" 평균 L1 Loss       : {l1LossEnumerable.Average()      :0.###}");
            Console.WriteLine($" 평균 L2 Loss       : {l2LossEnumerable.Average()      :0.###}");
            Console.WriteLine($" 평균 RMS           : {rmsEnumerable.Average()         :0.###}");
            Console.WriteLine($" 평균 Loss Function : {lossFunctionEnumerable.Average():0.###}");
            Console.WriteLine($" 평균 R-squared     : {rSquaredEnumerable.Average()    :0.###}");
        }

        #endregion
        #region 절대 경로 구하기 - GetAbsolutePath(relativePath)

        /// <summary>
        /// 절대 경로 구하기
        /// </summary>
        /// <param name="relativePath">상대 경로</param>
        /// <returns>절대 경로</returns>
        public static string GetAbsolutePath(string relativePath)
        {
            FileInfo fileInfo = new FileInfo(typeof(Program).Assembly.Location);

            string assemblyFolderPath = fileInfo.Directory.FullName;

            string fullPath = Path.Combine(assemblyFolderPath, relativePath);

            return fullPath;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 평가하기 - Evaluate(mlContext, trainingDataView, trainingPipeline)

        /// <summary>
        /// 평가하기
        /// </summary>
        /// <param name="mlContext">ML 컨텍스트</param>
        /// <param name="trainingDataView">훈련 데이터 뷰</param>
        /// <param name="trainingPipeline">훈련 파이프라인</param>
        private static void Evaluate(MLContext mlContext, IDataView trainingDataView, IEstimator<ITransformer> trainingPipeline)
        {
            Console.WriteLine("모델 정확도 메트릭을 구하기 위한 교차 검증");

            var crossValidationResults = mlContext.Regression.CrossValidate
            (
                trainingDataView,
                trainingPipeline,
                numberOfFolds   : 5,
                labelColumnName : "fare_amount"
            );

            PrintRegressionFoldsAverageMetrics(crossValidationResults);
        }

        #endregion
        #region 모델 저장하기 - SaveModel(mlContext, mlModel, modelRelativePath, modelInputSchema)

        /// <summary>
        /// 모델 저장하기
        /// </summary>
        /// <param name="mlContext">ML 컨텍스트</param>
        /// <param name="mlModel">ML 모델</param>
        /// <param name="modelRelativePath">모델 상대 경로</param>
        /// <param name="modelInputSchema">모델 입력 스키마</param>
        private static void SaveModel(MLContext mlContext, ITransformer mlModel, string modelRelativePath, DataViewSchema modelInputSchema)
        {
            Console.WriteLine("모델 저장");

            mlContext.Model.Save(mlModel, modelInputSchema, GetAbsolutePath(modelRelativePath));

            Console.WriteLine($"모델을 저장했습니다 : {GetAbsolutePath(modelRelativePath)}");
        }

        #endregion
    }
}

 

▶ Program.cs

using System;

using TestLibrary;

namespace TestProject
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            ModelInput input = new ModelInput()
            {
                VendorID       = "CMT",
                RateCode       = 1f,
                PassengerCount = 1f,
                TripDistance   = 3.8f,
                PaymentType    = "CRD",
            };

            ModelOutput output = ConsumeModel.Predict(input);

            Console.WriteLine($"공급자 ID : {input.VendorID      }");
            Console.WriteLine($"요금 코드 : {input.RateCode      }");
            Console.WriteLine($"승객 수   : {input.PassengerCount}");
            Console.WriteLine($"이동 거리 : {input.TripDistance  }");
            Console.WriteLine($"지불 타입 : {input.PaymentType   }");
            Console.WriteLine();
            Console.WriteLine($"예측 운임 : {output.Score        }");

            Console.ReadKey(true);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요