다음을 통해 공유


모델 빌드를 위한 데이터 준비

ML.NET 사용하여 추가 처리 또는 모델 빌드를 위한 데이터를 준비하는 방법을 알아봅니다.

데이터는 종종 정제되지 않고 희박합니다. ML.NET 기계 학습 알고리즘은 입력 또는 기능이 단일 숫자 벡터에 있을 것으로 예상합니다. 마찬가지로, 특히 범주 데이터인 경우 예측할 값(레이블)을 인코딩해야 합니다. 따라서 데이터 준비의 목표 중 하나는 ML.NET 알고리즘에서 예상하는 형식으로 데이터를 가져오는 것입니다.

데이터를 학습 & 테스트 집합으로 분할

다음 섹션에서는 과잉 맞춤 및 언더핏이라고 하는 모델을 학습할 때 발생하는 일반적인 문제를 간략하게 설명합니다. 홀드아웃 셋을 사용하여 데이터를 분할하고 모델의 유효성을 검사하면 이러한 문제를 식별하고 완화하는 데 도움이 될 수 있습니다.

과잉 맞춤 & 과잉 맞춤

과적합과 과소적합은 모델을 훈련할 때 흔히 겪는 가장 일반적인 두 가지 문제입니다. 과소 맞춤은 선택한 트레이너가 학습 데이터 세트에 맞게 충분히 할 수 없다는 것을 의미하며 일반적으로 학습 중에 높은 손실과 테스트 데이터 세트의 낮은 점수 /메트릭을 초래합니다. 이 문제를 해결하려면 더 강력한 모델을 선택하거나 더 많은 기능 엔지니어링을 수행해야 합니다. 과적합은 모델이 학습 데이터를 너무 잘 학습할 때 발생하는 현상으로, 반대의 개념입니다. 이렇게 하면 일반적으로 학습 중에 손실 메트릭이 낮지만 테스트 데이터 세트의 손실은 높아집니다.

이러한 개념에 대한 좋은 비유는 시험을 공부하는 것입니다. 질문과 대답을 미리 알고 있다고 가정해 보겠습니다. 공부하고 나면 시험을 보고 완벽한 점수를 받는다. 좋은 소식! 그러나 질문을 다시 정렬하고 약간 다른 표현으로 다시 시험을 받으면 점수가 낮아질 수 있습니다. 즉, 답변을 기억하고 실제로 테스트 중인 개념을 배우지 않았음을 시사합니다. 이는 과잉 맞춤의 예입니다. 과소적합은 시험 대비로 주어진 학습 자료가 실제 평가에 부합하지 않는 경우를 의미합니다. 그래서 충분한 지식이 없기 때문에 정답을 맞추지 못하고 추측에 의존하게 됩니다.

데이터 분할

다음 입력 데이터를 가져와서 IDataViewdata로 호출하여 로드합니다.

var homeDataList = new HomeData[]
{
    new()
    {
        NumberOfBedrooms = 1f,
        Price = 100_000f
    },
    new()
    {
        NumberOfBedrooms = 2f,
        Price = 300_000f
    },
    new()
    {
        NumberOfBedrooms = 6f,
        Price = 600_000f
    },
    new()
    {
        NumberOfBedrooms = 3f,
        Price = 300_000f
    },
    new()
    {
        NumberOfBedrooms = 2f,
        Price = 200_000f
    }
};

데이터를 학습/테스트 집합으로 분할하려면 TrainTestSplit(IDataView, Double, String, Nullable<Int32>) 메서드를 사용합니다.

// Apply filter
TrainTestData dataSplit = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);

testFraction 매개 변수는 테스트를 위해 데이터 세트의 0.2 또는 20% 사용하는 데 사용됩니다. 나머지 80개의%는 학습에 사용됩니다.

결과는 두 개의 IDataView(TrainSetTestSet를 통해 액세스할 수 있는)로 DataOperationsCatalog.TrainTestData입니다.

데이터 필터링

경우에 따라 데이터 세트의 모든 데이터가 분석과 관련이 있는 것은 아닙니다. 관련 없는 데이터를 제거하는 방법은 필터링입니다. DataOperationsCatalog은 모든 데이터를 포함하는 IDataView을 입력으로 받아 관심 있는 데이터 요소만 포함하는 IDataView을 반환하는 필터 작업 집합을 포함합니다. 필터 작업이 TransformsCatalogIEstimator 또는 ITransformer과 같지 않기 때문에, EstimatorChain 또는 TransformerChain 데이터 준비 파이프라인의 일부로 포함할 수 없다는 점이 중요합니다.

다음 입력 데이터를 가져와서 IDataViewdata로 로드합니다.

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=600000f
    }
};

열 값에 따라 데이터를 필터링하려면 FilterRowsByColumn 메서드를 사용합니다.

// Apply filter
IDataView filteredData = mlContext.Data.FilterRowsByColumn(data, "Price", lowerBound: 200000, upperBound: 1000000);

위의 샘플은 가격이 200000에서 1000000 사이인 데이터 세트의 행을 선택합니다. 이 필터를 적용한 결과는 데이터의 마지막 두 행만 반환하고 해당 가격이 지정된 범위 사이에 있지 않고 1000000이므로 첫 번째 행을 제외합니다.

누락된 값 바꾸기

누락된 값은 데이터 세트에 일반적으로 발생합니다. 누락된 값을 처리하는 한 가지 방법은 지정된 형식에 따라 존재하는 경우 기본값으로 바꾸거나, 데이터의 평균 값 등 의미 있는 다른 값으로 대체하는 것입니다.

다음 입력 데이터를 가져와서 data이라고 불리는 IDataView에 로드합니다.

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=float.NaN
    }
};

목록의 마지막 요소에는 Price대한 누락된 값이 있습니다. Price 열에서 누락된 값을 바꾸려면 ReplaceMissingValues 메서드를 사용하여 누락된 값을 채웁니다.

중요하다

ReplaceMissingValue 숫자 데이터에서만 작동합니다.

// Define replacement estimator
var replacementEstimator = mlContext.Transforms.ReplaceMissingValues("Price", replacementMode: MissingValueReplacingEstimator.ReplacementMode.Mean);

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer replacementTransformer = replacementEstimator.Fit(data);

// Transform data
IDataView transformedData = replacementTransformer.Transform(data);

ML.NET다양한 대체 모드를 지원합니다. 위의 샘플에서는 누락된 값을 해당 열의 평균 값으로 채우는 Mean 대체 모드를 사용합니다. 대체의 결과는 100,000과 300,000의 평균값이기 때문에, 데이터의 마지막 요소에서 Price 속성을 200,000으로 채웁니다.

정규화 도구 사용

정규화 기계 학습 알고리즘에서 보다 정확하게 처리할 수 있도록 기능을 동일한 범위(일반적으로 0에서 1 사이)로 확장하는 데 사용되는 데이터 전처리 기술입니다. 예를 들어, 연령과 소득의 범위는 크게 다르며, 연령은 일반적으로 0-100 사이이고 소득은 일반적으로 0에서 수천 사이입니다. 정규화 변환의 자세한 목록 및 설명은 변환 페이지을 방문하세요.

최소-최대 정규화

다음 입력 데이터를 가져와서 data이라는 이름의 IDataView에 로드합니다.

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms = 2f,
        Price = 200000f
    },
    new ()
    {
        NumberOfBedrooms = 1f,
        Price = 100000f
    }
};

정규화는 단일 숫자 값과 벡터가 있는 열에 적용할 수 있습니다. NormalizeMinMax 메서드를 사용하여 min-max 정규화를 사용하여 Price 열의 데이터를 정규화합니다.

// Define min-max estimator
var minMaxEstimator = mlContext.Transforms.NormalizeMinMax("Price");

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer minMaxTransformer = minMaxEstimator.Fit(data);

// Transform data
IDataView transformedData = minMaxTransformer.Transform(data);

원래 가격 값 [200000,100000]은 0-1 범위의 출력 값을 생성하는 MinMax 정규화 수식을 사용하여 [ 1, 0.5 ]으로 변환됩니다.

범주화

범주화 연속 값을 입력의 불연속 표현으로 변환합니다. 예를 들어, 당신의 특성 중 하나가 나이라고 가정해 보겠습니다. 비닝은 실제 연령 값을 사용하는 대신 해당 값에 대한 범위를 만듭니다. 0-18은 하나의 범주일 수 있고, 다른 하나는 19-35 등이 될 수 있습니다.

다음 입력 데이터를 가져와서 IDataViewdata이라고 불리는 곳에 로드합니다.

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=600000f
    }
};

NormalizeBinning 메서드를 사용하여 데이터를 bin으로 정규화합니다. maximumBinCount 매개 변수를 사용하면 데이터를 분류하는 데 필요한 bin 수를 지정할 수 있습니다. 이 예제에서는 데이터가 두 개의 bin에 배치됩니다.

// Define binning estimator
var binningEstimator = mlContext.Transforms.NormalizeBinning("Price", maximumBinCount: 2);

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
var binningTransformer = binningEstimator.Fit(data);

// Transform Data
IDataView transformedData = binningTransformer.Transform(data);

범주화의 결과는 [0,200000,Infinity]bin 범위를 만듭니다. 따라서 첫 번째 관측치는 0-200000 사이이고, 다른 관측값은 200000보다 크지만 무한대보다는 작기 때문에 결과적으로 bin은 [0,1,1]입니다.

범주 데이터를 다루기

가장 일반적인 데이터 형식 중 하나는 범주 데이터입니다. 범주 데이터에는 한정된 수의 범주가 있습니다. 예를 들어 미국의 주들 또는 그림 모음에서 찾을 수 있는 동물 유형의 목록입니다. 범주 데이터가 기능이든 레이블이든 관계없이 기계 학습 모델을 생성하는 데 사용할 수 있도록 숫자 값에 매핑되어야 합니다. 해결 중인 문제에 따라 ML.NET 범주 데이터로 작업하는 여러 가지 방법이 있습니다.

키 값 매핑

ML.NET 키는 범주를 나타내는 정수 값입니다. 키 값 매핑은 학습을 위해 문자열 레이블을 고유 정수 값으로 매핑한 다음 모델이 예측을 위해 사용될 때 해당 문자열 값으로 다시 매핑하는 데 가장 자주 사용됩니다.

키 값 매핑을 수행하는 데 사용되는 변환은 MapValueToKeyMapKeyToValue입니다.

MapValueToKey 모델에 매핑 사전을 추가하여 MapKeyToValue 예측을 수행할 때 역방향 변환을 수행할 수 있도록 합니다.

핫 인코딩 1개

하나의 핫 인코딩은 한정된 값 집합을 사용하여 문자열의 고유한 위치에 단일 1 값이 있는 이진 표현의 정수에 매핑합니다. 범주 데이터의 암시적 순서가 없는 경우 핫 인코딩을 선택하는 것이 가장 좋습니다. 다음 표에서는 우편 번호를 원시 값으로 사용하는 예제를 보여 줍니다.

원시 값 핫 인코딩된 값 1개
98052 00...01
98100 00...10
... ...
98109 10...00

범주 데이터를 원 핫 인코딩된 숫자로 변환하는 변환은 OneHotEncoding.

해시

해시는 범주 데이터를 숫자로 변환하는 또 다른 방법입니다. 해시 함수는 임의의 크기(예: 텍스트 문자열)의 데이터를 고정 범위가 있는 숫자에 매핑합니다. 해시는 기능을 벡터화하는 빠르고 공간 효율적인 방법이 될 수 있습니다. 기계 학습에서 해시의 한 가지 주목할 만한 예는 전자 메일 스팸 필터링입니다. 여기서 알려진 단어의 사전을 유지하는 대신 전자 메일의 모든 단어가 해시되고 큰 기능 벡터에 추가됩니다. 이러한 방식으로 해시를 사용하면 사전에 없는 단어를 사용하여 악의적인 스팸 필터링 우회 문제를 방지할 수 있습니다.

ML.NET 해시 변환을 제공하여 텍스트, 날짜 및 숫자 데이터에 대한 해시를 수행합니다. 값 키 매핑과 마찬가지로 해시 변환의 출력은 키 형식입니다.

텍스트 데이터 작업

범주 데이터와 마찬가지로 텍스트 데이터를 기계 학습 모델을 빌드하는 데 사용하기 전에 숫자 기능으로 변환해야 합니다. 텍스트 변환에 대한 자세한 목록 및 설명을 보려면 변환 페이지 방문하세요.

IDataView에 로드된 아래의 데이터와 같은 데이터를 사용하기:

ReviewData[] reviews = new ReviewData[]
{
    new ReviewData
    {
        Description="This is a good product",
        Rating=4.7f
    },
    new ReviewData
    {
        Description="This is a bad product",
        Rating=2.3f
    }
};

ML.NET은 텍스트의 문자열 값을 사용하여 개별 변환의 일련을 적용함으로써 텍스트에서 기능 집합을 생성하는 FeaturizeText 변환을 제공합니다.

// Define text transform estimator
var textEstimator  = mlContext.Transforms.Text.FeaturizeText("Description");

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer textTransformer = textEstimator.Fit(data);

// Transform data
IDataView transformedData = textTransformer.Transform(data);

결과 변환은 Description 열의 텍스트 값을 아래 출력과 비슷한 숫자 벡터로 변환합니다.

[ 0.2041241, 0.2041241, 0.2041241, 0.4082483, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0, 0, 0, 0, 0.4472136, 0.4472136, 0.4472136, 0.4472136, 0.4472136, 0 ]

FeaturizeText를 구성하는 변환은 특징 생성에 대한 세분화된 제어를 위해 개별적으로 적용할 수도 있습니다.

// Define text transform estimator
var textEstimator = mlContext.Transforms.Text.NormalizeText("Description")
    .Append(mlContext.Transforms.Text.TokenizeIntoWords("Description"))
    .Append(mlContext.Transforms.Text.RemoveDefaultStopWords("Description"))
    .Append(mlContext.Transforms.Conversion.MapValueToKey("Description"))
    .Append(mlContext.Transforms.Text.ProduceNgrams("Description"))
    .Append(mlContext.Transforms.NormalizeLpNorm("Description"));

textEstimator FeaturizeText 메서드에서 수행하는 작업의 하위 집합을 포함합니다. 더 복잡한 파이프라인의 이점은 데이터에 적용된 변환을 제어하고 표시할 수 있다는 것입니다.

첫 번째 항목을 예로 사용하여 textEstimator정의한 변환 단계에서 생성된 결과에 대한 자세한 설명은 다음과 같습니다.

원본 텍스트: 좋은 제품

변형하다 묘사 결과
1. NormalizeText 기본적으로 모든 문자를 소문자로 변환합니다. 좋은 제품입니다.
2. TokenizeWords 문자열을 개별 단어로 분할 이것은 좋은 제품입니다.
3. 기본 불용어 제거 같은 중지 단어를 제거합니다. ["좋은", "제품"]
4. MapValueToKey (값을 키에 매핑하기) 입력 데이터를 기반으로 값을 키(범주)에 매핑합니다. [1,2]
5. ProduceNGrams 텍스트를 연속 단어 시퀀스로 변환 [1,1,1,0,0]
6. NormalizeLpNorm lp-norm을 사용하여 입력 크기 조정 [ 0.577350529, 0.577350529, 0.577350529, 0, 0 ]