* 특이사항으로는 프로그래밍 실습 페이지가 들어가지지 않는다. 참고하길 바란다.
표현
머신러닝 모델은 입력 예를 직접적으로 보거나 듣거나 감지할 수 없습니다. 대신 데이터의 표현을 만들어 모델이 데이터의 핵심적인 특징을 들여다 볼 수 있는 유용한 관측 지점을 제공해야 합니다. 즉, 모델을 학습시키려면 데이터를 가장 잘 표현하는 특성 세트를 선택해야 합니다.
원시 데이터를 특성으로 변환
원리는 왼쪽에 있는 벡터의 각 요소를 오른쪽에 있는 특성 벡터의 하나 이상의 필드로 매핑하는 것입니다.
만약 'Main Street' 처럼 문자열이 있다면?
- 사전으로 각 거리 이름을 {0, ...,V-1} 범위의 정수에 매핑
- 이제 위의 원-핫 벡터를 <i>로 표현
좋은 특성의 조건
- 특성 값은 데이터 세트에서 너무 적지 않은 일정 횟수 이상 0이 아닌 값으로 나타나야 합니다.
❌ my_device_id:8SK982ZZ1242Z
✅ device_model:galaxy_s6
- 특성은 명확하고 알기 쉬운 의미를 가져야 합니다.
✅ user_age:23
❌ user_age:123456789
- 특성은 '특수' 값을 포함해서는 안 됩니다.
- is_watch_time_defined와 같은 추가적인 부울 특성을 대신 사용하세요.
❌ watch_time: -1.0
✅ watch_time: 1.023
✅ watch_time_is_defined: 1.0
- 특성의 정의는 시간이 지나도 변하지 않아야 합니다.
- 다른 ML 시스템에 종속되지 않도록 주의하세요.
✅ city_id:"br/sao_paulo"
❌ inferred_city_cluster_id:219
- 분포에 극단적인 이상점이 포함되지 않아야 합니다.
모든 특성을 (-1, 1), (0, 5)와 같은 유사한 범위로 변환하는 것이 가장 좋습니다.
비닝 기법
- 각각 새로운 고유 특성에 매핑되는 몇 개의 부울 빈을 만듭니다.
- 모델에서 각 빈에 서로 다른 값을 적용하도록 합니다.
좋은 습관
철저한 데이터 파악
- 시각화: 출현 빈도 순으로 히스토그램을 그립니다.
- 디버그: 중복된 예가 있나요? 누락된 값이 있나요? 이상점이 있나요? 데이터가 대시보드와 일치하나요? 학습 데이터와 검증 데이터가 서로 비슷한가요?
- 모니터링: 특성 분위 및 시간에 따른 예의 수
표현: 특성 추출
기존의 프로그래밍에서는 코드에 중점을 두었습니다. 머신러닝 프로젝트에서는 표현에 중점을 둡니다. 즉, 개발자는 특성을 추가하고 개선하여 모델을 다듬어 나갑니다.
원시 데이터를 특성에 매핑
그림 1의 왼쪽 부분은 입력 데이터 소스의 원시 데이터이고 오른쪽 부분은 특성 벡터, 즉 데이터 세트의 예로 구성된 부동 소수점 값의 집합입니다. 특성 추출이란 원시 데이터를 특성 벡터로 변환하는 과정입니다. 특성 추출에는 일반적으로 상당한 시간이 소요됩니다.
여러 머신러닝 모델은 특성 값에 모델 가중치를 곱해야 하므로 실수 벡터로 가중치를 표현해야 합니다.
그림 1. 특성 추출을 통해 원시 데이터를 ML 특성에 매핑
숫자 값 매핑
정수와 부동 소수점 데이터에는 숫자 가중치를 곱할 수 있으므로 특수한 인코딩은 필요하지 않습니다. 그림 2에서 제시하는 것처럼 원시 정수 값 6을 특성 값 6.0으로 변환하는 것은 큰 의미가 없습니다.
그림 2. 정수 값을 부동 소수점 값에 매핑
범주 값 매핑
범주형 특성은 가능한 값의 이산 집합을 갖습니다. 예를 들면 다음과 같은 옵션을 포함하는 street_name이라는 특성이 있을 수 있습니다.
{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}
모델은 학습된 가중치로 문자열을 곱할 수 없으므로 특성 추출을 통해 문자열을 숫자값으로 변환합니다.
이는 가능한 값의 어휘로 지칭할 특성 값에서 정수로의 매핑을 정의함으로써 가능합니다. 전 세계의 모든 거리가 데이터세트에 나타나는 것은 아니므로 다른 모든 거리를 포괄적인 '기타' 범주(OOV(out-of-vocabulary) 버킷이라고도 함)로 그룹화할 수 있습니다.
이 방법을 사용하면 다음과 같이 거리 이름을 숫자로 매핑할 수 있습니다.
- Charleston Road를 0으로 매핑
- North Shoreline Boulevard를 1로 매핑
- Shorebird Way를 2로 매핑
- Rengstorff Avenue를 3으로 매핑
- 기타(OOV)를 모두 4로 매핑
하지만 이러한 색인 번호를 모델에 직접 통합하면 다음과 같은 제약으로 인해 문제가 생길 수 있습니다.
- 모든 거리에 적용되는 하나의 가중치를 학습해보겠습니다. 예를 들어 street_name에 적용되는 가중치 6을 학습하면 Charleston Road에는 여기에 0을 곱하고 North Shoreline Boulevard에는 1, Shorebird Way에는 2를 곱합니다. street_name을 특성으로 사용하여 주택 가격을 예측하는 모델이 있다고 가정해 보겠습니다. 거리 이름을 바탕으로 가격을 선형 보정할 가능성은 없으므로 평균 주택 가격을 바탕으로 거리 순서를 결정했다고 가정할 것입니다. 모델은 거리별로 적용되는 각 가중치를 유연하게 학습할 수 있어야 하며, 이러한 가중치는 다른 특성을 사용하여 추정한 가격에 더해집니다.
- street_name이 여러 값을 가지는 사례는 고려하지 않습니다. 예를 들어 두 거리가 만나는 모퉁이에 주택이 여러 채 있고 street_name 값의 정보에 포함된 색인이 하나인 경우에는 가격 정보를 인코딩할 수 없습니다.
이러한 제약조건을 모두 제거하기 위해, 대신 모델의 범주형 특성에 바이너리 벡터를 생성할 수 있습니다. 이는 다음과 같이 값을 표현합니다.
- 예시에 적용되는 값의 경우 관련 벡터 요소를 1로 설정합니다.
- 다른 요소는 모두 0으로 설정합니다.
이 벡터의 길이는 어휘에 있는 요소의 수와 같습니다. 이러한 표현은 단일 값이 1일 때 원-핫 인코딩, 여러 값이 1일 때 멀티-핫 인코딩이라고 합니다.
그림 3은 Shorebird Way라는 특정 거리의 원-핫 인코딩을 나타냅니다. Shorebird Way의 바이너리 벡터에 있는 요소의 값은 1이고 다른 모든 거리의 요소 값은 0입니다.
그림 3. 원-핫 인코딩을 통한 거리 주소 매핑
이러한 방식을 통해 모든 특성 값(예: 거리 이름)에 대한 부울 변수를 효과적으로 만들 수 있습니다. 여기에서는 집이 Shorebird Way에 있는 경우 Shorebird Way에만 해당하는 바이너리 값은 1입니다. 따라서 모델은 Shorebird Way의 가중치만 사용합니다.
이와 유사하게 집이 두 거리가 만나는 모퉁이에 위치한 경우 두 바이너리 값은 1로 설정되며 모델은 각각의 가중치를 모두 사용합니다.
★ 원-핫 인코딩은 우편번호와 같이 가중치를 바로 곱하고 싶지 않은 숫자 데이터까지 확장됩니다.
희소 표현
데이터세트에 street_name의 값으로 포함하고 싶은 거리 이름이 백만 개가 있다고 가정해 보겠습니다. 1개 또는 2개 요소만 true인 요소 백만 개의 바이너리 벡터를 명시적으로 만드는 것은 이러한 벡터를 처리할 때의 용량 및 계산 시간을 고려했을 때 매우 비효율적인 표현입니다. 이러한 상황에서 일반적인 방식은 0이 아닌 값만 저장되는 희소 표현을 사용하는 것입니다. 희소 표현에서는 위에서 설명한 것처럼 여전히 각 특성 값에 독립적인 모델 가중치가 학습됩니다.
주요 용어
표현: 좋은 특성의 조건
원시 데이터를 적절한 특성 벡터로 매핑하는 여러 가지 방법을 살펴보았지만, 아직 남은 과정이 많습니다. 지금부터는 이러한 특성 벡터 내에서 어떠한 종류의 값이 실제로 좋은 특성이 되는지 알아보겠습니다.
거의 사용되지 않는 불연속 특성 값 배제
좋은 특성 값은 데이터 세트에서 5회 이상 나타나야 합니다. 이러한 특성 값은 모델에서 라벨과의 관계를 학습하기가 쉽습니다. 즉, 동일한 이산 값을 갖는 예가 많으면 모델에서 다양한 설정으로 특성을 확인하여 라벨을 예측하는 좋은 지표인지를 판단할 수 있습니다. 예를 들어 house_type 특성은 값이 victorian인 예를 많이 포함할 수 있습니다.
✅ house_type: victorian
반대로, 특성의 값이 한 번만 나타나거나 매우 드물게 나타난다면 모델에서 해당 특성을 기반으로 예측할 수 없습니다. 예를 들어 unique_house_id는 각 값이 한 번만 사용되어 모델에서 어떠한 학습도 불가능하므로 좋은 특성이 아닙니다.
❌ unique_house_id: 8SK982ZZ1242Z
가급적 분명하고 명확한 의미 부여
프로젝트의 모든 구성원에게 각 특성은 명확하고 분명한 의미를 가져야 합니다. 예를 들어 다음은 주택의 연령을 연 단위로 나타내는 것을 바로 알아볼 수 있는 좋은 특성입니다.
✅ house_age: 27
반대로, 다음 특성 값은 특성을 만든 엔지니어 이외에 다른 사람은 알아보기 어렵습니다.
❌ house_age: 851472000
엔지니어링 측면의 실수와 관계없이 데이터의 노이즈로 인해 값이 불명확해지는 경우도 있습니다. 예를 들어 다음의 user_age는 적절한 값을 확인하지 않은 소스에서 비롯된 것입니다.
❌ user_age: 277
'특수' 값을 실제 데이터와 혼용하지 말 것
좋은 부동 소수점 특성은 특이한 범위 외 불연속성 또는 '특수' 값을 포함하지 않습니다. 예를 들어 어떤 특성이 0~1 범위의 부동 소수점 값을 갖는다고 가정해 보겠습니다. 따라서 다음과 같은 값은 문제가 없습니다.
✅ quality_rating: 0.82 quality_rating: 0.37
그러나 사용자가 quality_rating을 입력하지 않은 경우 데이터 세트에서 다음과 같은 특수 값으로 데이터가 없음을 표현했을 수 있습니다.
❌ quality_rating: -1
특수 값이 나타나지 않게 하려면 특성을 다음과 같은 두 특성으로 변환하세요.
- 특성 하나는 특수 값 없이 오로지 품질 등급만 갖습니다.
- 특성 하나는 quality_rating이 입력되었는지 여부를 나타내는 부울 값을 갖습니다. 이 부울 특성에 is_quality_rating_defined와 같은 이름을 지정합니다.
업스트림 불안정성 고려
특성의 정의는 시간이 지나도 변하지 않아야 합니다. 예를 들어 도시의 이름은 일반적으로 바뀌지 않으므로 다음 값은 유용합니다. 단, 'br/sao_paulo'와 같은 문자열을 원-핫 벡터로 변환할 필요는 있습니다.
✅ city_id: "br/sao_paulo"
그러나 다른 모델에서 추론한 값을 수집할 때는 또 다른 문제점이 있습니다. '219'라는 값이 현재 상파울루를 나타내고 있더라도, 다른 모델을 이후에 실행할 때는 이 표현이 변경될 수도 있습니다.
❌ inferred_city_cluster: "219"
표현: 데이터 정제
한 그루의 사과나무에서는 좋은 사과와 벌레 먹은 사과가 같이 열립니다. 그러나 과일 가게에서 판매하는 과일들은 모두 최고의 품질을 자랑합니다. 유통 과정 중간에서 누군가가 심혈을 기울여 불량한 과일을 솎아내고 약간 흠집이 있는 과일을 깨끗이 손질한 것입니다. ML 엔지니어 역시 불량한 예를 솎아내고 약간 문제가 있는 예를 깨끗이 손질하는 데 막대한 노력을 기울입니다. '나쁜 사과' 몇 개가 거대한 데이터 세트를 망칠 수 있습니다.
특성 값 조정
조정이란 부동 소수점 특성 값을 100~900 등의 자연 범위에서 0~1 또는 -1~+1 등의 표준 범위로 변환하는 작업입니다. 특성 세트가 단일 특성으로만 구성된 경우 조정에 따르는 실질적인 이점은 거의 없습니다. 그러나 특성 세트가 여러 특성으로 구성되었다면 특성 조정으로 다음과 같은 이점을 누릴 수 있습니다.
- 경사하강법이 더 빠르게 수렴됩니다.
- 'NaN 트랩'이 방지됩니다. NaN 트랩이란 모델의 숫자 중 하나가 NaN(예: 학습 중에 값이 부동 소수점 정밀도 한도를 초과하는 경우)이 된 후 수학 연산 과정에서 모델의 다른 모든 숫자가 결국 NaN이 되는 상황입니다.
- 모델이 각 특성의 적절한 가중치를 익히는 데 도움이 됩니다. 특성 조정을 수행하지 않으면 모델에서 범위가 더 넓은 특성을 과도하게 중시합니다.
모든 부동 소수점 특성에 동일한 척도를 부여할 필요는 없습니다. 특성 A는 -1~+1로, 특성 B는 -3~+3으로 조정해도 심각한 부작용은 없습니다. 그러나 특성 B를 5000~100000으로 조정하면 모델이 부정적으로 반응할 것입니다.
숫자 데이터를 조정하는 알기 쉬운 방법 중 하나는 [최소값, 최대값]을 [-1, +1] 등의 작은 척도로 선형 매핑하는 것입니다.
각 값의 Z 점수를 계산하는 조정 방식도 널리 사용됩니다. Z 점수는 표준편차를 기준으로 평균에서 벗어난 정도를 계산합니다. 다시 말하면 다음과 같습니다.
$$ scaledvalue=(value−mean)/stddev. $$
아래와 같은 예를 들어 보겠습니다.
- 평균 = 100
- 표준편차 = 20
- 원래 값 = 130
결과는 다음과 같습니다.
\( scaled_value = (130 - 100) / 20 \)
\( scaled_value = 1.5 \)
Z 점수로 조정하면 대부분의 조정 값이 -3~+3 범위에 놓이지만, 이 범위보다 약간 높거나 낮은 값도 다소 존재하게 됩니다.
극단적 이상점 처리
다음은 캘리포니아 주택 데이터 세트에서 얻은 roomsPerPerson이라는 특성을 나타낸 플롯입니다. roomsPerPerson 값은 지역의 전체 방 수를 해당 지역의 인구로 나누어 계산합니다. 플롯을 보면 캘리포니아의 대부분 지역은 1인당 1~2개의 방을 갖추고 있습니다. 그러나 x축을 한번 살펴보시기 바랍니다.
그림 4. 매우 긴 꼬리
이러한 극단적 이상점이 주는 영향을 최소화하려면 어떻게 해야 할까요? 모든 값의 로그를 취하는 방법이 있습니다.
그림 5. 로그 조정을 거쳐도 꼬리가 남아 있음
로그 조정을 거치면 상황이 다소 개선되지만, 이상점 값의 꼬리가 아직도 상당히 남아 있습니다. 다른 접근법을 시도해 보겠습니다. roomsPerPerson의 최대값을 4.0 같은 임의의 지점에서 잘라내어 제한을 두면 어떻게 될까요?
그림 6. 4.0에서 특성 값 잘라내기
특성 값을 4.0에서 잘라낸다는 말은 4.0보다 큰 값을 모두 무시한다는 의미가 아니라, 4.0보다 큰 값을 모두 4.0으로 인식하겠다는 의미입니다. 따라서 4.0 지점에 부자연스러운 경사가 생깁니다. 하지만 조정된 특성 세트는 원래 데이터보다 훨씬 유용해진 상태입니다.
비닝
다음은 캘리포니아의 위도에 따른 상대적인 주택 분포를 보여주는 플롯입니다. 클러스터링을 잘 살펴보세요. 로스앤젤레스의 위도는 약 34도이고 샌프란시스코의 위도는 약 38도입니다.
그림 7. 위도별 주택 수
데이터 세트에서 latitude는 부동 소수점 값입니다. 그러나 이 모델에서 latitude를 부동 소수점 특성으로 표현할 수는 없는데, 이는 위도와 주택 값 사이에 선형적 관계가 없기 때문입니다. 예를 들어 위도 35도에 위치한 주택이 위도 34도에 위치한 주택보다 35/34만큼 싸거나 비싸지는 않습니다. 그러나 각각의 위도 값은 주택 가격을 예측하는 좋은 지표일 가능성이 높습니다.
위도를 유용한 예측 지표로 사용하기 위해 다음 그림과 같이 위도를 여러 '빈(bin)'으로 나누어 보겠습니다.
그림 8. 값 비닝
이제 부동 소수점 특성 하나가 아니라 11개의 개별 부울 특성(LatitudeBin1, LatitudeBin2, ..., LatitudeBin11)이 생겼습니다. 11개의 개별 특성은 다소 번잡하므로 하나의 11원소 벡터로 통일하겠습니다. 이렇게 하면 위도 37.4도를 다음과 같이 표현할 수 있습니다.
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
비닝을 사용하면 모델에서 각 위도에 대해 완전히 다른 가중치를 익힐 수 있습니다.
비닝 경계에 대해 자세히 알아보려면 여기를 클릭하세요.
위도 예제에서는 이해하기 쉽도록 빈 경계로 정수를 사용했습니다. 해상도를 더 높여야 한다면 빈 경계를 1/10도 간격으로 나눌 수도 있습니다. 빈을 더 추가하면 모델에서 위도 37.4도와 37.5도에 대해 서로 다른 동작을 익힐 수 있지만, 1/10도 간격으로 충분한 수의 예가 확보되어야 한다는 전제가 붙습니다.
분위를 기준으로 빈을 나누는 방법도 있는데, 이렇게 하면 각 버킷에 같은 개수의 예가 포함됩니다. 분위별 비닝을 사용하면 이상점에 대해 전혀 신경쓸 필요가 없습니다.
스크러빙
지금까지는 학습 및 테스트에 사용되는 모든 데이터를 신뢰할 수 있다고 가정했습니다. 그러나 실무에서는 다음과 같은 이유로 데이터 세트의 여러 예를 신뢰할 수 없습니다.
- 값 누락. 예를 들어 사용자가 주택의 연령을 실수로 입력하지 않았을 수 있습니다.
- 중복 예. 예를 들어 서버에서 같은 로그를 실수로 두 번 업로드했을 수 있습니다.
- 잘못된 라벨. 예를 들어 사용자가 참나무 사진에 실수로 단풍나무 라벨을 지정했을 수 있습니다.
- 잘못된 특성 값. 예를 들어 사용자가 숫자를 실수로 입력했거나 온도계를 햇빛에 두었을 수 있습니다.
잘못된 예가 발견되면 일반적으로 데이터 세트에서 삭제하여 해당 예를 '수정'합니다. 값 누락이나 중복 예를 탐지하고자 간단한 프로그램을 작성할 수 있습니다. 잘못된 특성 값 또는 라벨을 탐지하기는 훨씬 더 까다로울 수 있습니다.
잘못된 개별 예를 탐지하는 것 외에 집계에서도 잘못된 데이터를 탐지해야 합니다. 히스토그램은 집계 데이터를 시각화하는 유용한 메커니즘입니다. 또한 다음과 같은 통계를 구하면 도움이 될 수 있습니다.
- 최대 및 최소
- 평균 및 중앙값
- 표준편차
불연속 특성에서 가장 자주 나타나는 값으로 목록을 생성해 보세요. 예를 들어 country:uk가 예상한 숫자와 일치하는 예의 개수를 세어 보세요. 데이터 세트에서 language:jp를 가장 자주 나타나는 언어로 보아야 할까요?
철저한 데이터 파악
다음과 같은 규칙을 따르세요.
- 정상적인 데이터가 어떠한 모습이어야 하는지 항상 생각하세요.
- 데이터가 이러한 예상과 일치하는지 확인하고, 그렇지 않다면 그 이유를 파악해 보세요.
- 학습 데이터가 대시보드 등의 다른 소스와 일치하는지 재차 확인하세요.
핵심적인 코드를 다룰 때와 마찬가지로 데이터에 온 정성을 쏟아야 합니다. 좋은 데이터가 좋은 ML을 만듭니다.
주요 용어
'공부 > 구글 머신러닝 단기집중과정' 카테고리의 다른 글
구글 머신러닝 단기집중과정 - ML 개념 - 정규화 : 단순성 (0) | 2021.06.21 |
---|---|
구글 머신러닝 단기집중과정 - ML 개념 - 특성 교차 (0) | 2021.06.21 |
구글 머신러닝 단기집중과정 - ML 개념 - 검증세트 (0) | 2021.06.21 |
구글 머신러닝 단기집중과정 - ML 개념 - 학습 및 테스트 세트 (0) | 2021.06.18 |
구글 머신러닝 단기집중과정 - ML 개념 - 일반화 (0) | 2021.06.18 |