블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 


Classification & Clustering 모델 평가


조대협 (http://bcho.tistory.com)


클러스터링과 분류 모델에 대한 성능 평가 방법은 데이타에 라벨이 있는가 없는가에 따라서 방법이 나뉘어 진다. 사실 클러스터링은 라벨이 없는 데이타에 주로 사용을 하고, 라벨이 있는 경우에는 분류 모델을 사용한다. 클러스터링 모델에 대한 평가는 라벨이 없는 상태에서 클러스터의 응집도등을 평가하는데 대부분 그 정확도가 그리 높지 않기 때문에, 도메인 지식을 가지고 있는 전문가에 의한 휴리스틱한 방식의 평가 방식이 대부분이다.


분류 모델(Classification) 에 대한 모델 평가

라벨이 있는 경우에는 분류 모델에 대한 모델 평가 방법을 사용한다.

Confusion matrix

이진 분류 문제에서 암의 양성과 음성 데이타를 가지고 있는 데이타 가 있다고 하자


만약 모델의 정확도가 100%이면, 양성과 음성 데이타를 100% 잘 구분할것이다. 아래 그림과 같이, 양성으로 분 예측된 영역을 Positive prediction, 음성으로 분리된 영역을 Negative prediction 이라고 한다.


그런데 실제 세계에서는 정확도 100% 모델은 매우 드물고 실제로는 아래 그림과 같이 예측이 되는 경우가 많다.


양성과 음성 데이타가 각각 잘못되는 경우가 있다.

  • 양성인데, 양성으로 제대로 검출된것은 True Positive (TP)

  • 음성인데 음성으로 제대로 검출된것은 True Negative (TN)

  • 양성인데 음성으로 잘못 검출된것은 False Negative (FN)

  • 음성인데 양성으로 잘못 검출된것은 False Positive (FP)


라고 하고 그림으로 표현하면 다음과 같은 그림이 된다.


보통 이를 표로 표시하는데, 다음과 같이 표현이 된다.




P = TP + FN

N = FP + TN


그러면 이 지표를 가지고 무엇을 하느냐? 이 값을 기반으로 다음과 같은 지표들을 계산하여 모델 평가에 사용한다.

Accuracy

가장 대표적으로 사용되는 지표로 전체 데이타중에서, 제대로 분류된 데이타의 비율로


ACC = (TP + TN)  / (전체 데이타 수 = P + N)


모델이 얼마나 정확하게 분류를 하는지를 나타낸다.


Error Rate

Error Rate는 Accuracy 와 반대로, 전체 데이타 중에서 잘못 분류한 비율을 나타낸다


ERR = (FN+FP) / (전체 데이타수 = P+N)


Sensitivity (Recall or True positive Rate)

민감도라고도 하는데, Sensitive 또는  Recall이라고도 하는데, 원래 Positive 데이타 수에서 Positive로 분류된 수를 이야기 한다. 에를 들어 원본 데이타에 암 양성이 100개 있었는데, 모델에 있어서 90개가 분류되었으면, Sensitive Rate = 0.9 가된다.


SN = (TP) / P


모델이 얼마나 정확하게 Positive 값을 찾느냐를 나타낸다.

Recall (as opposed to precision) is not so much about answering questions correctly but more about answering all questions that have answer "true" with the answer "true". So if we simply always answer "true", we have 100% recall.


Precision

Precision (정밀성)은 Positive로 예측한 내용 중에, 실제 Positive의 비율을 뜻한다.


PREC = TP / (TP+FP)


Precision is about being precise. In common English, being precise means: if you give an answer, the answer will very likely be correct. So even if you answered only one question, and you answered this question correctly, you are 100% precise.


Specificity (True negative rate)

Specificity 값은 Negative 로 판단한것중에, 실제 Negative 값의 비율이다.


SP = TN / TN+FP


False Positive rate

원래는 Positive 값인데, 잘못해서 Negative로 판단한 비율로


FPR = FP / N


이 된다. 예를 들어 게임에서 어뷰징 사용자를 검출했을때 정확도도 중요하겠지만, FPR 값이 높으면, 정상 사용자를 비정상 사용자로 검출하는 경우가 많다는 의미가 된다. 어뷰징 사용자에 대해서는 계정 정지등 패널티를 주게 되는데, 모델이 아무리 어뷰징 사용자를 잘 찾아낸다 하더라도 FPR 값이 높게 되면, 정상적인 사용자를 어뷰징 사용자로 판단하여 선의의 사용자가 징계를 받게 되서, 전체적인 게임 충성도에 문제가 생길 수 있다. (어뷰징 사용자를 많이 찾아내는 것보다, 정상 사용자가 징계를 받게 되는 경우가 비지니스에 크리티컬 할때) 이런 경우에 FPR 값을 레퍼런스 할 수 있다.



그러면, Confusion Matrix를 통해서 계산된 결과를 가지고 모델을 어떻게 평가를 할까? 앞에서 나온 지표중에서 일반적으로 Accuracy 지표가 많이 사용되고, 그외에, ROC , Precision Recall Plot, F-Score 등이 많이 사용되는데 각각에 대해서 알아보자

ROC (Receiver Operating Characteristics)

ROC 그래프는 가로축을 FP Rate (Specificity) 값의 비율로 하고 세로축을 TP Rate (Sensitive) 로 하여 시각화 한 그래프이다.


  • Specificity = TN / TN+FP

  • Sensitive (Recall) = (TP) / P




보통 다음과 같은 그래프가 되고



(출처 : http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html )


그래프가 위로 갈 수록 좋은 모델이고, 적어도 Y=X 그래프보다 위에 있어야 어느정도 쓸모 있는 모델로 볼 수 있다. 아래 그래프는 3개로 결과를 분류하는 모델에 대한 ROC 그래프 이다.


(출처 : http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html )


ROC 그래프가 class 0, class 2, class 1 순서로 높은것을 볼 수 있다. 즉 이 모델은 class 0 을 제일 잘 분류하고 그 다음은 2,1 순서로 잘 분류 한다는 의미가 된다.

ROC는 그래프이기 때문에, 모델을 정확도를 하나의 숫자로 나타내기 어려워서 AUC (Area Under Curve) 라는 값을 사용하는데, ROC AUC값은 ROC 그래프의 면적이 된다. 최대값은 1이 된다. 위의 그래프를 보면 모델 0,2,1의 AUC값은 0.91, 0.79, 0.60 이 된다.

Precision Recall Plot

Precision Recall Plot (이하 PR 그래프)의 경우도 ROC 와 유사한데, 주로 데이타 라벨의 분포가 심하게 불균등 할때 사용한데, 예를 들어 이상 거래 검출 시나리오의 경우 정상 거래의 비율이 비정상 거래에 비해서 압도적으로 많기 때문에 (98%, 2%) 이런 경우에는 ROC 그래프보다 PR 그래프가 분석에 더 유리하다.


PR 그래프는 X 축을 Recall 값을, Y축을 Precision 값을 사용한다.


  • Sensitive (Recall) = (TP) / P

  • Precision = TP / (TP+FP)



다음은 이진 분류 (binary classification)의 PR 그래프의 예이다. 그래프가 위쪽으로 갈수록 정확도가 높은 모델이고, ROC와 마찬가지로 PR 그래프의 AUC (면적)값을 이용하여 모델의 정확도를 평가할 수 있다.



(출처 : http://scikit-learn.org/stable/auto_examples/model_selection/plot_precision_recall.html)


그러면 모델이 쓸만한 모델인지 아닌지는 어떤 기준을 사용할까? ROC 그래프의 경우에는 Y=X 그래프를 기준으로 그래프 윗쪽에 있는 경우 쓸만한 모델로 판단을 했는데, PR 그래프의 경우 Base line이라는 것을 사용한다.


Base line = P / (P+N) 으로 정하는데, P는 데이타에서 Positive 레이블의 수, N 은 전체 데이타의 수이다. 예를 들어 암 데이타에서 암 양성이 300개 이고, 전체 데이타가 700이면 Base line은 300/(700+300) = 0.3 이 된다.  


위의 PR 그래프에 Base line을 적용하여 모델이 좋고 나쁜 영역을 판단하는 그림이다.

아래 그림은 두 모델을 비교한 PR 그래프인데, 두 모델 다 베이스라인을 넘어서 쓸만한 모델이기는 하지만, 모델 A가 B모델보다 확연하게 위에 위치하고 있기 때문에, A 모델이 좋다고 이야기할 수 있다.


(출처 : https://classeval.wordpress.com/introduction/introduction-to-the-precision-recall-plot/)

F-Score

모델의 성능을 하나의 수로 표현할때, ROC나 PR 그래프의 AUC를 사용하면 되지만, AUC를 계산하려면 여러 Throughput에 대해서 Precision, Recall, Specificity 값을 측정해야 한다.

그렇다면 Throughput을 이미 알고 있거나 또는 다양한 Throughput에 대해서 어떤 Throughput이 좋은지를 하나의 수로 모델의 성능을 평가하려면 어떻게 해야할까? 이를 위해서 사용하는 것이 F-Score 라는 값이 있다.


When measuring how well you're doing, it's often useful to have a single number to describe your performance

When measuring how well you're doing, it's often useful to have a single number to describe your performance. We could define that number to be, for instance, the mean of your precision and your recall. This is exactly what the F1-score is.

https://www.quora.com/What-is-an-intuitive-explanation-of-F-score

F Score에 대한 계산은 다음 공식을 이용한다. 큰 의미상으로 보자면 Precision과 Recall에 대한 평균인데, 그냥 평균을 내면, 값의 외곡 현상이 생기기 때문에, 가중치를 주는 평균이라고 이해하면 된다.


특히 β가 1인 경우 (즉 F1)를 F1 Score라고 하고, 모델의 성능 평가 지표로 많이 사용한다.


참고 문서


수포자를 위한 딥러닝

#4 - 로지스틱 회귀를 이용한 이항 분류 문제의 해결

조대협 (http://bcho.tistory.com)


1장에서 머신러닝의 종류는 결과값의 타입이 연속형인 Regression (회귀) 문제와, 몇가지 정해진 분류로 결과(이산형)가 나오는 Classification(분류) 문제가 있다고 하였다. 2,3장에 걸쳐서 회귀 문제에 대해서 알아보았고, 이번장에서는 로지스틱 회귀를 이용한 분류 문제에 대해서 알아보자.

이 글의 내용은 Sung.Kim 교수님의 “모두를 위한 딥러닝”(http://hunkim.github.io/ml/) 을 참고하였다. 여러 자료들을 찾아봤는데, 이 강의 처럼 쉽게 설명해놓은 강의는 없는것 같다.

분류 문제(Classification)의 정의

분류 문제란 학습된 모델을 가지고, 입력된 값을 미리 정해진 결과로 분류해주는 모델을 이야기 한다.

분류 결과가 참/거짓과 같이 두개만 있을때 이항 분류 분석, 두개 이상일때는 다항 분류 분석이라고 하는데, 이번장에서 살펴볼 로지스틱 회귀 분석은 분류된 결과가 두 가지만 있는 이항 분류 모델이다. (다항 분류 모델은 로지스틱 회귀에 이어서 소프트맥스 회귀 분석에서 설명하도록 하겠다.)


이항 분류의 대표적인 예는 다음과 같다.

  • 이메일 스팸과 정상 이메일 검출

  • 신용카드 거래에서 정상 거래와 이상 거래 검출

  • 게임에서 어뷰징 사용자와 정상 사용자 검출


등이 이항 분류의 예가 될 수 있다.


예를 들어 아래와 같은 데이타가 있다고 가정하자



붉은 동그라미로 표시된 데이타와, 녹색 세모로 표시된 데이타를 분류하고 싶을때, 아래와 같이 이항 분류 문제는 이를 분류할 수 있는 이상적인 직선 그래프를 찾는 것이다.


로지스틱스 회귀 분석 (Logistics Regression)

선형 회귀 분석 (Linear regression) 으로 분류 문제 접근하기

이항 분류 모델에 대한 예를 들어보자. 종양의 크기에 따라서 양성 종양(암)인지 음성 종양인지를 판별하는 문제가 있다고 하자. 아래 그림은 종양의 크기에 대한 양성과 음성 여부를 그래프로 나타낸 것인데, X축은 종양의 크기, Y축은 종양의 양성과 음성 여부를 나타낸다. 1이면 양성 0이면 음성이다.


이 문제를 선형 회귀 모델로 정의해서 그래프를 그려보면 다음과 같다.

y=W*x

와 같은 그래프가 그려지고 대략 아래 그림에서 보는것과 같이 y > 0.5 보다 크면 양성 암, y <0.5 보다 작으면 음성암으로 판단할 수 있다.


그런데, 만약에 새로운 트레이닝 데이타에서, 종양의 크기가 큰 데이타가 들어오면 어떻게 될까?

아래 그림을 보자, 예를 들어 새로운 트레이닝 데이타에 종양의 크기가 5인 경우 양성 암이라는 데이타가 새로 들어왔다고 하자


이 경우 앞에서 선형 회귀로 만든 그래프의 기울기가 새로 들어온 데이타를 포함하면 맞지 않기 때문에 선형 회귀로 재학습을 시키게 되면 다음과 같은 기울기(점선 그래프)로 변하게 된다.


이 경우에는 앞에서 암이 양성인 여부를 판단할때 사용한 y가 0.5라는 기준은 더이상 사용할 수 없게 되고, y가 0.2 일때를, 새 기준으로 잡아서, 암의 양성/음성 여부를 판단해야 한다.

그러면 새로운 데이타가 들어올때 마다 기준점을 다시 잡아야 하는것인가? 또한 그렇게 만든 모델로 예측을 한다면, 학습에 사용되지 않은 큰 데이타가 들어온다면 오류가 발생할 수 도 있다.

그래서, 선형 회귀 분석 모델(Linear regression) 은 이항 분류에 적절하지 않다. 그렇다면 어떤 모델이 적절할까 ?

참고



시그모이드(sigmoid) 함수

이런 형태의 이항 분류 분석에 적절한 함수로 시그모이드(sigmoid)함수라는 것이 있다. 그래프의 모양은 다음과 같다. S 자 형태의 그래프 모양으로 중심축 (x=0)을 중심으로 좌측은 0으로 수렴하고 우측은 1로 수렴한다.



이 시그모이드 함수에 앞의 데이타를 적용해보면 다음과 같은 형태가 된다.


그림과 같이 y축을 0.5를 기준으로 판단할때 y가 0.5 일때 x가 2 인데, x<2 인 부분은 y=0으로 음성, x>2인 부분은 y=1로 양성이 된다.

큰 데이타 (x=100)가 추가된다하더라도 시그모이드 함수는 그 값이 1로 수렴되기 때문에, 앞의 선형 회귀 분석의 경우 처럼 암의 양성/음성인 경우를 결정하는 y와 x값이 변화하지 않는다.

가설 (Hyphothesis)

그래서, 이 시그모이드 함수를 사용하여 가설을 정의할 수 있다.

가설은 아래와 같다

y = sigmoid(Wx + b)


결과 값 y 는 0 또는 1의 값을 갖는다. 시그모이드 함수를 수학 공식으로 표현하면, 아래와 같다. (그렇다는 것만 알아두고 외워서 쓰자)
1 / (1+ math.exp(-(W*x+b) )


디시전 바운드리(Decision boundary)


y = sigmoid (W*x + b) 을 가설 함수로 그려진 위의 그래프에서 W는 1, b는 -2로 그래프로 우측으로 두칸을 이동하였다.

W에 1,  b에 -2 를 대입해보면 y = sigmoid(1*x-2) 의 형태의 그래프인데, “x가 2를 기준으로 좌,우측이 양성암이냐 아니냐” 를 결정하기 때문에 때문에,

1*x-2 <0 이면,  y=0이 되고

1*x+2 >0 이면, y=1이 된다.

이를 일반화 해보면, 시그모이드(sigmoid) 함수 내에 들어가는

W*x+b < 0 이면,  y=0이 되고,

W*x+b > 0 이면,  y=1이 된다.

즉 로지스틱 회귀 분석은 위의 조건을 만족하는 W와 b의 값을 찾는 문제이다.

그리고  시그모이드 함수내의

z=W*x+b

그래프를 기준으로나눠서 y가 0또는 1이 되는 기준을 삼는데, 이 그래프를 기준으로 결정을 하기 때문에, 이를 디시전 바운드리 (Decision boundary) 라고 한다.


변수가 x하나가 아니라, x1,x2가 있는 문제를 살펴보자


이 문제에서 가설 함수 y = sigmoid (W1*x1 + W2*x2 + b)가 될것이고,

z=W1*x1+W2*x2+b 가 디시전 바운드리 함수가 되며, 위의 그래프상에서는 붉은선과 초록선을 나누는 직선이 되고 이것이 바로 디시전 바운드리가 된다.

코스트 함수 (비용함수/Cost function)

자 그러면 가설 함수를 정의 했으니 적정 W와 b값을 찾기 위해서 코스트 함수를 정의해보자.

다시 한번 앞에서 코스트 함수의 개념을 되집어 보면, 코스트 함수의 개념은 가설 함수에 의해서 예측된 값과 트레이닝을 위해서 입력된 값(실제값) 사이의 차이를 계산해주는 함수로, 예측된 값과 입력된값 들의 차이에 대한 평균 값을 구한다.

로지스틱 회귀에서 사용되는 코스트 함수는 다음과 같다.

cost_function =(1/n) * Sum(
                              -y_origin*log(sigmoid(Wx+b)) - (1-y_origin)*log(1-(sigmoid(Wx+b)))

                        )

  • n 의 트레이닝 데이타의 수

  • Y_origin  는 트레이닝에 사용된 x에 대한 입력값


의미를 설명하겠지만, 머리가 아프면 넘어가도 좋다. 그냥 가져다 쓰면 된다.


그러면 어떻게 저런 코스트 함수가 사용되었는지를 알아보자.

선형회귀분석(Linear regression)의 코스트 함수를 다시 한번 살펴보자

코스트 함수는 측정값과 가설에 의해서 예측된 값의 차이의 제곱 평균을 나타내는 함수였다.

선형 회귀 분석에서의 코스트 함수는 다음과 같았다.

Cost =  Sum( (y_data_n - y_origin_n) ^ 2) / n

그리고 이 함수를 그래프로 그려보면 다음과 같이 매끈한 그래프가 나왔다.


그래프의 모양이 매끈한 골짜기 모양이였기 때문에 경사 하강법(Gradient descent)을 사용할 수 있었다.

그러면 로지스틱 회귀 분석에도 기존의 코스트 함수를 이용하여 경사하강법을 적용할 수 있는지 보자

코스트 함수에서 y_data_n에 가설 함수를 대입 시켜 보면

Cost = Sum(  ( sigmoid(Wx + b) - y_origin) ^ 2) /n

Sigmoid 함수를 풀어서표현하면


Cost = Sum(  1 / (1+ math.exp(-(W*x+b) )- y_origin) ^ 2) /n

가 되는데, exp( -(W*x+b) ) (즉 e^(-Wx+b) ) 형태로 표현되기 때문에,e 가 들어간 코스트 함수의 그래프는 다음과 같은 형태를 띄게 된다.

경사 하강법은 그래프를 타고 내려가면서 가장 작은 값을 찾는 알고리즘인데, (물이 골짜기를 따라서 내려가듯이), 이 코스트 함수의 그래프는 작은 골짜기들이 모여서 큰 골짜기 형태를 만든 모양이 된다. 그래서 경사 하강법을 적용할 경우 아래 그림과 같이 코스트 함수의 최소값으로 수렴하지 않고, 중간에 작은 골짜기에서 수렴해 버린다.


그래서 로지스틱 회귀 분석에서는 경사 하강법을 사용하기 위해서 이 코스트 함수를 메끈한 형태로 만들 필요가 있고, 새로운 코스트 함수를 사용한다. “e” 때문에 이런형태의 그래프가 그려지는 건데, e를 상쇄할 수 있는 역치함수는 log 함수가 있다. 그래서 log 함수를 적용하여 메끈한 형태의 코스트 함수를 정의해보자.코스트 함수는 y=1일때와 y=0일때 나눠서 계산해야 한다. 각각의 함수를 보면 다음과 같다.


y=1
cost = (1/n) * sum (-log(가설) )
cost = (1/n) * sum (-log(sigmoid(Wx+b)) )


y=0
cost = (1/n) * sum( -log(1-가설) )
cost = (1/n) * sum( -log(1-sigmoid(Wx+b)) )


코스트 함수는 측정한 값과, 가설에 의해 예측된 값의 차이를 나타내는 함수로, 개별값이 작을 수록 적절한 모델이 된다. 그래서 측정값과 가설값이 같거나 유사할 수 록 코스트 함수의 결과값이 작게 나와야 한다.

먼저 y=1 (측정한 값이)일때를 보자,  

코스트 함수는 cost = (1/n) * sum (-log(sigmoid(Wx+b)) ) 이다.

전체 코스트 평균 말고, 개발 값에 대한 측정값과 예측값에 대한 차이는 이 함수에서 -log(sigmoid(Wx+b)) 이다. 시그모이드 함수 특성상 sigmoid(Wx+b)는 0~1까지의 범위를 가지기 때문에 -log(0~1)을 그래프로 그려보면 다음과 같다.


측정값이 1이기 때문에, 가설함수 (시그모이드 함수  sigmoid(Wx+b) )에 의한 결과가 1이면 예측이 잘된것이고, 1에서 멀어져서 0으로 갈수록 예측된 값과 측정된 값의 차이가 크다고 할 수 있는데, 위의 그래프에서 보면, 가설에 의해 계산한 결과(x축)가 1에 가까울 수록 코스트(y축)은 0으로 수렴하고, 가설에 의해 계산한 결과가 0에 수렴할 수 록, 코스트는 높아지는 것을 볼 수 있다. 즉 y=1에서는 가설이 1에 수렴해야 하기 때문에, 1에 가까워질 수록 코스트가 낮아지는 그래프를 띄게 된다.


y가 0일때도 마찬가지 원리인데 측정값이 0이기 때문에, 가설에 의한 결과값이 0이 되어야 한다. 0에서 멀어질 경우 코스트가 늘어나고 0에서 가까워질 경우 코스트가 줄어드는 형태의 비용 함수를 정의해야 한다.

마찬가지로 코스트 함수의 평균이 아닌 개별값을 보면, -log(1-sigmoid(Wx+b)) 이 되고 sigmoid(Wx+b)는 0..1의 범위이기 때문에, -log(1- (0..1) ) 이 된다. 단 1에서 0..1을 뺄셈을 했기 때문에, 그래프는 -log(1.0, 0.99,0.98,....) 형태로 y=1인 경우와 반대 모양의 그래프가 된다.



자 이제, y=1인 경우와 y=0인 경우에 대한 각각의 코스트 함수를 정의하였다. 이를 코딩으로 옮기려면 y=1인 경우와 0인 경우에 대해서 각각 다른 코스트 함수로 처리하기 위해서 if  문을 사용해야 하지만, 그러면 코딩이 복잡해지기 때문에 이를 하나의 식으로 간단히 할 수 있는 방법을 찾아보자

y=1
cost_y1 = (1/n) * sum (-log(sigmoid(Wx+b)) )


y=0

cost_y0 = (1/n) * sum( -log(1-sigmoid(Wx+b)) )


y=1일때는 y=0인 코스트 함수 cost_y0 가 0이 되고, y=0일때는 y=1의 코스트 함수 cost_y1가 0이 되면 된다.

즉 cost = y*cost_y1 + (1-y)cost_y0 형태가 되면,


y=1 이면, cost = 1*cost_y1 + (1-1)*cost_y0 = cost_y1이 되고

y=0 이면, cost = 0*cost_y1 +  (1-0)*cost_y0 = cost_y0 이 된다.


그래서 y=1인 코스트 함수와 y=0인 코스트 함수를 위의 식 cost_y1과  cost_y=0에 각각 대입해보면


cost = y*[ (1/n) * sum (-log(sigmoid(Wx+b)) )]  + (1-y)[(1/n) * sum( -log(1-sigmoid(Wx+b)) )]


으로 평균 함수인 (1/n)* sum을 앞으로 빼면

cost = (1/n)*Sum(

y*(-log(sigmoid(Wx+b)))

        + (1-y)(-log(1-sigmoid(Wx+b) ))

     )


가 된다.

수식을 따라가면서 이해하면 제일 좋겠지만, 코스트 함수가 저런 원리로 생성이 되는 구나 정도 이해하고, 그냥 가져도 쓰자. (왠지 주입식 교육 같은 느낌이 들기는 하지만)


옵티마이져 (Optimizer)

코스트 함수가 정해졌으면, 코스트를 최소화할 옵티마이져로 어떤 옵티마이져를 사용해야 할지 결정해야 한다.

앞에서 경사 하강법에 적절하도록 코스트 함수를 수정했기 때문에, 경사 하강법(Gradient descent) 알고리즘을 사용한다. 이 경사하강법은 텐서플로우 코딩에서는 간단하게

optimizer = tf.train.GradientDecentOptimizer(learningRate)

train = optimizer.minimize(cost_function)


정의하여 옵티마이져로 사용할 수 있다.

예측 (Prediction)

자 이렇게 해서, 로지스틱 회귀에 대한 학습을 끝내고, W와 b 값을 구했다고 하자. 그렇다면 이 학습된 모델을 가지고, 들어오는 데이타에 대한 분류는 어떻게 할것인가? (예측은 어떻게 할것인가)


가설 함수를 다시 생각해보면 가설함수는 sigmoid(Wx + b) 이다.

그래서 예측이 필요한 값 x가 들어왔을때, 가설함수에 의한 결과값이 y’ 이라고 하면, y’은 0..1 까지의 실수가 되고, y’은 0.75일 경우, x에 대한 결과가 1일 확률은 75%, 0일 확률은 (100-75%인) 25%가 된다.


앞에서 종양의 크기에 대한 양성암 문제를 다시 예를 들어보면, 종양의 크기 x=5이면, sigmoid(Wx+b)에 의해서 계산된 결과가 0.95라고 하면, 이 경우 양성 종양인 확률은 95%, 음성인 확률은 5% 이다.


정리

분류 문제는 회귀 분석과 함께 머신러닝에서 가장 대표적인 문제이고, 로지스틱 회귀 분석은 분류문제에 있어서 기본적이고 대표가 되는 모델이다. 수식이 많이 나와서 다소 복잡할 수 있겠지만 정리를 해보면 다음과 같다.


먼저 가설 함수 (Wx+b) 를 정의하고, 이 가설 함수에 사용된 변수 W와 b에 대한 적정값을 계산하기 위해서 코스트 함수를 정의한후, 이 코스트 함수를 이용한 W와 b를 구하기 위해서 옵티마이저를 정의해서 학습을 통해서 W와 b값을 구한다.


이 과정에서 복잡한 수학적인 설명이 있었지만, 다음과 같은 접근 방법이 좋지 않을까 한다.

  1. 로지스틱 회귀 분석은 결과가 참/거짓인 이항 분석 문제에 사용된다.

  2. 비용 함수가 있다는 것을 알고 로지스틱 회귀 분석용 비용 함수를 가져다 쓴다. 단 비용 함수가 낮을 수 록 학습이 정확하다는 의미 정도는 알아야 학습 도중에 비용 함수의 결과를 보고 학습의 정확도를 파악할 수 있다.

  3. 옵티마이져는 그레디언트 디센트 알고리즘을 사용한다. 그냥 가져다 쓴다.
    단 여기서 학습 속도(Learning Rate, 2장 선형 회귀 분석을 구현하는 문서에서도 설명하였음)의 의미를 파악하고,학습 프로그램을 돌릴때 이 패러미터를 조정하면서 사용한다.

  4. 나온 결과값 (W와 b) 값을 이용하여 예측을 수행한다.


참고





나이브 베이즈 분류 (Naive Bayesian classification) #1 - 소개

조대협 (http://bcho.tistory.com)


지금 부터 소개할 알고리즘은, 머신러닝 알고리즘 중에서 분류 알고리즘으로 많이 사용되는 나이브 베이스 알고리즘이다. 


배경 지식

나이브 베이스 알고리즘을 이해하려면 몇가지 배경 지식이 필요하다. 


베이스 정리

먼저 베이스 정리를 보면, 매개 변수, x,y가 있을때,  분류 1에 속할 확률이 p1(x,y)이고, 분류 2에 속할 확률이 p2(x,y)일때, 

  • p1(x,y) > p2(x,y) 이면, 이 값은 분류 1에 속한다.
  • p1(x,y) < p2(x,y) 이면, 이 값은 분류 2에 속한다.
  • 나이브 베이스 알고리즘은 이 베이스의 정리를 이용하여, 분류하고자 하는 대상의 각 분류별 확률을 측정하여, 그 확률이 큰 쪽으로 분류하는 방법을 취한다.

예를 들어, 이메일에 대해서 분류가 스팸과 스팸이 아닌 분류가 있을때, 이메일에 들어가 있는 단어들 w1,…,wn 매개 변수 (“쇼핑”,”비아그라”,”보험”,….)에 대해서,  해당 이메일이 스팸일 확률과 스팸이 아닌 확률을 측정하여, 확률이 높은 쪽으로 판단한다.


조건부 확률

나이브 베이스를 이해하기 위해서는 확률의 개념 중 조건부 확률이란 것을 이해 해야 한다. 존건분 확률 이란, 사건 A에 대해서, 사건 A가 일어났을때, 사건 B가 일어날 확률

“사건 A에 대한 사건 B의 조건부 확률” 이라고 하며, P(B|A)로 표현한다.

예를 들어, 한 학교의 학생이 남학생인 확률이 P(A)라고 하고, 학생이 키가 170이 넘는 확률을 P(B)라고 했을때, 남학생 중에서, 키가 170이 넘는 확률은 B의 조건부 확률이 되며 P(B|A)로 표현 한다.

베이스 규칙

이 조건부 확률을 이용하면, 모르는 값에 대한 확률을 계산할 수 있는데

  • P(A|B) = P(A∩B) / P(B) <- 1)
  • P(B|A) = P(A∩B) / P(A) <- 2)

1),2)를 대입 하면

  • P(A|B)*P(B) = P(B|A)*P(A)
  • P(A|B) = P(B|A)*P(A)/P(B)

앞의 남학생인 확률 P(A)와 키가 170이상인 확률 P(B)를 알고, 남학생중에서 키가 170인 확률 P(B|A)를 알면, 키가 170인 학생중에, 남학생인 확률 P(A|B)를 알 수 있다.


나이브 베이스 알고리즘을 이용한 분류 예


다음과 같이 5개의 학습 문서가 존재하고, 분류가 comedy(코메디 영화), action(액션 영화) 두개가 존재한다고 하자. 

movie

단어(Word)

분류

1

fun,couple,love,love

Comedy

2

fast,furious,shoot

Action

3

Couple,fly,fast,fun,fun

Comedy

4

Furious,shoot,shoot,fun

Action

5

Fly,fast,shoot,love

Action


이제, 어떤 문서에 “fun,furious,fast” 라는 3개의 단어만 있는 문서가 있을 때, 이 문서가 코메디인지 액션 영화인지 분리를 해보자 


해당 영화가 코메디인 확률은

P(comedy|words) = P(words|comedy)*P(comedy)/P(words)  A.1 이며

액션 영화인 확률은

P(action|words) = P(words|action)*P(action)/P(words)  A.2 이 된다.

A.1 > A.2이면, 코메디 영화로 분류하고, A.1<A.2이면 액션 영화로 분리한다.

이때, A.1과 A.2는 모두 P(words)로 나누는데, 대소 값만 비교 하기 때문에 때문에 굳이 P(words)를 구해서 나눌 필요가 없이 

  • P(comedy|words) = P(words|comedy)*P(comedy) <-- B.1
  • P(action|words) = P(words|action)*P(action) <-- B.2

만 구하면 된다. 그러면, B.1과 B.2의 값을 실제로 계산해보자

먼저 각 단어의 빈도수를 계산하면

  • Count (fast,comedy) = 1 (코메디 중, fast 라는 단어가 나오는 횟수)
  • Count(furious,comedy) = 0
  • Count(fun,comedy) = 3
  • Count(fast,action)= 2
  • Count(furious,action)=2
  • Count(furious,action) = 1

P(words|comedy)는 comedy 영화중, 지정한 단어가 나타나는 확률로, 이를 개별 단어로 합치면펼치면 P(fast,furious,fun|comedy)으로, 각 단어가 상호 연관 관계가 없이 독립적이라면 (이를 조건부 독립 conditional independence라고 한다), 


P(fast|comedy)*P(furious|comedy)*P(fun|comedy)로 계산할 수 있다.


이를 계산 해보면, Comedy 영화에서 총 단어의 개수는 9번 나타났기 때문에, 모수는 9가 되고 그중에서 각 단어별로 comedy에서 나타난 횟수는 위와 같이 comedy이면서 fast인것이 1번, comedy 이면서 furious인것이 0번, comedy이면서 fun인것이 3번이 되서, 


P(fast|comedy)*P(furious|comedy)*P(fun|comedy) 는 { (1/9) * (0/9) * (3/9)} 가 된다.


그리고, P(comedy)는 전체 영화 5편중에서 2편이 comedy이기 때문에, P(comedy)=2/5가 된다.

이를 B.1에 대입해보면,

P(comedy|words) = { (1/9) * (0/9) * (3/9)} * 2/5 = 0 이 된다.

같은 방식으로 B.2를 계산하면 액션 영화에서 총 단어수는 11이고, 각 단어의 발생 빈도로 계산을 해보면

P(action|words) = { (2/11) * (2/11)*(1/11) } * 3/5 = 0.0018이 된다.

결과 “P(action|worlds) = 0.0018” > “P(comedy|word) = 0” 이기 때문에, 해당 문서는 액션 영화로 분류가 된다.


Laplace smoothing

위의 나이브 베이스 알고리즘을 사용할때, 하나의 문제점이 학습 데이타에 없는 단어가 나올때이다. 즉 분류를 계산할 문서에 “cars”라는 단어가 있다고 하자, 이 경우 학습 데이타를 기반으로 계산하면, cars는 학습 데이타에 없었기 때문에, P(cars|comedy)와 P(cars|action) 은 모두 0이 되고, P(comedy|words)와 P(action|words)도 결과적으로 모두 0이 되기 때문에, 분류를 할 수 없다.

즉 문서가 “fun,furious,fast,cars”로 되면

P(comedy|words) = { (1/9) * (0/9) * (3/9) * (0/9:cars 단어가 나온 확률) } * 2/5 = 0

P(action|words) = { (2/11) * (2/11)*(1/11) * (0/9:cars 단어가 나온 확률)  } * 3/5 = 0

이를 해결하기 위한 방법이 Smoothing이라는 기법으로, 이 기법은 새로운 단어가 나오더라도 해당 빈도에 +1을 해줌으로써 확률이 0이 되는 것을 막는다

다시 P(x|c)를 보자

 


이렇게 계산했다.

즉, P(“fun”|comedy) = “comedy중 fun”이 나오는 횟수 / “comedy 중 나오는 모든 단어의 수 중 중복을 제거한수” 로 계산했다.

.Laplace smoothing을 하려면 빈도에 1씩을 더해 줘야 하는데, 빈도를 더해주면 공식은

 


같이 된다.

여기서 |V|는 학습 데이타에서 나오는 전체 단어의 수(유일한 개수)가 된다. 위의 학습데이타에서는 fun,couple,love,fast,furious,shoot,fly로 총 7개가 된다.

이 공식에 따라 분자와 분모에 빈도수를 더하면

P(comedy|words) = { (1+1/9+7) * (0+1/9+7) * (3+1/9+7) * (0+1/9+7:cars 단어가 나온 확률) } * 2/5 = 0.00078

P(action|words) = { (2+1/11+7) * (2+1/11+7)*(1+1/11+7) * (0+1/9+7:cars 단어가 나온 확률)  } * 3/5 = 0.0018

※ 수식에서 편의상 (2+1)/(11+7) 등으로 괄호로 묶어야 하나 2+1/11+7과 같이 표현하였으나 분자에 +1, 분모에 +7을 해서 나눈 것으로 계산하기 바란다

로 액션 영화로 판정 된다.


Log를 이용한 언더 플로우 방지


이 알고리즘에서 문제는 P(words|comedy)나 P(words|action)은 각 단어의 확률의 곱으로 계산된다는 것인데, P(fun|comedy)*P(furios|comedy)*…. 각 확률은 <1 이하기이 때문에, 항목이 많은 경우 소숫점 아래로 계속 내려가서, 구분이 어려울 정도까지 값이 작게 나올 수 있다.

이를 해결 하기 위해서 로그 (log)를 사용하면 되는데

log(a*b) = log (a) + log(b)와 같기 때문에,

  • P(comedy|words) = P(words|comedy)*P(comedy)  B.1
  • P(action|words) = P(words|action)*P(action) B.2

양쪽 공식에 모두 Log를 취하면 (어짜피 대소 크기만 비교하는 것이니까)

  • Log(P(comedy|words)) = Log(P(words|comedy)*P(comedy))<-- B.1
  • Log(P(action|words)) = Log(P(words|action)*P(action))<--B.2

가 되고, B.1을 좀 더 풀어보면

Log(P(words|comedy)*P(comedy)) 

= Log(P(fun|comedy)*P(furios|comedy)*…*P(Comedy) ) 

= log(P(fun|comedy))+log(P(furios|comedy)+…+log(P(Comedy)) 로 계산할 수 있다.


위의 자료는 http://unlimitedpower.tistory.com/entry/NLP-Naive-Bayesian-Classification%EB%82%98%EC%9D%B4%EB%B8%8C-%EB%B2%A0%EC%9D%B4%EC%A6%88-%EB%B6%84%EB%A5%98 를 참고하였습니다.