메일에 특정한 단어나 단어들이 나오는 경우에 어떻게 자동으로 스팸으로 분류할 수 있을까? 베이시안 추론을 이용하면 여기에 대한 간단한 답을 얻을 수 있다. 먼저 특정한 단어가 메일에 들어있는 경우에 이것이 스팸인지 아니면 정상정인 메일(햄)인지를 구별하는 방법을 알아본다. 메일 문장에서 특정한 단어 X 가 나온 경우에 이것이 스팸일 확률은, 조건부 확률   P(spam|X)로, 그리고 정상적인 메일일 확률을 P(ham|X)으로 표기하자. 베이즈 공식을 쓰면

    P(spam|X)=P(X|spam)*P(spam)/P(X).

로 쓸 수 있다. P(X|spam)은 스팸메일에서  X라는 단어가 나타날 빈도(likelihood)은 전체 메일중에서 스팸이 차지할 비율이고, P(spam)는 전체메일 중에서 spam의 빈도(prior)이다. P(X)은 전체메일에서 X가 나타날 확률은 정상적인 메일에서 X가 나타날 빈도에 전체메일중에서 정상적인 메일일 확률의 가중치를 곱한것에 스팸에서 X가 나타날 빈도에 전체메일중에서 스팸일 확률의 가중치를 곱한 것을 더한 것과 같다.

    P(X)=P(X|ham)*P(ham) + P(X|spam)*P(spam)

따라서, 이것을 이용하면, 특정한 단어가 문장에서 발견이 되었을 때, 그것이 스팸일 확률(posterior)는

    P(spam|X)=P(X|spam)*P(spam)/{P(X|ham)*P(ham) + P(X|spam)*P(spam)}.

으로 주어진다.

만약에 전체메일중에서 정상적인 메일과 스팸의 비율이 같다면, P(ham)=P(spam), 위 식은 좀더 간단해 진다.

    P(spam|X)=P(X|spam)/{P(X|ham) + P(X|spam)}

 단어 X가 들어간 경우에 스팸으로 분류하는 기준은 그 단어가 정상적인 메일에 많이 들어있는가 아니면 스팸메일에 많이 들어있는가가 결정하게 된다. 따라서, 초기에 일정한 양의 메일을 인위적으로 정상과 스팸으로 분류하여서 그 속에 들어있는 단어의 빈도를 표로 만들어 두면, 추후에 들어온 메일은 이 표에 기반해서 자동으로 분류할 수 있다. 물론, 새로운 메일에서 얻은 지식으로 P(X|spam), P(X|ham)의 값을 지속적으로 업데이트하여서 필터의 성능을 계선할 수 있다.

이제까지는 한 단어에 대해서만 이야기했는데, 만약에 여러단어를 가지고 판단을 해야하는 경우에 어떻게 하여야 하는가? 역시 마찬가지로, 여러단어의 조합에 대한 likelihood값에 대한 표를 만들어야 하는가? 만약에 그렇다면 이것은 너무 방대한 작업이 된다. 그러나, 문제는 간단히 해결할 수 있다.
만약에 두개의 단어 X,Y가 들어간 메일이 있는 경우에 이것이 스팸인지의 여부를 알고자 한다면, 마찬가지로 조건부확률 P(spam|X,Y) 를 계산하여야 한다. 베이즈 공식을 쓰면

   P(spam|X,Y)=P(X,Y|spam)*P(spam)/P(X,Y)

로 쓸 수 있다. 여기서, P(X,Y|spam)은 스팸메일에서 두 단어 X,Y가 동시에 나타날 확률(likelihood)이다. P(X,Y)는 전체 메일에 두 단어, X,Y가 동시에 나타날 확률이다. 좀 더 단순한 모양을 얻기 위해서 두개의 단어가 나타나는 것이 독립적이라고 하자(그러나 naked라는 단어가 들어간 메일에서 sex라는 단어가 더 빈번히 발견되지 않을까?) 그러면,

     P(X,Y|spam) = P(X|spam)*P(Y|spam)
     P(X,Y|ham) = P(X|ham)*P(Y|ham)
     P(X,Y) = P(X,Y|ham)*P(ham)+P(X,Y|spam)*P(spam)
               = P(X|ham)*P(Y|ham)*P(ham) + P(X|spam)*P(Y|spam)*P(spam)

으로 쓸 수 있다.
 
이제 한개의 단어에 대한 결과(posterior)를 이것에 적용하기 위해서, 모든 likelihood를 베이즈 공식을 이용해서 posterior로 바꾸자. P(X|spam)=P(spam|X)*P(spam)/P(X),....., 그리고 마찬가지로 정상적인 메일과 스팸의 prior가 같다고 놓는다. 그러면, 두 단어 X,Y가 들어간 메일이 스팸일 확률은

    P(spam|X,Y)=P(spam|X)*P(spam|Y)/{P(ham|X)*P(ham|Y)+P(spam|X)*P(spam|Y)}

그런데 어떤 단어가 들어간 메일이 정상적인메일이면 스팸이 아니므로(배반사건) P(ham|X)=1-P(spam|X)
으로 주어진다.

    P(spam|X,Y)=P(spam|X)*P(spam|Y)/{(1-P(spam|X))*(1-P(spam|Y))+P(spam|X)*P(spam|Y)}

으로 주어진다. 따라서 개별 단어가 들어간 메일의 스팸여부에 대한 정보가 주어지면 그 단어들의 조합이 들어간 메일에 대한 스팸의 여부도 알 수 있다. 같은 방법으로 임의의 갯수의 단어조합에 대한 것도 한 단어에 대한 정보를 이용해서 얻을 수 있다. 물론 여기에는, 단어와 단어 사이의 연관성을 무시하였기 때문에 가능하였다.

만약에, "sex"라는 단어가 들어가 메일이 스펨메일일 확률, P(spam|"sex")=0.90 이고, "naked"라는 단어가 들어간 메일이 스팸메일일 확률 P(spam|"naked")=0.80 인 경우에, 두 단어가 동시에 들어간 단어는 스팸일 가능성이 훨씬 커질거라는 것은 쉽게 예상을 할 수 있다. 실제로는 위의 식에서 보면:

    P(spam|"sex","naked") = 0.90 * 0.80/(0.10*0.20 + 0.90*0.80) = 0.72/(0.02+0.72) = 0.973

이 "sex"와 "naked"가 동시에 들어가면 스팸일 확률이 개별적인 단어가 들어간 메일의 경우보다도 높아진다.

참고: http://en.wikipedia.org/wiki/Bayesian_spam_filtering

'Image Recognition' 카테고리의 다른 글

KMeans Algorithm  (0) 2008.07.19
Robust Line Fitting  (0) 2008.07.08
Bayesian Spam Filtering  (0) 2008.07.03
EM : Binarization  (0) 2008.07.01
EM Algorithm : Line Fitting 예  (0) 2008.06.29
Shuffling  (0) 2008.06.21
Posted by helloktk