페이지

2018년 3월 27일 화요일

laradock on mac


mysql bash -> hostname -I

.env DB_HOST SETTING

php artisan make:auth



php artisan migrate

CHAPTER12 다중 계층에서의 오차의 역전파

다음은 3개 계층(입력 계층, 은닉 계층, 출력 계층)으로 구성된 간단한 신경망입니다.


 입력          입력계층               은닉계층            출력계층          출력


--->             (1)  --->               (1)     ------>         (1)     ---->


오른쪽 끝의 최종 출력 계층부터 보겠습니다. 출력 계층의 오차를 이용해 출력 계층의 연결된 노드들의 가중치를 업데이트하게 됩니다. 이를 조금 더 일반화해보면 출력 계층의 오차는 e(output)으로, 여기에서는 가중치 who로 표현할 수 있습니다. 물론 e(output)은 가중치 비율에 따라 나뉘어 전달될 것입니다.
이렇게 시각화해봄으로써우리는 새로 추가된 계층에 대해 어떻게 하면 좋을지 감을 잡을 수 있을 것 같습니다. 즉 은닉 계층의 노드으 ㅣ출력 값과 관련된 오차를 e(hidden)이라고 하고 이 오차를 입력 계층과 은닉계층을 연결하는 가중치 wih에 대해 그 비율에 맞게 나누어 주면 되는 것입니다. 다음 그림에 이를 표현햅습니다.

만약 계층이 더 많이 있다면 이처럼 최종 출력 꼐층으로부터 역방향으로 동일한 과정을 반복하면 될 것입니다. 이처럼 오차 관련 정보가 뒤쪽으로 계속해서 전파되므로 역전파라고 부르는 것입니다.

출력 계층의 경우에는 출력 계층의 노드의 결과 값의 오차인 e(output)을 사용했지만, 은닉 계층의 노드에서 e(hidden)은 어떤 오차 값으 ㄹ사용하면 될까요? 만약 이런 의문이 들었다면 지금까지의 내용을 제대로 이해하고 있는 것이라고 보룻 었을 것 같습니다. 중간에 위치하는 은닉 계층은 사실 명백한 오차를 가지고 있지 않기 때문입니다. 앞에서 배웠던 내요을 다시 상기해볼까요? 은닉 계층의 각각의 노드는 직전 계층으로부터 입력을 받아 적절한 출력값을 다음 계층으로 전달하게 됩니다. 이때 이 출력 값이란 직전 계층의 입력 값에 가중치를 적용한 다음이를 모두 더한 값에 활성화 함수를 적용한 값입니다. 그럼 도대체 어떻게 오차를 구해낼 수 있는 것일까요?

은닉 노드에 대해서는 목표로 하는 출력 값이 없습니다. 오직 최종 출려 ㄱ계층의 노드만이 학습데이터로부터 얻은 실제값, 즉 목표로 하는 출력 값을 가지고 있다는 것이죠. 앞으로 그림을 보면 다시 한번 생각해보기 바랍니다. 은닉 계층의 첫 번째 노드는 2개의 연결 노드를 가지는데 이들은 출력 계층의 2개의 노드로 각각 연결됩니다. 그리고 우리는 출력 계층의 노드에서의 오차를 이 연결 노드에 나누어줄 수 있다는 점을 알고 있습니다. 이 말은 결국 중간의 은닉 계층의 노드로부터 오는 2개의 연결 노드 각각에 대해 어떤 오차가 존재한다느 말입니다. 우리는 이러한 2개의 연결노드의 오차를 재조합함으로써 은닉 계층의 노드의 에러로 사용할 수 있습니다. 즉 중간 계층의 노드는 목표로 하는 출력 값을 가지지 않기 때문에 이처럼 차선의 방법을 사용하는 것입니다. 이와 같은 아이디어를 다음 그림에 표현해봤습니다.

그림을 보면 좀 더 명확해질 것입니다. 우리에게 필요한 것은 은닉 계층의 노드들에 대한 오차입니다. 이 오차를 이용해 직전 계층과의 연결 노드에 존재하는 가중치를 업데이트할 것이기 때문입니다. 은닉 계층의 노드의 오차를 e(hidden)이라고 하겠습니다. 아직까지 우리는 실제 이 오차의 값이 얼마인지에 대한 답을 가지고 있지 않습니다. 그 이유는 (반복해서 말하지만) 학습 데이터로부터 얻을 수 있는 목표 값은 (으닉 계층이 아니라) 오직 최종 출력 계층의 노드에 대한 것이므로, 으닉 계층에서의 오차를 목표 값과 실제 값 간의 차이라고 정의할 수 없기 때문입니다.

학습 데이터들은 최종 노드의 결과 값이 가져야 할 목표 값에 대해서만 말해줍니다. 이 외의 노드들의 결과 값에 대해서는 아무것도 말해주지 않습니다. 이것이 이 퍼즐의 핵심입니다.

우리는 앞에서 본 대로 오직의 역전파를 이용해 연결 노드에 대해 나뉜 오차를 재조합해야 합니다. 따라서 은닉계층의 첫 번째 노드의 오차는 이 은닉계층에서 다음 계층으로 연결되는 모든 연결 노드에 있는 나뉜 오차들의 합이 됩니다. 앞의 그림에서 보면 e(output.1)은 w11과 연결되어 있으면 e(output2)는 w12와 연결되어 있습니다. 이를 수식으로 써보면 다음과 같습니다.

e(hidden1) = 연결 노드 w11, w12로 나뉘어 전달되는 오차의 합
               = e(output1) * w11 /(w11 + w21) + e(output2) * w12/(w12 + w22)

수식으로만 보면 이해가 어려울 수 있으니 실제 숫자를 대입해서 보겠습니다. 다음 그림은 오차가 역전파하는 과정을 실제 숫자와 함께 표현한 것입니다.

앞의 그림에서 출력 계층의 첫 번째 노드의 오차 0.8은 이와 연결된 2개의 가중치 2.0과 3.0에 비례해 각각 0.32와 0.48로 나뉘어 전달된다는 것을 확인할 수 있습니다. 출력 계층의 두 번째 노드의 오차 0.5는 연결된 2개의 가중치 1.0과 4.0에 비례해 각각 0.1과 0.4로 나뉩니다. 따라서 은닉 계층의 첫 번째 노드의 오차는 0.32와 0.1의 합인 0.42가 되고 두번 째 노드의 오차는 0.48과 0.4의 합인 0.88이 되는 것입니다.
다음 그림은 한 단계 더 나아가 은닉 계층의 오차 값을 이용해 입력 계층이 오차를 구하는 것을 보여줍니다.

핵심정리
- 인공 신경망에서 학습이란 연결 노드의 가중치를 업데이트하는 과정을 의미합니다. 가중치의 업데이트는 오차에 의해 주도되는데, 오차는 학습데이터로부터 주어진 정답과 출력값 간의 차이를 의미합니다.
- 출력 노드의 오차는 실제 값(정답)과 출력 값 사이의 차이를 의미합니다.
- 중간 계층의 존재하는 노드들의 오차는 명백하지 않습니다. 한 가지 접근 방법은 출력 계층의 노드들의 오차를 이와 연결된 가중치의 크기에 비례해 누눠서 역전파하고 이를 재조합하는 방법입니다.




2018년 3월 26일 월요일

CHAPTER 11 여러 노드에서의 오차의 역전파

이번에는 2개의 출력 노드를 가지는 그림을 보겠습니다.
                                                              결과값의 오차


i1  ->  계층1(1)  -> (w1.1)->  계층2(1)  -> o1         e1
                     -> (w1.2)
         
                     -> (w1.2)
i2  ->  계층1(2) ->  (w2.2) ->  계층2(2)  ->o2         e2

2개의 출력 노드 모두 오차를 가질 수 있습니다. 특히 우리가 아직 네트워크를 학습시키지 않은 경우에는 거으 ㅣ무조건 오차를 가지고 있겠죠. 그러므로 2개의 오차 모두 가중치를 어떻게 업데이트해야 할지에 대한 정보를 줘야 합니다. 우리는 앞에서 했던 대로 출력 노드의오차를 앞 단의 각 가중치에 비례해 나누어 주는 접근 방법을 활용할 수 있습니다.

출력노드가 여러 개라고 해서 변하는 것은 아무것도 없습니다. 그저 첫 번째 출력 노드에서 했던 작업을 두 번째 출력 노드에서 동일하게 반복하면 되는 것입니ㅏㄷ. 어떻게 이렇게 간단할 수 있냐고요? 그 이유는 하나의 출력 노드로의 연결은 다른 출력 노드로의 연결과 완전 별개이기 때문입니다. 각각의 연결 간에 는 전혀 의존 관계가 존재하지 않는다느 ㄴ말입니다.

앞의 그림을 다시 한번 보면 첫 번째 출력 노드의 오차를 e1이라고 표기했습니다. 이 초차는 학습데이터 t1에 의해 제공된 실제 값과 우리가 계산한 ㅜㅊㄹ력 값 o1사이의 차이를 의미합니다. 다시 말해 e1 = t1 -01입니다. 그리고 두 번째 출력 노드에서의 오차는 e2라고 표기해습니다.

그림을 자세히 보면 e1은 w11과 w21의 가중치의 값에 비례해서 나눠어 연결된 노드로 전달됩니다. 이와 유사하게 e2는 w12와 w22의 값에 비례해 나뉩니다.

좀 더 이해가 쉽도록 이를 수식으로 표현해 보겠습니다. 오차 e1은 w11과 w21의 업데이트에 영향을 주게 됩니다. 그러므로 w11을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현 가능합니다.

w11 / (w11 + w21)

그리고 w21을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현할 수 있습니다.

w21 /( w21 + w11)

이러한 수식의 의미는 결국 무엇일까요? 오차 e1은 나뉘어 전달될 때, 작은 가중치를 가지는 연결 노드보다 큰 가중치를 가지는 연결 노드에 더 많이 전달된다는 것입니다.
만약 w11 = 6이고 w21 = 3이라는 값을 가진다고 하면 w11은 w21보다2배 큽니다. 이때 w11을 업데이트하기 위해 전달되는 오차 e1의 일부는 6 / (6 +3) =6 /9 = 2/3 가 됩니다. 그럼 1/3이 남는데요. 실제로 오차 e1에서 w21을 업데이트 하기 위해 전달되는 부분은 3/ (6 +3) = 3/ 9 = 1/3입니다.

만약 가중치가 같다면 1/2씩 전달되게 될 것입니다. 예를 들어 w11 = 4, w21 = 4라면 약쪽으로 나눠어 전달되는 오차는 2개 모두 4 /( 4+4) = 4/8 = 1/2이 될 것 입니다.

지금까지 공부한 내용을 정리해보겠ㅅ브니다. 우리는 오차를 이용해서 네트워크 내의 매개변수들의 값(가중치)을 조정해나간다는 사실을 알게 되었습니다. 최종 출력 계층으로부터 그 직전 계층으로 가는 연결 노드으 ㅣ가중치를 업데이트하는 방식을 살펴봤는데 여러개의 출력 노드가 있는 경우에도 그 각각으 ㅣ출력노드를 개별적으로 처리하면 될 뿐, 복잡해질 것이 전혀 없다는 사실을 알게 되었습니다.
그렇다면 2개 보다 더 많은 꼐층을 가지는 신경망에서는 어떻게 하면 될까요? 다시 말해 최종 출력 계층에 인접하는 계층이 아니라, 멀리 떨어져 있는 꼐층과 관련된 가중치는 어떻게 업데이트를 해야 할 까요? 이데 대해서는 다음장에서 살펴보겠습니다.


CHAPTER 10 여러 노드에서 가중치 학습하기

이 책 앞부분에서 선형함수의 매개변수인 기울기의 값을 조정해감으로써 선형분류자를 업데이트해나갔던 것을 기억할 겁니다. 그때 오차라는 개념을 공부한 바 있습니다.
오차는 예측 값고 ㅏ실제 값(정담)과의 차이를 의미하는데, 우리는 이 오차에 기반을 두고선형 분류자를 정교화해나갔습니다. 오차와 기울기의 관계가 매우 단순했기 때문에 이를 조정해가는 ㅓㄳ은 별로 어려운 과정은 아니였습니ㅏㄷ.
그렇다면 여러 개의 노드가 결과 값과 오차에 영향을 주는 경우에는 가중치를 어떻게 업데이트해야 할까요? 이를 그림으로 표현하면 다음과 같습니다.

                     <---- p="">(1) ->W1.1(3.0)->   (1)  -> 결과 값의 오차
(2) -> W2.1(1.0) ->
                      <---- p="">
결과 노드에 영향을 주는 노드가 한 개인 경우에는 월씬 간단했지만, 이와 같이 2개의 노드를 가지는 경우에는 결과 값의 오차를 어떻게 활용해야 할까요?

오차를 하나의 가중치 업데이트에만 사용하는 것은 합리적이지 못합니다. 나머지 하나의 가중치를 무시하는 것이기 때문이죠. 오차가 발생하는데에는 이 다른 연결 노드분도 공헌을 했다는 사실을 무시할 수 없다는 말입니다.
물론 수많으 연결 중에 단 하나의 연결만 해당 오차의 발생에 영향을 미치느느 경우가 있을 수는 있겠지만, 이런 가능성은 매우 낮습니다. 설령 우리가 이리미 정확한 값을 가지게 된 가중치의 값을 변경해 상황을 악화시키게 된다고 하더라도 이런상황은 다음번의 업데이트를 통해 개선될 것입니다.

한가지 방법은 다음 그리과 같이 모든 연결된 노드에 대해 오차를 균일하게 나누어 분배하는 것입니다.

                     <----1 p="">(1) ->W1.1(3.0)->   (1)  -> 결과 값의 오차
(2) -> W2.1(1.0) ->
                      <----1 p="">
또 다른 방법은 오차를 나누어 분배하지만 차별을 두는 것인데, 더 큰 가중치를 가지는 연결에 더 큰 오차를 분배하는 것입니다. 더 큰 가중치를 가진다는 것은 그만큼 오차의 형성에 더 큰 영향을 줬다는 의미이기 때문입니다. 이를 그림으로 표현하면 다음과 같습니다.

                     <----3 p="">(1) ->W1.1(3.0)->   (1)  -> 결과 값의 오차
(2) -> W2.1(1.0) ->
                      <----1 p="">
이 그림에서 2개의 노드는 한 노드에 서로 다른 가눙치로 영햐응ㄹ 줬습니다. 각 연결의 가중치는 3.0과 1.0 입니다. 만약 오차르 ㄹ이들 가중치에 비례해 나눠준다면 오차의 3/4이 위쪽 가중치를 업데이트하는 데에 사용되고 나머지 1/4이 아래쪽으 ㅣ가중치를 업데이트하는데에 사용될 것입니다.

이방법은 노드가 더 많아지더라도 동일하게 적용 가능합니다. 만약 100개의 노드가 다음 계층의 노드에 연결되어 있다고 한다면 우리는 오차를 100개의 연결에 나누어주되 그 값은 각각의 가중치에 따라, 즉 각각의 견결이 오차에 영향을 주는 정도에 비례해서 전달하면 되는 것입니다.

따라서 우리는 가중치를 두 가지 방법을 ㅗ활용한다는 점을 확인할 수 있습니다. 우선 앞에서 여러 사례를 살펴본 바오 ㅏ같이 신호를 하나의 계층에서 다음 계층으로 전파하는데에 가중치를 이용합니다. 두 번째로 오차를 하나의 계층에서 직전 계층으로, 즉 역으로 전파하는 데에도 가중치를 이요합니다. 첫 번째 방식은 앞에서 이비본 전파법이고 두 번째 방법을 역전파(backprogagation)라고 부릅니다.

만약 출력 계층의 2개의 노드를 가진다면 우리는 두 번째 노드에서 대해서도 동일한 작업을 하게 됩니다. 두 번째 노드의 결과 값 역시 그 자체의 오차를 가지므로 연결되는 노드에 대해 이 오차를 분배해주면 되는 것입니다. 다음 장에서 이에 대해 상세히 살펴보게습니다.

CHAPTER 8 머신러닝의 다양한 문제점 해결하기

이 장에서는 머신러닝 시스템의 성능이 잘 나오지 않을 때 고려할 만한 사항을 살펴보겠습니다. 머신러닝으로 문제를 해결한다는 것은 데이터에 맞는 모델, 적립한 손실함수, 최적화 방법, 평가 방버을 찾는 과정입니다. 처음에서 성능이 잘 나오지 않더라도 너무 실망히지 마시고 개선 방안을 찾아내면 됩니다.

8.1 모델 문제
지금부터 8.2절 '데이터 문제'에서 다룰 데이터 처리, 8.3절 '속도 문제  '에서 다룰 속도 향상 외에 모델 자체에서 비롯된 문제를 해결해서 모텔의 성능을 향상하는 방법을 크게 둘로 나눠 설명합니다. 첫 번째는 학습할 때는 잘 동작했는데 실제로 사용하니 성능이 생각보다 잘 나오지 않는 과학습(오버피팅, 과적합, 과적응) 문제를 해결하는 방안을 알아보고, 두 번째는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다.

8.1.1 과학습
머신러닝 시스템 시스템을 기존 데이터로 학습시킨 후 평가했을 때는 좋은 성능이 나와 학습이 잘되었다고 판단했는데, 새로운 데이터에서 예상대로 성능이 나오지 않는 경우의 원인은 대부분 과 학습 때문입니다. 과학습은 말 그대로 모델이 과하게 학습 데이터에 집중한 나머지 필요 이상으로 패턴을 학습한 경우입니다. 다음 그림과 같은 경우를 들 수 있습니다.

그림 8-1 과학습의 예. 거시적으로는 선형 패턴(점선으로 표시)을 가지는 데이터인데 필요 이상으로 복잡하게 학습한 경우(실선으로 표시)

[그림 8-1]은 과학습의 한 예입니다. 그래프에서 x로 표시된 점은 관착된 데이터입니다. 얼핏 봐도 데이터가 왼쪽 아래부터 오른쪽 위까지의 선형 패턴을 가집니다. 이 데이터를 기반으로 X값이 7일 때의 Y 값을 예측한다면 11 정도가 될 겁니다. 그런데 전체적인 패턴을 무시한 채 학습 데이터를 완벽하게 예측하는 것에만 중점을 두어 모든 점을 지나는  선을 모델로 만들게 되었습니다. 그 결과 실선과 같은 과학습된 모델을 가지게되고 X값이 7일 때의 Y값을 제대로 예측할 수 없게 된 겁니다.

그렇다면 이문제를 어떻게 해결해야 할까요? 그리고 이런 현상이 일어날지 어떻게 미리 알 수 있을까요? 2.1.5.2절 '정규화'와 2.4.1절 '모델의 일반화 특성 평가'에서 이론상으로 다룬 바 있습니다. 이제부터 과학습을 해결하는 실용적인 방법을 알아보겠습니다.

8.1.1.1 학습- 평가 데이터 나누기

과학습 문제를 발견하는 가장 효과적인 방법은 전체 데이터의 일부분만으로 모델을 학습시키고 나머지 데이터를 이용해 모델을 평가해서 얼마나 데이터의 일반적인 패턴을 잘 학습하는지 판단 하는 겁니다. 일반적인 패턴을 잘 파악하지 못하는 모델은 그렇지 않은 모델에 비해 학습용 데이터에서는 좋은 성능을 보이지만, 평가용 데이터에서는 성능이 잘 나오지 않는 현상을 보이게 됩니다. 자세한 내용은 2.4.1절 '모델의 일반화 특성 평가'를 참조하세요

8.1.1.2 정규화
모델의 정규화는 바로 이런 과학습 문제를 해결하기위해 등장했습니다. 정규화는 데이터를 설명할 수 있는 가장 간단한 가정만을 사용한다는 '오컴의 면도날 가정'을 이용하여 과학습을 막습니다. [그림 8-1]을 보면 데이터의 패턴을 설명하기에는 점선이 실선으로 표시된 복잡한 모델보다 더 간단합니다. 이렇게 데이터의 패턴을 복수의 가정으로 설명할 때는 데이터의 패턴에서 심하게 벗어나지 않으면 되도록 간단한 가정을 사용하는 것이 좋습니다.
2.1.5.2절 '정규화'에서 설명했듯이 '데이터의 패턴에서 너무 벗어나지 않는 것'과 '더 간단한 모델을 사용하는 것'의 균형은 정규화 파라미터로 결정합니다. 그렇다면 그 파라미터를 어떻게 결정해야 할 까요? 2.4.1절 '모델의 일반화 특성 평가'에서 설명한 것과 같이 정규화 파라미터를 결정하는 데이터셋을 따로 빼놓고 학습하는 방법을 많이 사용합니다.
정규화 파라미터가 실제로 어떻게 영향을 미치는지 간단한 예제를 통해 알아보겠습니다. 사이킷런의 linear_model.Ridge 클래스는 정규화 파라미터를 지원하는 선형 회귀 클래스입니다. 클래스의 원형은 다음과 같습니다.

class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False, copy_X=True, max_iter=None, tol=0.001, solver='auto', random_State=None)

여기서 정규화와 관련된 파라미터는 alpha인테, 값이 클수록 정규화의 강도가 더욱 강해집니다.
실제로 어떻게 문제가 발생하는지 시각적으로 보여드리기 위해 2차 함수를 따르는 데이터를 만든 후 10차 함수 형태의 모델을 사용하는 경우를 알아보겠습니다(현샐에서는 데이터가 몇 차원 함수를 따르는지 알 수 없으므로 임의로 높은 차원을 가정합니다). 여기서는 구현보다는 어떻게 되는지 설명에 집중하기 위해 자세한 코드는 생략하도록 하겠습니다.

데이터는 다음과 같은 가우스 분포도 생성되었습니다.
y = x*x -2x -1 + 노이즈

그리고 우리 모델은 10차 함수 형태까지 학습할 수 있는 능력을 가진 10차 다항함수를 사용했습니다. 수식으로 나타내면 학습과정에서 상수 부분까지 모두 11개의 파라미터(w10, w9,...w0)를 학습하게 됩니다.

모델이 표현할 수 있는 한계(10차 함수)가 실제 데이터(2차 함수)보다 훨씬 높죠? 이런 경우에 과학습이 심하게 발생할 수 있습니다. 과학습이 나타나는 현상을 실제로 ㄹㄴ덤한 데이터를 만들고 학습해서 시각화해보겠습니다. 먼저 정규화 없이 그냥 모델을 단순하게 학습시킨 결과를 살펴보겠습니다.

[그림 8-2]를 보면 단순히 오목하게 생긴 2차 함수의 패턴을 학습하면 되는데 모델이 필요 이상으로 복잡해서 굉장히 구불구불한 모양으로 학습된 것을 볼 수 있습니다. 똑같은 데이터에 정규화 파라미터 alpha값을 증가시켜 보겠습니다.

그림 8-3 정규화가 있을 때(alpha=0.1)의 변화
[그림 8-2]에 비해 곡선이 훨씬 부드러워졌습니다. 다시 말해, 모델이 표현 가능한 범위보다 좀더 간단한 모델을 사용하도록 강제된 것을 확인할 수 있습니다.

그림 8-4 정규화가 좀 더 강할 때(alpha =1)
[그림 8-4]는 [그림 8-3]보다 더욱 강하게 정규화 값을 설정한 경우입니다. 곡선이 좀 더 부르러워져서 더 간단한 모델이 되었습니다.

이렇게 정규화 파라미터를 조절하면서 필요 이상으로 복잡한 패턴을 학습하지 않도록 머신러닝 모델을 조절할 수 있습니다. 그렇다면 적절한 파라미터 값은 어떻게 찾을 수 있을까요?

그림 8-5 검증용 데이터를 나누어 정규화 파라미터 정하기

1. 데이터를 학습 및 검증용(A)과 테스트(B)으로 나눕니다.
2. A를 다시 학습용(C)와 검증용(V)로 나눕니다.
3. 학습용 데이터에 대해 정당한 정규화 파라미터로 학습을 수행한 후 검증용 데이터를 사용해 성능을 측정합니다. 반봅해서 V에서 가장 성능이 좋은 정규화 파라미터를 찾습니다.
4. 과정 3에서 찾은 정규화 파라미터를 이용해서 A에 대해 학습을 수행합니다.
5. 모델 자체에 대한 평가는 B로 하면 됩니다.

과정 2부터 4까지는 교차 검증을 이용해도 됩니다. 교차검증은 2.4.1.2절 '교차검증'을 참조하기 바랍니다.

8.1.1.3 학습을 일찍 끝내기
정규화와 비슷하지만 훨씬 더 간단한 방식이 있습니다. 이 방식은 딥러닝에서 주로 사용되지만, 그 외의 분야에서도 많이 쓰이고 있습니다. 우선 아래 그래프에서 과학습이 되는 시점에 주안점을 두어 살펴보고 이야기를 더 진행하겠습니다.

그림 8-6 머신러닝 모델을 학습할 때 일반적으로 보게 되는 학습 데이터와 테스트 데이터에서의 손실 곡선

[그림 8-6]은 머신러닝 모델을 학습할 때 보게 되는 일반적인 손실 그래프입니다. 위에 있는 고선이 테스트 데이터에서의 손실, 아래 있는 곡선이 학습 데이터에서의 손실입니다. 학습 데이터에서의 손실은 학습을 진행할수록 줄어드는데, 테스트 데이터에서의 손실은 학습데이터에 모델이 과하게 최적화된 이후 오히려 늘어나게 됩니다. 손실이 늘어나기 시작하는 지점이 바로 과학습의 시작점입니다. 이 지점 이전까지는 학습 효과가 좋았으므로 과학습이 나타나는 시점까지만 학습하면 과학습을 예방할 수 있게 됩니다. 물론 '어느 시점'에 그만둘지 결정하는 것은 쉬운 일이아닙니다. 하지만 정규화가 쉽게 되지 ㅏㅇㄶ는 모델에는 이 방식을 더 유욯하게 사용할 수 있습니다.
딥러닝으로 유명한 힌튼 교수는 '일찍 끝내기(early stopping)는 아름다운 공짜 점심'이라고 표현했습니다. 아주 쉽고 거의 공짜로 이득을 본다는 뜻이죠. 실제로 현업에서도 학습을 완전히 수행하기보다는 최대 몇 번까지 반복한다고(예를 들어 100번) 적당히 정해놓고 학습을 하는 식으로 많이 사용합니다.

8.1.1.4 드롭-아웃(딥러닝 기법)
딥러닝에는 뉴렐넷의 과학습을 예방하는 방법으로 드롭-아웃(drop-out)을 널리 사용합니ㅏㄷ. 본 개념을 먼저 살표고벴습니다.

드롭-아웃은 딥러닝 모델으 ㄹ학습할 때 레이어와 레이어를 잇는 연결 중에서 일정한 확률 p로 몇 가지 연결을 무작위로 끊은 채 학습합니다. 즉, 학습이 진행될 때(파라미터를 업데이트 할 때) 마다 연결이 조금씩 달라진 상태로 딥러닝 모델을 학습하게 됩니다.

1. 아래와 같은 딥러닝 모델이 있다고 합시다. 동그라미는 레이어고, 선은 그것을 잇는 가중치 연결입니다.

2. 학습중 일부 업데이트는 아래와 같이 확률 p에 따라 레이어 연결을 임의로 몇 개 누락시키고 업데이트합니다.

3. 또 다른 업데이트는 다른 패턴으로 임의로 몇 개 누락시키고 업데이트 합니다.

4. 학습이 모두 끝난 후 모델을 실제로 사용할 때는 모든 연결을 사용하지만 p 만큼 연결의 강도를 약화시켜서 사용합니다.

드롭-아웃을 이용한 딥러닝 모델 학습이나 학습된 모델을 사용하는 방법 자체는 앞에서 설명한 것처럼 상당히 간단합니다. 연결을 무작위로 끊으면서 학습하고, 학습된 모델을 사용할 때는 연결 강도를 조절하면 됩니다. 또한 텐서플로에서 라이브러리로 제공하므로 그냥 가져다 쓰면 됩니다. 하지만 왜 이렇게 하는 것이 정규화에 도움이 되는지 이해하기 쉽지 않을 겁니다. 그 이유를 순서에 입각하여 살펴보면 다음과 같습니다.

1. 학습 시 연결을 임의로 몇 개를 끊으면 모델이 더 '간단하게'됩니다.
2. 간단한 모델로 학습하면 원래 모델보다 조금 제한된 모델로 학습이 이루어지게 되고 결과적으로 필요 이상으로 모델이 데이터의 복잡한 패턴을 학습하는 것을 방지하는 효과를 발휘하게 됩니다.
3. 이 과정을 반복하면 간단한 모델들의 밈의 조합을 이용해서 데이터를 설명하려는 시도를하게됩니다.
4. 그 결과 모델은 피처와 레이어 사이의 연결 가능한 모든 레이어 간의 조합에 대해 학습을 수행하는 것이 아니라 적은 연결로 전체를 설명하는 방향으로 학습하게 됩니다.

이 과정은 앞에서 설명한 정규화와 비슷하게 모델을 단순화시키는 효과를 볼 수 있습니다. 드롭-아웃은 구현이 쉬우면서도 딥러닝 모델의 성능을 늘리는데 매유 효과적입니다. 만일 딥러닝기법을 사용한다면 도입을 꼭 고려해보기 바랍니다. 참고로 텐서플로에서는 이 기능을 깁본으로 지원합니다.

8.1.2 좋은 모델을 좀 더 수월하게 찾는 방법
머신러닝은 모델에 따라 성능이 크게 좌우됩니다. 딥러닝이 발전하고 데이터양이 증가하면서 모델 자체에 대한 고민은 예전보다 적어진 듯 보이지만, 그럼에도 더 좋은 성능을 얻으려면 더 데이터에 적합한 모델을 이용하여 학습해야 합니다. 따라서 모델의 중요성은 아무리 강조해도 지나치지 않습니다.

이절에서는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다. 1장과 2장에서도 잠깐 어급했지만'머신러닝을 적용한다'는 것은 '데이터에 적합한 모델과 학습 방법을 차즌ㄴ 일련의 과정을 적용한다'는 뜻입니다. 특히 적합한 모델을 찾는 것은 핵심입니다.

그렇다면 어떻게 하면 적합한 모델을 쉽게 찾을 수 있을 까요? 다음과 같은 방법을 생각할 수 있습니다.

- 간단한 모델부터 적용하기
- 데이터와 모델 시각화 하기
- 모델의 최대 성능 가늠하기

8.1.2.1 간단한 모델부터 적용하기
가장 중요한 원칙은 처음부터 복잡한 모델을 곧바로 적용하는 것이 아니라 간단한 모델을 적용시켜서 성능을 확인해보는 것입니다. 어차피 복잡한 모델이 더 좋은 성능을 낼 확률이 높은데 왜 굳이 시간을 낭비하는지 의문이 들 수도 있을 겁니다. 간단한 모델 부터 테스트해보는 데는 다음과같은 이유가 있습니다.

간단한 모델은 구현이쉽고 학습도 쉽습니다.
대부분의 머신러닝 라이브러리는 선형 휘귀, 로지스틱 휘귀, 레이어가 1개인 뉴런넷 모델 등 간단한 모델을 제공하고 있어 손쉽게 시도할 수 있고 학습도 굉장히 빠릅니다. 또한 적은 학습과 정 튜닝으로 최대의 성능을 쉽게 확인할 수 있습니다. 복잡한 모델은 구현, 학습, 그리고 파라미터 튜닝에 오랜 시간이 걸립니다.

간단한 모델의 성능은 다른 모델이 얼마나 잘 동작하는지에 대한 지표가 됩니다.
간단한 모델을 실제 시스템에 사용하지 않더라도 그 성능을 더 복잡합 모델의 성능 지표로 삼을 수 있습니다. 복잡한 모델의 1차 구현물이 간단한 모델의 성능보다 월등히 좋지 않다면 뭔가 개선 방법을 찾아야 합니다. 반대로 간단한 모델보다 성능이 좋다면 모델이 잘 작동한다고 판단하고 튜닝에 돌입하면 됩니다.

간단한 모델은 원인을 파악하기가 상대적으로 쉽습니다.
모델의 성능이 떨어지는 원인은 다양합니다. 데이터 처리 버그, 모델의 학습방법, 아니면 그냥 문제 자체가 예측이 어려운 경우일 수도 있습니다. 이유가 뭐든 간단한 모델일 때보다 복잡한 모델에서 문제의원인을 찾기가 상대저그로 어렵다는 건 두말할 필요 없을 겁니다. 먼저 간단한 모델을 사용해서 전체가 잘 동작하는지 검증한 후 복잡한 모델을 적용하기 바랍니다.

8.1.2.2 데이터와 모델 시각화하기
데이터를 시각화해보는 것도 적합한 모델을 찾는데 도움이 됩니다. 하지만 추가 노력이 들기 때문에 생략하는 경우도 적지 않습니다. 전체 데이터를 완전히 시각화하지 않더라도 패턴을 살펴볼 수 있는 수준이면 도움이 됩니다. 그 이유는 다음과 같습니다.

데이터 이상 파악
예를 들어 일반적인 선형 회귀를 해보려고 생각하고 있었는데, 데이터를 시각화해보니 데이터가 선형적인 양상이 아니라 로그 스케일을 따른다든가, 소수점 단위를 예상하고 있었는데 음수가 나온다든가, 혹은 기본값이 특이하게 들어 있는 경우를 생각할 수 있습니다. 실숫값을 기대하고 있었는데 정숫값만 존재하거나 카테고리 ID가 들어오는 경우처럼 데이터 자체에 대한 가정에 문제가 잇는지 등도 파악하기 좋습니다.

데이터 특성 파악
데이터를 분석할 때 가장 기본적인 것은 데이터가 정규 분포를 따른다고 가정하느 것입니다. 대부분의 경우에는 큰 무리가 없지만, 가끔 데이터가 정규분포를 크게 벗어난느 경우가 있습니다. 예를 들어[그림8-7]과 같이 데이터가 한개 의 정규분포(가우스분포)를 따르지 않는 경우입니다. 이 경우에는 2개의 정규분포를 포함하는 머신러닝 기법이 적합합니다.

모델 동작 방식 이해
데이터를 시각화 하는 것과 함께 모델의동작 결과를 시각화하는 것도 많은 도움이 됩니다. 예를 들어 분류 모델의 경우에는 모델이 각 데이터 포인트를 어떻게 분류하는지, 희귀모델의 경우에는 모델이 출력하는 결괏값이 어떻게 분포된느지 시각화하면 모델이 어떤 방시긍로 동작하는지 이해하는 데 도움이 됩니다.

시각화는 이책의 여러붑ㄴ에서 쓰였는데, 8.2.3.2 절'데이터의 값이 치우쳐 있을 때'에서는 데이터를 시각화에서 데이터의 편중 정도를 파악하고, 8.1.1.2절 '정규화'에서는 모델을 시각화해서 실제로 정규화가 모델에 어떻게 영향을 미치는지 살펴 보았습니다.

아래 URL에 방문하면 사이킷런에서 사용할 수 있는 다양한 시각화 예제를 확인할 수 있습니다.

http://scikit-learn.org/stable/suto_examples/

|2차원 이상의 데이터 시각화하기|
2차원 이상의 데이터를 시각화하는 일은 쉽지 않습니다. 데이터들의 상관관계를 이용해서 2차원으로 관곌르 재정의해서 그리는 방법이 있는데, 데이터의 절대좌표를 직접 입력하는 것이 아니라 한 데이터의 위치가 다른 데이터와 얼마나 다른지 상대거리를 이용해서 시각화하게 됩니다. 그리고 데이터의 절대거리보다는 근처에 있는 점들과의 관계를 보존하는 방법으로 시각화합니다. 이런 경우에 t-SNE 같은 방법이 특히 많이 이용됩니다. 예를 들어 텐서플로 튜터리얼에서 t-SNE를 사용하여 단어 벡터들을 시각화한 예를 착을 수 있습니다. 더 자세한 사항은 해당 튜터리엉ㄹ을 참고하세요. 대표적으로 Isomap, L.I.E, MIDS와 같은 방법이 있습니다. 자체한 사항은 사이킷런 홈페이지를 참고하세요.

8.1.2.3 모델의 최대성능 가늠하기
구현한 모델이 99.99% 정확도를 보인다면 더할 나위 없겠죠, 반대로 성능이 너무 좋지 않나면 더 적극적으로 새로운 모델을 찾아봐야 할 겁니다. 그러면 과연 성능이 얼마나 좋은지 어떻게 판단 할 수 있을까요? 지금 얻은 성능의 수치는 낮지만 사실 엄청나게 잘하고 있는것 아닐까요? 단순히 성능 수치만으로는 애매한 부분이 있기 때문에 가능한  한 최고 성능르 가늠해보고 현재 어느 정도 수준인지 판단하는 것이 중요합니다.

물론 최고 선을을 가늠하는 것은 쉽지 않은 일입니다. 대에 따라 다르겠지만 다음과 같은 시나리오를 생각할 수 있습니다.

머신러닝 시스템과 사람의 성능 비교
사람의 직접 해당 일을 수행했을 때 얻을 수 있는 정확도 등의 예측 성능은 좋은 지표가 됩니다. 예를 들어 몇 명의 수동으로 이미지에 보이는 몰체를 태깅하거나 분류한 다음 평균 성능을 평가하여 머신러닝 시스템이 얼마나 잘 동작하는지 가늠해보는 겁니다. 예를 들어 아마존 메커니컬 피크는 수많은 사람에게 태깅을 부탁하고 소액을 지불하는 크라우드 소싱을 이용합니다. 만일 사람조차도 공통 의견을 만들기가 쉽지 않다면 머신러닝 시스템도 좋은 성능을 내기 쉽지 않을 겁니다.

이론상 성능의 한계나 보장된 값이 존재할 때
데이터에 따라 다소 제한적이긴 하지만 보장된 성능이 존재하는 경유가 있습니다. 예를 들어 제품의 불량률이 정해져 있고, 센서가 얻을 수 있는 불량에 대한 정보에 한계치가 있다면, 이 두요소에 의존하여 불량을 판볻하는 시스템의 성능에는 한계가 있겠죠. 이와 같은 정보를 미리 알면 현재 머신러닝 시스템이 얼마나 잘 동작하는지 알 수 있습니다.

8.2 데이터 분제
학습 데이터가 어떻게 구성되어 있는지에 따라 학습 성능이 크게 달라집니다. 이 장에서는 데이터가 너무 많거나 너무 적거나, 아니면(가장 일반적인) 치우침이 심할 때 어떻게 하면좋을지 살펴보겠습니다. 참고로 8.1.2.2절 '데이터와 모델 시각화하기'에서 언급한 데이터 시각화도 이런 데이터의 특성을 이해하는데 도움이 됩니다.

8.2.1 데이터가 너무 많을때
앞서 머신러닝에서 데이터가 많을 수록 좋다고 언급했습니다. 이론상으로는 데이터가 많을 수록 성능이 좋은 모델을 얻을 수 있지만, 데이터가 많으면 처리 시간이 오래 걸리기 때문에 문제가 될 수 있습니다. 특히 같거나 비슷한 데이터가 많이 들어오는 경우를 생각해 봅시다. 예를 들어 1분마다 물체의 움직임을 감지하여 데이터를 송신하는 센서를 이용하여 물체의 이동 곙로를 학습하는 모델을 만들려고 할 때 물체가 거의 정지해 있다면 대부붕의 데이터가 움직임 없음(0)으로 채워질 겁니다. 또 다른 경우는 특정 분류 항목의 데이터가 너무 많아서 전체 적으로 학습이 오래 걸리는데 그렇지 않은 항목은 적은 경우가 있습니다. 예를 들어 사진 데이터에서 하늘이나 구름 사진은 어첨 많은데 휘귀한 동뭀진은 적은 경우가 있습니다. 이를 해결하기 위해 다음과 같은 방법을 생각해 볼 수 있습니다.

과소표집
과소표집(언더샘플링)은 전체 데이터셋에서 데이터를 무작휘 확률로 선택해서 선택된 데이터로 이우러진 작아진 데이터셋을 사용하는 방식입니다. 데이터를 무작위로 선택하는 방법은 다양하지만, 가장 중요한점은 데이터의 특성과 상관없이 뽑아야 한다는 것입니다. 예를 들어 사용자 구매 이력 데이터에서 50%확률로 데이터를 뽑는것은 괜찮지만, 사용자 이름 가나다순으로 정렬된 데이터셋의 앞부분 절반만 사용하는 것은 데이터으 ㅣ특성을 바꿀 수 있기 때문에 안됩니다.

중요도 표집
중요도 표짐(중요도 샘플링)은 데이터의 중요도에 따라 선택 확률을 변도하여 샘플링하는 기법이다. 무작위 확률로 선택하다 보면 특정 경우에 해당하는 데이터가 거의 없어지는 문제가 발생할 수 있습니다. 예를 들어 이미지 분류 문제를 푼다고 가정합시다. 학습용 데이터에서 '하늘'에 해당하는 이미지는 엄청 많은데 '오리너구리'에 해당하는 이미지는 적다고 합시다. 이런 경우 이미지를 무작위로 선택하면 오리너구리 이미지는 정말로 적은 수만 남게 됩니다. 그러면 오리너구리에 대한 학습이 제대로 이루어지지 못하겠죠. 이런 경우에는 데이터의 중요도에 따라 선택확률을 변동시키는 방법이 더 적합합니다. 예를 들어 하늘에 해당하는 사진은 10%의 확률로 뽑고 오리너구리 사진은 너무 개수가 적으니 80%의 확률로 뽑는 방법을 고려 할 수 있습니다.

피처 선택
'피처 선택'은 중요한 피처만 선택해서 전체 학습률과 성능을 증가시키는 방법입니다. 피처가 많으면 학습에 사용하는 데이터가 많아 학습률이 느려지고,  모델이 복잡해져서 과학습을 할 우려가 있습니다. 피처를 고르는 방법으로 '카이제곱 피처 선택법', '상호-정보 피처 선택법', '검증셋에서의 성능'이 주로 사용됩니다. 어떤 방법을 사용하든 성능에 도움이 되는 피처는 고르고 그렇지 않은 피처는 삭제하는 방향으로 진행됩니다.

1. 카이제곱 피처 선택법(이하 카이제곱 선택법): 피처와 성능 간의 통계학적 독립성을 테스트하는 방법입니다. 성능과 연관이 많은 피처는 나두고 그렇지 않은 피처는 제거합니다.
2. 상호-정보 피처 선택법(이사 상호 정보 선택법):중요한 피처만 선택하는 것은 카이제곱 선택법과 같지만, 실제로 계산하는 방법과 의미는 약간 다릅니다. 카이제곱 선택법이 각 피처가 모델의 성능에 얼마나 통계적으로 유의미한 기여를 하느냐를 검토한다면, 상호-정보 선택법은 선택한 피처 한 쌍이 서로 예측하는 데 얼마나 도움이 되느냐를 검토합니다. 결과적으로 상호-정보 선택법은 카이제곱 선택법보다 좀 더 자주 나오는 피처를 선택합니다.

3. 검증셋에서의 성능: 학습용 데이터에서 검증용 데이터를 따로 분리하여 피처의 일부만을 사용해서 모델을 학습한 후 검증셋에서의 성능 평가를통해 어떤 피처가 좋을지 측정합니다.
앞의 방법을 통해 전체 피처 셋에서 피츠를 하나씩 제외하거나, 아니면 아무것도 없는 상태에서 가장 많이 도움 되는 피처를 하나씩 추가하는 식으로 사용할 피처를 결정합니다.

8.2.2 데이터가 너무 적을때
데이터가 적을 때 할 수 있는 일은 그렇게 많지 않습니다. 다음과 같은 방법을 통해 약간이나마 개선해볼 수는 있습니다.

8.2.2.1 레이블된 데이터는 별로 없지만 일반적인 데이터가 많은 경우(표현형 학습)
이런 경우에는 먼저 데이터의 일반적인 특성을 배우는 학습을 휴행하여 얻어진 정보를 이용해서 추가로 학습하ㅕㄴ 어느 정도 효과를 볼 수 있습니다.

예를 들어 제품 리뷰를 받는 사이트에서 제품에 대한 리뷰가 호의적이거나 적대적인지 판단하는 모델을 만든다고 가정해 봅시다. 이 모델을 학습시키면 각 리뷰에 대해 '호의적' 또는 '적대적' 레이블이 붙어 있어야 합니다. 사용자가 리뷰를 작성할 때는 호의적 또는 적대적이라고 명시하지 않으므로 이런 데이터셋을 만들려면 사람이 수작업으로 각 리뷰가 어떤 성격인지 일일이 체크해야 합니다(별점 데이터가 있다면 4점 이상이면 호의적, 2점 이하면 적대적이라고 레이블하기도 하지만, 이 경웅에도 문장 단위의 호의적 또는 적대적 레이블은 어렵습니다). 이런 수작업 레이블이 없는 이뷰는 손쉽게 많은 양을 얻을 수 있습니다. 그렇다면  이러한 리뷰를 통해 리뷰의 일반적인 패턴(예를 들면 어떤 단어가 많이 나오는지 파악해서 단어의 의미를 추론)을 먼저 추출해서 리뷰를 잘 표현할 수 있는 간명한 표현ㅅ형을 만든 다음, 실제 레이블을 가진 리뷰를 표현형으로 변환한 뒤 이를 이용해 분류를 합니다. 이렇게 데이터 자체에 대해 알고 있는 정보의 도움을 받아서 성능을 향상할 수도 있습니다.
이러한 과정을 딥러닝에서는 표현형학습 혹은 비지도 선행학습 등의 분야에서 다룹니다. 유명한 방식으로는 오토인코더나 토픽 모델링이 있습니다. 이 중 토픽 모델링은 5.2절 '토픽 모델링'에서 다뤘습니다.

8.2.2.2 전이학습
전이학습은 성격이 다른 데이터셋(예를 들면 이미지와 텍스트 데이터)을 이용해서 학습시킨 모델을 현재 데이터셋에 적용하는 방법입니다. 넓은 의미로는 다른 데이터셋에서 얻은 정보를 이용해서 현재 문제의 성능을 향상시키는 방법도 포함합니다. 앞서 다룬 방법에서는 데이터 성격이 모두 같았지만, 전이 학습에서는 데이터 성격이 다릅니다. 예를 들어 리뷰 데이터 분석을 하는 경우 백과사전이나 제품의 이미지 등을 이용해 모델을 학습시킨 후, 그 모델을 이용해 리뷰가 호의적인지 적대적인지 예측하는 겁니다.

이렇게 다른 성격의 데이터를 이용하여 학습시킨 모델을 활용하는 방법은 생각보다 쉽지 않습니다. 다행이 딥러닝에서는 중간 레잉어를 공유하는 방식으로 생각보다 쉽게 이런 정보를 이용할 수 있습니다. 더 자세한 내용은 이 책의 범위를 벗어나므로 이런 정보가 있다는 정도만 알아두기 바랍니다.






2018년 3월 17일 토요일

CHAPTER 7 이미지 인식 시스템 만들기

이미지 인식은 전자상거래 사이트의 상품인식, 디지털 카메라 및 구글 포토의 얼굴 인식, 자율 주행 자동차의 도로상황 파악 등 다양한 곳에서 사용됩니다. 또한 최근 딥러닝의 발달로 인식 성능과 처리 속도가 놀랍게 향상되어 응용범위가 확대되고 있습니다.

이 장에서는 이미지 인식의 기본 개념과 자주 사용되는 피처에 대해 알아보고, 이미지에 담긴 물체의 카테고리를 정하는 물체 분류와 이미지에 담긴 물체를 인식하는 물체인식 기법을 소개합니다. 또한 이미지 인식에서 최근 각광받고 있는 딥러닝 기법인 CNN(합성곱 신경망)에 대해서도 살펴봅니다.

7.1 이미지 처리 기본 개념
이 절에서는 이미지 처리에서 사용하는 기본 개념인 픽셀, 필터링, 합성곱에 대해 알아보겠습니다.

7.1.1 픽셀
디지털 이미지는 픽셀로 구성되어 있습니다. 화면 크기가 17인지, 해상도가 1920*1080픽셀이라는 표현에는 아마 다들 익숙할 겁니다. 픽셀은 컴퓨터 모니터에서 표시할 수 있는 가장 작은 단위라고 생각하면 됩니다. 픽셀은 밝기의 강도(intensity)와 컬러 채널값을 가집니다.

그레이스케일 이미지에서 각 픽셀은 흰색(강도 255), 검은색(강도 0), 다양한 강도의 회색(1~124)으로 채워져 있습니다. 컬러 이미지는 픽셀 하나가 R,G,B 세 채널로 구성되고 각각 0~255의 강도를 가집니다. 예를 들어 빨간색은 [255,0,0], 녹색은 [0, 255,0], 파란색은 [0, 0, 255]이런식입니다. 따라서 채널별로 높이 m픽셀과 넓이 n픽셀을 가지는 이미지를 m*n행렬로 표현할 수 있습니다. 채널이 하나인 그레이 스케일 이미지는 m*n*1행렬로, 컬러 이미지는 m*n*3 행렬로 표현할 수 있습니다.
이미지를 픽셀 좌표(x,y)의 강도값을 변환하는 함수로 볼 수도 있습니다. 즉 I(x,y) = 강도값인 함수가 됩니다. 이 함수를 이미지 강도함수 혹은 강도함수라고 합니다.

7.1.2 필터링
기존 이미지의 픽셀값을 선형적으로 조합하여 새로운 픽셀값으로 변환한 뒤 그 픽셀들로 새로운 이미지를 생성하는 것을 필터링이라고 합니다. 필터링은 결괏값이 저장될 픽셀 좌표의 +-1, +-2... 범위의 ㅍ픽셀 정보를 조합하는 방식을 사용합니다. 예를 들어 가로3개*새로3개= 9개의 픽셀 정보를 조합한다면 3*3 크기의 원도우(혹은 커널)를 사용합니다. 자주 사용되는 원도우 크기로는 3*3와 5*5가 있습니다.
대표적인 필터링 방식으로 이동평균 필터링이 있습니다. (그림 7-3). (2n+1)*(2n+1)크기의 원도우를 사용하여 이동평균 필터링을 적용할 경우, 목표 픽셀에서 +-n위치의 값을 모두 ㄷ더한 후 (2n+1)(2n+1)(원도우의 넓이)로 나누면 됩니다. 예를 들어 [그림 7-3]의 첫 번째 이미지는 새 이미지의 G의 (1,1) 픽셀값을 정하기 위해 이전 이미지 F의 (0,0), (0,1), (0,2), (1,0), (1,1), (1,2),(2,0), (2,1), (2,2) 픽셀값을 모두 더한 후 9로 나누었습니다. 이 작업을 이미지 F의 모든 픽셀에 대해 반복합니다.
하지만 이미지 G의 (0,0)픽셀을 생성하려면 이미지 F의 (-1,-1), (0,-1), (1,-1), (0,-1), (0,0), (0,0), (1,-2), (1,0), (1,1)픽셀값이 필요한데, -로 시작하는 픽셀은 존재하지 않습니다. 이와 같이 이미지의 네 가장자리 픽셀은 원도우 안의 픽셀값이 비어 있기 때문에 별도로 처리합니다. 네 가장자리의 픽셀값을 처리하는 방ㅂ버으로 이미지 바깥 값을 0으로 채우는 제로 패딩(zero-padding)과 이미지 바깥 값을 가장 가까운 가장자릿값으로 처리하는 가장자릿ㄱ밧 복제(edge value replicaiton)가 있습니다. 그림으로 나타내면 [그림 7-4]와 같습니다. 일반적으로는 제로 패딩을 많이 사용합니다. 이동평균 필터링은 픽셀을 주벼 ㄴ픽셀값의 평균으로 변환하므로 더 부드러운(스무딩된) 이미지를 생성합니다. 이동평균 외에도 원도우 안의 픽셀 주 최댓값으로 픽셀을 생성하는 최댓값필터링, 단순히 주변 값들의 편균을 구하는 대신 거리에 따라 차등을 주는 가우스 필터링(혹은 가우스 원도우), 이미지의 경계선을 얻어내는 엣지 필터링 등이 있습니다. 이러한 필터링 방식은 다음 절에서 설명하는 합성곱 원도우를 용도에 맞게 설정하여 구현할 수 있습니다.

7.1.3 합성곱
필터링 방식은 합성곱(convolution)의 특별한 경우입니다. 사실 이미지 처리에서의 필터링은 합성곱의 적용이라고 생각해도 됩니다. 합성곱은 함수와 이동한 함수의 값을 곱한 다음, 구간에 대해 적분하여 새로운 함수를 구하는 연산입니다. 연산 기호는 *입니다. 함수 f와 함수 g의 합성 곱 f*g를 식으로 표현하면 다음과같습니다.
(f*g)(t) = 적분(f(임의의값)g(함수입력값 - 암의의값)d*암의의값

함수의 이동은 함수의 그래프를 일정 방향으로 평행이동 혹은 대칭이동하는 것 입니다. 중학교에서 배운 이차함수의 이동을 떠올리면 이해하기 쉬울 겁니다. 함수 y = f(x)에 대한 이동을 식으로 표현하면 다음과 같습니다.

- p 만큼 평행이동 : y = f(x-p)
- x 축 대칭 이동 : -y = f(x)

따라서 합성곱은 함수 g를 임의의 축으로 대칭이동 하고 t마큼 평행이동한 후 , f(임의의 값)와 곱하고 그 결괏값을 적분하는 연산입니다. 여기서 적분 범위는 함수 f와 g의 범위에 따라 달라집니다. 대칭이동은 반전이라고 합니다. 합성곱은 적분을 하는 것으로 입력값 t와 적분 구간의 정보를 동시에 고려하는 값을 얻게 되므로 연속된 값으로 이루어지는 신호 처리, 시계열 분석 등 다양한 분야에 사용됩니다.

7.1 절에서 언급한 대로 이미지는 함수로 볼 수 있으므로 이미지를 합성곱 계산의 입력으로 사용할 수 있습니다. 이미지 함수는 연속함수가 아닌 이산함수이므로 적분대신 총합을 사용합니다. 또한 전 구간의 값을 더하는 것이 아니라 원도우 안의 값만 더하므로 위 식이 다음과 같이 바뀝니다.

f*g(n) = -M에서 M의 총합(f(n-m)g(n))

n: 원도우의 중심
2M: 원도우의 한변의 길이

위 식을 말로 표현하면 다음과 같습니다.
1. f로 정의된 운도우 안의 값이 x,y 좌표 반전
2. 1에서 만든 원도우로 이미지g를 흟으면([그림 7-3]의 원도우 이동 참조) 원도우 안의 값과 원도우를 적용할 이미지 g부분의 강도값의 내적을 계산
3. 2에서 생성된 값으로 새로운 픽셀값 생성

그림으로 표현하면 [그림 7-6]과 같습니다. 원도우를 반전하는 것으로 상화좌우가 바뀐 것을 볼 수 있습니다. 새 합성곱 이미지의 좌표(1,1)안에 들어갈 강도값을 계산하기 위해 원래 이미지의 좌표(1,1)이 원도우의 중심이 되도록 포갭니다. 이때 앞에서 살펴본 제로 패딩으로 가장자리 값을 채움니다. 합성곱 이미지의 (1,1)좌표의 강도값은 다음과 같습니다.

i * 5 + h * 6 + g * 0 + f * 8 + e * 9 + d * 0 + c * 0 + b * 0 + a * 0

합성곱을 이미지에 적용할 땐느 좌우대칭 필터를 사용하는 경우가 대부분이므로 반전의 영향을 미치지는 않습니다. 또한 7.4절 '딥러닝을 이용한 이미지 인식'에서 살펴볼 CNN(합성곱 신경망)도 원도우를 반전하지 않습니다. 하지만 이미지를 이동하는 필터라면 반드시 반전을 해야 원하는 결과를 얻을 수 있습니다. 원도우 안에 있는 픽섹값들을 합하여 하나의 픽셀로 만드는 이유는원래 이미지에 있던 여러 픽셀의 정보를 하나로 모으기 위해서입니다.

합성곱을 이용한 계산은 원도우를 어떻게 지정하냐에 따라 이동뿐만 아니라 블러, 샤프닝 등 다양한 효과를 이미지에 적용할 수 있습니다. GNU 이미지 편집 프로그램(GIMP)사이트 에서 다양한 원도우에 의한 합성곱 결과를 확인할 수 있습니다.

7.2 이미지 인식
이미지 인식 태스크에 대해 알아보겠습니다. 이미지 인식 태스크는 크게 다음과 같이 나뉩니다.

- 이미지 분류(image classification):이미지에 특정 물체가 존재하는지 여부를 판단합니다. 예를 들어'[그림 7-7]에 고양이가 존재하는가?'라는 물음에 '그렇다', '아니다'로 분류하는 것이죠
- 이미지 검출(image detection):이미지에 어떤 물체가 존재하며, 어디에 존재하는지 판단합니다. '[그림 7-7]'에 무엇이 있는가? 그리고 그것이 어디에 있는가?' 라는 더 구체적인 질문에 대해 답을 해야 합니다.

7.2.1 이미지 분류
어떻게 해야 위 이미지가 고양이와 관련되었다고 할 수 있을까요? 여러 개의 비슷한 고양이 이미지를 이용하여 분류기를 학습시키면 됩니다. 5장에서문서를 이루는 단어들을 이용하여 피처를 생성하고 문서를 분류하는 방법을 배웠습니다. 이미지도 마찬가지로 이미지를 이루는 픽셀을 이용하여 피처를 생성할 수 있습니다. 피처는 크게 전역 피처와 지역피처로 나눌 수 있습니다. 전역 피처는 하나의 이미지에서 한만 얻을 수 있으며 이미지의 강도 히스토그램이 그 예입니다. [그림7-8]은 이미지(왼쪽)에서 추출한 강도 히스토그램(오른쪽)을 보여주고 있습니다. 강도 히스토그램의 x축은 강도값(0~255), y축은 그 강도값을 가지는 픽셀 수 입니다.
하나의 이미지에서 얻을 수 있는 지역 피처의 종류는 다양합니다. 대표적인 지역 피처로 이미지안 물체의 코너를 들 수 있습니다. 코너에 대해서는 7.3.2 절 '코너'에서 자세히 설명할 겁니다. 이미지에서 전역 피처와 지역 피처를 추출한 뒤 이를 이용하여 이미지를 군집화하거나 분류기를 만들어 이미지 분류하게 됩니다.

7.2.2 이미지 검출
이미지 검출은 이미지에 존재하는 물체가 무엇인가, 어디에 있는지 인식합니다. 분류와 달리 어떤 물체인지에 대한 정보가 없으므로 인식하려면 우선 이미지에서 한 물체를 이루는 픽셀들을 분할해야 합니다. 이미지 분할은 이미지 내부에 있는 관련 픽셀들을 모아 그룹을 만드는 것으로, 픽셀 군집화로 생각할 수 있습니다. 그러므로 4장에서 살펴본 군집화 알고리즘을 사용할 수 있습니다. 이때 주로 사용되는 피처는 픽셀의 강도와위치 입니다.

예를 들어 파워포인트의 배경 제거 기능(그밀 7-9)은 이미지 분할의 예입니다. 파워포인트에서는 이미지의 배경을 제거하는 기능을 제고하는데 이때 그랩컷(GrabCut)기법을 이용한 이미지 분할이 사용됩니다. 그랩컷은 선택한 영역의 중앙에 사용자가 인식하고 싶은 물체가 있다고 가정하고, 그 물체 주위로 사각형을 그립니다. 그 후 사용자로부터 보조 입력을 받아 더욱 정확한 배경 범위를 찾습니다. 사용자의 보조 입력을 받기 때문에 그랩컷을 대화형 전경 추출법(interactive foreground extraction)이라고 부릅니다.

7.3 이미지 인식에 사용하는 피처
머신러닝으로 모델을 학습시킬 때 무엇을 피처로 삼아 학습해야 할지 알려줄 필요가 있습니다. 5장에서 문서를 분류할 때는 단어 빈도, TF-IDF등 텍스트와 관계된 피처를 사용했습니다. 이미지 분류에서도 이미지에 특화된 피처를 사용하는데, 이 절에서는 윤곽선, 코너, SIFT등의 이미지 인식과 검출에 사용하는 고전적인 피처에 대해 살펴보겠습니다.

7.3.1 윤곽선
흑백만화나 수묵화 등의 이미지는 색이나 질감에 대한 정보 없이 선으로만 이루어져 있는데도 사람들은 그 이미지에 있는 물체를 쉽게 판별합니다. 이는 사람이 윤곽선(edge)혹은 실루엣을 통해 물체를 인식하기 때문입니다. 그래서 이미지 안에 있는 물체를 인식하고자 이미지 안에 있는 윤곽선을 검출하는 방법에 대한 많은 연구가 있었습니다. 윤곽선을 검출하려면 이미지에서의 픽셀 강도값의 급격한 변화(혹은 불연속성)를 검출하면 됩니다.[그림 7-11]을 보면 이해하기 쉬울 겁니다.
가장 왼쪽의 이미지에서 윤과석을 찾는다고 생각해봅시다. 윤곽선은 검은 직석과 흰색 바탕의 경계선입니다. 회색 선이 지나가는 픽셀들의 강도값을 보면, 흰색(255)에서 검은색(0)이 되었다가 횐색(255)이 됩니다. 강도값을 함수로 나타낸 것이 가운데 이미지입니다. 이 강도 함수를 1차 미분하면 흰색에서 검은색이 되는 부분, 검은색에서 다시 흰색이 되는 부분에 미분의 최솟값과 최댓값(이 둘을 합쳐 극값이라고 합니다)이 나옵니다. 즉, 강도함수의 극값이 존재하는 곳에 윤곽선이 존재하고, 이 극값은 회색 선에 수직으로 존재합니다. 윤곽선 검출에 가장 널리 사용되는 캐니 윤곽선 검출기(canny edge detector)도 위 성질을 이용합니다. 1차 미분값은 노이즈에 굉장히 약하기 때문에 캐니 윤곽선 검출기는 가우스 값으로 채워진 원도우에 합성곱을 적용하여 노이즈를 줄이고, 여러 윤곽선 후보를 이용하여 최종 윤곽선을 만들때 복수의 임계치를 이용하여 검출 정확도를 높입니다. 캐니 윤곽선 검출기는 13장에서 살펴볼 이미지 라이브러리인 OpenCV를 비롯한 다양한 이미지 처리 라이브러리를 이요하여 쉽게 구현할 수 있습니다.

7.3.2 코너
[그림 7-8]에서 살펴본 이미지의 강도 히스토그램이나 [그림 7-10]의 윤곽선을 이용하면 이미지를 잘 분류할 수 있을 것 같습니다. 하지만 같은 장소를 찍은 사진이라 하더라도 시간대나 날씨에 따라 사진을 구성하는 색이 다릅니다. 윤곽선은 물체의 각도가 조금만 달라져도 완전히 바뀌므로 다양한 상황에서의 물체 인식에는 적합하지 않습니다.

그렇다면 어떻게 다양한 상황에서도 같은 물체로 인식할 수 있을까요? 이미지를 더 정확히 인식하려면 학습에 사용되는 피처가 회전 불변성(rotation invariance), 크기 불변성(scale invariance), 평행이동 불변성(translation invariance)을 만족시켜야 합니다.

- 회전 불변성: 같은 물체가 있는 이미지를 찾을 때는 (이미지 매칭)물체 방향의 변화에 영향을 받지 않아야 합니다.
- 크기 불변성: 이미지의 척도 변화에도 영향을 받지 않아야 합니다.
- 평행이동 불변성: 한 이미지 안에서 물체가 움직여도 같은 물체라고 인식할 수 있어야 합니다.

강도 히스토그램과 같이 이미지 전체에서 뽑아내는 전역 피처나 이미지 전체의 윤곽선만으로는 위 성질을 만족시키기 어렵습니다. 따라서 이미지 인식에서는 이미지의 일부분에서 뽑은 지역 피처를 많이 이용합니다.

회전 불변성과 평행이동 불변성을 만족시키면서(크기 불변성은 만족시키지 못합니다) 이미지에서 대량으로 얻을 수 있는 대표적인 지역 피처로 코너(corner)가 있습니다. 이미지에 있어서 코너는 선이 꺽이는 모든 곳에 존재하므로 많이 얻을 수 있고, 또한 한 이미지에 하나만 있는 전역 피처가 아닌 이미지의 부분에서 얻는 지역 피처이므로 물체의회전에 영향을 덜 받습니다. 다음 그림은 [그림 7-10]의 이미지에서 코너를 찾은 것입니다.
캐릭터의 눈썹 끝, 눈, 코에 코너가 존재한다는 것을 알 수 있습니다. 따라서 캐릭터가 회전하더라도 이미지에서 눈썹, 눈, 코를 검출할 수 있을 것이고 윤곽선보다는 더 강한 피처가 될 겁니다.
그럼 어떻게 코너를 검출할 수 있을까요? 7.3.1절 '윤곽선'에서 윤곽선을 찾을 때 강도의 변화를 검출했습니다. 코너도 마찬가지로 강도의 변화를 검출하는데, 여러 방향에서 강도의 변화가 일어나는 곳을 검출합니다.
[그림 7-13]에서는 이미지의 영역을 평면, 윤곽선, 코너로 나누었습니다. 작은 사각형(원도우)을 움직이면서 강도 변화를 관찰하느데, 평면인 경우는 원도우를 모든 방향으로 움직여도 강도 변화가 없습니다(상하좌우가 다 검정색입니다). 윤곽선인 경우는 윤곽선의 방향([그림 7-13]에서 수직선)을 따라 움직이면 강도 변화가 없습니다. 하지만 코너의 경우 어느 방향으로움직여도 강도 변화가 나타납니다.
이 성질을 이용하여 코너를 검출하는 대표적인 기법으로 해리스 코너 검출기(Harris corner detection)가 있습니다. 헤리스 코너 검출기는 x축 미분값,  y축 미분값, 그리고 x축 미분값 * y축 미분값을 이용하여 2*2의 정방행렬을 만든 후 , 그행렬을 고윳값 분해하여 고유벡터가 고윳값을 찾습니다.

행렬의 고윳값 분해는 6.4.1절 '평균 제곱근 편차'에서 설명한 대로 행렬을 이루는 기본 요소를 찾는 방법 중 하나입니다. 특잇값 분해와 달리 고윳값 분해는 선형독립인 정방행렬에만 적용할 수 있습니다. 선형독립인 행렬 A는 간단히 말해 v가 O벡터일 경우만 Av = O를 만족하는 행렬입니다.

정방행렬 A와 A의 고유벡터 v, 고윳값 Y의 관계를 수식으로 표현하면 다음과 같습니다.
AY = Yv
즉, 고유벡터란 행렬 A가 곱해져도 그 방향(v)이 변하지 않고 크기(Y)만 변하는 벡터를 말합니다. 행렬 A가 정방행렬이고 선형 독립일 경우 다음과 같이 분해할 수 있습니다.

강도함수의 x축, y축 미분값으로 이루어진 행렬이 이미지 안의 강도값의 변화를 나타낸다는 점을 생각해보면 그 행렬을 분해한 고유벡터는 변화의 축(방향)이 되고 고윳값은 강도 변화의 크기라고 볼 수 있습니다. 그리고 앞에서 말했듯이 해리스 코너 검출기는 2*2의 정방행렬을 분해하므로 두 고유벡터와 두 고윳값이 나올 겁니다. 이 과정에서 얻은 두 고윳값을 이용하여 이미지 부분을 평명, 윤곽선, 코너 중 하나로 결정합니다. [그림 7-14]를 보면 이해하기 쉬울 겁니다. 한 고윳값이 다른 한 고윳값보다 매우 클 경우, 즉 한쪽 방향으로만 강도가 급격히 변할 경우 윤곽선이 됩니다. 두 고윳값이 모두 클 경우, 즉 모든 방향으로 강도가 급격히 변할 경우 코너, 두 고윳값이 둘 다 작으면 평면이 됩니다. 헤리스 코너 검출기로 캐니 윤곽선 겸추기와 마찬가지로 특별한 구현 없이 라이브러리로 바로 사용할 수 있습니다.

7.3.3  SIFT
SIFT(Scale-Invariant Feature Transform:크기 불변 피처 변화)는 크기 불변성, 회전 불변성, 평행이동 불변성을 동시에 만족시키는 피처를 생성하는 기법입니다. 7.3.2절 '코너'에서 회전불변성, 크기 불변성, 평행이동 불변성을 만족시키며 대랴응로 얻을 수 있는 피처가 이미지 인식에 유용하다고 언급했습니다. 그리고 코너가 크기 불변성을 만족시키지 않는다는 말도 잠깐 했습니다. 왜 그런지는 다음 그림을 보겠습니다.
[그림 7-15]는 같은 크기의 두 이미지를 보여조고 있는데, 왼쪽에는 토끼가 한 마리가 있고, 오른쪽에느 토끼가 세 마리 있습니다. 사람은 오른쪽 이미지에 있는 토끼와 왼쪽 이미지에 있는 토끼가 같다는 것을 금방 알 수 있지만, 컴퓨터로 이미지 처리를 하면 이미지 안의 물체 사이즈(혹은 이미지 척도(scale))와 상관없이 이미지 크기에 따라 원도우 크기(그림에서는 사각형으로 표시했습니다)가 정해지므로 두 이미지에서 검출하는 코너가 완전히 달라집니다.
이 문제를 해결하는 가장 쉬운 방법은 한 이미지의 확대/축소 버전을 여러개 만든 후(이를 이미지 피라미드(image pyramid)라고 합니다) 이미지를 비교하는 겁니다.[그림 7-15]의 오른쪽 이미지를 확대하다 보면(혹은 척도를 줄이다 보면)언젠가는 왼쪽 이미지에 있는 토끼와 크기가 같아지겠죠.
한편 아우스 원도우를 이용한 필터링(블러)처리 결과와 이미지의 척도(스케일)이 작아지는 효과, 즉 이미지 안의 물체가 커지는 것이 비슷한 효과를 낸다는 점에 착안하여 가우스 함수를 이용하여 각 지역마다 다른 척도를 찾는 방법이 제안되었습니다. 대표적인 방법으로 LoG(laplacian of Gaussian(가우스 라플라스)와 DoG(differece of Gaussian(가우스 차))가 있습니다.
LoG와 DoG는 모두 가우스 원도우를 이용하여 이미지에 블러효과를 준 후 그렇게 얻어진 이미지의 강도합수를 미분하여 지역 극값을 찾습니다. 지역 극값을 찾는것으로 이미지 강도의 급격한 변화가 일어나는 점을 찾을 수 있게 되고, 이 점들이 지역 피처를 추출할 후보가 됩니다. 이때 다양한 척도에서의 극값을 검출하기 위해 다른 표준편차값을 가지는 복수의 가우스 운도우를 이용합니다. [그림 7-16]은 다른 표준편차를 가지는 가우스 원도우를 이용해서 이미지를 처리한 것을 보여줍니다. 표준편차가 클수록 이미지가 흐릿해지는데, 이는 이미지가 커지는 것과 같은 효과로 생각할 수 있습니다.
이렇게 다양한 표준편차를 가지는 가우스 원도우로 생성된 여러 이미지(즉, 척도가 다른 이미지)의 특징(x, y)좌표에서 일관되게 극값이 검출된다면, 그 위치는 이미지의 척도에 영향받지 않는다고 여길 수 있습니다. 이 좌표를 특징점(keypoint)이라고 합니다. 그리고 가장 큰 극값을 얻은 이미지의 척도(즉, 가우스 원도우의 표준편차)가 그 특징점의 척도가 됩니다. 그결과 각 특징점과 그와 연결된 척도를 얻게 됩니다.

이렇게 척도에 영향받지 않는 특징점을 찾은 후에는 특징점의 방향을 찾습니다. 특징점의 방향을 고려하면 회전한 물체도 인식할 수 있게 됩니다. 특징점과 그 주변의 회전 방향을 찾기 위해 각 특징점의 척도에 해당하는 이미지를 이용하여 주변 이미지의 강도 함수를 x축 y축으로 미분한 후 변화가 가장 급격한 곳을 찾아 그 특징점의 방향으로 정합니다.[그림 7-17]에서 볼 수 있듯이 SIFT는 각 특징점에 대해 16개 주변 구역을 정한 뒤 각 구역마다 8개의 방향을 정하므로 특징점 하나는 128개의 값을 가지게 됩니다. 이러한 특징점의 주변 값들을 특징량(keypoint descriptor)이라고 합니다. 두 이미지를 비교할 때는 두 이미지 안의 특징점의 특징량을 이용해서 유사도 계산(옐르 들면 유클리드 거리 계산)을 하게 됩니다.
[그림 7-18]에서는 SIFT를 이용해 왼쪽의 기차와 개구리를 가운데 이미지에서 찾는 예를 보여줍니다. 개구리와 기차가 다른 물체 뒤에 숨어 있고 놓인 방향이 달라도 특징점(개국리 다리, 기차 바퀴 등)을 이용해서 성공적으로 찾앗습니다. 또한 각 특징짐마다 사용하는 척도가 다르므로 실제 피처를 뽑는 이미지 범위(사각형의 크기)가 다른 것도 볼 수 있습니다. SIFT기법은 2004년에 소개된 이후 많은 곳에서 사용되었지만, 특허 등록이 되어 있어 2016년 현재 상업적인 용도로는 사용할 수 없습니다. 대신 Brisk(Binary Robust Invariant Scalable Keypoints)나 Kaze 등을 사용하면 됩니다. 두 알고리즘 모두 OpenCV에 라이브러리로 구현되어 있으므로 어렵지 않게 사용할 수 있습니다.
7.3.4 주성분 분석
주성분 분석(PCA(principal component analysis))은 데이터에서 의미 있는 축을 찾아낸 후 그 축을 이용하여 고차원 데이터를 저차원으로 사영하는 방법입니다. 데이터에서 차원 수만큼 축이 존재하는데 주성분 분석 기법은 이들 중 가장 중요한 축, 즉 데이터의 특징을 가장 잘 표현할 수 있는 축부터 순서대로 찾아냅니다.
예를 들어[그림7-19]에서 데이터의 차원을 축소한다고 생각해봅시다. x축은 키, y축은 몸무게, 각 점은 해당 키와 몸무게를 가진 사람이라고 합시다. 이 데이터는 키와 나이라는 2가지 차원을 가집니다. 각 데이터는 z-점수 표준화 했습니다.

이 데이터를 검은 축과 회색 축 중 하나를 골라 사영한다고 생각해 봅시다. 회색 축 위의 점들은 떨어져 있는 반면, 검은 축 위의 점은 다닥다닥 붙어 있게 됩니다. 위 데엍에서 사람들의 키와 몸무게보다 더 다양하기 때문입니다.(즉, 키의 분산의 크기 때문입니다). 따라서 이 데이터를 1차원으로 축소할 때는 회색축을 이용해야 데이터의 특징을 더 잘 보존할 수 있습니다. 주성분 분석은 이와 같이 분산이 큰 순서대로 축을 찾아내면서 데이터의 차원을 줄여가는 방식입니다.  각 차원의 분산을 이용하기 위해 공분산행렬을 계산한 후 그 행렬을 고유벡터 분해하여 축을 찾습니다. 공분산행렬에 대해서는 4.5.2절 '마할라노비스 거리'를 차모하세요. 공분산행렬은 늘 정방행렬이고 대칭행렬입니다. 공분산행렬을 7.3.2절 '코너'에서 설명한 것처럼 고유벡터로 분해하는 것으로 데이터를 설명하는 축, 즉 성분들을 구하게 됩니다.

이미지 인식에 주성분을 이용하는 이유는 복수의 이미지에서 주성분을 뽑아내면 그 이미지들의 공통된 특징을 찾을 수 있기 때문입니다. 예를 들어 사람 얼굴의 경우, 세세한 부분은 다르지만 눈이 둘, 코가 하나, 입이 하나라는 공통점이 있습니다. 그리고 개개인의 특징은 눈 크기나 이마넓이 차이 등으로 분산할 수 있습니다.

이 아이디어를 바탕으로 한 것이 고유 얼굴 검출(eigenface detection1991)입니다. 고유 얼굴 검출은 대부분의 얼굴 이미지를 공통된 주성분으로 분해할 수있다는 가정을 바탕으로 얼굴 이미지를 설명할 수 있는 주 고유 얼굴(즉, 다양한 얼굴 데이터를 가장 잘 설명할 수 있는 주성분)을 찾아낸 후 고유 얼굴의 선형 조합을 이용하여 원래 얼굴 이미지를 나타냅니다.

고유텍터, 즉 주성분을 많이 이용할수록 차원을 덜 축소하게 되므로 고유 어굴을 조합한 이미지가 원래 이미지와 가깝게 됩니다.[그림 7-20]은 사용하는 주 성분수(K)를 4개, 128개, 256개로 바꾸었을 때 복원된 얼굴 이미지의 변화를 보여줍니다. 차이점을 확실히 알 수 있습니다.

하지만 주성분을 많이 쓴다고 좋은 것은 아닙니다. 예를 들어 이미지에서 '머그컵'이 있는지 여부를 인식하려고 할 때 주성분을 많이 사용하면 무늬가 있는 머그겁과 없는 머그겁을 구별하게 될 것이고, 그러면 일반화를 할 수 없어서 시스템의 목적에는 맞지 않게 됩니다. 분류하려는 이미지에 따라서 K값을 적절히 정하는 것이 중요합니다. PCA의 구현 방법에 대해서는 13장의 고유 얼굴 검출 예제에서 살펴봅니다.

7.4 딥러님을 이용한 이미지 인식
이 절에서는 딥러닝을 이용한 이미지 인식에 대해 알아보겠습니다. 모든 머신러닝 문제에서 그렇듯 '어떤 피처를 뽑아 학습시키느냐'가 모델의 성능을 좌우합니다. 7.3절 '이미지 인식에 사용하는 피처'에서는 이미지 인식 시스템을 만들 때이미지에서 무엇이 중요한지 고려해서 피처를 사람이 직접 하나하나 정의했습니다. 즉, 사람이 '윤곽선이 중요할 것이다', '코너가 중요할 것이다'라고 생각하고 피처를 뽑았습니다. 그런데 딥러닝을 이용하여 머신러닝을 할 때는 이렇게 수동으로 정의한 피처를 사용하지 않습니다. 학습과정에서 어느 것이 중요한 피처인지 모델이 스스로 학습합니다. 이것이 딥러닝과 전통적인 머신러닝 간의 가장 큰 차이입니다.

7.4.1 CNN 소개
CNN(convolutional netural network, 합성곱 신경망)은 딥러닝 기법 중에서도 이미지 인식에서 강력한 성능을 발휘합니다. CNN의 기본 개념은 편지봉투에 쓰인 우편번호를 인식하기 위해 1989년 레쿤에 의해 제안되었습니다. 그 후 1998년에 초기 CNN인 LeNet-5가 소개되었지만 컴퓨팅 리소스의 한계로 고해상도 이미지 분류에 좋은 성능을 보이지 못한 탓에 당시에는 주목받지 못했습니다.

그 후 컴퓨팅 하드웨어의 계산 능력 향상과 학습 데이터의 증가로 2012년 이미지넷 챌린지에서 알렛스넷(AlexNet)이 기존 모델과는 비교도 할 수 없는 놀라운 성능을 보여준 후 CNN은 이미지 인식의 표준 모델로 자리잡았습니다. 알렉스넷의 아키텍처를 살펴보면 CNN의 기본 개념에 대해 알 수 있습니다. 알렉스넷의 아키텍처는 [그림 7-21]과 같습니다.

알렉스텟은 합성곱 레이어 5개와 완전 연결(fully-connected)레이어 3개로 이루어져 있습니다. 위쪽 레이어와 아래쪽 레이어로 나눤 이유는 알렉스넷이 GPU 2개를 사용하여 만들어졌기 때문입니다. 입력은 가로 224 * 세로 224 크기 이미지입니다. 따라서 224 * 224 * 3(컬러 채널 RGB)행렬로 표현됩니다. 출력은 0부터 1사이의 실숫값 요소로 이루어지는 1000*1 크기의 벡터인데, 요소 하나가 클래스 하나에 속하는 가능성을 나타냅니다. 즉, 알렉스넷은 이미지 하나를 클래스 1000개 중 하나로 분류합니다. 기존 머신러닝과 다른 점은 합성곱 레이어를 통해 피처를 생성하는 겁니다. 즉, 이미지에서 피처를 추출하여 모델의 입력으로 사용하는ㄱ ㅔ 아니라 이미지 자체를 그대로 모델의 입력으로 사용합니다. 그리고 학습과정에서 이미지의 어떤 부분에 중점을 둘지 배우게 됩니다.

7.4.2 합성곱 레이어
합성곱 레이어는 필터를 이용해 입력값을 변형하는 레이어입니다. 7.1.2절 '필터링'에서 필터 원도우를 이미지에 적용하여 이미지를 변환한다는 것을 배웠습니다. CNN의 합성곱 레이어도 비슷한 역할을 수행하지만 7.1.2절의 필터와는 달리 이미지의 행렬을 다른 모형의 행렬로 변경합니다. 예를 들어 [그림 7-22]에서 볼수 있듯 알렉스 넷의 가장 최초의 합성곱 레이어는 11 * 11* 3 크기의 원도우를 사용해 224 * 224 * 3 크기의 이미지를 55* 55* 96 크기로 변경했습니다. 이 행렬의 넓이와 높이는 이미지의 워치와 관련된 특징을 잡아내고 깊이는 이미지의 다양한 피처를 잡아냅니다. 이렇게 하여 입력 이미지의 모든 부분의 정보를 조합한 피처를 96개(깊이의 수) 생성합니다. ConvertJS페이지의 Activation란이 이렇게 생성된 피처들을 보여줍니다. 피처 수를 정하는 데는 특별한 기준이 없습니다. CNN의 성능을 높이기 위해 피처 수, 레이어 수 및 레이어 구조를 어떻게 바꾸어야 하는지 활발하게 연구되고 있습니다.

합성곱은 7.1.2절 '필터링'에서 설명한 필터링 및 7.1.3절 '합성곱'에서 설명한 합성곱 처리와 마찬가지로 원도우를 옮겨가며 구합니다. 이때 원도우를 몇 픽셀씩 옮길 것인지 지정할 필요가 있는데 이를 스트라이드(stride)라고 합니다. [그림 7-23]에서 스트라이드 1인 경우와 2인 경우 원도우를 어떻게 옮기는지 보여줍니다. 알렉스넷은 스트라이드 4, 원도우를 4픽셀씩 옮겨가며 합성곱을 구합니다. 이미지의 가장자리는 [그림 7-4]에 살펴본 제로 패딩을 사용했습니다.

7.4.3 폴링
합성곱 레이어의 결과를 그대로 다음렝이어로 넘길 수도 있지만, 일반적으로는 샘플링으로 볼수 있는 폴링(pooling)단계를 거칩니다. 즉, 생성된 모든 정보를 사용하는게 아니라 다운샘플링된 정보를 사용하는 것으로 과학습을 막고 노이즈에 강한 피처를 생성합니다. [그림 7-24]는 원도우 크기 2 * 2, 즉 스트라이드 2를 이용한 최댓값 폴링(max pooling)과 평균값 폴링(average poooling)을 나타냅니다. 최댓값 폴링은 원도우 안의 가장 큰 값을 뽑는 것이고, 평균값 폴링은 원도우 안의 값들의 평균을 이용하는 겁니다. [그림 7-24]에서 최댓값 폴링의 결과 이미지의 (0,0) 픽셀은 (12, 20, 8, 12)의 최대값인 20으로 채워졌고, (0,1) 픽셀은 (30, 0,2,0)의 최댓값인 30으로 채워졌습니다. 평균값 폴링의 경우 (0,0) 픽셀은 (12, 20, 8, 12)의 평균값인 13으로 채워진 것을 알 수 있습니다. 이렇게 폴링을 이용해 합성곱 레이어의 정보를 압축하여 다음 레이어로 넘기게 됩니다.
그럼 평균값 폴링과 최댓값 폴링 중 어떤 것을 이용해야 할까요? 7.3절 '이미지 인식에 사용하는 피처'에서 살펴보았듯 이미지 인식에서는 이미지의 특징점을 찾은 후 그 주변의 특징량을 이용합니다. 합성곱 레이어의 결괏값이 클수록 이미지 인식에서 중요한 역할을 합니다(강도함수의 극값이 클수록 종요한 것과 마찬가지죠). 따라서 활성화된 결괏값 중 최댓값을 활용하는 최댓값 폴링이 좋은 성능을 낸다고 알려져 있습니다.

7.4.4 활성화 함수
신경망 모델에서 사용되는 비선형합수(activation function)라고 합니다. 비선형합수는 선형합수, 즉 직선으로 표현할 수 없는 데이터 사이의 관계도 표현할 수 있으므로 [그림 7-25]에서 선형함수, 대표적인 활성화 함수인 시그모이드 함수, 하이퍼볼릭 탄젠트, ReLU(rectified linear unit)함수를 볼 수 있습니다.

- 선형함수 : y = x
- 시그모이드 함수 : y = 1 / ( 1 + exp(-x))
- 하이퍼볼릭 탄젠트 함수 : y = (exp(x) - exp(-x))/(exp(x) + exp(-x))
- ReLU 함수 : y = max(0,x)

알렉스넷 이휴 합성곱 신경망 모델에서는 더 빠른 계산을 위해 ReLU를 이용합니다. ReLU는 입력값이 0보다 작을 때는 무시하고 , 0보다 클 때는 입력값을 그대로 사용하는 것으로 간단하게 비선형함수를 구현할 수 있고 괜찮은 성능을 보장하므로 자주 사용됩니다.

7.4.5 완전연결 레이어
완전연결 에이어는 일반적인 신경망과 같은 방식으로 이전 레이어의피처와 다음 레이어 사이의 모든 연결을 고려합니다. 즉, 원도우를 이용한 필터나 폴링으로 인한 변형 없이 입력 데이터를 그대로 이용합니다.
CNN은 합성곱 레이어 폴링을 반복하는데 이 과정에서 이미지의 강한 지역 피처들의 특징을 합성하여 전역적인 특징도 표현하게 됩니다. 알렉스넷에서는 하나의 이미지가 클래스 1000개의해당하는 확률을 출력하므로 최종 결과는 7.4.1절 'CNN 소개'에서 보았듯 이미지의 클래스 확률을 나타내는 1000*1 크기의 벡터입니다. [그림 7-26]에서 입력 이미지를 합성곱 레이어를 이용하여 변환한 뒤 와전연결 레이어에 통과시킨 결과 고양이 카페고리에 속할 확률이 가장 높게 나왔습니다. 따라서 이 이미지는 고양이로 분류됩니다.

7.5 마치며
이 장에서는 이미지 인식에 필요한 기본 개념과 주요 기법 및 알고리즘에 대해 고부했습니다. 특히 이미지 연구에서 좋은 성능을 보이는 CNN에 대해서도 가단히 설펴봤습니다. 이미지 인식의 필수 개념인 회전 불변성, 크기 불변성, 평행이동 불변성에 대해 이해하고 전통적인 이미지 치러체 대해 이해하여 합성곱 레이어와 폴링을 사용하는 이유를 알게 되었습니다.
이장에서 소개한 대부분의 기법은 다양한 프로그래밍 언어의 라이브러리로 구현되어 있습니다. 이에 대해서는 13장에서 살펴보겠습니다.












2018년 3월 11일 일요일

CHATER 6 영화 추천 시스템 만들기

영화 추천 시스템은 정보 필터링 시스템의 일종으로,각 정보 (상품, 신문기사, 친구 등)에 대한 사용자 점수나 선호도 등을 예측합니다. 아마존을 비롯한 거의모든 전자상거래 사이트에서는 사용자에게 상품을 추천합니다. 뉴스 포털에서 제공하는 사용자는 사용자별 추천 기사는 이제 너무나도 익합니다. 이렇게 추천 시스템은 오늘날 인터넷 기반 서비스에서 없어서는 안 될 중요한 서비스를 제공합니다. 이 장에서는 그중에서 넷플릭스 프라이즈(Netflix Prize)로 널리 알려진 영화 추천 시스템에 대해 알아봅시다.

6.1 영화 추천 시스템
영화 추천 시스템은 사용자가 해당 영화에 별점을 몇 개 줄 것인지 예측하는 문제입니다. 우선 추천 시스템에 쓰일 만한 데이터를 생각해 볼까요? [표 6-1]과 같이 사용자가 영화에 준 별점 데이터가 있어야 합니다.

표 6-1 사용자 별점 데이터
사용자 ID        abcd
영화 ID          00001
별점               4
별점을 준 일시      2012-03-02

[표 6-1]에 있는 정보만으로는 00001이 어떤 영화인지 알 수 없으므로 사용자가 왜 영화 0001에 별점 4를 줬는지 알 수 없습니다. 영화의 내용을 알기 위해서는 별도로 [표6-2]와 같은 영화 정보도 있어야 합니다.

[표 6-2 영화 데이터]
ㄹㅇㅁㄴㄹㄴㄹㅇㄴㄹ


회귀 모델로 영화의 특징을 이용해서 사용자의 별점을 예측하는 경우를 생각해 봅시다. 영화의 특징으로는 영화 제목, 영화 장르, 상영개시일 등이 있습니다. IMDB 같은 지식 베이스를 이용하면 등장하는 배우나 영화 장르 같은 정보를 이용할 수 있습니ㅏㄷ. 이를 이용하여 회귀식을 작성한다면 '영화수 * 영화의 특징 수 * 사용자 수'만큼의 변수를 고려해야 하므로 모델이 복잡해집니다.

한 사용자의 취향은 그 사용자가 보는 영화 내용으로 알 수 있습니다. 예를 들어 어떤 사용자가 해리포터 1편부터 4편까지 보았다고 할 때 5편을 추천하는 건 당연하겠죠, 또한 비스산 판타지 소설 기반의 영화인 나니아 연대기를 추천해도 좋을 겁니다. 이렇게 상품 내용에 기반하는 방식을 내용 기반 추천 시스템이라고 합니다.

또한 비슷한 영화 취향을 지닌 사용자들은 비슷한 영화를 볼 겁니다. 만약 사용자 1이 스파이더맨, 아이언맨, 어벤져수, 닥터 스트레인지를 보았고, 사용자 2가 스파이더맨, 아이언맨, 어벤져스를 보았다면, 사용자 2에게 닥터 스트레인지를 추천해도 될 겁니다. 이렇게 다른 사용ㅈ 정보를 이용하는 방법이 협업 필터링입니다.

이 장에서는 내용 기반 추천 시스템에서 유사도 계산에 사용하는 자카드 계수와 코사인 유사도, 협업 필터링에 사용하는 수학적 기법인 행렬 분해에 대해 알아봅시다.

6.2 유사도 계산
유사도란 두 객체가 얼마나 유사한지 나타내는 척도입니다. 4.5절 '유사도 계산'에서는 수치 데이터의 유사도를 측정하는 방법에 공부했습니다. 여기서는 두 문서 간의 유사도 평가와 협업 필터링에 자주 사용하는 자카드 계수와 코사인 유사도, 그리고 단어의 유사도 평가에 사용하는 편집거리에 대해 알아봅시다. 자카드 계수와 편집 거리는 문서 안의 문자열을 그대로 사용하여 유사도를 계산할 수있습니다. 코사인 유사도는 문서 안의 문자열의 빈도를 사용합니다.

- 자카드 계수: 두 집합이 공유하는 원소 수에 기반한 유사도
- 코사인 유사도: 두 벡터 사이의 각도에 기반한 유사도
- 편집거리: 문자열을 편집하는데 필요한 연산 수에 기반한 유사도

6.2.1 지카드 계수
자카드 계수(Jaccard coefficient)는 두 집합의 유사도를 측정하는 계수입니다. 집합 S와 T가 있을 때, 두 집합의 자카드 계수는 두 집합의 교집합의  원소수를 합집합의 워소수로 나눈값입니다. 식으로 표현하면 다름과같습니다.


식 6-1 자카드 계수

| S 교집합 T   |
| ____________  |
| S 합집확 T   |

각 영화 줄거리의 유사도를 비교하여 사용자가 구매한 영화와 비슷한 내용의 영화를 추천한다고 생각해 봅시다. 영화 줄거리에 출현하는 단어와 전체 단어 사이에는 다음과 같은 관계가 있습니다.

- P00: 영화 1과 영화 2의 줄거리에 사용되지 않은 단어
- P01: 영화 1 줄거리에만 사용된 단어
- P10: 영화 2 줄거리에만 사용된 단어
- P11: 영화 1과영화 2 줄거리에 동시에 사용된 단어

예를 들어 '해리포터와 마법사의 돌'(영화1)과 '해리포터와 불의 잔'(영화2)의 내용을 비교한다고 할 때, P01은 마법사의 돌, P10은 불의 잔, P11은 해리포터, 론, 헤르미온느, P00은 아이언맨, 스트레인지, 미녀와 야슈등이 될 겁니다.

단순히 생각해보면 영화 1과 영화 2의 유사도는 P11/(P00+P01+P10+P11)이 될 것 같습니다. 이렇게 계산하는 유사도를 단순 일치계수(simple matching coefficient)라고 합니다. 즉, 두 영화 줄거리에 공통으로 사용되는 단어를 모든 단어 수로 나누는 거죠, 하지만 한 영화의 줄거리 소개에 사용되는 단어 수가 모든 단어 수보다 월등히 적으므로 워 식을 사용할 경우 P00의 값이 다른 값에 비해 굉장히 크게 됩니다.

협업 필터링에서도 비슷한 문제가 생깁니다. 예를 들어 한 사용자가 구매하는 상품 수가 온라인 쇼핑몰에 존재하는 전체 상품 수에 비해 월등히 적으므로 두 사용자 중 어느 쪽도 구매하지 않은 상품수 (P00)가 많아집니다. 이렇게 데이터 하나에 존재하는 피처 수가 가능한 피처 수에 비해 월등하게 적은 경우 데이터가 희박하다고 표현합니다. 지 카드 계수는 이렇게 희박한 데이터 간의 유사도를 측정하는 데 유용합니다.

6.2.2 코사인 유사도
코사인 유사도(cosine similarity)는 두 벡터 사이의 각도를 -1부터 1사이의 값으로 나타내는 척도입니다. 두 벡터가 같은 방향(두 벡터 사이의 각도가 0도)이면 1, 두 벡터가 완전 반대 방향(두 벡터 사이의 각도가 180도)이면 -1이 됩니다. 값이 1일 경우 벡터 간의 유사도가 크다는 거고, -1일 경우 유사도가 매우 작다는 겁니다. 정의는 다음과 같습니다.

식 6-2 코사인 유사도


각도와 유사도는 무슨 관계가 있을까요? 문서에 나오는 단어 빈도를 사용하여 유사도를 측정한다고 생각해봅시다. [표6-3]은 각 문서에 출현하는 단어 수를 보여줍니다.

표 6-3
문서당 단어 빈도
                      단어1       단어2
문서1            4               3
문서2           2                1
문서3           1                3

위 표를 다음과 같은 벡터로 나타낼 수 있습니다.

문서1 = (4,3)
문서2 = (2,1)
문서3 = (1, 3)

그림으로 나타내면 [그림 6-1]과 같습니다. 그림에서 볼수 있듯이 코사인 유사도는 벡터의 크기를 무시하고 각도를 이용하여 유사도를 계산합니다.

문서 2와 문서3 중 어느 문서가 문서 1에 가까운지 살펴보겠습니다.

sim(문서1, 문서2) = (4*2 + 3*1)/루트(4*4 + 3*3)루트(2*2 + 1*1) = 0.98
sim(문서1,  문서3) = (4*1 + 3*3)/루트(4*4 + 3*3)루트(1*1 + 3*3) = 0.82

문서 2가 문서 3보다 문서 1에 더 가깝다는 것을 알 수 있습니다. 이때 연산 횟수가 많을 수록 거리가 멀다고 정의합니다. 문자열에 대해 가능한 연산은 문자 삽입(insertion), 삭제(deletion), 대체(substitution), 전치(transposition)가 있습니다. 편집 거리는 허용하는 연산에 따라 종류가 나뉘는데, 예를 들어 대체 연산만 허용하는 해밍 거리와 삽입, 삭제, 대체 연산을 허용하는 레벤슈타인 거리 등이 있습니다. 문자열 비교 시 가장 자주 사용하는 거리는 레벤슈타인 거리 입니다.

옐르 들어 다음과 같은 문자열이 있다고 합시다.
S1 = abcd
S2 =acfdg

S1을 S2로 만들려면 다음과 같은 과정을 거칩니다.

1. b 삭제
2. f 삽입
3. g 삽입

3번의 연산을 거쳤으므로 편집 거리(S1, S2)는 3이 됩니다.

그럼 이런 편집거리는 어디에 사용할 수 있을까요? 아래와 같은 영화 제목을 생각해 봅시다.

- 영화1: 스파이더맨1
- 영화2: 스파이더맨2
- 영화3: 아이언맨1

영화 1과 2는 편집 거리가 2(1삭제 후 2삽입)인 반면, 영화 1과 3은 편집 거리가 7('스, 파, 이, 더' 삭제 후 '아, 이, 언' 추가)이라는 것을 알 수 있습니다. 편집 거리는 이렇게 시리즈몰의 제목을 찾는데 유용합니다. 또한 문서의 안의 오탈자를 고려하여 유사도를 측정하는데도 유용합니다. 예를 들어 '해리포터'와 '헤리포터'의 경우 다른 문자열리지만 편집 거리가 2로 작으므로 오탈자로 인해 차이가 생겼다고 보고 같은 문자열로 취급하는 식입니다.

6.3 내용 기반 추천 시스템
내용 기반 추천 시스템은 사용자가 과거 좋은 별점을 준 영화와 비슷한 영화를 추천합니다.
그럼 어떤 영화가 비슷한 영화일까요? 단순히 생각하면 영화 내용이  같으면 될 것 같지만 모든 문장이 같을 순느 없을 테니 영화 내용 소개 문서 안에서 사용된 단어가 비슷하면 되겠네요. 비슷한지 여부를 판ㄹ별하는 것 유클리드 거리잖아요! 그렇다면 문서의 모든 단어를 3.3.2절 '카테고리 데이터 표준화'에서 설명한 원-핫 인코딩 방식을 적용해 수치 데이터로 바꾼 후 문서 같의 유클리드 거리를 계산하면 되겠군요. 그런데 문제가 있습니다. 일반적으로 문서에는 사용된 단어가 됭장히 많고, 춫ㄹ현 빈도가 다르며, 같은 단어라도 다른의미로 쓰일 수 있습니다.

이 문제를 해결하려면 문서 내의 모든 단어를 사용하는 대신 5.1.1절 '문서 분류에 많이 사용하는 피처'에서 배운 대로 문서에 나오는 중요단어를 피처로 추출하여 비교합니다. 그리고 문사 간 유사도를 계산하기 위해서는 6.2절 '유사도 계산'에서 설명한 유사도 계산법을 이용합니다.

이런한 내용 기반 추천 시스템은 다른 사용자의 정보가 없어도추천이 가능하고, 독특한 취향을 가진 사용자(즉, 다른 사용자와 겹쳐지 않는 상품만 구매하는 사용자)에게도 상품을 추천할 수 있으며, 상품을 추천하는 이유를 설명하기도 쉽습니다. 반면 특이한 상품을 추천하는 ㅔㄷ 제한적이며, 과거 구매 이력이 없는 신규 사용자에게 추천하기 어렵다는 단점이 있습니다.

6.4 협업 필터링
협업 필터링은 다른 사용자의 구매 이력을 이용해서 영화를 추천하는 방법입니다. 한 사용자의 구매 이력만 생각하는 내용 기반 추천 시스템과 달리 협업 필터링은 여러 사용자 혹은 여러 아이템 정보를 동시에 사용하여 추천합니다. 그림으로 나타내면 다음과 같습니다.

그림 6.2 사용자 기반 필터링

사용자 1이 영화1, 2, 3를 보고, 사용자 2가 영화 1,4를 보았을 때 , 사용자 2에게 영화2를 추천하는 것이 사용자 기반 협업 필터링의 아이디어 입니다. 반면 상품 기반 협업 필터링은 사용자으 상품 평가 유사성을 이용하여 상품을 추천합니다. 예를 들어 영화1과 영화2에 사용자 1과 사용자3이 좋은 별점을 줬을 경우, 사용자 2도 좋은 별점을 줄 거라고 생각하는 겁니다.

두 필터링 방법 모두 상품, 사용자, 별점의 괄계를 이용합니다. 이런 관계를 [표6-4]와 같이 행별로 표시한 것을 유틸리티 행렬(utlity matrix)이라고 합니다. 유틸리티 행렬은 '사용자 수 * 상품수(혹은 사품 수 * 사용자 수)' 크기 행렬입니다. 행렬의 각 원소는 사용자가 상품에 준 점수를 나타냅니다. ?는 사용자가 상품에 아직 점수를 주지 않은 항입니다.

표 6-4 유틸리티 행렬
                  영화1        영화2         영화3       영화4
사용자1           1            5               2              4
사용자2           2            2               5              1
사용자3           2            4               ?               ?

[표 6-4]에서 사용자 1은 영화 1에 별점 1을 줬습니다. 사용자 3은 아직 영화 3과 영화 4에 별점을 주지 않았습니다. 그럼 영화 3과 4를 사용자 3에게 추천할 지 여부를 정하려면 (사용자 3, 영화 3), (사용자3, 영화4) 별점을 예측할 필요가 있습니다. 별점 예측 기법으로는 사용자/상품 기반 협업 필터링과 잠재성 요인 모델이 있으며, 성능 평가에는 평균 제곱근 편차를 사용합니다.

6.4.1 평균 제곱근 편차
사용자가 입력할 별점을 되도록 실제 값에 가깝게 예측하는 것(근사)이 추천 시스템의 목표입니다. 예를 들어 사용자 1이 '어메이징 스파이더맨'에 줄 실제 별점이 5라고 할때 별점 3으로 예측하는  것보다 별점 4로 예측하는 것이 더 정확한 예측이고 더 정확한 추천입니다. 즉 실제 별점과 근사 별점의 차가 적을수록 좋은 예측이 됩니다. 이를 평가하는 것이 평균 제곱근 편차(Root Mean Square Error:RMSE)입니다.

실제 별점이 들어 있는 행렬 M, 예측한 별점이 들어 있는 행렬을 M', 행렬의 각각 mij, m'ij로 나타내고, 유틸리티 행렬의 원소 수를 N이라 할 때, 평균 제곱근 편차는 다음과 같이 계산합니다.

6-3 평균 제곱근 편차

루트(함(mij - m'ij)**/N)

mij: 실제 별점 행렬의 (i,j) 항
m'ij:예측 별점 행렬(i,j) 항
N: 유틸리티 행렬의 원소 수:

즉, 평균 제곱근 편차는 예측값과 실제 값의 차이를 제곱한 값의 평균의 제곱근입니다. 예측값과 실제값의 차이가 적을수록, 또 예측값과 실제값의 차이가 적은 항이 많을 수록 이 값은 작아집니다. 그러므로 값이 적을수록 좋은 예측입니다.

[표 6-4]의 유틸리티 행렬을 이용해 평균 제곱근 편차를 계산했습니다.

실제 별점 행렬M
              영화1                  영화2                 영화3                 영화4
사용자1      1                       5                        2                       4
사용자2      2                       2                        5                       1
사용자3      2                       4                       1                         4

예측 별점 행렬 M1
                   영화1           영화2            영화3         영화4
사용자1       1                  5                      2                 4
사용자2       2                 2                       5                 1
사용자3       2                 4                       1                  3

예측 벌점 행렬 M2
                   영화1           영화2            영화3         영화4
사용자1       1                  5                      2                 4
사용자2       2                 2                       5                 1
사용자3       2                 4                      4                  2

여기서 평균 제곱근 편차는 유틸리티 행렬(표6-4)에서 ?로 표시된 미지항에 대새서만 계산합니다. 즉, 예측한(사용자 3, 영화3)과 (사용자3, 영화4)의 항만 고려하여 값을 구합니다.  유틸리티 행렬의 원소 수는 12개이므로 N은 12가 됩니다. 따라서 예측 별점 행렬 1과 예측 별점 행렬 2의 평균 제곱근 편차는 다음과 같습니다.

RMSE(M1) = 루트(((1-1)** + (4-3)**/12)) = 0.29
RMSE(M2) = 루트(((1-4)**+(4-2)**/12)) = 1.04

예측 별점 행렬1이 더정확히 실제 별점을 예측했다는 것을 알수 있습니다.

6.4.2 사용자 기반, 상품 기반 협업 필터링
사용자 기반, 혹은 상품 기반 협업 필터링은 추천을 위해 사용자 혹은 상품의 유사도를 사용합니다.
사용자 간의 유사도를 계산할 때는 사용자가 본 영화와 별점을 이용합니다. 자카드 계수를 사용할 경우에는 두 사용자가 본 영화 중 공통된 영화가 많을수록 두 사용자가 비슷하다고 보는데, 이 경우 영화의 별점 정보를 무시하게 되므로 적절하지 않습니다. 예를 들어 두 사용자가 완전히 같은 영화를 봤더라도 상반되게 별점을 줬다면 두 사용자의 영화 취향이 비슷하다고는 할 수 없겠죠. 따라서 상품에 별점과 같은 선호도 정보가 있을때는 코사인 유사도를 계산하는 것이 좋습니다. 계산 절차는 다음과 같습니다.

1.  열마다 별점 평균값 구하기
2. 각 별점에서 평균값 빼기
3. 미지항을 0으로 채우기

[표 6-4]의 유틸리티 행렬에 이 방법을 적용해서 사용자1, 사용자2, 사용잦3의 유사도를 계산해 볼까요?

사용자1의 별점 평균: (1+5+2+4)/4 = 3
사용자2의 별점 평균:(2+2+5+1)/4 = 2.5
사용자3의 별점 평균:(2+4)/2 = 3

[표6-4]의 각 열에서 위에 계산한 별점 평균을 뺀 것이 [표 6-5]입니다. 사용자 3의 미지항은 0으로 채웠습니다.

표 6-5 수정된 사용자 별점

                     영화1           영화2            영화3         영화4
사용자1       -2                  2                      -1                 1
사용자2        -0.5                -0.5                      2.5                -1.5
사용자3       -1               1                     0                  0

[표6-5]의 값을 이용해서 계산한 사용자의 코사인 유사도는 다음과 같습니다.

sim(사용자1, 사용자3) = 0.89
sim(사용자2, 사용자3) = 0.0

사용자 1이 사용자 3과 비슷하므로, 사용자 3에게는 사용자1이 좋은 점수를 준 영화 4를 추천하면 될 것 같습니다.

상품 기반 추천 방식으로 영화를 추천할 경우 영화 정보 등을 이용하여 유사도를 계산하므로 기본적으로는 내용 기반 추천 시스템에서 사용하는 방식과 같습니다. 카테고리나 가격 같이 피처가 정해져 있는 상품은 유사도 계산이 더쉬우므로 실전에서는 사용자 기반 협업 필터링보다 상품 기반 협업 필터링을 더 자주 습니다. 상품 기반 협업 필터링을 이용한 사용자의 상품 별점 계산은 일반적으로 다음과 같습니다.

rxi = bxi  + (합(Sij*(rxj  - bxj))/합(Sij))

bxi = u  + bx + bi
rxi = 사용자 x의 상품 i에 대한 별점
i = 사용자 x의 별점 정보가 존재하지 않는 상품
Sij = 상품 i와 사품 j의 유사도
j = Sij가 높고 사용자 x 의 별점 정보가 존재하는 상품
bxi = 사용자 x의 상품 i에 대한 별점 편향
u = 전체 상품의 별점 평균
bxi = 사용자 x의 상품i에 대한 별점 편향
u = 전체 상품의 별점 평균
bx = 사용자 x의 별점 편향
bi = 상품 i의 별점 편향

미지의 별점을 구하려면 영화(상품) 전체의 평균 별점에 사용자 및 영화의 별점 편향(치우침)을 고려합니다. 별점 계산에서 편향을 다루는 표준화에 대해서는 6.5절 '표준화'에서 자세히 살펴보겠습니다.

6.4.3 잠재성 요인 모델
사용자/상품 기반 협업 필터링은 상품이나 사용자의 유사도를 계산해서 별점을 예측하지만 잠재성 요인 모델(latent factor model)은 유사도 계산하지 않고 유틸리티 행렬로 별점을 직접 예측합니다. 잠재성 요인 모델은 유틸리티 행렬이 두 행렬(사용자 요인 행렬, 별점 요인 행렬)의 곱으로 이루어져 있다고 가정합니다.

6.4.3.1 특잇값 분해
행렬 분해는 행렬 하나를 여러 행렬의 곱으로 분해하는 방법입니다. 이 방법에는 여러가지가 있지만, 그 중에서 가장 널리 사용되는 방법은 특잇값 분해(Singular Value Decomposition:SVC)와 7.3.2절 '코너'에서 공부할 고유벡터 분해 (eigen vector decomposition) 입니다.
행렬 A가  m*n 행렬일 때, A를 특잇값 분해하면 크기 m*m의 행렬  U, 크기 m * n행렬  합, 크기  m * n의 행렬 V로 분해할 수 있습니다. 그림으로 나타내면 [그림6-3]과 같습니다.

그림 6-3 특잇값 분해


특잇값 분해는 계산에 시간이 많이 걸리기 때문에 일반적으로 고윳값이 큰 고유벡터 k개만으로 U와 V를 만듭니다. 이를 절단 특잇값 분해(truncated SVD)라고 합니다. 적은 수의 고유벡터를 사용하여 만들어진 U와 V의 곱은 워래의 행렬에 가까운 행렬(근사 행렬)을 만들어낼 수 있습니다. 따라서 전단 특잇값 분해는 차원 축소에 이용되기도합니다.

절단행렬 분해를 크기라 '사용자 수 * 영화 수'인 유틸리티 행렬에 적용하면 유틸리티행렬을 크기가 '사용자수 * k'인 상요자 요인 행렬 X와 크기가 '영화 수 * k'인 영화 요인 행렬 Y로 나눌 수 있습니다. 여기서 K는 원래 사용자 수 및 영화 수보다 작습니다. 그리고 이 행렬의 곱을 구하는 것으로 원래 행렬을 예측하게 됩니다.

특잇값 분해를 적용하려면 행렬의 모든 값을 알아야 합니다. 하지만 지금 행렬에는 미지항(사용자의 별점이 없는 영화)이 있습니다.  따라서 미지항을 임의의 값으로 초기화 하고 가중치 행렬을 적용해서 무시하게 만들거나, 아애 손실함수를 존재하는 별점 값에 대해서만 계산합니다. 그리고 이미 값이 존재하는 항에 의한 과학습을 막기 위해 정규화를 적용합니다. 행렬의 전 항의 별점을 이용한 정규화된 손실함수는 [식 6-4]와 같습니다.



[식 6-4]의 값을 구하는 방법은 다양합니다. 여기서는 자주 쓰이는 교대 최소제곱법과 경사하강법에 대해 설명하겠습니다.

교대 최소제곱법
미지 행렬 X,  Y를 하나씩 구해나가는 방법입니다. X, Y를 임의의 행렬로 초기화한 후, 임의의 Y를 사용하여 X를 구하고, 그렇게 구해진 X를 업데이트 합니다. 이 과정을 각 단계마다 XY로  근사한 행렬 Q와 실제 점수 행렬 R을 이용하여 [식 6-4]의 손실을 계산하고,  이 손실값을 전 단계로 부터 변하지 않을  때 갱신을 멈춥니다. 일반적으로 반복횟수를 제한하거나, 이전 단계의 손실값과 비교하여 사용자가 지정한 차이보다 작을 경우 갱신을 머춥니다.

X와 Y로 행렬을 근사할때 이미 알고 있는 별점에 의한 근사 결과에 가중치를 더 주면 결과가 더 정확할 것 같습니다. 이를 위해 가중치 행렬을 정의합니다. 이  행렬은 점수 행렬 R과 같은 크기(m * n)인데, Rij 에 유저가 준 점수값이 있으면 1, 없으면 0입니다. 수식으로 표현하면 다음과 같습니다.

식 6-5 가중치 행렬
Wui = 0, rui = 0이면
Wui = 1 그렇지 않으면
wui = 가중치 행렬의 (i, j)의 값

가중치 행렬이 들어간 손실 함수는 다음과 같이 바뀝니다.

이와 같이 사용자와 상품 행렬을 더 이상 값이 바뀌지 않을 때까지 번갈아가며 갱신합니다. 그 후 두 행렬의 곱으로최종 근사 행렬을 계산합니다.

경사하강법
행렬 X,Y는 2.3.1절 '경사하강법'에서 공부한 경사하강법으로  풀 수 있습니다. 초기 X, Y를 임의로 정한 후 이를 이용하여 근사 행렬 Q를 구합니다. 그 후 R과  Q를 구합니다. 그 후 R과 Q를 잉요하여 손실을 구하고 그 값울 경사하강법에 적용합니다.


경사하강법을 전체 행렬에 적용하기 보다는 관측된 일부 값에 대해서만 SGD를 적용하면 빠른 속도를 얻을 수 있습니다. SGD에 대해서는 ㄹ제 구현은 12장에 살펴보겠습니다 2.3.3절 '활률적 경사하강법'에서 자세히 설명했으니 그곳을 참조하세요.

2018년 3월 9일 금요일

CHAPTER 5 문서 분석 시스템 만들기

문서 분석 시스템은 말 그대로 문서를 분석해서 유용한 정보를 얻어내는 시스템입니다. 문서의 내용을 분석해서 분류하거나, 문서의 주제를 추출하거나, 문법 분석을 해서 문장 구조를 파악하거나, 고유명사를 추출하는 등의 용도로 사용합니다. 문서 데이터는 다른 데이터보다 구하기 쉽고 종류도 굉장히 많습니다. 내용에 관계없이 대량의 텍스트가 필요하다면 웹페이지, 잘 정리된 백과사전 자료는 위키백과, 사용자 간의 사회활동 정보는 트위터, 상품에 대한 평가는 쇼핑몰 댓글에서 얻을 수 있습니다. 이렇게 많은 문서 데이터가 존재하는 이유는 인테넷에서의 소통이 대부분 텍스트를 통해 이루어지기 때문입니다. 따라서 문서의 내용을 분석하여 결과를 활요하면 경쟁에서 우위를 확보하거나 통찰력을 얻을 수 있기 때문에 최근 들어 쇼핑몰, 인터넷방송사, 정부기관, 포털사이트 등 다양한 분야에서 문서 분석 시스템을 사용합니다.

하지만 3.1.1절 '텍스트 데이터'에서 말했듯이 문서 분석에서 좋은 성능을 얻기란 생각보다 쉽지 않습니다. 문서의 의미라는 것은 중의적일 때도 있고, 단어가 배열된 순서에 따라 달라지며, 의미가 미묘하게 다른 단어들이 많아서 각각을 구분하기도 어렵기 때문입니다.
이런 어려움을 이겨내고 텍스트의 복잡한 의미를 파악하는 방법에 대해 알아보도록 하겠습니다.(실제 구현은 11장에서 다룹니다.) 이장에서 다루는 내용은 다음과 같습니다.
- 문서 분류 시스템 만들기
- 토픽 모델링
- 문법 분석
- 단어 임베딩

5.1 문서 분류 시스템 만들기
문서 분로(document classification, document categorization)는 말 그대로 문서를 분류하는 것이 목적입니다. 예를 들어 문서를 항목별로 분류하기(도서관에서 책 분류하기), 제품 리뷰로 상품에 대한 긍정/부정 의견 판단하기(sentiment analysis), 문서 내용을 보고 사람과 봇 중 누가 생성했는지 판단하기 등을 들 수 있습니다. 이 절에서는 일상에서쉽게 접할 수 있는 스팸 필터를 머신러닝을 이용해서 만들어 보겠습니다(실제 코드는 11장에서 다룹니다)

5.1.1 문서 분류에 많이 사용하는 피처
문서는 어떤 기준으로 분류할까요? '문서 내요을 분석해서 분류해야지'라고 생각했다면 반은 맞춘 겁니다. 문서에서는 내용, 글쓴이, 서식, 문서 구조, 문서 길이 등 여러가지 피처를 얻을 수 있는데, 그중 문서 내용이 가장 기본이 됩니다.

5.1.1.1 단어 빈도 피처
문서 내용을 완벽하게 이해하는 머신러닝 시스템은 아직 존재하지 않습니다. 그래서 간단한 모델을 이용하여 약간은 부정확하지만 적당한 수준의 시스템을 만든 후 많은 문서로 학습시켜 조금씩 더 나은 좋은 결과를 만들어 내는 방식이 주로 사용됩니다.

이러한 간단한 모델에 사용되는 피처의 예로는 단어 빈도(word frequency, term frequency)를 들 수 있습니다. 이 피처는 문서에서 단어가 얼마나 자주 나오는지 측정해서 문서 내용을 팡가하는 방법입니다. 예를 들어 문서에 축구와 관련된 단어가 자주 등장한다면 그 문서를 축구와 관련된 문서라고 여기는 것입니다. 단어 빈도는 단어가 문서에서 얼마나 나오는지 계산한 후 문서 전체 단어 숫자로 나누어 그 비율을 계산합니ㅏㄷ. 물론 단어가 단순히 몇 번 출현하는지 세는 단어 카운팅(word counting)방식도 많이 사용하지만, 이 방식은 한 문서가 길고(즉, 많은 단어로 이루어져 있고) 다른 문서가 짧은 경우(즉, 적은 단어로 이루어져 있을 경우)공정한 비교가 어렵기 때문에 횟수보다는 빈도를 더 많이 사용합니다. 때로는 단어의 존재 여부만 체크하는 단어 출연(word occurrence)도 유용합니다(단순히 문서를 긍정 또는 부정으로 평가할 때 의외로 좋은 성능을 보여 줍니다).
엄밀하게 정의하면 단어 빈도 피처는 다음과 같습니다.

i 번째 단어 빈도 피쳐 = i 번째 단어가 문서에 나타난 횟수/문서의 총 단어수

즉, 단어 빈도 피처는 가능한 모든 단어(보통 단어집vocabulary이라고 부릅니다)의 개수만큼의 피처를 가지며 각각의 값은 단어가 문서에 나타난 횟수와 문서의 총 단어 수로 결정됩니다.

5.1.1.2 TF-IDF
단어 빈도 피처의 한가지 문제점은 단어 하나하나의 중요도가 동일하기 때문에 빈도수가 높은 단어를 상대적으로 중요하다고 오인할 수 있습니다. TF-IDF(Term-Frequency Inverse-Document Frequency)단어를 이용하면 단어의 희귀도를 고려해서 피처를 생성할 수 있습니다.
단어의 중요도는 어떻게 결정할까요? 다음과 같은 문서가 있다고 합시다.

11살 생일을 몇칠 앞둔 어느 날 해리에게 초록색 잉크로 쓰여진 한 통의 편지가 배달된다. 그 편지의 내용은 다름 아닌 해리의 11살 생일을 맞이하여 전설적인 '호그와트 마법학교'에서 보낸입학 안내장이었다..(이하 생략)

이 문서에서 가장 많이 나오는 단어는 '해리'이므로 해리가 가장 주용한 단어인 것 처럼 보입니다. 하지만 해리포터 시리즈의 각 편을 다룬 기사를 구분하는 데 과연 해리라는 단어가 유용할까요?
예를 들어 해리포터 시리즈를 다룬 기사 3편에 대해 각각 단어 수를 세어봤더니 [표5-2]와 같은 결과를 얻었다고 합시다.

표5-2 기사에 따라 다르게 등장하는 단어 수에 대한 예
                             기사1                    기사2            기사3
해리                      132                        98                103
호그와트                 90                         95                55
지팡이                    0                           120              55
성물                       0                           0                 49

세 기사 모두에서 '해리'라는 단어가 가장 많이 등장하므로, 이 세 기사를 서로 구분하는데 해리는 별로 중요하지 않습니다. 반면 '성물'은 가사 3과 나머지 기사를 구분하는데 쓰일 수 있습니다. 이런 식으로 각 단어가 문서(여기서는 기사)를 구분하는데 얼마나 중요한지 고려하는 피처가 바로 TF-IDF입니다. 여기서 TF는 앞서 설명한 단어 빈도(Term-Frequency)를 뜻하고 IDF는 역문서 빈도(Inverse Document Frequency)를 뜻합니다.

TF-IDF=단어 빈도 * 역문서 빈도

단어 빈도는 5.1.1.1절 '단어 빈도 피처'에서 설명했듯이 단어가 나온 횟스를 문서 전체에 나온 단어 수로 나눈 값입니다. 역문서 빈도는 다음과 같습니다.
가능한 모든 단어 중 I번째 IDF피처 = log( 전체 문서수/i번째 단어가 나타나는 무서 수)

[표 5-2]에서 성물은 한번 나왔기 때문에 IDF가 log(3/1)= 0.477, 해리는 모든 문서에서 나왔기 때문에 log(3/3)=0.000이 됩니다. 많은 문서에 흔하게 등장하는 단어의 IDF가 낮다는 것을 알 수 있습니다. 각 단어의 IDF 는 다음표와 같습니다.

                  IDF 피처값
해리            log(3/3) = 0.000
호그와트      log(3/3) = 0.000
지팡이         log(3/2) = 0.176
성물            log(3/1) = 0.477

그렇다면 TF도 계산해서실제로 TF-IDF를 구해보도록 합시다. 문서 1에서 해리의 TF는 132/(132+90) = 0.595고 IDF는 0이므로 TF-IDF는 0입니다. 마찬가지로 호그와트의 TF-IDF도 0입니다. 지팡이와 성물의 TF는 0이므로 문서1의 TF-IDF 피처는 [0,0,0,0]입니다. 문서 3의 TF피처가 [0.393, 0.210, 0.210, 0.187]이므로 각각에 IDF를 곱한 TF-IDF는 [0,0,0.210*0.176, 0.198 * 0.477]= [0,0,0.037, 0.0094]입니다.

TF-IDF 피처는 이렇게 중요한 단어에 강조를 주어 문서를 구분하는데 도움을 줍니다.
전체적으로 자주 나오지 않는 단어의 로그값이 너무 작아서 IDF가 예외적으로 커지는 것을 막기 위해 IDF에 약간 변형을 주어 사용하기도 합니다. 바로 log를 취하기 전에 1을 더해서 다음과 같이계산하는 방법입니다.

스무딩된 IDF피처 = log(1 + 전체문서수/i번째 단어가 나타나는 문서수)

5.1.1.3 토픽 또는 군집에 기반한 피처
지금까지는 단순희 단어 출현 횟수를 세거나 그 중요도를 고려해서 피처를 정하는 방법을 알아 보았습니다. 단어외에 더 큰 의미 단위를 이용해보면 어떻까요? 예를 들어 단어들을 군집한 후 각 문서에 나타나는 단어가 어떤 군집에 해당되는지, 혹은 각 문서가 어떤 토픽으로 구성되는지 파악한 다음 그 토픽들이 가지는 중요도를 계산해서 피처를 만드는 방법을 생각해 볼 수 있습니다.
여기서는 이러한 방법의 문서에서 피처를 만들 수 있다는 정도만 언급하겠습니다. 자세한 내용은 5.2절'토픽 모델링'에서 다룹니다.

5.1.2 피처를 이용해서 실제로 분류하기
5.1.1절 '문서 분류에서 많이 사용하는 피처'에서는 문서에서 피처를 뽑아보았으며, 그를 통해 문서를 어떤 고정된 길이의 숫자로 변환시켰는데, 여기서는 그것을 이용해서 문서를 어떻게 분류할 수 있는지 이양기 해보겠습니다.
문서를 피처로 변환한 후에는 피처를 분휴할 수 있는 먼신러닝 기법을 사요하면 됩니다. 이 절에서는 대표적인 문서 분류 기법인 로지스틱 희귀와 SVM에 대해 살펴보겠습니다.(물론 결정 트리등 거의 모든 분류 깁버을 사요할 수 있습니다.)

5.1.2.1 로지스틱 회귀
로지스틱 회귀는 2.1.2절 '간단한 모델'에서 잠깐 소개햇던 선형 회귀 모델에 로지스틱 함수를 적용해서 분류를 하는 기법입니다. 이 모델은 간단해서 구현이 쉬우며 좋은 성능을 내기 때문에 자주 사용됩니다.  로지스틱 회귀는 선형 회귀와 밀접한 연관관계를 가지고 있습니다.

선형 회귀는 2.1.2절 '간단한 모델'에서도 잠깐 소개를 했었느데요, 주어진 입력과 출력 사이에 선형 관계가 존재한다는 가정을 합니다. 주어진 피처(xi)에 따라 다음과같이 정의됩니다.
선형 회귀는 간단하지만 학습이 빠르고 모델이 단순함에도 불구하고 좋은 성능을 보이므로굉장히 널리 쓰입니다. 하지만 주어진 입력에 따라 연속적인 산술값을 출력하는 회귀 기법이기 때문에 분류를 할 때는 약간 변형시켜 사용해야 합니다. 이 변형을 위해 로지스틱 함수를 이용합니다.

로지스틱 함수는 선형 회귀의 연속적인 숫자값을 확률값으로 변환합니다. 이를 이용해서 결과가 어떤 분류에 해당하는지와 해당 하지 않는 지 알 수 있습니다.(이항 분류라고 합니다.) 옐르 들어 입력 데이터의 로지스틱 회귀 값이 0.5보다 크면 분류 1에 속하고, 0.5보다 작으면 분류 0에 속한다는 것을 알 수 있습니다.

좀 더 복잡한 로지스틱 회귀에는 다항 로지스틱 회귀가 있습니ㅏㄷ. 이를 소프트맥스 회귀라고 부릅니다.(딥러닝에서 스프트맥스 회귀라는 표현을 더 많이 사용합니다.) 다항 로지스틱 회귀는 다음과같이 정의되며, 이항 로지스틱 회귀와 굉장히 비슷하다는 것을 알 수 있습니다.

수식이 조금 복잡하게 보일텐데,간단히 설명하면 모든 가능한 항목에 대해 선형 회귀를 수행한 다음 소프트맥스 함수에 통과시킨 겁니다. 소프트맥스 함수는 로지틱스 함수의 확장판으로 생각하면 되는데, 여러 개의 선형 회귀 값을 가지고 각각을 0 부터 1까지 변환시킨다고 생각하면 됩니다.
예를 들면 항목 A에 대한 파라미터 (Wa)가 벡터로 [3, -1]이고, 항목 B에 대한 파라미터(Wb)가[5,2], 항목 C에 대한 파라미터(Wc)가 [-1,10]인 예를 생각해 봅시다. 각각의 항목에 대한 W와 입력의 벡터곱에 exp를 취한 값으로 해당 항목의 확률을 계산합니다. 그러므로 만일 입력(x)이 [1,1]이면 다음과 같이 계산됩니다.

- 항목 A: exp(3*1 + -1*1)= 7.4
- 항목 B: exp(5*1 + 2*1) = 1096.6
- 항목 C: exp(-1*1 + 10 *1) = 8103.1

각각의 항목에 대한 확률은 각각의 값을 전체 합(7.4 + 1096.6 + 8103.1 = 9707.1)으로 나눈 값입니다.

- 항목 A가 맞을 확률: 7.4/9707.1 = 0.0008
- 항목 B가 맞을 확률: 1096.6/9707.1 = 0.1191
- 항목 C가 맞을 확률: 8103.1/9707.1 = 0.8801
이렇게 문서를 피처로 변환시켜서 그것을 입력으로 계산하면 각 항목에 속할 확률값이 나옵니다. 그중 가장 높은 확률을 가지는 항목이 문서의 분류값이 됩니다.

5.1.2.2 SVM
SVM은 문서 분류 문제에 사용하는 표준적인 분류 모델입니다. 로지스틱 회귀가 확률을 로지스틱 함수를 사용해서 모델링한다면 SVM은 확률을 직접 계산하지 않고 데이터가 어떤 '경계선'을 넘지 않는지 검사하는 분류합니다. 결과적으로 SVM은 확률값이 아닌 분류값을 출력합니다.

'경계선'에 대해 좀 더 이야기 하겠습니다(경계선의 머신러닝 공식 용어는 결정 경계선(decision boundary입니다). 데이터가 피처값에 의해 어떤 공간에 분포하고 있다고 합시다. 여기서 한 데이터에 피처 값이 두개 주어졌을 때를 생각해 봅시다.

5.1.2.3 그 외에 만히 쓰이는 분류 방법
로지스틱 회귀와 SVM이 문서 분류에 굉장히 널리 사용되지만, 결정 트리나 그레디언트 부스티드 트리 등의 모델도 많이 사용됩니다. 일단 5.1.1절 '문서 분류에서 만힝 사용하는 피처'에서다룬 것처럼 문서를 피처로 변환합니다. 그리고 나서 앞서 소개한 몇 가지 유명한 머신러닝 모델중 성능이 잘 나오는 것을 고르면 됩니다.
문서에서 좋은 피처를 뽑는 것과 좋은 모델을 찾는 것 중 어떤 것이 더 중요한지 궁금할 것입니다. 사실 정답은 없지만(정확하게는 데이터에 따라 다릅니다). 우선 단어 빈도나 TF-IDF피처로 시작해서 몇 가지 머신러닝 기법을 시도해 보는 것이 좋을 것 같고, 분류가 잘되지 않는 문서를 직접 보면서 어떤 피처가 분류에 도움이 될지 생각해 보는 것이 좋을 것 같습니다.

5.2 토픽 모델링
토픽 모델링은 문서에 존재하는 토픽을 추출하는 기법입니다. 토픽은 문서의 주제를 뜻하는데, 문서 분석의 경우 어떤 단어가 특정하게 분포하는 것을 토픽이라고 합니다. 옐르 들어 스포츠에 대한 단어가 다른 단어보다 많이 나오면 그 문서의 토픽은 스포츠와 관련되었다고 볼 수 있고, 연예인에 대한 단어가 많이 나오면 연예인과관련되었다고 볼수 있습니ㅏㄷ.
토픽 모델링은 문서가 토픽들로부터 생성된 단어로 이루어진다고 가정합니다.

- 문서에는 여러 토픽이 각각의비중을 가지고 존재합니다.
- 토픽마다 단어의 분포가 달라집니다.
- 문서를 작성할 때 토픽의 비중에 따라 토픽을 고라가면서 단어를 뽑습니다.

문서가 토픽에 기반하여 생성된다고 가정하면 문서 내용을 단순히 단어가 아니라 토픽이라는 큰 의미 단위를 통해 파악할 수 있습니다. 예를 들어 어떤 문서는 스포츠 토픽과 연예인 토픽을 7:3으로 썪었고, 또 다른 문서는 과학과 기술을 8:2로 썩였다고 판단할 수 있는 거죠. 그리고 일반적으로 토픽에 따라서 단어가 나오는 비율만 달라질 뿐 단어의 순서는 고려하지 않습니다.
이렇게 토픽을 가정하고 이를 문서를 분석하는 머신러닝 기법을 토픽 모델링이라고 합니다. 이 절에서는 토픽 모델링에 가장 유명한 LDA에 관해 알아보도록 하겠습니다.

5.2.1 LDA
LDA는 확률모델을 통해 문서의 토픽과 토픽에 분포하는 단어들을 분석합니다. 이전에도 말했듯이 LDA는 잠재 디리클레 할당이라는 뜻인데, 문서 안의 토픽 하나하나 디리클레 분포를 따르며, 문서를 그런 토픽에 할당한다는 의미에서 이렇게 부릅니다.

LDA에서는 하나하나의 문서가 다음 과정을 거쳐 생성된다고 가정합니다.
1. 문서에 단어가 몇 개 있는지 결정합니다.
2. 문서마다 토픽이 어떻게 분포되어 있는지, 토픽마다 단어 분포가 어떤지 디리클레 분포(Dirichlet distribution)에 따라 정의합니다.
3. 문서의 제일 첫 단어부터 끝 단어까지 다음 과정을 거칩니다.
  a. 현재 위치의 단어가 어떤 토픽과 관계있는지 정합니다.
  b. a에서 정한 현재위치의 토픽에 따라 단어의 분포를 결정하고 그 중에서 가장 높은 확률의 단어를 선택합니다.

간단히 요약하면, 문서가 어떤 토픽을 가질 확률, 각 위치의 단어가 어떤 토픽에 해당할지의확률, 그 토픽에 따라 단어가 어떤 확률로 생성될지 정의해서 문서를 활률 모델로 설명한 것으로 볼수 있습니다.
이제부터 LDA가 어떤 일을 하는지 구체적인 예제를 살펴보겠습니다. 다음은 LDA 논문에 수록된 내용으로, LDA를 이용해서 AP통신 기사에서 토픽을 추출한 것입니다.

이렇게 LDA를 통해 각 토픽이 어떤 단어들로 이루어져 있는지, 문서가 어떤 토픽을 가지는지 알 수 있습니다. 추출한 토픽 정보를 이용해서 5.1.1.3 절 '토픽 또는 군집에 기반한 피처'에서 설명한 것처럼 분류에 사용될 피처를 만들기도 하고, 문서 분석을위해 토픽 자체를 사용하기도 합니다. 또한 이러한 토픽을 이용해서 문서를 요약하거나 군집화하기도 합니다.

여기서는 토픽 모델링을 문서에 적용했는데, 문서 데이터와 비슷한 양상을 보이는 데이터가 있다면 토픽 모델링을 적용해서 내용을 간추리는데 도움이 될 수도 있습니다. 예를 들어 한 사용자의 쇼핑 정보를 문서로 간주하고 구매 항목을 단어로 취급하면 여러 상품을 토픽처럼 묶어서 분석할 수 있습니다.

5.3 문법 분석
문법분석은 문서의 문법 구조를 분석해서 내용을 파악하는 기법입니다. 문법을 분석해서 파악하기 때문에 단순히 단어 수만 세서 파악할 때보다 내용을 좀 더 정확하게 파악할 수 있습니다. 같은 단어를 사용하더라도 문법 구조에 따라 의미가 정반대가 되기도 하고, 대명사가 지칭하는 단어가 달라질 수 있기 때문입니다.
물론 앞서 잠시 이야기 했듯이 문서를 하나하나 완벽하게 분석하는 ㅣㅇㄹ은 어렵습니다. 문법 분석은 아직 완전히 풀린 문제로 보기 어렵고, 현존하는 기술로는 아직 단어 중심의 분석만큼 큰 규모의 분석을 하기 어렵습니다. 그렇기 때문에 문서의 뜻을 광의적으로 파악하는 문제보다 문장 하나의 뜻을 세부적으로 파악하는 것이 결정적인 역할을 하는 경우에만 적용합니다. 옐르 들어 신문기사를 분류하는 문제보다는 채팅 메시지를 보고 그것이 긍정인지 부정인지 파악하는 것을 생각해 볼 수 있습니다.

이 절에서는 두 가지 대표적인 문법 분석방법에 대해 알아보겠습니다. 첫 번째는 문서 내의 각 단어의 품사를 파악하는 품사 태깅(POS :Part of Speech Tagging)문제고, 두 번째는 각 단어가 어떤 의미 단위에 속하는지(옐르 들어 장소인지 사람인지)파악하느 고유명사 추출(NER: Named Entity Recognition)입니다.

5.3.1 품사 태깅
품사 태깅 문제는 주어진 문서에서 각 단어의 품사(주어, 목적어, 형용사 등)를 파악하는 것입니다. 보통 문서 전체에서 품사를 한번에 파악하기보다는 각 문장의 품사를 파악하는 것이 일반적입니다. 다음 문장을 읽으면서 단어들의 품사를 어떻게 결정하느지 생각해 봅시다.
  The brown fox jumps over the lazy dog.
위 문장은 'The'로 시작합니다. 이 단어는 항상 관사로 상요되므로 뒤에 오는 단어가 명사임을 알 수 잇습니다. 그다음에 나온 단어는 'brown'인데, 이 단어는 형용사나 명사로 사용되며, 다음에 명사가 나왔기 때문에 이 명사를 수식하는 형용사로 쓰였다는 것을 아 수 있습니다. 그 다음에 'fox'라는 명사가 나오면서 이 명사절은 끝납니다. 문장 구조에서는 명사절 뒤에 동사가 나옵니다. 여기서 'jumps'가 그 역할을 하고 있습니다. 이런 식으로 문장을 끝까지 처리하면 다음과 같은 문법 트리를 얻게 됩니다.
(주어(명사구 The brown fox)
    (동사 jumps
       (전치사 over
         (명사구 the lazy dog))))
POS 태깅 문제를 푸는 과정을 살펴보면 현재 단어와 이전 단어에 따라 품사가 결정 된다는 것을 알 수 있습니다. 이런 방식의 문제를 2.1.4.1절 '순차 모델'에서 잠깐 다루었는데, 바로 순차 모델링(sequential modeling)입니다. 품사 태깅에 순차 모델을 이용하면 문자으이 첫 단어부터 마지막 단어까지 단어 하나하나가 입력으로 들어가고, 모델의 상태를 순차적으로 업데이트해가며 문장 구조를 분석합니다.
이런 순차 모델링의 가장 대표적인 기법으로는 CRF와 최근 많이 쓰이는 딥러닝 기법인 RNN과  그중에서도 유며안 LSTM(Long Short-Term Memory)이 있습니다. 이어서 RNN과 LSTM을 간단히 소개하겠습니다.

5.3.1.1 RNN
2.1.4.1절 '순차 모델'에서 순차 모델을 설명하면서 잠깐 RNN의 정의에 대해 살펴봤습니다. 여기서는 그 정의에 좀 더 살을 붙여보겠습니다.

RNN을 사용한 POS 태깅의 경우 앞서 설명했듯이 순서를 가지는 데이터(여기서는 문장에서의단어들)를 앞에서부터 하나씩 읽어나가면서 품사 예측을 수행합니다. x는 문장의 단어의 각 단어들의 피처가 됩니다. 간단하게 전체 단어집에서 명 몇번째 단어에 해당하는지 생각할 수 있겠고요, 복잡하게는 사전에서 이 단어에 어떠한 뜻이 있는지 혹은 어떤 품사들을 가질 수 있는지에 대한 정보를 담을 수 있습니다. 출력 y는 모델이 예측한 품사입니다. h는 문장의 첨음부터 단어를 하나씩 보면서 전에 어떤 단어들이 모델의 입력으로 들어왔는지 기억하는 부분입니다. 즉,각 단어를 하나씩 보면서 바로 직전의 상태(ht-1)와 현재 단어(xt)를 가지고 현재 상태(ht)를 업데이트 합니다.

순서에 입각한 RNN의 학습은2장에서 예로 든 순서가 없는 모델보다 약간 더 복잡합니다. 순서가 없는 경우에는 입력 x와 출력y의 한 쌍이 다른 입출력과 독립적이기 때문에 각각의입출력에 대해 최적화를 했었는데,  RNN의 경우에는 현재 단어와 지단 단어가 h를 통해 연결되기 때문에 한 문장 안의단어들은 함께 연관되어 학습되어야 합니다.(문장끼리는 보통 독립적이라고 생각합니다.) 이 학습을 위해서는 보통 경사하강법을 시간에 따라 거슬러 올라가면서 계산하는 방법(Backpropagation Though Time)을  많이 사용하며, 보통 이 방법은 라이브러리에 구현되어 있기 때문에 직접 작성하기 보다는 구현된 라이브러리를 활용하면 됩니다.
학습 방법에 대해 굳이 설명을 한 이유는 RNN이 가지고 있는 한계점에 대해 설명을 하고 싶었기 때문입니다. RNN은 문장이길어져서 단어 간의 연관관계가 멀리 떨어져 있을 때 제대로 모델링하지 못하는 문제가 있습니다. 이론적으로는 내부에 존재하는 표현형(h)과 연관관계가 멀리 떨어져 있더라도 제대로 모델링할 수 있어야 합니다. 하지만 앞서 언급한 '시간에 따라 거슬러 올라가며 계산하는 방법'으로 멀리 떨어져 있는 단어의 정보가 제대로 전달되지 않는 문제가 있습니다. 이 문제를 소멸하는 1차 미분값(vanishing gradient)이라고 부릅니다. 나열된 순서를 거슬러 올라가며 1차 미분값을 계산하다보면 그 값이 점점 작아져서 정보가 잘 전달되지 않습니다. 그렇기 때문에 문장이 길어지면 연관관계를 잘 모델링 하지 못해서 원하는 성능을 얻지 못하는 문제가 있게 되는 것입니다.

이 문제를 해결하고자 등장한 것이 LSTM(long Short-Term Memory)입니다. 물론 LSTM 모델이 앞서 설명한 기본적인 RNN보다 훨씬 더 복잡하기 때문에 학습이 어려워서 항상 잘 동작하는 것은 아니지만 멀리 떨어진 연관관계를 모델링하는 데는 탁월한 성능을 보여줍니다.

지금까지는 간단한 RNN모델만 이야기 했는데, [그림 5-6]처럼 직전 표현형만 고려하는 것을 넘어 두 단계 이전 표현형을 고려하는 등의 시도가 있습니다. 간단한 RNN 구조를 층층이 쌓아서 더 복잡한 연관관계를 학습하려는 시도인데, 보통 딥러닝이라고 불리는 모델은 이러한 복잡한 구조를 많이 사용합니다. 2.1.4 절 '구조가 있는 모델'에서 설명한 것처럼 구조가 복잡할수록 데이터가 많아야 제대로 동작합니다.

5.3.1.2 LSTM
LSTM은 RNN 모델 중 하나로 RNN기본 모델의 단점을 해결하고자 고안되었습니다. 가장 기본적인 차이점은 전에 가지고 있던 정보를 계속 가지고 갈지 혹은 잊을지 판단하는 신경망 구조가 들어 있다는 것입니다.

[그림 5-7]을 보면 [그림 5-6]과 비슷하게 문장의 흐름(xt-1, xt, xt+1)에 따라 각 단어가 입력으로 들어가고 각각에 해당하는 출력(yt-1, yt, yt+1)이 있습니다. 하지만 [그림 5-6]과는 다르게 상태를 저장하는 부분에 복잡한 박스가 있습니다.
이 박스는 입력과 현재까지의상태를 이용해서 내부에 가지고 있던 정보를 업데이트할지 잊을지 판단합니다. 문장을 앞에서부터 보다가 내용이 어느정도 정리된 것 같다고 판단되면 지금까지의 상태 정보를 잊고 새로 입력된 단어가 별로 유용하지 않으면 지난 단계까지의 상태를 많이 기억하고 업데이트를 조금만 합니다. 그리고 이 상태를 C(셀cell)라고 불리는 곳에 저장합니다.
이러한 선택적인 업데이트와 기억방식은 박스의 특별한 구조 때문인데, 자세한 동작 방식은 다음과 같습니다. 앞서 설명한 것처럼 C는 상탯값, W는 모델의매개변수를 뜻합니다.

1. 맨 왼쪽 첫번째 구조는 망각 게이트(forget gate)라 불리는데, 지금까지 기억했던 상태와 현재 입력에 파라미터를 곱해서 상태를 잊을지 말지 정합니다.
ft = Q(Wforget[Ct-1, Xt])

2. 그다음 구조는 입력 게이트(input gate)인데, 상태와 현재 입력을 가지고 얼마나 기억할지 정합니다.
it = Q(Winput[Ct-1, xt])

3. 그리고 그다음 상태를 앞에서 설명한 RNN과 비슷하게 추측합니다.
Ct =tanh(Wcell[Ct-1, Xt])

4. 이렇게 3가지를 계산하고 나면 망각을 얼마나 하고(항목 1) 업데이트를 얼마나 할지(항목2) 어떤 값을 업데이트할지(항목 3) 정해서 업데이트 합니다.
Ct = ft*Ct-1 + itCi

5. 실제 출력은 현재 상태(Ct)와 입력을 이용해서 결정합니다.
y = Q(Wy[Ct, xt])

수식 때문에 햇갈린다면 한글로 된 설명 부분만 이해해도 됩니다. 기본 RNN과 비슷한게, 내부에 어떤 상태가 있고(C, RNN의 h와 동일하지만 LSTM에서는 주로 셀이라고 부릅니다), 전 상태와 현재 입력에 따라 현재 상태를 얼마나 기억할지, 얼마나 업데이트할지, 무엇을 업데이트 할지 파라미터로 정합니다.

LSTM학습은 파라미터들이 어떻게 기억하는지, 출력을 어떻게 내는지에 대한 손실함수를 만들고(보통 교차 엔트로피를 많이 사용합니다) 경사하강법을 응용한 방법으로 학습을 수행합니다. 이걸 직접 구현하기는 복잡하므로 라리브러리에 주어진 기본 구현을 사용하면 됩니다.

[그림 5-7]은 광장히 단순화한 모델이며, 실제 사용할때는 구조가 훨씬 더 복잡해집니다. 옐르 들어 망각 게이트나 입력만 고려하는 것이 아니라 전 단계의 출력값까지 교려하거나, 아니면 몇 단계 전의 입력을 고려하기도 합니다. 또한 입력과 출력 사이에 LSTM박스를 하나만 두는것이 아니라 박스를 층층이 쌓아서 더 복잡한 학습에 사용합니다(보통 딥러링은 이렇게 복잡한 구조를 지칭합니다.) 반면 LSTM의 망각과 입력 게이트를 묶어서 망각하는 만큼 기억을 하는 GRU(Gated Recurrent Unit)같은 약간 더 간단한 모델도 있습니다.

이렇게 LSTM을 이용하면 RNN보다 더 복잡하고 멀리 떨어진 연관관계를 모델링할 수있습니다.LSTM은 POS 태깅 문제에도 사용되지만, 음성 데이터처럼 시간에 따라 변화하는 데이터를 분석하느데도 많이 사용됩니다.

5.3.2 고유명사 추출(NER)
구글 어시스턴트, 시리, 아마존 에코 등 대화형 봇이  유행입니다. 이런 봇들이 대화에서 장소나 시간 정보를 발견하면 일정을 만들어주는 머신러닝 시스템을 만든다고 생각해봅시다. 그렇다면 문장에서 어떤 부분이 장소고 어떤 부분이 시간인지 추측해야겠지요? 이런일을 가능하게 해주는 것이 바로 NER(Named-Entitiy Recognition)입니다. NER은 텍스트에서 인물, 조직, 장소, 일정 등을찾아내는 문법 분석 방법입니다. 책이나 웹 페이지에서 이름, 장소, 주소, 제품명을 인식하는 데 사용할 수 있습니다.

NER은 POS 태깅 문제와 몇 가지 비슷한 성질을 가집니다. 첫 번째로 품사 문제 때처럼 사전정보를 사용하면 많은 도움이 됩니다(유명한 사람의 이름이나 장소 같은 고유명사가 특히 중요합니다.) 두번째로 품사 문제를 풀 때와 마찬가지로 앞뒤에 나열된 단어에 따라 영향을 받습니다. 예를 들어'정문 앞에서 만나자'라는 부분이 있다고 합시다. 이때 '에서 만나자'라는 표현은 장소와 연관성이 있기 때문에 '정문 앞'에 해당하는 단어가 장소사전에 등록되어 있지 않더라도 장소일 확률이 높습니다.

이 절에서는 앞서 설명한 RNN이나 LSTM모델을 이용해서 어떻게 NER문제를 푸는지 알아보겠습니다. 또한 참고로 머신러닝 기법을 사용하지 않고서도 어떻게 NER문제를 풀 수 있는지에 대해서도 살펴보겠습니다.

5.3.2.1 순차 모델을 사용한 NER(RNN/LSTM)
NER도 머신러니의 순차 모델을 많이 사용합니다. 예를 들어 LSTM과 같은 순차 모델에 입력으로 NER 문제에 도움이 되는 장소사전이나 품사를 넣고, 출력값으로 NER 항목들을 주어서 학습하는 방식입니다. NER 항목은 필요에 따라 여러가지를 생각할 수 있지만 일반적으로 '장소, 일정, 인물, 해당 항목 없음' 이런 식으로 분류를 만들어 학습을 진행하면 됩니다.

다음 절에서 설명하겠지만 이 방식의 가장 큰 문제는 문장 하나하나마다 순차 모델을 돌려야 하므로 속도가 그렇게 빠르지는 않아서 문서를 대규모로 분석하기에는 시간이 많이 소요된다는 것입니다.

5.3.2.2  머신러닝은 아니지만 NER에 사용되는 기법
NER은POS태깅 문제와 약간 다르게 큰 규모의문서 분석에서도 종종 사용됩니다. 옐르 들어 소셜 네트워크나 포털사이트에서 사용자가 신문 기사를 포스팅하면 기사에 나오는 장소나 인물에 자동으로 링크를 만들어 주는 시스템을 생각할 수 있습니다.

물론 향휴에는 머신러닝의 발전으로 RNN이나 LSTM도 이런 큰 규모의 문제를 잘 처리할 거라 생각합니다. 하지만 머신러닝을 이용하지 않고 정규표현식을 이용해서 처리하는 방법도 있다는 점을 알려드립니고 싶습니다. 예를 들어 \d\d\d\d-\d\d\d\d-\d\d\d\d와 같이 숫자 3개, 4개,4개가 '-'로 연결되어있다면 전화번호일 확류이 굉장히 높습니다. 앞서 말씀드린 인물사전, 장소사전과 적절한 정규표현식을 사용하면 순차 모델을 사용하는 것보다 정확도나 발견 확률이 떨어지지만 빠르게 대규모 분석이 가능합니다.

5.4 단어 임베딩 학습-word2vec
컴퓨터로 단어의 의미를 나타내는 방법은 크게 이산표현(discrete representation)과 분산표현(distributed representation)이 있습니다.
쉽게 설명하자면 이산표현은 그 단어 자체를 이요하며 의미를 나타내는 것입니다. 옐르 들어 고양이라는 단어가 있다면 사전을 이용하여 단어를 정의하는 것이죠, 따라서 이산표현에서 단어 하나의 의미는 말뭉치에 든 모든 단어 수를 벡터 크기로 하는 원-핫 인코딩 벡터(3.3.2절'카테고리 데이터 표준화'참조)로 표현합니다.

이와 달리 분산 표현은 한 단어의 주변 단어를 이용해서 의미를 표현합니다. 즉, 분산 표현에서는 고양이는 '귀엽다', '야옹거린다'라는 주변 단어로 의미가 정해집니다. 이러한 분산 표현은 사전에 정의되지 않은 새로운 단어도 표현할 수 있으므로, 더 많은 단어를 분석에 이용할 수있습니다. 분산 표현을 이용하면 단어 하나는 실숫값으로 이루어진 벡터가 되는데, 이를 단어 임베딩(word embedding)이라고 합니다.
이산 표현과분산 표현의 예는 다음과 같습니다.
- 이산 표현
고양이 = [0,0,0,....1,0,0](원-핫 인코딩 벡터. 하나의 항만 1이 됩니다.)
여기서 벡터의 길이는 말뭉치 안의 단어(어휘집의 크기) 수가 됩니다.

- 분산 표현
고양이= [1.281, -2.321, 4.509,....3.212]
여기서 벡터의 길이는 사용자가 지정한 길이가 됩니다.

word2vec은 뉴럴넷을 이용하여 분산 표현을 학습하는 모델입니다. 이러한 시도는 오랫동안 있어왔지만 2013년에 소개죈 word2vec이 계산이 빠르고 간단해서 널리 쓰이므로, 이 책에서는 word2vec에 대해 자세히 살펴보겠습니다.

word2vec은 단어가 주어지면 그 단어와 주변 단어가 같이 일어날 확률을 구합니다.
word2vec의 목적 함수로는 스킵-그램과 COW가 있습니다.

- 스킵-그램(skip-gram):단어 하나(xt)를 받아서 그 주변에 같이 나타날 확률이 높은 단어들(context)을 구합니다. 즉, p(context|xt)를 구합니다.
- COW(continuous bag or words): 주변 단어들(context)을 받아서 그 단어들과 같이 나타날 확률이 높은 단어(xt)를 구합니다. 즉p(xt|context)를 계산합니다.

그림으로 나타내면 다음과 같습니다.

word2vec 은 한 단어wc가 주어졌을 때 그 주변에 단어가 존재하면 0, 그렇지 않으면 1로 하는 원-핫 인코딩을 생성해서 학습합니다. 예를 들어 '귀여/운 태비 고양이/가 고등어 통조림 앞/에서 야옹/하고 울/었/다'라는 문장을 앞뒤 두 단어를 이용하여 word2vec을 학습할때, 고양이를 중앙 단어로 입력받으면 (고양이, 태비)는 1, (고양이, 울)은 0이 되겠죠.

이 책에서는 의미적인 유사성을 얻기 위해 자주 사용하는 스킴-그램의 목적 합수를 살펴보겠습니다.
현재의 단어를 wt, 학습에 사용할 위도우 크기(주변 단어의 수+1)를 2m+1이라고할때, 스킴-그램의 목적은 다음의확률을 최대로 하는 파라미터의 집합 Q를 찾는 것입니다.
 

2018년 3월 6일 화요일

CHAPTER 4 구매 이력 데이터를 이용한 사용자 그룹 만들기

이 장에서는 사용자 그룹을 만드는 방법을 알아보겠습니다. 온라인 상거래 사이트는 사용자를 그룹으로 나누어 캠페인, 세일 등의 마케팅 전략을 세웁니다. 예를 들어 디비디와 블루레이를 판매하는 사이트에 20대 남성이 많을 경우, 20대 남성이 좋아할 만한 영화를 적극 프로모션하는 식 입니다.'20대 남성'과 같은 성별 및 연령 정보 말고도 구매 이력을 이용하여 그룹을 만들 수도 있습니다. 예를 들어 마블 슈퍼 히어로 영화를 구매하는 마블팬 그룹 같은 것 말이죠. 그러려면 제일 먼저 사용자으 ㅣ구매 이력을 살펴볼 필요가 있습니다. [표 4-1]은 가사의 사용자 구매 이력 데이터 입니다.

표 4-1 사용자 구매 이력 데이터
피처                    피처값
사용자 ID              abdc
구매일시               2017/04/01
구매상품영            [Blu-ray]캡틴 아메리카:시빌 워 2D + 3D Combo (2Disc)
구매상품 가격        30000
구매상품 수           1
구매상품 카테고리   DVD/블루레이

이 데이터를 이요해서 사용자의 구매 패턴을 정의해 봅시다. 일반회원/VIP(구매 횟수 및 구매 총액), 정기구매회원/단발성회원(구매횟수), 가전제품구매자/생활용품구매자(구매상품 카테고리), 저가 상품구매자(구매상품 가격의 평균), 마블팬(구매상품명) 등 하나의 데이터셋으로 무수한 패턴을 정의할 수 있습니다. 2장에서 설명한 대로 모델을 만들어 문제를 풀 경우 각 패턴에 대해 일일이 모데을 만들어야 합니다. 여기에서 사용자의 성별, 연령, 주소 등 사용자 정보까지 더해지면 계산이 매우 복잡해집니다. 어쩌면 우리가 상상도 할 수 없는 패턴이 존재할 수있습니다. 이와 같이 '사용자 그룹 만들기'는 수학적 모델을 만들기 어려운 대표적인 무제입니다. 이 문제를 푸는 방법으로 군집화에 대해 알아보겠습니다.

4.1 군집화
데이터 특징을 이요한 그룹핑 문제에서는 특정 패턴을 정의하여 모델을 만드는 방법보다 비슷한 데이터를 한데 모으는 방법이 더 효율적입니다. 이 방법을 군집화라고 합니다. 이 방법은 미리 그룹을 정의하지 않기 때문에 비지도학습에 속합니다. 크게 중심 기반 군집화, 계층적 군집화, 밀도 기반 군집화로 나눌 수 있습니다. 다음은 각 방법에 대한 간단한 소개입니다.
-중심 기반 군집화(prototype-based clustering): 클러스터를 크러스터 중심점으로 정의하는 기법입니다.
- 계층적 군집화(hierarchical clustering): 클러스터의 크기에 따라 클러스터의 계층을 정의하고 계층의 상하위를 이용하는 기법입니다.
- 밀도 기반 군집화(density-based clustering): 클러스터를 데이터가 높은 밀도로 모여 있는 공간으로 보는 기법입니다.

군집화의 핵심 아이디어는 비슷한 데이터를 한데 묶는다는 겁니다. 그렇다면 비슷하다는 것, 즉 유사도가 높다는것은 무슨 의미일까요? 데이터를 이루는 피처값이 비슷하다는 겁니다. 사용자 구매이력을 생각해보면, 비슷한 상품을 구매하는 사용자를 한데 묶을 수 있습니다. 또한 비슷한 연령대 사용자를 한데 묶을 수도 있습니다.

예를 들면 X는 사용자 1, Y는 사용자 2를 의미하고, 데이터를 X를 X={x1, x2, x3, x4,...xm}으로, 데이터 Y를 Y={y1, y2, y3....ym}으로 정의합니다. 여기서 m은 피처 수입니다. [표 4-1]을 기준으로 예를 들어보면 x1과 y1은 구매상품 개수, x2와 y2는 구매상품명 등으로 생각할 수 있습니다. 그럼 각 피처의 차이의 총합 가 적을 수록 비슷한 사용자라고 할 수 있습니다.

하지만 단순히 차이를 전부 한 피처에 대해 +가 나오고, 다른  한 피처에 대해 - 가 나오면 두 데이터 사이의 피처값이 많이 다름에도 불구하고 전체 합이 0이 될 수 있습니다. 따라서 단순한 차이 대신 그 차이를 제곱한 값을 더하여 얻어진 값에 루트를 사용합니다. 수학적 정의는 다음과 같습니다.

식4-1 유클리드 거리(민코스키 거리의 특수한 경우)
d(X, Y) = 루트(합((xi-yi)제곱))) = ||X-Y||
그러고 보니 이 식은 두 점사이의 최단 거리인 유클리드 거리(Euclidean distance)를 구하는 식과 같습니다. 일반적으로 유클리드 거리를 구하는 식은 계산의 편의를 위해 위 식을 제고(제곱유크릴드 거리)하여 사용합니다.

여기서 궁금한 점이 생깁니다. 가격 2만원과 1뭔의 차이인 100000이, 연령 25세와 25세의 차이인 1과 같다고 할 수 있을까요? 또 연령의 차이를 뺄셈으로 구하는 것 이해가 되는데, 상품명의 차이는 어떻게 구할 까요? 성별의 차이는 수학적으로 표현할 수 있을까요? 이에 대해서는 3.3절 '데이터 표준화'에서 살펴본 데이터 표준화 방법을 적ㅇ둉하면 됩니다. 또한 [식 4-1]에서 차이값을 제곱하지 않고 그냥 절댓값을 취하면 어떻게 될까요? 이에 대해서는 4.5절 '유사도 계산'에서 자세히 살펴보겠습니다.

4.2 K-중심 군집화
이 절에서는 중심기반 군집화의 대표적인 예인  K-중심 군집화( K-centroid clustering, K-medoid clustering) 에 대해 알아보겠습니다. 중심 기반 군집화는 클러스터 중심점을 정한 후 클러스터 중심점에 가까운 데이터들을 모아가며 클러스터를 확장하는 방법으므로 군집화 초기에 몇 개의 중심점을 어떻게 배치하는가 중요합니다. K-중심 군집화는 초기에 K개의 중심점을 랜덤으로 선택하여 군집화를 시작합니다.

중심 기반 군집화에서는 클러스터 수 K와 함께 클러스터 중심을 어떻게 구하느냐를 정할 필요가 있습니다. 여러 데이터를 요약하는 방법으로 평균(mean), 대푯값(median), 최빈값(mode)이 있다는 것은 아실 겁니다(중학교 때 변량, 도수 등을 배운 것 기억하시죠?). 클러스터 안의 데이터의 평균값을 중심으로 사용할 경우 K-평균 군집화, 대푯값을 사용할 경우 K-대푯값 군집화( K-medians clustering),최빈값을 사용할 경우 K-최빈값 군집화(K-modes clustering)라고 합니다. 3가지 방법 모두 중심점을 구르는 방법이 다를 뿐 전체 군집화 과정은 동일합니다.

K-주심 군집화는 다음 절차를 거칩니다.

1. 임의로 뽑은 K개의 데이터를 중심으로 하는 클러스터를 만듭니다(각 클러스터가 데이터 하나씩만 가지고 있습니다.)
2. 각 데이터와 클러스터 중심 간의 거리를 계산합니다.
3. 데이터와 클러스터 중심 간의 거리가 가장 짧은 클러스터에 데이터를 할당하고 이 데이터를 포함하여 클러스터 중심을 업데이트 합니다.
4. 과정 2와 3을 반복하는데, 과정3에서 더 이상 중심의 위치가 변하지 않거나, 업데이트 정후 중심점의 차이가 사용자가 지정한 허용 오차 이내이거나, 사용자가 지정한 횟수만큼 반복했으면 종료합니다.

과정 3에서 가장 가까운 클러스터에 데이터를 할당하고 있습니다. K-중심 군집화에서 클러스터는 클러스터 중심으로 정의되므로 결국 데이터와 클러스터 중심 사이의 거리가 가장 짧게 되는 클러스터를 찾는 것입니다.[식4-2]를 이용하여 거리를 구할 수 있습니다.

식4-2 클러스터 안의 데이터와 클러스터 중심 간의 거리
||x-uc||2
x:데이터
uc: 클러스터 c의 중심점

군집화는 각 데이터에 대해 [식4-2]의 값을 최소화하는 것이 목적입니다. 그런데[식4-2]를 자세히 보면 2.2.1절 '산술 손실함수'에서 살펴본 제곱 손실함수와 같은 형태임을 알 수 있습니다.
loss(f) = (y - y')2
f : 모델
y : 데이터로부터 주어진 출력
y':모델에 데이터로부터 주어진 입력을 넣어서 계산한 값

따라서 분산 분석과 같은 제곱 손실함수에 대한 이론을 k-중심 군집화에도 적용할 수 있습니다.

과정 4에서 업데이트가 없으면 군집화를 종료한다고 했는데, 이는 각 데이터가 속한 ㅡㄹ러스터가 변하지 않는 것, 즉 수렴한다는 것을 의미합니다. 하지만 수렴되기까지 상당한 시간이 걸리므로 실제로는 이전 단계의 총제봅합과 새로 얻은 총제곱합의 차이가 허용오차보다 작거나, 클러스터 중심 업데이트의 횟수가 사용자가 지정한 반복 횟수 이상이면 군집화를 종료합니다.

클러스터 수 k, 허용 오차, 반복 횟수 모두 사용자가 지정하는 파라미터이므로 군집화 결과를 보면서 바꾸어 가며 시도해야 데이터를 잘 표현하는 그룹을 만들 수 있습니ㅏㄷ. 이에 대해서는 10장에서 실제 구현을 통해 설명하겠습니다.

4.3 계층적 군집화
계층적 군집화에서의 계층은 클러스터의 계층을 의미합니다. 최상위 계층의 클러스터느 모든 데이터를 포함하는 하나의 클러스터입니다. 최하위 계층의 클러스터는 단 하나의 데이터만을 포함하므로 클러스터 수가 데이터 수와 같게 됩니다.

계층적 군집화에는 하향식인 분할적 군집화와 상향식인 집괴적 군집화가 있습니다. 사용자가 클러스터 수 k를 명시적으로 지정하는 k-중심 군집화와는 달리 계층적 군집화는 클러스터 수를 지정할 필요가 없습니다.

계층적 군집화는 각 단계마다 한 쌍의 클러스터를 비교하는데, 하향식인 분할적 군집화는 각 계층의 클러스터들을 둘로 쪼개어 하위 계층으로 진행하고, 상향식인 집괴적 군집화는 각 계층의 클러스터들 중에 가장 가까운 두 개를 하나로 합쳐 상위 계층의 클러스터를 만들어 갑니다.
같은 계통 트리를 만들어서 클러스터의 생성 과정을 시각화하기 쉽다는 것이 계층적 군집화의 장점입니다.
계층적 군집화에서 주의할 점은 늘 한쌍의 클러스터만 비교한다는 겁니다. 예를 들어 데이터에 실제 존재하는 클러스터가 3개라고 하더라도 계층적 군집화는 2n개의클러스터만 생성할 수 있으므로 데이터를 잘 표현할 수 없습니다. 군집화 전에 클러스터 수가 2n개가 아니라는 점을 알고 있다면 계층적 군집화보다는 k-중심 군집활르 하는 것이 좋습니다.
k-중심 군집화에서는 k 값에 따라 군집화의 성능이 달라지는 것과 마찬가지로, 계층적 군집화에서는 클러스터를 어느 정도로 분할 혹은 병합하는가에 따라 군집화의 성능이 달라집니다. 계통 트리를 통한 클러스터 생성 과정, 클러스터 안의 데이터 분석 등을 통해 적절한 클러스터를 찾을 수 있습니다.

집괴적 군집화는 다음 순서로 진행됩니다.
1. 하나의 데이터를 하나의 클러스터로 지정합니다.
2. 과정 1의 클러스터들에 대해 가장 유사도가 높음 클러스터 둘을 하나로 합칩니다.
3. 과정 2에서 생성된 클러스터들에 대해 다시 같은 과정을 반복합니다.

클러스터 둘을 합칠 때 복수의 데이터로 이루어진 클러스터 간의 유사도를 측정할 필요가 있습니다. 대표적인 방법으로 단일 연결법(single linkage), 완전 연결법(complete linkage), 평균 연결법(averae linkage)이 있습니다.

- 단일 연결법: 두 클러스터에 속하는 데이터들의 거리 중에 가장 짧은 거리를 클러스터 사이의 거리로 간주합니다.
- 완전 연결법: 두 클러스터에 속하는 데이터들의 거리 중에 가장 먼 거리를 클러스터 사이의 거리로 간주합니다.
- 평균 연결법: 두 클러스터에 속하는 데이터들의 거리 평균을 클러스터 사이의 거리로 간주합니다.

그럼 어떤 방법이 가장 나을까요? 알핏 생각하면 클러스터 안의 모든 데이터를 고려하는 평균 연결법이 가장 나을 것 같기도 합니다. 하지만 평균 연결법을 사용할 경우 한 쌍의 클러스터 내의 모든 데이터의거리를 구하므로 다른 두 방식보다 계산량이 늘어난다는 단점이 있습니다. 데이터에 따라서는 평균 연결법 혹은 단일 연결법이 시간이 덜 걸리고 비슷하게 좋은 클러스터를 만들 수도 있습니다.

분할적 군집화의 대표적인 예인 DIANA(Divisive Analysis,분할 분석)는 다음과 같은 과정으로 클러스터를 생성합니다.

1. 현 단계에서 가장 큰 클러스터를 선택합니다(가장 처음에는 전체 데이터를 하나의 클러스터 안에 있다고 간주합니다).
2. 과정 1의 클러스터에서 가장 이질적인 데이터를 찾습니다. 예를 들어 클러스터 안의 데이터 평균에서 가장 동떨어진 데이터를 찾습니다. 이로써 클러스터를 평균점과 이질적인 점을 중심으로 하는 두 클러스터로 나눌수 있게 됩니다.
3. 과정 2에서 구한 두 점(평균점, 이질적인 점)과 각 데이터의 거리를 계산하여 거리가 짧은 점을 중심으로 하는 클러스터로 데이터를 할당합니다.
4. 한 클러스터가 데이터 하나만을 가질 때까지 과정 1, 2, 3을 반복합니다.

분할적 군집화도 앞에서 사용한 연결 방법을 통해 거리를 측정합니다. 하지만 모든 데이터를 작은 클러스터로 나눈다는 점에서 k-중심 군집화와 굉장히 비슷한데다가, 클러스터 수의 지정이 자유로운 k-중심 군집화와는 달리 클러스터 수가 2n개라는 제약이 있어 많이 상요하지 않습니다.

4.4 밀도 기반 군집화
밀도 기반 군집환느 데이터 밀도가 높아지는 방향으로 데이터를 군집화하는 방식입니다. 대표적인 밀도 기반 군집화 알고리즘에는 평균이동 군집화와 DBSCAN(density-based spatial clustering of application with noise, 디비크캔, 노이즈를 가지느 애플리케이션의 밀도 기반 공간 군집화)이 있습니다.
평균이동 군집화는 다음과 같은 과정으로 진행됩니다.

1. 임의의 초기 중심점을 지정하거나 탐색 반경을 지정합니다(초기 중심점을 지정하지 않으면 탐색 반경에 따라 초기 중심점이 결정됩니다.)
2. 지정한 줌심점으로부터 지정한 반경을 가지는 원 안의 밀도를 계산한 후 데이터의 밀도가 가장 높은 곳을 중심점으로 재지정합니다. 데이터의 밀도가 높다는 것은 데이터가 많이 몰려 있다는 뜻입니다. 일반적으로 데이터가 정규분포(가우스분포)를 따른다고 가정하여 평균 주변에 데이터가 가장 많이 몰려 있다고보고, 반경 안의 평균점을 새로운 중심점으로 지정합니다.
3. 더 이상 중심점이 이동하지 않을 때까지, 즉 중심점이 가장 밀도가 높은 곳으로옮겨질 때까지 단계2를 반복합니다.
4. 단계 3에서 얻은 마지막 중심점이 클러스터의 중심점이 되고, 중심점의 이동 경로에 있던 데이터들을 그 클러스터에 할당합니다.

평균이동은 중심점을 갱신한다는 점에서 중심 기반 군집화로 분류되기도합니다.

DBSCAN은 반경의 밀도가 아니라 클러스터 중심의 데이터 수와 가장자리의 데이터 수의 차이를 이용합니다. DBSCAN에서 데이터는 다음과같이 나누어집니ㅏㄷ.

- 중심 포인트(core point):반경e 안에 일정 개수 이상의 데이터가 존재하는 데이터
- 경계 포인트(border point): 반경 e안에 있는 데이터 수는 중심 포인트보다 적지만, 중심 포인트로부터 반경 e안에 존재하는 데이터
- 노이즈 포인트(noise point): 중심 포인트도 경계 포인트도 아닌 데이터

데이터셋 안의 모든 데이터를 군집화하는 k-중심 군집화나 계층적 군집화와는 달리 밀도 기반 군집화는 예외 데이터를 정의하고 군집화 과정에서 그것을 제외시킵니다. 또한 클러스터 중시과 데이터 사이의 거리를 이용하는 k-중심 군집화와 계층적 군집화의 경우 중심으로부터의 같은 거리 안에 있는 모든 점이 같은 클러스터에 속하게 되므로 클러스터가 원형이 될 수빡에 없습니다. 이와 달리 밀도 기반 군집화는 클러스터 모양에 제한이 없습니다.

4.5 유사도계산
이 절에서는 유사도를 측정하는 대표적인 척도인 '거리'에 대해 자세히 살펴보겠습니다. 유사도가 클수록 거리가 줄어들기 때문에 거리가 가깝다는 것은 유사도가 크다는 것이고 거리가 멀다는 것은 유사도가 작다는 겁니다. 이절에서는 다음과 같은 거리를 다룹니다.

- 민코스키 거리: 벡터 공간 안의 두 점 사이의 거리
- 마할라노비스 거리: 점들의 분포를 고려한 거리

4.5.1 민코스키 거리
4.1절'군집화'에서 데이터를 X를 X={x1,x2, x3....xn},데이터Y를 Y={y1, y2, y3...yn}, 피처수를 m이라고 했을 때의 유크릴드 거리를 정의했습니다. 그때의 [식 4-1]은 민코스키 거르의 특수한 경우입니다. 민코스키 거리는 다음과 같이 정의됩니다.

식 4-3 민코스키 거리
d(x,y)= p루트(총함(i=1~m)|xi-yi|p
여기서 p가 1일 때는 맨해튼 거리(Manhattan distance혹은 L1 거리), 2일 때는 유크릴드 거리(Euclidean distance 혹은 L2거리)라고합니다.

맨해튼 거리는 맨해튼의 도로가 격자 모양으로 되어 있어서 한 빌딩에서 다른 빌딩까지의 이동 거리가 두 좌푯값의 차의 절댓값을 합한 값이 되기 때문에 붙여진 이름입니다.

그럼 언제 맨해튼 거리를 쓰고 언제 유클리드 거리를 싸야 할까요? 맨해튼 거리는 거리 계산 시 제약이 있을때 유용합니다. 예를 들어 체스 케임의 경우 각각의 말은 체스 판 위를 자유롭게 움직이는 게 아니라 움직일 수 있는 방향이 정해져 있습ㄴ디ㅏ. 비숏과비숍이 이동할 수 있는 칸을 별표로 표시했습니다. 체스 판의 한칸 (a1,b1)에서 다른칸(a2, b2)으로 비숍을 이동시킬 때 비숍의 디오거리는 루트 | a2 -a1| + | b2 - b1|이 됩니다. 반면 유클리드 거리는 두점 사이의 최소거리르 제약 없이 구할 때 사용합니다.

4.5.2 마할라노비스 거리
마할라노비스 거리(Mahalanobis distance)는 두 점사이의 거리를 계산할 때 데이터의 분포를 고려하는 거리입니다.
공분산이란 두 변수가 얼마나 연관성이 있는지 나타내는 값입니다. 공분산의 값이 1이면 한 변수가 증가할 때 다른 변수도 증가하는 것이고, -1이면 한 변수가 증가할 대 다른 변수가 감소하는 것입니다. 0이면 두 변수 간에 아무런 상관관계가 없습니다. X와 Y가 k개의 실수로 이루어진 벡터고, ux가 X값의 평균, uy가 Y값의 평균일 때, 공분산은 다음과 같이 계산합니다.

Cov(X,Y) = E[(X-ux)(Y-uy)]

X = {x1, x2, x3...,xk}
Y = {y1, y2, y3...yk}
ux = X값의 평균
uy = Y값의 평균

공분산을 고려한다는 것은 X값의 증감과 Y값의 증감의 관계를 거리 계산에 넣는 것입니다. 즉, 키가 평균에서 표준편차의 2배로 멀어지는 것은 몸무게가 평균에서 표준편차의 1배로 멀어지는 것과 같다는 정보를 이용합니다.
마할라노비스 거리는 거리 계산에 위에서 설명한 데이터의 분포 및 공분산을 사용합니다. 수식으로 표현하면 다음과 같습니다.

d(x,y) = 루트((xi-yi)TS-1(xi-yi))




2018년 3월 3일 토요일

CHAPTER3 데이터와 문제

데이터는 머신러닝에서 정말 중요합니다. 머신러닝은 데이터를 이용해서 문제를 해결하기 때문에 데이터의 중요성은 몇 번이고 강조해도 부족하지 않습니다. 머신러닝으로 문제를 풀 때는 데이터형, 품질, 양에 따라 고려해야 할 점이 달라집니다. '풀고자 하는 문제 유형' 역시 중요합니다. 어떤 문제를 풀지에 따라 고민거리가 달라지기 때문입니다. 이 장에서는 데이터와 풀고자 하는 문제 유형에 대해 알아봅시다.
- 데이터형에 따라 머신러닝에서 고려해야 할 점
- 데이터양과 품질이 달라질 때 고려해야 할 점
- 데이터에 치우침이 있을때 표준화하여 효율적으로 학습하는 방법
- 머신러닝 문제 휴형과 다양한 기법

3.1 데이터 형
데이터에도 유형이 있을까요? 있다면 머신러닝과 데이터형 간에는 어떤 연관이 있을까요? 이 절에서는 데이터형별 특징을 살펴보고 각각의 특징에 따라 어떤 머신러닝 기법을 사용하는지 살펴보겠습니다. 2장에서 설명한 바와 같이 머신러닝의 모델을 결정한느 것은 데이터에 대한 믿음(가정)입니다. 만일 우리가 다루는 데이터가 어떤 유형인지 알고 있다면 당연히 모델을 선택하는 일도 쉬워질 겁니다. 그리고 거의 대부분의 경우 데이터양이나 품질 때문에 생기는 고민에 비해 데이터형에 의한 고민은 쉽게 해결할 수 있습니다.

3.1.1 텍스트 데이터
텍스트 데이터는 다른 데이터에 비해 쉽게 구할 수 있습니다. 예를 들어워키피디아 덤프 파일이라든가 전자책 등 다양한 유형의 공개 텍스트 데이터가 있습니다. 또한 데이터의 의미 단위가 개별 단어나 연속하는 단어로 이루어져 있으므로 다른 데이터에 비해 의미 단위를 족각내기도 쉽습니다. 하지만 단위 데이터를 쉽게 조각내기 힘든 이미지 데이터나 음성 데이터와 달리 의미를 파악하려면 단어 간의 관계를 유추하거나 문법을 분석해야 합니다. 또한 의미 단위인 단어의 유형이 너무 다양하다는 문제도 있습니다. 텍스트 분석이 언뜻 보면 쉬워보이지만 이러한 문제들 때문에 사실은 굉장히 까다롭습니다.

특히 행렬을 이용해서 문서의 단어 분포를 표현하는 경우에는 존재하는 단어에 비해 문서에 나타나는 단어가 적으므로 행렬의 원소 대부분의 0인 상황이 많이 발생합니다. 이런 경우 데이터가 굉장히 희박(sparse)하다고 표현하며, 이러한 희박한 데이터를 이용하여 머신러닝을 하면 모델 학습이 잘못되어 실전 성능이 제대로 나오지 않게 됩니다. 그렇기 때문에 텍스트를 모델링하려면 이러한 상황을 해결해야 합니다.
또한 텍스트 데이터는 순서가 중요합니다. 순서에 따른 의미 변화를 모델링하기 위해서는 순차 모델 머신러닝 기법을 사용해야 합니다.

3.1.2 수치 데이터
수치 데이터는 금융, 생산 공정, 관측 장치 등으로 부터 얻을 수 있습니다. 많은 양을 쉽게 얻을 수 있지만 항상 노이즈가 섞여 있습니다. 노이즈가 생기는 이유는 다양하지만 일반적으로는 센서 노이즈와 현상의 무작위성이 원인입니다. 그렇기 때문에 수치 데이터 분석에는 노이즈에 강한 머신러닝 기법을 사용합니다.

수치 데이터는 대부분 수수자 피처를 가지기 때문에 텍스트에 비해 데이터 밀도가 높습니다. 그렇기 때문에 텍스트 데이터와는 다른 방식으로 접근해야 합니다.

텍스트 데이터와 비슷하게 데이터의 순서가 중요한 수치 데이터도 있습니다. 예를 들면 주식 데이터를 생각해 볼 수 있는데, 굉장이 노이즈가 많기 때문에 노이즈에 강한 숫차 모델, 예를 들면 칼만 필터(Kalman Filter)와 같은 모델을 사용합니다.

3.1.3 이미지 데이터
이미지 테이터는 최근 들어 주목받고 있습니다. 스마트폰, 디지털 카메라, 사진 및 동영상 공유 서비스가 발전함에 의해 사용할 수 있는 데이터양이 급격하게 늘어났고, 이는 데이터양이 많을 수록 성능이 향상되는 딥러닝을 이용한 모델이 전에 없던 성능을 낼 수 있게 해주었기 때문입니다.

이미지 데이터의 가장 큰 특징은 값(색상, 채도, 명도 등)과 위치에 따라 점의 의미가 달라진다는 겁니다.

이미지 데이터는 각 구역을 픽셀로 쪼개어 표현하게 되는데, 주변 픽셀에 따라 한 픽셀이 갖는 값의 의미가 달라집니다. 예를 들어 검은 구역이 있을 경우, 주변이 모두 검은 구역이면 사과의 가운데, 오른쪽 옆이 흰구역이면 사과의 가장자리가 되는 식이죠. 이렇게 픽셀 데이터가 근접한 픽셀 데이터와 강한 연관 관계를 가지는 것이 이미지 데이터의 가장 큰 특징입니다.

이러한 근접 연관성을 효과적으로 모델링하는 데는 '그래프 모델'에서 다룬 구조 모델 등을 사용합니다. 예를 덜어 대표적인 딥러닝 기법인 CNN(Convolutional Neural Network)은 한 픽셀과 그 주변 픽셀의 값을 동시에 고려하여 피처를 생성합니다.
비디오 데이터도 머신러인에 사용됩니다.예를 들어 비디오를 이용한 머신러닝을 할 경우, 비디오를 연속되는 이미지로 분할하여 사용하게 됩니다. 이때 연속된 이미지가 어떤 장면을 나타내는지 학습하기 위해 앞서 설명한 구조 모델을 확장시켜 화면의 위치 근접도와 시간 근접도를 복합적으로 사용하는기법이 적합합니다

3.1.4 음성 데이터
음성 데이터는 수치 데이터와 많은 부분에서 비슷합니다. 노이즈가 많으며 특히 시간에 따른 변화가 중요하기 때문에 시간에 따른 변화를 모델링할 수 있는 머신러닝 기법이 사용됩니다. 하지만 몇 가지 주목할 점이 있습니다.

음성 데이터는 소리에 관한 데이터이므로 일반적으로 소리의 높낮이나음색을 신호 처리 기법으로 전처리한 후에 사용하게 됩니다. 때표적인 기법으로 스펙트로그램(spectrogram)이나 퓨리에(Fourier)피처 등이 있습니다. 이러한 신호 처리 기법을 적용하여 얻은 피처와원래 신호를 조합하여 머시너닝을 하는 경우가 많습니다.
또한 데이터를 수집할 때 보통 한 가지 소리만 깔끔하게 얻는 경우는 많지 않습니다. 그래서 녹음된 소리를 여러 가지 소리로 나누는 머신러닝 기법을 사용한 이후에 앞서 언급한 기법을 일반적으로 사용합니다.

3.1.5 복합 데이터
복합 데이터는 다양한 유형의 데이터가 썩여 있는 것을 말합니다. 단순하게 생각하면 데이터의 특성에 따라 각기 다른 머신러닝 기법을 적용하여 분석을 할 수도 있지만, 연관 관계를 이용해서 여러 기법을 한번에 학습시키는 방법도 생각할 수 있습니다.

 예를 들어 비디오(이미지 데이터, 음성 데이터)와 자막(텍스트 데이터)이 동시에 입력으로 들어오는 경우를 생각할 수 있습니다. 시간대별 이미지, 음성, 자막이 연관 관계를 가지고 있기 때문에 이러한 연관 관계를 한번에 학습할 수 있는 기법을 사용하면 각각을 따로 처리하는 것보다 더 좋은 결과를 얻을 수 있습니다. 최근에 각광받는 방법으로는 이미지 분류와 자막분류를 하는 신경망 모델을 동시에 중간 레이어를 공유해서 학습합니다. 그 결과로 이미지를 입력하면 그 이미지에 무엇이 있는지 텍스트로 설명할 수 있습니다.

3.2 데이터양과 품질
데이터양과 품질은 유형만큼이나 머신러닝 기법의 선택과 적용에 큰 영향을 끼칩니다. 이미 2장에서 간단히 설명했지만 여기서는 머시러닝을 실제로 적용할 때의 고려사항을 자세히 살펴보겠습니다.

3.2.1 데이터양과 머신러닝의 연관성
모든 머신러닝 기법은 데이터가 적으면 유용한 학습 결과를 얻기 힘듭니다. 그렇기 때문에 데이터를 많이 모으는 것은 괸장히 중요합니다. 하지만 데이터가 많더라도 특정 항목(레이블)에 대한 데이터가 적으면 해당 부분에 대해서는 학습이 제대로 되지 않을 수 있습니다. 이 문제는 이미지 태깅처럼 분류 항목 수가 굉장히 많은 경우에 비번히 발생합니다. 구체적으로 다음 세 경우를 들 수 있습니다.

데이터의 레이블을 얻기 굉장히 어려운 경우
사람이 일일이 예측 결과(예를 들면 이미지 태깅이나 문법 파싱)를 제공하는 경우에는 큰 비용이 들기 때문에 데이터의 레이블을 얻기 어렵습니다. 이런 경우에는 학습이 잘되지 않은 부분을 머신러닝 시스템이 사람에게 질문하는 방식으로 학습 성능을 높이는 액티브 러닝(active learning)기법을 사용하는 것도 좋습니다.

데이터양은 많지만 특정 레이블의 데이터가 부족한 경우
데이터가 전체적으로는 많지만 레이블 유형이 다양해서 어떤 레이블은 굉장히 적은 수의 데이터만 가지는 경우입니다. 사람이 레이블을 태깅하는 경우에는 특정 레이블로의 쏠림이 더 많이 발생해서 이 현상이 더 심각해지는 경우가 많습니다. 균형이 맞지 않게 되면 손실 함수는 데이터가 많은 레이블에 집중하고 나머지를 무시하기 때문에 균형잡힌 성능을 보여주지 못합니다.

이를 해결하려면 데이터양이 많은 레이블에서 임의로 데이터를 누락시켜(과소표집) 데이터의 균형을 맞추거나, 데이터가 적은 경우에도 잘 동작하는 원샷러닝(one-shot learning, 또는원샷학습)등의 기법을 사용할 수 있습니다. 데이터를 한 번만 보고 학습이 가능하다고 해서 원샷러닝이라 부릅니다.

데이터양은 많지만 특정 경우의 데이터가 아예 없는 경우
데이터가 들어오는데 새로운 레이블이 끊임없이 생성되는 경웅에는 제로샷러닝(zero-shot learning, 또는 제로샷학습)을 사용합니다. 대표적인 제로샷러닝 기법으로 다른 형식의 데이터를 이용해서 유사도를 판별하여 새로운 레이블을 학습 데이터 없이 예측하는 방법이 잇습니다. 예를 들어 비디오와 자막이 입력으로 주어지는 경우 자막의 유사도를 판단하여 이미지의 내용을 추측하는 방식을 사용할 수 있습니다.

3.2.2 데이터 품질과 머신러닝의 연관성
데이터양뿐만 아니라 품질도 머신러닝 기법 선택에 여향을 미칩니다. 데이터 품질은 노이즈양에 가장 크게 여향을 받습니다. 유용한 피처와 함께 레이블이 주어졌을 때 레이블의 무작위성에 따라 머신러닝 기법이 달라집니다. 데이터 품질에 따른 고려 사항은 다음과 같습니다.

관측 데이터에 노이즈가 많은 경우
무작위성이 높아 노이즈가 많은 경우는 수치 데이터에서 굉장히 비번하게 발생합니다. 데이터 양이 적으면 성능에 더 큰여향을 주는데, 이를 해결하려면 '간단한 모델'을 사용합니다. 간단한 모델은 가정이 가합니다. 이 모델은 유연하지 않고 노이즈에 강하기 때문에 이 경우에 적합한 모델이라고 볼  수 있습니다. 노이즈 자체를 가정에 두는 칼만 필터 같은 모델도 많이 이용됩니다.

레이블이 일정하지 않은 경우
크라우드 소싱이나 여러 사람이 수작업으로 레이블링하는 경우에는 작업자의 데이터나 레이블에 대한 해석 차이로 레이블이 통일되지 않을 수 있습니다. 예를 들어 단어가 긍정적인지 부정적인지 수치로 나타내는 작업을 여럿이서 한다고 가정합시다. A는 전반적으로 점수를 낮게 주고 B는 높게 주었다고 합시다. 이런 경우에는 평가자로 인한 편차를 줄이는 전처리 작업이 필요합니다. 수치값이라면 레이블의 평균과 분산을 구해서 맞춰주는 경우가 일반적이고, 여러 항목에서 고르는 작업의 경우에는 몇 명 이상이 동일한 항목을 고른 경우에만 그 값을 활용하는 방법이 있습니다. 즉, 전처리 작업을 한 후 에 머신러닝을 적용합니다.


3.3 데이터 표준화
데이터 척도 및 단위를 변환하여 데이터를 비교하기 쉽게 만드는 방법을 데이터 표준화(data normalization)라고 합니다. 데이터형에 따라서 데이터 표준화의 방식이 달라집니다. 여기서 다룰 데이터형에 따른 표준화 방법은 담음과 같습니다.

- 수치 데이터 표준화: 단위가 다른 수치 데이터를 비교하기 위해 데이터르 ㄹ변환하는 기법입니다.(예를 들면 키와몸무게_
- 카테고리 데이터 표준화: 숫자로 표현할 수 없는 항목을 수치 데이터로 변환하는 방버입니다.(예를 들면 성별)
- 서수 데이터 표준화: 순서 혹은 크기가 있는 데이터의 카테고리 차이를 나타내기 위해 데이터를 변환하는 기법입니다.(예를 들면 영화 별점, 설문지 응답등)

3.3.1 수치 데이터 표준화
키와 몸무게, 구매상품 수와 구매 가격 등 단위가 다른 두 수치 데이터를 직접 비교하는 것은 의미가 없습니다. 이럴 때는 각 데이터를 평균이 0, 표준편차 1인 데이터로 바꾼후 비교하면 효과적입니다. 이런 식으로 데이터를 변환하는 방법을 z-점수 표준화(z-score standardization)라고 합니다.

z-점수 표준화 외에 데이터를 변환하는 방법으로 척도화와 벡터 정규화가 있습니다. 척도화(scaling)는 피처의 최댓값 및 최솟값을 이용하여 피처 값의 범위를 조정하는 방법입니다. x를 원래 데이터의 피처값, x1를 변환된 피처값으로 표기할 때의 척도화를 식으로 나타내면 다음과 같습니ㅏㄷ.

척도화

x1 = (x - min(x)) /(max(x)-min(x))

벡터 정규화(vector normaliztion)는 한 데이터 가지는 피처 벡터의 노름(norm)이 1이 되게 하는 방법입니다. 노름은 벡터의 크기라고 볼수 있으며, 벡터 x의 노름은 ||x||로 표시하고 다음 식으료 계산합니다.

||x|| = 루트(xx1 + xx2  + xx3 .... xxn)
x1 = x / ||x||

즉, 벡터 정규화는 벡터의 각 요소를 벡터의 총 크기로 나누는 것이라고 볼 수 있습니다. 이렇게 하면 크기가 다른 벡터들의 요소를 비교할 수 있게 됩니다.
예를 들어 구매 항목 피처 벡터가 디비디 카테고리 구매 수와 간식 카테고리 구매수로 이루어진 경우을 생각해 봅시다. 사용자가 A가 디비디10개와 감자침 5개를 샀고, 사용자 B가 디비디 6개와 감자칩 3개를 샀다고 했을 때, 구매한 상품의 총 수는 다르지만 두 사용자 모두 디비디를 감자칩의 2배수로 구매했다는 점에서 두 사용자는 비슷하다고 볼 수 있습니다. 이 경우 두 사용자의 벡터 크기는 다음과 같이 구합니다.

사용자 A 의 피처 벡터 크기 루트(10*10 + 5*5) = 11
사용자 B 의 피처 벡터 크기 루트(6*6 + 3*3) = 7

각 피처 요소를 나누면(즉, 벡터 정규화를 하면) 사용자 A의 피처 벡터는 (10/11, 5/11), 사용자 B의 피처 벡터는 (6/7, 3/7)로 비슷한 값이 됩니다. 이 두 벡터로 유클리드 거리를 계산하면 사용자 A와 B의 유사도가 높게 나올 겁니다.

데이터형과 데이터 값 및 학습에 사용하는 모델에 따라 데이터 표준화 방법을 바꾸는 것이 성능에 도움이 됩니다. 예를 들어 선형 희귀의 경우 z-점수 표준화를 하는 편이 성능도 좋고 이해하기 쉬운 결과가 나옵니다. 길이가 다른 문서 안의 단어 빈도를 피처 벡터로 바꾼 뒤 유사도를 계산할 경우 피처 벡터를 벡터 정규화한 후 계산해야 정확한 비교를 할 수 있습니다.

3.3.2 카테고리 데이터 표준화
상품 카테고리의 차이는 어떻게 계산해야 할까요? 상품명, 상품 카테고리, 성별과 같은 비수치 데이터 사이의 유사도 계산에는 원-핫 인코딩(혹은 더미코딩)방식을 이용합니다. 원-핫 이코딩이란 카테고리 데이터 값을 피처로 만든 후 1 또는 0으로 지정하는 방법입니다. 예를 들어 '성별:나성, 성별:여성' 대신 남성은 0, 여성은 1로 수치화하여 '성별:0, 성별:1' 로 표기하는 겁니다.

3.3.3 서수 데이터 표준화
카테고리 데이터이면서 카테고리에 순서가 있는 데이터형을 서수(ordinal)데이터라고 합니다.

서수는 설문조사 답변(예를 들면 '전혀 그렇지 않다, 그렇지 않다, 어느 쪽도 아니다, 맞다, 매우 맞다')이나 영화의 별점을 생각하면 쉽습니다. 담변이나 별점을 1 부터 5의 숫자로 표시하기는 하지만 가능한 별점이 카테고리로 정해져 있으므로 이는 수치 데이터가 아닙니다. 예를 들어 가능한 별이 1~5점인 경우와 1~10점인 경우, 별점 3점이 가지는 의미는 매우 다릅니다.
하지만 각 카테고리가 동등하지 않다는 점에서 카테고리 데이터도 아닙니다. 따라서 다순히 수치 데이터로 취급하여 평균과 분산을 이용해서 표준화하거나 원-핫 인코딩으로 변환하는 것은 적절하지 않습니다. 이러한 경웅에는 일반적으로 다음 식을 이용하여 0과 1사이의 값으로 표준화 합니다.

서수형 데이터 표준화
(t -1 /2 )/M, i = 1,2,...,M

t: 카테고리
M: 가능한 카테고리

옐르 들어 별점 5점 만점에 별점 3인경우에는 표준화한 값이 (3-1)/5 = 0.5가 됩니다. 별점 3점이 1점과 5점의 한가운데임을 생각하면 0.5로 표시하는게 적절한 것 같습니다. 별점 10점 만점에 별점 3인 경우에는 (3 - 12)/10 = 0.25로 다른 값이 나오게 됩니다.
0부터 1사이로 척도화하는 방법도 생각할 수 있지만, 이 경우 별점 1을 수치 0 으로 바꾸게 되므로 데이터의 의미가 약간 달라집니다. 별점 1과 수치가 존재하지 않음을 의미하는 0은 다르니까요.

3.4 문제 유형
지금까지 데이터양과 품질에 따른 고려 사항을 살펴봤습니다. 이 절에서는 문제 유형에 따른 고려 사항을 살펴보겠습니다. 문제 휴형은 크게 희귀, 분류, 군집화, 표현형학습으로 구분할 수 있습니다. 문제 휴형을 잘못 선택하면 원하는 답을 얻지 못할 수 있기 때문에 문제를 구별하기는 기준은 꼭 숙지해둬야 합니다.

3.4.1 회귀문제
회귀는 머신러닝 문제 중에서도 가장 기본입니다. 회귀는 간단히 말해 입력을 받아서 가장 적합한 숫자값을 예측하는 문제입니다. 옐르 들어 주어진 상황 정보를 종합해서 주식값이 얼마가 될지 예측하는 겁니다.
회귀를 가장 기본적인 문제로 보는 이유는 출력된 결과를 해석하는 방식에 따라 여러가지 문제를 풀 수 있기 때문입니다. 예를 들어 출력된 숫자를 확률로도 특정 항목 번호로도 해석할 수 있습니다. 그렇기 때문에 어떤 문제를 풀더라도 결귀에는 회귀문제로 환원되는 경우가 많습니다.
회귀문제에 사용되는 머신러닝 기법은 다른 머신러닝 기법의 기초가되는 경우가 많습니다. 회귀문제를 푸는 기법으로는 통계학에서도 널리 쓰이는 선형회귀, 가우시안 프로세스 회귀, 칼만 필터가 유명합니다.

3.4.2 분류문제
분류는 회귀만큼이나 기본적인 머신러닝 문제입니다. 회귀 기법으로 분류 문제를 풀 수도 있지만, 보통은 분류에 해당하는 손실함수를 직접 최적화해서 푸는 방법을 많이 사용합니다. 예를 들어 인터넷 신문기사의 단어들을 가지고 이 기사가 어떤 분류 항목에 해당하는지 선택하는 경우들 들 수 있습니다.

분류 문제에서는 주어진 입력에 대해 여러가지 가능한 항목 중에서 한 가지를 선택하는 경우가 많지만, 기법에 따라서는 여러가지 선택하기도 합니다. 여러가지 항목에서 하나를 고르는 문제를 멀티 클래스(혹은 다중 클래스)분류라고 부르고, 복수를 고르는 문제를 멀티레이블(혹은 다중 레이블) 분류라고 부룹니다.
분류는 주어진 이미지가 어떤 항목에 속하는지 판별하는 문제, 생산 공정에서 제품의 데이터로 하자를 판별하는 문제, 텍스트의 의미가 어떤 항목에 해당하는지 판별하는 문제 등 셀수 없이 다양한 경우에 사용됩니다. 이전 시간을 고려한 주어진 상황을 보고 여러가능성이 있는 답 중에서 하나를 고르는 경우는 모두 분류 문제입니다.
분류문제를 풀 때는 기본적으로 로지스틱 회귀, 서프트 벡터 머신, 신경망 등 사용합니다. 그리고 입력이 시간에 따라 변화하는 데이터를 모델링 하는 경우에는 CRF나 RNN등을 사용합니다.

3.4.3 군집화 문제
군집화는 비슷한 성격의 데이터를 묶는 머신러닝 문제입니다. 물론 각각의 입력을 받아 출력으로 항목(레이블)을 예측하는 분류 문제로 볼 수도 있지만, 가장 큰 차이는 항목이 주어지는 것이 아니라 데이터에 내재된 분류를 찾아내야 한다는 점입니다. 즉, 받은 입력을 비슷한 성격별로 묶어야 합니다.
군비화 문제는 현재 주어진 데이터를 분석하는 데 사용합니다.(기존 데이터와 비교하여 미래 데이터에 대해서도 군집화를 할 수 있습니다). 예를 들어 비슷한 비디오나 문서끼리 묶어서 찾기 편하게 만들거나 비슷한 사용자를 군집화해서 군집별 특성을 살펴보는 경우를 떠올릴 수 있습니다. 군집화 기법을 문서에 활용한 것으로는 토픽 모델링이 유명합니다. 이 기법은 많은 그리고 레이블이 없는 문서에서 공통 주제를 발견하여 문서를 주제별로 묶습니다.

군집화 문제에서 가장 중요하게 여기는 것은 데이터 유사도(혹은 유사상)입니다. 이 유사도를 어떻게 정의하느냐에 따라 군집화 결과가 크게 달라집니다. 옐르 들어 이미지 데이터에서 크기에 따른 군집화와이미지 색상에 따른 군지화의 결과는 크게 다릅니다.

군집화 깁버은 종종 입력을 간추리는 용도로도 사용됩니다. 입력을 직접 사용하는 대신 군집에 얼마나 속하는지에 대한 강도를 이용해서 입력을 간단하게 표현해서 사용하는 것 입니다. 이렇게 변형된 군집화 기법은 다음 절에서 소개할 표현형학습과 유사한 역할을 수행하게 됩니다.

대표적인 기법으로는 K-평균 군집화(K-means clustering)와 평균이동 군집화(mean shift)가 있습니다. 문서를 토픽에 따라 군집화하는 방법은 토픽 모델링이라고 부르는데, LDA(latent dirichlet allocation, 잠재 디리클레 할당)라는 기법이 유명합니다. 엄밀하게 따지자면 군집화와 토픽 모델링은 접근하는 관점이 약간 다르지만, 비슷한 성격을 묶는다는 의미에서 이처럼 분류해보았습니다.

3.4.4 표현형학습(임베딩학습)
표현형학습은 앞서 설명한 3가지 문제보다 더 근본적인 문제를 다루는데 사용합니다. 표현형 학습은 풀고자 하는 문제에 적합한 표현형(representation)을 데이터로부터 추출하는 것을 말합니다. 표현형과 데이터로부터 직접적으로 추출하는 피처 차이는 다음과 같습니다.

1. 표현형은 피처보다 훨씬 더 간략합니다(표현형의 차원이 훨씬 더 낮습니다.)
2. 피처는 높은 차원을 가지는 경우가 많기 때문에 많은 부분이 0으로 차 있습니다(희박하다고 표현합니다). 표현형은 훨씬 낮은 차원으로서 데이터를 잘 설명해야 하기 때문에 밀집도가 높습니다.

블로그에 올린 일기를 통해 그날그날마다 글쓴이가 느낀 감정을 파악하려 하는 경우를 생각해봅시다. 분류 문제를 이용해서 푼다면 일기 문서의 구성 단어를 한하나 '긍정적'인 것과 '부정적'인 것으로 분류하고 그 수를 비교해서 날마다에 대해 긍정과 부정 두 가지 중 하나를 고르게 하는 문제로 환원할 수 있을 겁니다. 하지만 한 단어의 의미는 단순하게 긍정이나 부정만으로 결정되지 않죠. 더 복잡한 의미를 지니는 경우가 많습니다.

딥러닝에서는 이러한 문제를 해결할 때 긍정 혹은 부정에 속하는 단어 대신 표현형학습을 통해 얻은 단어 임베딩을 사용합니다. 보통표현형학습은 더 쉽게 구할 수 있는 다른 데이터를 이용해서 학습을 합니다. 예를 들어 데이터양이 훨씬 많은 워키백과를 이용하여 단어의 표현형을 학습한 후 그 표현형을 블로그 기사의 분류에 사용하여 문제를 풉니다.

이렇게 표현형은 다른데이터에서 학습하여 다양한 문제를 푸는데 사용할 수 있습니다. 즉, 위키백과에서 '고양이'라는 단어와 '야옹이'라는 단어의 표현형이 비슷하게 나오도록 학습한다면 그 결과를 블ㄹ로그 분류에도 유용하게 사용할 수 있습니다.

대표적인 임베딩 학습으로 문서 처리에 강점을 보이는 word2vec 모델과 그 파생모델, 행렬 분해가 있습니다.





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) 전체를 사용하는 경우도 있습니다. 두 방법 모두 검색 엔진의 평가에 많이 쓰입니다.