페이지

2018년 3월 2일 금요일

CHAPTER 2 머신러닝의 주요 개념

머신러닝을 도입한다는 것은 단순히 프로그램에 새로운 기능을 추가하거나 좀 더 빠른 알고리즘을 도입하는 것과는 다릅니다. 머신러닝은 보유한 데이터의 성격이나 양, 품질에 따라서 결과가 달라지기 때문입니다. 머신러닝 시스템이 기계라면 데이터는 그 기계의 연료입니다. 맞지 않은 연료를 넣거나 양이 적절하지 않으면 기계가 고장나게 되지요.

머신러닝 시스템을 구축하는 과정은 탐구의 연속입니다. 보유한 데이터가 어떤 성질을 가지는지, 그 데이터에 맞는 머신러닝 기법은 무엇인지, 어떻게 해야 적합한 데이터를 얻을 수 있는지, 실제로 시스템을 구현해보니 기대했던 성능이 나오지 않는 이유는 무엇인지에 대한 해답을 찾아가는 과정입니다. 여러 기법을 시도해 보고 실패하고 수정하는 과정에서 좋은 머신러닝 시스템을 만들게 됩니다.

이런 탐구 과정에서 시행착오는 필연입니다. 머신러닝 이론을 알면 '왜'와 '어떻게'에 해당하는 문제를 좀 더 쉽고 효율적으로 진행할 수 있어 더 좋은 성능의 시스템을 구축할 수 있게 됩니다.

이 장에서 다룰 머신러닝의 4가지 햇김 개념은 다음과 같습니다.
- 모델: 데이터를 바라보는 시점과 가정
- 손실함수 : 모델의 수식화된 학습목표
- 최적화: 손실함수로 표현된 모델을 실제로 학습
- 모델 평가: 모델의 성능의 실제 상황에서 어떨지 추정

2.1 모델: 문제를 바라보는 관점
모델은 머신러닝의 시작점이라고도 할 수 있습니다. 이제부터 모델의 정의와 분류, 좋은 모델의 특징에 대해 알아보겠습니다.

2.1.1 모델이란?
데이터 분석을 하거나 머신러닝으로 문제를 해결하려면 무엇부터 해야 할까요? '데이터가 어떤 패턴을 가지지 않을 까? 그 패턴들을 이용하면 어떻게든 되지 않을까? 여러 생각이 들 겁니다. 그런데 패턴이 있기는 할까요? 사실 패턴이 있을 것이라는 생각도 어찌 보면 데이터 자체에 대한 믿음입니다. 그러한 믿음을 수학에서는 가정이라고 합니다. 이러한 여러 가정을 한데 모은 것을 머신러닝에서는 모델이라고 합니다.

쉽게 말해 현재 상태를 어떠한 시각으로 바라보고 어떠한 기대를 하고 있는가 하는 것이 모델입니다. 그러핟면 모델은 머신러닝에서 어떤 역할 을 할까요? 일반적으로 머신러닝의 과정은 다음과 같습니다.

모델 정하기-> 모델 수식화하기-> 모델 학습하기-> 모델 평가하기 -> 모델 정하기-> 모델 ...

1. 모델정하기(데이터가 어떻게 생겼을지 가정하기)
2. 모델의 학습 목표를 수식화 하기
3. 실제 데이터로 모델 학습하기(최적화)
4. 평가하기

그런데 과정1에서 데이터가 어떻게 생겼을지 이미 가정을 해 놓고 왜 또 과정 3에서 실제 데이터 학습이 필요할 까요?

예를 들어 과정 1의 가정이 다음과 같다고 합시다.
"이 데이터에서 x  와 y는 선형적인 상관관계를 가진다. 즉, 임의의 w 에 대해 y=wx 와 같은 관곌르 가질 것이다."

그렇다면 과정 3의 가정은 다음과 같을 수 있습니다.

"데이터 토대로 추측해본 결과 y = 2x와 같은 형태를 가진다. 즉, 데이터에 가장 잘 맞는 w 는 2다."

모델이란 가정에 따라 생성될 수 있는 함수들의 집합입니다. 이런 의미에서 보면 '모델이 바뀐다'는 것은 어떤 함수의 꼴이 완전히 달라진다는 겁니다. 정해진 함수(위에서는   y=wx) 안에서 함수의 파라미터(여기서는 w)를 데이터를 통해 추측하는 것을 학습이라고합니다. 머신러닝의 러닝의 바로 학습을 뜻합니다. 그리고 학습이라는 것은 그 모델이 표현하는 함수 집합 중에서 가장 데이터에 적합한 함수를 고르는 과정입니다.

1. 모델은 데이터를 어떻게 바라볼지에 대한 가정(통계학 용어로는 믿음(belief)이라고 함) 입니다.
2. 모델은 머신러닝의 시작점입니다.

2.1.2 간단한 모델

모델이 '가단하다'는 말은 '데이터의 구조가 간단하다'는 뜻입니다. 이는 '괸장이 강렭한 가정'을 한다고 해석할 수 있습니다.

가장 간단하지만 아주 효과적인 모델로 선형 모델이있습니다. 선형 회귀라는 말을 아마 많이 들어보았을 겁니다. 선형 휘귀는 대표적인 선형 모델입니다. 예측할 결괏값을 y라고 예측에 사용하는 값을 x1, x2, x3,...라 합시다.
선형 회귀, 데이터(x)로 학습된 모델(쩜선), 수식은  y -= 5 + 0.4x

선형 휘귀 정의는 다음과 같습니다.

- 수식: y = w0 + w1x1 + w2x2  +w3x3 + w4x4 ....
-  출력값(y)이 입력값(피처)(x1, x2, x3, ...)에 대새 선형적인 관계

선형 관계는 출력값이 입력값(피처값)들에 가중치를 곱한 값의 합(선형 결합)으로 표현되는 관계입니다. 한 가지 속성( x1)이 1만큼 증가하면 결괏값은 w1만큼 증가합니다. 감소하는 경우에는 w1만큼 감소합니다. 이러한 선형적인 관계는 많은 곳에서 찾을 수 있습니다. 옐르 들어 제품의생산량(x)과 불량품수(y)를 들 수 있습니다. 생산량과 불량품 수는 일반적으로 양의 상관관계인 경우가 많으므로선형 회귀 모델이 아주 적합합니다.

이러헌 선형 회귀 예시와 같이, 간단한 모델은 이해하기가 쉽다는 장점이 있습니다. 또한 간단한 모델은 일반적으로 데이터를 간단하게 설명하려 하기 때문에 가정 자체에 제약이 많고 데이터의변화에 비해 모델 자체의 변화폭(분산)이 적습니다. 모델 자체의 변화폭이 적으므로 예외 데이터가 들어와도 여향을 적게 받기 때문에 신경을 써야 할 부분이 적습니다.

간단함 모델의 단잠은 무엇일까요? 간단한 모델은 복잡한 관계를 학습할 수 없습니다. 입출력 데이터의 관계가 단순한 선형 관계가 아니면 어떻게 될까요? 예를 들어 w0x1/(w1+x1) 같은 관계 말이죠. 당연히 간단함 도델로 복잡한 데이터를 제대로 표현하지 못할 겁니다.

'간단한 모델'은 다음과 같이 간단히 정리할 수 있습니다.
- 데이터가 복잡하지 않고 간단하게 생겼다고 가정합니다.
- 결과를 이해하기 쉽습니다.
- 학습이 쉽습니다.
- 가정 자체가 강력해서 모델의 표현 능력에 제약이 많습니다.

2.1.3 복잡한 모델
복잡한 도델은 모델의 유연성을 더 중요시합니다. 예를 들어 결정 트리 모델을 들 수 있습니다.
- 트리의 한 분기점마다 한 가지 조건(보통 입력의 한 부분)을 검사하여 분기를 합니다.
- 모든 분기가 끝나는 리프노드(맨 끝의 노드)에는 결괏값이 들어 있습니다.

결정트리는 선형 모델과 달리 복수의 비교식으로 정의됩니다. 그리고 이 비교식은 무수히 늘어 날 수 있기 때문에 더 일반적이고 유현한 가정을 할 수 있습니다. 예를 들어 앞서 설명한 선형 모델도 결정 트리로 구현할 수 있습니다. 각 분기점마드 모든 값에 대한 결과를 작성해서 결과를 저장하면 되나까요. 복잡한 모델은 간단한 모델에 비해 전체 데이터에 일괄적인 가정이 적습니다. 예를 들어 결정 트리는 데이터 전체에 대한 가정이 거의없다시피 합니다. 그렇다면 왜 모든 걸 포함할 수 있는 복잡한 모델을 사용하지 않고 간단한 모델을 사용하는 걸까요? 2.1.5절 '좋은 모델이란 무엇인가?'에서 설명합니다.

복잡한 모델의 가장 큰 장점은 복잡한 데이터의 모델링에 적합하다는 겁니다. 결정 트리처럼 유연성이 뛰어난 모델은 많은 종류의 데이터를 모델링할 수 있습니다. 하지만 데이터의 모든 부분에 대해 일일이 가정을 만듦으로써 불필요한 노이즈까지 학습하여 성능이 나빠질 수 있습니다.

'복잡한 모델'은 다음과 같이 간단히 정리 할 수 있습니다.
- 데이터가 어떻게(간단하거나 복잡하게)생격ㅆ을 것이라는 가정 자체가 별로 없습니다.
- 결과를 이해하기 어려울 수도 있습니다.
- 학습이 복잡합니다.
- 한정된 데이터에서만의 변화를 그대로 학습하므로 새로운 데이터에 대해 성능이 떨어질 수 있습니다.

2.1.4 구조가 있는 모델
모델의 복잡도는 모델을 구분하는데 중요한 기준이지만, 몇 가지 특정 상황에서 요긴하게 쓰이는 모델이 있어서 따로 다룹니다. 바로 '구조 가 있는 모델'인데요, 단순히 입력과 출력의 상관관계를 학습할 뿐만 아니라 데이터 구조 자체를 모델링하는 조금 특이한 모델입니다. 앞서 말한 간단한 모델이나 복잡한 모델 어느 항목에도 속할 수 있다는 점에 유의해주세요.

구조가 있다는 말이 조금 생소하게 들릴 수도 있을 겁니다. 이는 입력과 출력 요서가 서로 연관관계가 있는 것으로 이해하면 됩니다. 구조가 있는 모델은 다양하지만, 이 절에서는 유명한 순차 모델과 그래프 모델에 대해 다루겠습니다.

2.1.4.1 순차 모델
순차 모델은 연속된 관측값이 서로 연관성이 있을 때 주로 사용합니다. 문서의 텍스트, 시간과관계된 데이터 분석을 예로 들 수 있습니다. 순차 모델의 대표적인 예로 문장 구조 분석에서 많이 사용하는  CRF(conditional random field)(조건부 랜덤 필드, 조건부 무작위장)와 RNN(recurrent neural net)(순환 신경망, 재귀 신경망)이 있습니다. 이들 모델의 가장 큰 특징은 특정 시점에서 상태를 저장하고, 상태가 각 시점의 입력과 출력에 따라 변화한다는 점입니다.

RNN은 여러 가지 변형 형태가 있지만 기본적인 정의는 다음과 같습니다.

- 수식:  h1 = w0 + w1ht-1 + w2.xt
- 실재로 관측되지는 않았지만 특정 시점에 어떤 상태(ht)가 존재한다고 가정합니다.
- 현재의상태(ht)는 바로 직전의 상태(ht-1)와 현재의 입력 데이터(xt)에 영향을 받습니다.
- 상태(ht)에 따라 출력(yt)이 결정됩니다.

RNN과 같은 순차 모델은 숨겨진 상탯값을 가정하고 이를 이용해서 순차적인 의존성을 표현합니다. 이 순차적인 의존성을 가지는 상탯값이 다른 모델과의 가장 큰 차이점입니다. 물론 상태 (h)를 가지지 않는 모델도 현재 시점의 입력(xt)과 이전 시점의 입력(xt-1)을 합쳐서 비슷한 효괄르 낼 수 있지만, 모든 시점의 입력을 이용하기에는 계산의 한걔로 넓은 범위의 의존성을 나타내기 어렵습니다.

2.1.4.2 그패프 모델
그래프 모델은 그래프를 이용해서 순차 모델보다 좀 더 복잡한 구조를 모델링합니다. 예를 들어 문서의 문법 구조(보통 트리 형태)를 직접 모델링하거나 이미지의 픽셀 사이의 관계를 네트워크로 보고 그래프로 표현하여 모델링 합니다. 대표적인 예로 마르코프 랜덤 필드(MRF)를 살펴보겠습니다.
- 데이터의 숨겨진 상태(h) 사이에 어떤 연결 구조가 있다고 가정한 후, 연결된 위치의 숨겨진 상태끼리는 연관성이 있다고 가정합니다.
- 보통 사진을 처리할 때 많이 사용하는데, 이런 경우에는 사진의 특정 위치의 상태(h)가 바로 근접한 위치의 상태들과 관계가 있다고 가정합니다.
- 그리고 실제로 관측된 값(x)은 상태에 따라 결정된다고 가정합니다.

임의의 그래프 구조를 사용하면 순차 모델보다 더 복잡한 관계를 표현할 수 있습니다.

2.1.5 좋은 모델이란 무엇인가?
좋은 모델이란 쉽게 생각하면 '데이터의 패턴을 잘 학습한 모델'이라고 할 수 있습니다. 모델을 평가하는 이론이 많이 존재하지만, 이 책에서는 그중 모델의 복잡도와 표현력에 대한 균형을 다루는 편향-분산 트레이드오프와 균형을 자동으로 학습하는게 하는 정규화에 대해 알아 보겠습니다.

2.1.5.1 편향-분산 트레이드오프
앞에서 우리는 간단한 모델과 복잡한 모델의 특징에 대해 이미 살펴봣습니다. 그런데 모델의 표현력과 가정 강도와의 관계는 생각보다 더 오표합니다. 어떤 모델을 데이터 x로 학습한 결과를 f(x)라 하고 가능한 모든 모델 중에서 가장 좋은 모델을 f, 원하는 출력값(정답)을 y라 할 때 가장 기본적인 에러인 평균 제곱근 에러는 다음과 같은 성질을 만족합니다.

1번 식은 모델이 데이터를 예측할 때 생기는 오류가 편향(bias)의 제곱과 분산(variance)으로 쪼개진 다는 것을 보여줍니다. 즉, 모델이 더 나은 성능을 내려면 편향을 줄이거나 분산을 줄여야 한다는 뜻입니다.

2번 식(분산)은 데이터로 학습한 결과와 이상적인 모델 간의 차이입니다. 데이터로 학습한 결과가 모델의 표현력이 부족해서 이상적인 모델과 많은 차이를 보인다면 값이 커지게 됩니다. 간단한 모델일수록 가정이 강합니다. 따라서 표현력이 부족하므로 편향이 크게 나타납니다. 물론 약한 가정을 하는 복잡한 모델이라 할지라도 데이터와 터무니없이 맞지 않으면 편향이 강하게 나타날 수 있습니다.

3번 식(분산)은 데이터를 이용해서 얻은 모델이 학습할 때마다 얼마나 달라질 수 있는지 나타냅니다. 일반적으로 모델이 복잡할 수록 학습할 때마다 나타나는 모델 편차가 큽니다. 즉, 모델이 복잡할수록 분산이 더 크게 나타납니다.

그렇다면 모델의 성능을 극대화하려면 어떤 모델을 골라야 할까요? 편향이 너무 크지 않아 적당히 유연하면서 너무 복잡하지 않아 분산이 작게 나오는 모델이 적합할 겁니다. 즉, 표현력이 크다고 항상 좋은 것이 아니며 그렇다고 항상 단순한 모델만 이용해서는 제대로 된 결과를 얻지 못한다는 뜻입니다.

편향이나 분산을 직접적으로 줄이는 대표적인 예로 다음과 같은 방법을 들 수 있습니다.

- 부스팅:간단한 모델ㅇㄹ 여러 개 조합하여 편향을 줄이는 방법
- 랜덤 포레스트: 복잡한 모델인 결정 뜨리를 여러 개 조합하여 분산을 줄이는 방법

2.1.5.2 정규화
정규화는 정해진 모델이 필요 이상으로 복잡해지지 않도록 조절하는 트릭입니다. 모델이 데이터에 비해 필요 이상으로 복잡하면 불필요한 노이즈까지 학습해서 학습할 때는 성능이 좋지만, 실제로 사용할 때는 좋지 않은 성능을 보일 수 있습니다. 모델의 복잡도를 줄이는 방법으로는 크게 다음 2가지가 있습니다.

- 모델 변경: 데이터를 표현하는 방법을 완전히 새롭게 전환해서 적합한 모델을 찾는 방법
- 정규화: 모델에 들어 있는 인자에 제한을 주어 모델이 필요 이상으로 복잡해지지 않게 하는 방법

제약 조건과 데이터를 이용해서 적당한 복잡도를 가지는 모델을 자동적으로 찾아주는 기법이 정규화 입니다.

2.2 손실함수: 모델의 수식화된 학습목표
모델이 실제로 데이터를 바르게 표현했는지 혹은 얼마나 예측이 정확한지 수학적으로 표현하는 것이 손실함수(loss function)입니다. 앞서 다우었던 선형 회귀를 예로 들면 만들어낸 직선에서 데이터가 얼마나 떨어져 있는지 계산하는 함수가 손실함수입니다.

손실함수의 값이 작을수록 모델이 더 정확하게 학습된 겁니다. 이때 손실함수로 언은 결과값을 보통 에러라고 부릅니다.

손실함수는 거의 같은 모델을 대상으로 하더라도 중요하게 생각하는 데이터의 특성에 따라 변형될 수 있습니다. 예를 들어 데이터의 전체적인 패턴을 중시할지 지엽적인 패턴을 중시할지에 따라서 기본적인 손실함수에 추가적인 손실함수를 덧붙일 수 있습니다. 엄밀히 따지면 데이터를 보는 관점이 조금 변화했기 때문에 다른 모델이라고 말할 수도 있지만, 이러한 손실함수의 조합은 같은 모델의 변형으로 열겨지는 경우가 많으며 자주 사용되는 기법입니다.
손실함수는 데이터 전체에 대해 계산하는 함수지만, 간단하게 표시하기 위해 할 개의 데이터에 대새서만 정의하기도 합니다. 이때 각 데이터에 대한 손실함수 계산 결과의총합이 그 모델과 데이터 전체에 대한 손실함수 결과입니다. 물론 이런 경우에는 몇 가지 가정이 추가됩니다. 예를 들어 데이터셋에서 각각의 데이터가 서로 확률적 독립이고 같은 분포를 가진다는 i,i,d가정(independent and identically distributed:독립항등부포)이 대표적입니다.

여기서 다룰 손실함수는 다음 4가지 입니다.

- 산술 손실함수: 모델로 산술값을 예측할 때 데이터에 대한 예측값과 실제 관측값을 비교하는함수입니다. 주로 희귀 문제에서 사용합니다.

- 확률 손실함수: 모델로 항목이나 값에 대한 확률을 예측하는 경우에 사용합니다. 매우 유연하기 때문에 회귀 문제를 비롯해 보편적으로 사용합니다.

- 랭킹 손실함수: 모델로 순서를 결정할 때 사용합니다. 추천 시스템에서 주로 사용합니다.

- 모델 복잡도와 관련된 손실함수: 보통 위 손실함수들과 합쳐져서 모델이 필요 이상으로 복잡해지지 않도록 방지하는 손실함수입니다. 앞에서 설명한 정규화의 일종으로 볼 수 있습니다.

2.2.1 산술 손실 함수
모델로 산술값을 예측할 때는 각 데이터에 대한 예측값의 차이를 산술적으로 계산하는 손실함수를 많이 사용합니다. 차이의 제곱을 사용하는 제곱 손실함수와 차이의 절댓값을 사용하는 손실함수가 많이 쓰입니다.

제곱 손실합수는 굉장이 많은 곳에서 사용됩니다. 제곱 손실함수를 사용하는 이유에 대해서는 여러가지 이론이 존재하지만, 가장 간단한 설명으로는 주어진 데이터 출력값(y)과 모델의 예측값의 차이의 제곱을 계산하므로, 최적화가 쉽고, 손실값의 이해가 쉽기 때문입니다.

이 손실함수는 주어진 데이터 1개(입력x와 출력 y의 쌍)에 대해 학습된 모델(w0과 w1인자로 결정되는)이 얼마만큼의 에러를 가지는지, 즉 얼마나 데이터를 잘 표현하는지 정량적으로 계산합니다. 물론 이 식은 데이터 하나에 대해 정의를 한 것으로, 전체 데이터에 대해서는 각 손실함수의 값을 전부 합산하거나 평균을 낸값을 사용합니다.(참고로 평균의 경우에는 평균 제곱편차라는 표현을 주로 사용합니다.).

2.2.2 확률 손실함수
앞에서 산술값을 예측하기 위한 모델(회귀)에 적합한 산술 손실함수에대해 살펴봣습니다. 이와 달리 특정 항목을 고르는 분류 모델에서는 확률 손실함수가 더 적합합니다.

확률 손실함수는 모델이 관측된 데이터를 예측할 확률을 최대화하는 방식으로 계산됩니다. 접근 방식에 따라 많은 확률 손실함수를 만들 수 있습니다. 대표적으로 MLE(maximum likehood estimation:최대 가능도 방법)와 쿨백-라이블러 발산(Kullback Leibler divergence:KL-divergence, KL-발산)이 있습니다.

여기서는 확률 손실함수 중에서 자주 사용되는 교차 엔트로피(cross entropy)함수에대해 알아봅니다. 이 함수는 딥러닝에서 특히 많이 사용됩니다.

이 함수는 MLE방식에 따라 만들어 집니다. 여기서 가능도 likelihood(혹은 우도)란 주어진 데이터가 얼마나 적합한지에 대한 조건부 확률입니다. 수식은 p(x|f)와 같이 씁니다. 여기서 x는 데이터, f는 모델입니다. 가능도가 클 수록 주어진 모델이 관측된 데이터를 더 잘 표현한 것이 됩니다. 따라서 이 값을 최대화 하는 쪽으로 모델을 학습시켜야하는데, 보통 손신할수를 풀 때는 최소값을 구하는 최적화 방식을 사용하므로, 계산의 편의를 위하여 가능도의 부호를 바꾸고 log값을 취한 음의 로그 가능도(negative log-likelihood) 손실함수를 많이 사용합니다.

loss(f) = -log p(x|f)
음의 로그 가능도 손실함수는 실제 모델 f에 따라 정의되겠지만, 분류에서 많이 사용되는 다항로지스틱 희귀(multinomial logistic regression)의 음의 로그 가능도 손실 함수에 대해 살펴보겠습니다.

다항 로지스틱 희귀는 입력값을 {1,2,...C} 중 하나로 분류합니다. 이때 모델의 각 항의 예측 값은 0부터 1사이의 실수가 되고 모든 항의 예측값의 총합은 1이 됩니다. 각 분류에 대한 확률을 y라고 합시다.

2.2.3 랭킹 손실 함수
랭킹 손실함수는 지금까지 설명한 산술 소실함수나 확률 손실함수화는 달리 특정한 결괏값에 대한 손실을 측정하지 않습니다. 대신 모델이 예측해낸 결괏값의 순서가 맞는지만 판별합니다. 랭킹 손실함수는 목록에서 몇가지를 추천 시스템이나 랭킹학습 분야에서 많이 사용합니다.

순서를 예측하느 문제는 손실함수를 조금 다르게 표현합니다. 예플 들어 데이터의 순서가 x1> x2> x3> x4> x5라고 들어오면 모델은 각 데이터의 순서를 x의 의미에 따라 학습힌다. 여기서 x의숫자를 의미한다기보다는 어떤 개념을 나타낸다고 생각하면 됩니다.(예를 들어 x1은 사과, x2는 바나나등).
다양한 랭킹 손실함수가 있는데 그 중에서도 모델이 만들어낸 순서 목록에서 모든 쌍의 순서가 맞았는지 틀렸는지 확인하는 방식이 가장 간단합니다. 예를 들어 모델이 x3> x1> x2> x4> x5라는 결과를 만들었다면 각 쌍에 대해 다음과 같은 결괏값 쌍을 가집니다.
1. x3 > x1
2. x3 > x2
3. x3 > x4
4. x4 > x5
5. x1 > x3
6. x1 > x4
7. x1 > x5
8. x3 > x4
9. x3 > x5
10. x4 > x5
이 모델의 결괏값 쌍과 정답인 x1> x2> x3> x4> x5를 비교하면 10가지 관계 중에서 몇가지가 틀렸는지 알 수있습니다. 이 경우에는 x3 > x1, x3> x2이렇게 두 관계가 잘못되었으므로 손실 함수 결과는 2입니다. 이 손실함수는 페어와이즈 제로-원 손실함수 라고 부릅니다.
다른 방식으로손실을 측정하는 편집 거리 라는 랭킹 손실함수도 있습니다. 이 손실함수는 모델이 예측한 순서 목록에서 몇 번의 맞바꿈을 해야 워래 순서로 돌아갈 수 있는지 측정합니다.

2.2.4 모델 복잡도와 관련된 손실함수

2.3 최적화: 실제로 학습을 하는 방법

지급까지 데이터를 바라보는 시각인 모델과 모델이 데이터를 얼마나 잘 표현하는지를 수학적으로 측정하는 손실함수에 대해 알아봤습니다. 이제부터 손실함수를 이용해서 모델을 학습하는 방법에 대해 알아보겠습니다.

손실함수의 결괏값을 최소화하는 모델의 인자를 찾는 것을 최적화라고 합니다. 이렇게 임의로 여러 값을 대입해 보면서 손실을 최소화하는 방법도 있지만 보통은 수학적으로 손실함수를 분석해서 최적화 합니다. 그리고 그 방식은 사실 이미 고등하교 때 배웠습니다.

함수의 최솟값과 최대값에 대해서는 익히 알고 있으리라 생각합니다. 이 최속값은 위 식처럼 인수분해로 한번에 구할 수 있지만, 한번에 풀리는 경우는 많지 않고 보통은 여러 번 반복해서 업데이트를 해야 최소값을 찾을 수 있습니다. 이 절에서는 그중 많이 쓰이는 경사하강법, 뉴턴/준뉴턴 방법, 확률적 경사하강법, 역전파 그리고 몇가지 최신 최적화 방법을 살펴보겠습니다.

2.3.1 경사하강법
경사하강법은 간단한 최적화 방법 중 하나로 임의의 지점에서 시작해서 경사를 따라 내려갈 수 없을 때까지 반복적으로 내려가며 최적화를 수행합니다. [그림 2-8]에 경사하강법을 적용해보면 [그림 2-9]와 같습니다.

1. 현재 @값에서의 경사값을 구합니다.
2. 경사를 따라 n만큼 내려갑니다.
3. 손실함수의 출력값이 많이 줄어들었는지 보고 그렇다면 1로 돌아가 계속 하강합니다. 많이 줄어들지 않았다면 경사를 다 내려온 것으므로 @값 구하기를 그만둡니다.

위 그림은 @=4에서의 경사를 보여줍니다. 경사는 곡선의 접선 방향으로 결정되는데, 이를 계산하려면 손실함수 인자 @에 대해 미분하면 됩니다.
이 경사값을 이용해 앞에서 서술한 과정 1,2,3을 반복하면 손실함수를 쉽게 최적화 할 수 있습니다. 이런 이유로 미분 가능한 손실함수를 많이 사용합니다. 예를 들어 모든 점에서 미분 가능한 제곱 손실함수를 절댓값 손실함수보다 많이 씁니ㅏㄷ.

경사는 방향을 결정합니다. 얼마나 빨리 내려가는지를 학습률 혹은 스템 크기라고 불리는 n에 의해 결정됩니다.

2.3.2 뉴턴/준 뉴턴 방법
학습률 n와관련된 몇 가지 고전적인 이론이 있습니다. 대표적인 이론으로 뉴턴 방법과 준 뉴턴 방법이 있는데요, 그 중 뉴턴방법은 임의의 학습률을 사용하는 대신 1차 미분값과 2차 미분값을 활용하여 업데이트를 수행합니다.

뉴턴 방법은 단순한 경사하강법보다 훨씬 빠른 최적화 속도를 보이지만 현실적으로 2차 미분은 식을 풀기도 어렵고 계산에도 많은 자원이 필요해서 잘 사용하지 않습니다.

준 뉴턴 방식은 2차 미분을 직접 계산하는 대신 1차 미분값을 활용해 2차 미분값을 근사해서 사용합니다. 그렇기 때문에 2차 미분값을 계산하지 않고도 빠르게 많은 문제를 풀 수가 있으며, 대표적인 방법으로 BFGS(broyden-fletcher-goldfarb-shanno algorithm)와 LBFGS(limited-memory BFGS)가 있습니다. BFGS와 LBFGSㄴ느 데이터가 너무 많지 않은 경우에 뛰어난 성능을 보입니다. 최근에는 데이터가 많아지면서 확률적 경사하강법이 많이 쓰이기는 하지만 준 뉴턴 방식은 여전히 효율적인 최적화 방법입니다. 유명한 기법이라 대부분의 머신러닝 소프트웨어에 구현되어 있으니 궁금한 분은 사용해 보기 바랍니다.

2.3.3 확률적 경사하강법
앞에서 설명한 경사하강법이나 뉴턴/준뉴턴 방법은 데이터가 많아지면 계산량이 증가해서 학습 시간이 길어집니다(데이터에 따라 다르겠지만 몇심만 개 정도는 크게 문제가 없습니다.) 시간이 오래 걸리는 이유는 손실함수와 1차 미분값을 전체 데이터에 대해 걔산하기 때문입니다. 이를 해결하고자 일부 데이터만 이용해서 손실함수와 1차 미분값을 근사적으로 계산하는 확률적 경사하강법(SGD)이 만들어졌습니다.
SGD는 전체 데이터를 가지고 계산하기보다는 다음과 같이 n개의 샘플을 뽑아서 손실함수와 1차 미분값을 계산합니다.
-SGD의손실함수: (데이터 전체에 대한 평균을 사용하는 대신) 데이터에서 n개의 샘플을 뽑아서 그 평균을 사용합니다.
-SGD의 1차 미분값: 손실함수와 마찬가지로 n개의 샘플을 뽑아서 계산합니다.

SGD는 n개의 샘플을 뽑는 방법은 여러 가지가 있는데, 대표적으로 다음 2가지 방법을 많이 사용합니다.
-데이터를 처음부터 끝까지 하나씩 업데이트하는 SGD
-미니배치 SGD
 데이터를 처음부터 끝까지 하나씩 업데이트 하는 SGD는 다음과 같이 동작합니다.

1. 데이터의 처음부터 끝까지 루프를 돕니다(i=0 ~ 데이터 크기).
  a. 현재 @ 값과 현재 데이터(i번째 데이터)에서의 1차 미분값을 구합니다.
  b. 경사를 따라 n만큼 내려갑니다(즉, 경사값에 -1을 곱한 방향으로 n 만큼 움직입니다.).

2. 손실 함수의 출력값이 많이 줄어들었는지 보고 그렇다면 1로 돌아가 반복합니다. 많이 줄어들지 않았다면 경사를 다 내려온 것이므로 @값 구하기를 그만둡니다.

이 방식에서는 데이터 업데이트가 일어날 때마다 데이터를 몇 번 처음부터 끝까지 훑으면서(sweep이라고 합니다) 손실함수가 수렴했는지 검사합니다(모든 데이터를 순차적으로 하나씩 뽑는 방식 대신 정해진 숫자만큼 임의로 데이터를 뽑아서확인하는 방식도 사용합니다). 이 방식은 경사하강법보다 굉장히 공격적으로 업데이트하기 때문에 속도가 빠르지만, 각 데이터의 1차 미분값은 전체 데이터를 이용한 1차 미분값보다 부 정확하므로 손실함수의 출력값이 불안정해지곤 합니다. 그래서 이 방식과 단순한 경사하강법의 중간 정도 되는 미니배치 SGD같은 방식이 자주 쓰입니다.

미니배치 SGD는 다음과 같이 동작합니다. 데이터를 n개씩 뽑아서 하는 SGD입니다.

1. 데이터를 랜덤하게 n개 뽑습니다.
  a. 랜덤하게 뽑은 n개 데이터의 1차 미분값의 평균을 구합니다.
  b. 경사를 따라 n만큼 내려갑니다(즉, 경사값에 -1을 곱한 방향으로 n만큼 움직입니다).
2. 손실함수의 출력값이 많이 줄어들었는지 보고 그렇다면 1로 돌아가 반복합니다.

이 경우는 데이터별로 1차 미분을 구해서 업데이트하는 방식에 비해 1차 미분값이 좀 더 정확하므로(전체 데이터에서 루하는 정확한 1차 미분값에 근접하므로) 매번 계산량은 비교적 많지만 좀 더 안정적인 모습을 보입니다. 미니배치 SGD는 최근 들어 많이 사용되고 있습니다.

SGD는 경사하강법에 비해 적은 양의 데이터를 사용하여 ㅂ차 미분값을 계산하므로 미분값이 불안정해집니다. 결과적으로 학습률에 많은 영향을 받습니다. 그렇기 때문에 SGD를 사용한다면 본격적으로 시스템을 완성하기 전에 미니 배치의 크기(n)와 학습률(N)을 다양하게 시도해 보고 적절한 값을 선택하는 것이 중요합니다. 이렇게 배치의 크기나 학습률의 초기 설정에 민감한 SGD의 성질 때문에 최근에는 이를 보안하는 많은 연구가 이루어지고 있습니다.

2.3.4 역전파
역전파 최적화 방법은 딥러닝에서 많이 사용하는 방식입니다. 딥러닝 모델은 보통 손실함수가 층층이 쌓인 구조로 정의됩니다. 그래서 입력과 출력 부분 외에도 많은 부분에 함수 인자가 들어갑니다. 예를 들면 다음 그림과 같이 구성됩니다.

층층이 쌓이 구조가 복잡해 보이더라도 모델을 일단 손실함수로 표현하면 최적화 방법으로 풀 수 있습니다. 하지만 파라미터가 서로 연관되고 얽혀 있어서(예를 들어 입력 계층과 은닉 계층 사이의 파라미터가 바뀌거나 은닉 계층과 출력 계층 사이의 파라미터가 바뀌면 출력값이 바뀌어서 손실이 뀌는 등단순한 최적화 방법을 사용하면 중복 연산이 많이 일어날 수 있습니다.

역전파는 이렇게 한쪽 방향으로 층층이 연결된 구조에서의 최적화를 효율적으로 수행하는 방식입니다. 한번에 손실함수를 계산하는 것이 아니라 다음과 같이 계층별로 계산해서 업데이트를 수행합니다.

1. 순방향 패스(forward-pass): 입력부터 출력까지 현재 파라미터로 예측함
  a. 현재 파라미터를 넣고 한 계층씩 꼐산을 수행합니다.
  b. 마지막 계층까지 계산하고 출력값을 꼐산합니다.

2. 역방향 패스(backward-pass):출력부터 입력까지 차례로 에러를 계산
  a. 예측된 출력값과 데이터를 비교해서 에러를 계산합니다.
  b. 바로 전 단계의 계층에 대한 손실을 순방향 패스와 반대로 거슬러 올라가며 계산합니다. 옐르 들어 은닉계층과 출력 계층 사이의 에러를 계산하고 이를 이용해서 입력 계층과 은닉계층의 에러를 계산합니다.

3. 역방향 패스에 의해 계산된 계층사이의 에러를 이용해서 1차 미분값을 구하고 그에 따라 업데이트 합니다.

4. 손실함수의 출력값이 많이 줄어들었는지 확인하고 그렇다면 1로 돌아가서 반복합니다. 많이 줄어들지 않았으면 종료합니다.

이렇게 에러가 뒤(출력계층)에서 앞(입력계층)으로 거슬러 퍼져나간다고 해서 역전파라고 합니다. '역전파'는 인터넷 상에도 자세한 설명이 많이 나와 있습니다. 또한 머신러닝소프트웨어가 이 부분을 구현하고 있으므로 실전에서는 직접 구현하지 않고도 사용할 수 있습니다.

2.3.5 최신 최적화 방법
경사하강법이나 SGD는 학습률에 따라 성능이 아주 크게 영향을 받습니다. 특히 데이터가 많을 때 SGD는 학습률에 따라 성능이 심하게 요동치기 때문에 이를 해결하려는 연구가 많습니다.

현재 1차 미분값과 과거의 1차 미분값이 변하는 추이를 이용해서 학습률을 자동으로 조절하는 방식도 있습니다. 대표적으로 Adam(Adaptive Moment Estimation)과 AdaGrad(Adaptive gradient)가 있습니다. Adam은 과거의 미분값의 방향과 분산을 계속 가중평균 내면서 효율적인 데이트 방향과 크기를 선택합니다. AdaGrad는 미분값의 크기를 추적하고 학습률을 데이터에 적응하면서 학습을 수행합니다. 최근에는 Adam을 더 많이 사용합니다.

2.4 모델 평가: 실제 활용헤서 성능을 평가하는 방법

손실함수가 모델을 최적화하고자 수식으로 표현하는 방법이라면 모델 평가(model evaluation)는 모델이 얼마나 좋은 성능을 보일지 평가하는 방법입니다.  손실함수와 모델 평가 방식이 정확하게 일치하는 경우도 있지만, 개념이 서로 다르고, 모델 평가 방식을 수학적으로 직접 최적화 하기 어려운 경우가 많아서 별도로 취급합니다.

모델 평가를 할 때는 학습 데이터뿐만 아니라 학습 데이터가 아닌 새로운 데이터가 들어왔을 때도 잘 동작하는지 측정합니다. 이를 일반화(generalization)라고 하며, 실제 머신러닝 시스템을 구축할 때 굉장히 중요한 요소입니다.

일반화가 중요한 이유는 학습에 사용되는 관측된 데이터들은 한정된 패턴들만 보여주기 때문입니다. 따라서 관측된 데이터에 지나치게 의존해 학습하면 진짜 분포(true distribution)에서 오히려 멀어질 수 있습니다. 결과적으로 학습된 데이터에서만 잘 동작하고 관측될 데이터에 대해서는 성능이 잘 나오지 않게 됩니다. 이런 문제를 과학습(오버피팅overfitting)이라고 합니다.

이런 문제가 발생하는 것을 막고자 '좋은 모델이란 무엇인가?'에서 '좋은 모델은 지나치게 복잡하지 않아야 한다'라 했던 것이면 정규화를 통해 복잡도를 적절하게 조절해보았습니다. 모델 평가는 정규화를 어느 정도 강하게 해야 할 지와 모델이 관측되지 않은 데이터에 대해서 잘 동작할지 평가합니다. 이 절에서는 모델의 일반화 특성을 살피고, 어떻게 해야 실제 사용에 가깝게 평가할 지 다룹니다.

2.4.1 모델의 일반화 특성 평가
모델 일반화 특성 평가는 한정적인 데이터를 이용해서 모델의 일반화 특성을 알아내는 것을 목표로 합니다. 다른 성능 평가 기준인 정확도나 정밀도 등과 복합적으로 상요합니다. 모델이 학습용 데이터에서만 잘 동작하는 것이 아니라 일반적인 상황에 잘 동작하는지 파악하는 일이기 때문에 중요한 평가 기준입니다.

일반화는 모델의 관측된 데이터(학습데이터)가 아닌 데이터에 대해서도 좋은 성능을 내는지를 의미합니다. 일반화가 얼마나 잘되었는 측정하는 에러를 일반화 에러(generalization error)라고 합니다. 일반화 에러를 구하는 방법은 다양하지만 여기서는 가장 유명한 학습-평가 데이터 나누기(train-test data split)와 교차검증(cross-validation)에 대해 알아보겠습니다.

2.4.1.1 학습-평가 데이터 나누기
학습-평가 데이터 나누기 방법은 데이터를 학습용과 평가용으로 나누어 평가하는 방법입니다. 간단하게 일반화 에러를 평가할 수 있어 가장 많이 쓰입니다. 이 방법은 평가하기에 앞서 데이터를 학습을 위한 데이터(학습셋)와 평가를 위한 데이터(평가셋)로 나눕니다. 80:20이나 50:50의 비율이 가장 흔하게 사용됩니다. 보통은 무작위로 해당 비율만큼 데이터를 선택하여 학습용 데이터를 만들고, 나머지를 평가용으로 사용합니다. 시간에 따라서 달라지는 데이터를 다룰 때는 오래된 데이터를 학습용으로 사용하고 최근 데이터를 평가용으로 사용하는 것이 일반적입니다.

데이터를 나누고 나서는 학습용 데이터로 모델을 학습시키고, 평가용 데이터로 성능을 평가합니다. 이렇게 평가용 데이터를 사용해서 모델이 학습용 데이터를 단순히 외운 것인지, 아니면 학습용 데이터에서 실제로 유용한 패턴을 학습했는지 검증합니다.

2.4.1.2 교차 검증
교차검증은 학습-평가 데이터 나누기를 한번만 하는 것이 아니라 여러 번 반복해서 좀 더 정확하게 일반화 에러를 평가하는 방법입니다. 교차검증은 학습-평가 데이터 나누기만큼 유명하고 많이 쓰이는 방법으로, 여기서는 교차검증 방법 중에 가장 유명한 K겹 교차검증(K-fold cross-validation)에 대해 알아보겠습니다.

K겹 교차검증은 다음과 같이 동작합니다.

1. 데이터셋을 K개로 나눕니다.
2. 그중 첫번째 세트를 제외하고 나머지에 대해 모델을 학습합니다. 그리고 첫번째 세트를 이용해서 평가를 수행합니다.
3. 과정 2를 마지막 세트까지 진행합니다.
4. 각 세트에 대해 구했던 평가 결과의 평균을 구합니다.

교차검증은 학습-평가 데이터 나누기에 비해 데이터의 여러 부분을 학습과 평가로 사용한 결과로 일반화 특성을 평가하므로 더 안정적이고 정확합니다. 하지만 여러 번 학습하고 평가하는 과정을 거치기 때문에 계산량이 많다는 단점이 있습니다.

2.4.2 정확도
정확도(accuracy)는 모델이 데이터를 얼마나 정확하게 분류했는지에 대한 평가 지표입니다. 상당수 머신러닝 시스템은 데이터를 활용하여 몇 가지 선택지 가운데에서 가장 적합한 것을 고르는데, 이때 선택이 올바른지 아닌지 측정하여 수치로 나타낸 것이 정확도입니다. 정확도의 정의는 다음과 같습니다.

정확도 = 맞게 분류한 데이터 숫자/평가하는 데 쓰는 총 데이터 숫자

즉, 정확도가 0.5라면 전체 데이터 중 반은 정답을 맞힌 것이고 반등ㄴ 틀린 겁니다. 0.9라면 전체 데이터 중 90%는 정답을 맞힌 것입니다.

정확도는 모델이 어떠한 성능을 보일지에 대한 아주 직관적인 평가 기준입니다. 하지만 정확도만으로 모델을 평가하면 여러 거지 문제가 발생할 수 있습니다.

2.4.3 정밀도와 포괄성
정확도가 0.9인 모델은 정말 좋은 모델이라고 볼수 있을 까요? 예를 들어 다음과 같은 경우에는 정확도가 상대적으로 덜 중요할 겁니다.

데이터의 항목이 한쪽으로 치우쳐져 있을 경우
사막에서 다음날 비가 올지 안 올지 예측하는 모델이 있다고 해봅시다. 사막에는 거의 비가 오지 않으므로 모델이 잘 동작하지 않더라도 비가 오지 않을 거라는 사실을 쉽게 맞출 수 있습니다. 실제로 비가 올 확률이 0.1%라면 항상 '그냥 비가 오지 않는다'는 결과를 돌려주는 모델이더라도 정확도가 0.999가 됩니다. 아주 높은 정확도지만 실제로 좋은 모델이라고 할 수 없습니다.

한 분류가 다른 분류보다 중요한 경우
혈액을 분석하여 암에 걸렸는지 판별하는 경우를 봅시다. 암에 걸렸는데 그렇지 않다고 잘못판별하면 자칫 환자의 생명이 위험할 수 있습니다. 반면 암에 걸리지 않았는데도 걸렸다고 예측할 경우에는 추가 검사를 하는 것이 일반적이므로 일반적인 과정이므로 검사비가 조금 더 들긴 하겠지만 생명이 위험하지는 않을 겁니다. 이런 경우에는 조금 부정확하더라도 암환자를 모두 발견해내는 것이 중요합니다.

이러한 경우에는 정확도만으로는 모델이 얼마나 유용하닞 판단이 어렵습니다. 그래서 모델의 유용성을 따질 때는 정밀도(precision)와 포괄성(recall)도 함께 고려합니다. 정밀도와 포괄성은 긎어(positive,양성)이냐 부정(negative,음성)이냐를 결정하는 이진화 분류 문제(binary classification)에서 다음 4가지 경우에 따라 정의 됩니다.

                                            모델의 예측 값
데이터의 실제 값        양성으로 예측                        음성으로 예측
실제로 양성           참 양성(진짜 양성)                    거짓 음성
실제로 음성           거짓 양성                               참 음성(진짜 음성)

정밀도는 모델이 양성으로 예측한 데이터 중에서 얼마나 정답을 맞혔는지 평가합니다. 정의는 다음과 같습니다.

정밀도 = 참 양성  / ( 참 양성 + 거짓 양성)

모델이 1년 중 10일 비가 온다고 예측했는데, 비가 오기로 예측한 날 중에서 실제로 며칠이나 비가 왔는지 평가한다고 합시다. 이때 예측한 10일 중 8일 비가 왔다면 정밀도는 0.8이 됩니다. 하지만 정밀도는 모델이 예측하지 못한 비오는 날(실제로는 비가 20일 왔을 경우)을 고려하지 않으므로 위에서 설명한 암환자 분류 문제에는 적합하지 않은 평가 방법이 될 것입니다.

포괄성은 실제로 양성인 데이터 중에서 몇 명이나 양성으로 예측했는지 평가합니다. 정의는 다음과 같습니다.

포괄성 = 참 양성 / (참 양성 + 거짓 음성)

암 환자가 10명인데 여기서 암환자를 몇 명이나 찾아냈는지가 바로 이 경우입니다. 하지만 단순희 포괄성만 높으면 좋지 않은데 그 이유는 모델이 모든 환자를 양성으로 판별된 모든 환자에 대해 정밀 검사를 해야 하므로 모델을 사용하는 의미가 없겠죠. 즉, 정밀도과 포괄성 둘 다 높으면 좋지만 단순하게 각각을 최대화 하는 것이 항상 좋은 것은 아닙니다.

그렇기 때문에 정밀도와 포괄성을 조합한 F1평가 방식이 있습니다. F1은 정밀도와 포괄성 두다 높아야 점수가 높아집니다 F1 은 다음과 같이 정의 됩니다.

F1 = (2 * 정밀도 * 포괄성)/ (정밀도 + 포괄성)

또한 AUC(area under receiver operating characteristic curve, ROC 커브 밑면적)를 이용해서 정밀도와 포괄성을 한번에 평가하는 방법도 있습니다. AUC는 모델의 결괏값을 해석하는데 있어서 정밀도와 포괄성의 트레이드오프를 계산함으로써 앞서 말씀드린 정확도보다 모델의 성능을 더 다각도로 평가합니다.

2.4.4 랭킹 평가

2.4.4.1 정밀도 @K
정밀도 @K(precision@K) 방식은 항목들의 랭킹을 구한 후 앞에서부터 K번째까지의 결과 중에서 몇개가 올바른지 검사합니다. 검색 엔진 결과를 생각하면 편한데요, 예를 들어 한 페이지에 검색 결과 20개를 보여주는 엔진이 있다고 합시다. 이때 검색 결과의 품질을 평가하기 위해 모든 결과가 아니라 1페이지의 결과 20개만 확인할 경우엔 정밀도 @20의 평가입니다. 사용자에게 ㄴ노출이 덜되는 랭킹이 낮은 항목에 대해서는 신경 쓰지 않으므로 모든 랭킹에 대해 신경 쓸 때 보다 더 효율적입니다.

2.4.4.2 NDCG
정밀도 @K와 비슷하게 랭킹이 높음 결과에 더 가중치를 줍니다. 하지만 정밀도@K와는 달리 NDCG(Normalized Discounted Cummulative Gain)는 중요도를 순휘에 따라 바꾸어가면 평가합니다. 정밀도 @K와 마찬가지로  K개만 ㅅ사용하는 경우도 있고 (NDCG@K) 전체를 사용하는 경우도 있습니다. 두 방법 모두 검색 엔진의 평가에 많이 쓰입니다.










댓글 없음: