728x90
반응형
728x170
[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
반응형
그리드형(광고전용)
'C# > ML.NET' 카테고리의 다른 글
[C#/ML.NET] k-평균 클러스터링(k-means clustering) 사용하기 (0) | 2022.05.27 |
---|---|
[C#/ML.NET] 누겟 설치 : Microsoft.ML.DataView (0) | 2022.05.27 |
[C#/ML.NET] 누겟 설치 : Microsoft.ML.CpuMath (0) | 2022.05.27 |
[C#/ML.NET] 누겟 설치 : Microsoft.ML (0) | 2022.05.27 |
[C#/ML.NET/.NET5] ONNX와 YOLOv5를 사용해 이미지 객체 인식하기 (0) | 2021.09.26 |
[C#/ML.NET] 다중 클래스 분류 모델 사용하기 (0) | 2019.06.27 |
[C#/ML.NET] 이진 클래스 분류 모델 사용하기 (0) | 2019.06.27 |
[C#/ML.NET] 선형 회귀 모델 사용하기 (0) | 2019.06.26 |
댓글을 달아 주세요