오늘의 인기 글
최근 글
최근 댓글
Today
Total
12-21 08:06
관리 메뉴

우노

[자연어처리] Naive Bayes란? 본문

Data/Natural Language Processing

[자연어처리] Naive Bayes란?

운호(Noah) 2020. 11. 23. 16:20

스팸 필터

  • 스팸 메일은 어떻게 분류 할 수 있을까?

Naive Bayes

  • 통계적 분류기
  • 각 분류별 확률 값을 계산
    • 분류 해주는 게 아니라 확률 값을 계산해준다.
  • 베이즈 정리에 따라 확률 계산
  • 확률 계산의 단서(메일에 포함된 단어)들이 서로 조건부독립임을 가정
    • 확률 계산이 단순해진다.

Naive Bayes 스팸 필터

  • 새로운 메일이 왔다. 스팸인지 알아보려면?

    • 해당 메일의 내용을 보지 않았을 때
      • 예) 기존 스팸 메일과 일반 메일의 비율 만 보고 단순하게 일반 메일 80%, 스팸 메일 20%와 같이 예측 할 수 있다.
    • 해당 메일의 내용을 봤을 때
      • 메일에 포함된 단어들이 스팸 메일에 자주 나오는 단어인지, 일반 메일에 자주 나오는 단어인지를 살펴보고 스팸 여부를 판단 할 수 있다.
  • 위와 같은 결과를 위해선 먼저, 스팸 메일과 일반 메일들을 수집한 뒤 다음을 계산해야 한다.

    • P( S ) : 스팸 메일과 일반 메일의 비율을 계산
    • P( wi | S = True ) : 각 단어가 스팸 메일에서 얼마나 자주 등장하는지 계산
    • P( wi | S = False ) : 각 단어가 일반 메일에서 얼마나 자주 등장하는지 계산
  • 새로운 메일(M)이 왔다. 스팸인지 알아보려면?

    • 스팸메일일 확률

      • P ( S = T ) * 해당 메일에 존재하는 단어들이 스팸메일에서 존재할 확률
    • 일반메일일 확률

      • P ( S = F ) * 해당 메일에 존재하는 단어들이 일반메일에서 존재할 확률

사전확률 (Prior probability)

  • P( S ) : 가지고 있는 스팸 메일과 일반 메일의 단순한 비율을 계산
    • P( S = T ) = 0.4
    • P( S = F ) = 0.6

가능도 (Likelihood)

  • P( wi | S = True ) : 각 단어가 스팸 메일에서 얼마나 자주 등장하는지 계산

    • 스팸 메일만 모아서 각 단어가 몇번이나 등장하는지 계산한다.
      • P( 롤 | S = T ) = 1/15
      • P( 시공 | S = T ) = 5/15
      • P( 조아 | S = T ) = 3/15
      • P( 옵치 | S = T ) = 0/15
      • P( 폭풍 | S = T ) = 4/15
      • P( 접속 | S = T ) = 2/15
  • P( wi | S = False ) : 각 단어가 일반 메일에서 얼마나 자주 등장하는지 계산

    • 일반 메일만 모아서 각 단어가 몇번이나 등장하는지 계산한다.
      • P( 롤 | S = F ) = 4/18
      • P( 시공 | S = F ) = 1/18
      • P( 조아 | S = F ) = 2/18
      • P( 옵치 | S = F ) = 6/18
      • P( 폭풍 | S = F ) = 1/18
      • P( 접속 | S = F ) = 4/18

스팸 분류하기

  • 새로운 메일이 왔다. 스팸인지 알아보려면?

    • 메일 내용 : 시공 조아 폭풍 조아
  • 해당 단어들이 등장했을 때, 이 메일이 스팸메일일 확률

    • P( S = T | 시공, 조아, 폭풍, 조아)
  • 베이즈 정리에 의해

    • P( 시공, 조아, 폭풍, 조아 | S = T ) P( S = T ) / P(시공, 조아, 폭풍, 조아)

    • 참고) 베이즈 정리

      • 두 확률 변수의 사전확률과 사후확률 사이의 관계를 나타내는 정리

  • 나이브 베이즈의 조건부독립 가정에 의해 이 메일이 스팸메일일 확률

    • P( 시공 | S=T ) P( 조아 | S=T) P( 폭풍 | S=T ) P( 조아 | S=T ) P( S=T ) / P(시공, 조아, 폭풍, 조아)
  • 이 메일이 일반메일일 확률

    • P( 시공 | S=F ) P( 조아 | S=F ) P( 폭풍 | S=F ) P( 조아 | S=F ) P( S=F ) / P(시공, 조아, 폭풍, 조아)
  • 스팸메일 확률과 일반메일 확률을 비교 할 때, 동일만 분모를 사용하므로 제거해서 비교해도 된다.

스팸 분류하기

  • 새로운 메일이 왔다. 스팸인지 알아보려면?

    • 메일 내용 : 시공 조아 폭풍 조아

    • 스팸메일 가능성: P(S=T) P(시공|S=T) P(조아|S=T) P(폭풍|S=T) P(조아|S=T)

      • 스팸메일 가능성: 0.4 × (5/15) × (3/15) × (4/15) × (3/15) = 0.00142222
    • 일반메일 가능성: P(S=F) P(시공|S=F) P(조아|S=F) P(폭풍|S=F) P(조아|S=F)

      • 일반메일 가능성: 0.6 × (1/18) × (2/18) × (1/18) × (2/18) = 0.00002286
    • 스팸메일일 확률이 더 크므로, 해당 메일은 스팸메일이다.

  • 또 다른 메일이 왔다. 스팸인지 알아보려면?

    • 메일 내용 : 시공 시공 시공 ㄱㄱ

      • ㄱㄱ는 그 동안 스팸 메일에서 한 번도 등장하지 않았다.
    • 스팸메일 가능성 : P(S=T) P(시공|S=T) P(시공|S=T) P(시공|S=T) P(ㄱㄱ|S=T)

      • 스팸메일 가능성 : 0.4 × (5/15) × (5/15) × (5/15) × (0/15) = 0
    • 일반메일 가능성 : P(S=F) P(시공|S=F) P(시공|S=F) P(시공|S=F) P(ㄱㄱ|S=F)

      • 일반메일 가능성 : 0.6 × (1/18) × (1/18) × (1/18) × (6/18) = 0.00003429
    • ㄱㄱ는 그 동안 스팸 메일에서 한 번도 등장하지 않아 확률값이 0이므로

    • 해당 메일은 일반 메일로 판단된다.

    • 이 때, 사용하는 방법이 라플라스 스무딩이다.

라플라스 스무딩 (Smoothing)

  • 기존 스팸메일이나 일반메일에서 한 번도 등장하지 않은 단어가 나올 경우 계산 결과가 이상해진다.

  • 스무딩 : 모든 단어가 일반 / 스팸메일에 한 번씩은 등장했다고 가정 (한 번씩 → α 번씩)

  • 스무딩 후 다시 메일을 분류해보면

    • 메일 내용 : 시공 시공 시공 ㄱㄱ

    • 스팸메일 가능성 : P(S=T) P(시공|S=T) P(시공|S=T) P(시공|S=T) P(ㄱㄱ|S=T)

      • 스팸메일 가능성: 0.4 × (6/21) × (6/21) × (6/21) × (1/21) = 0.0004442
    • 일반메일 가능성 : P(S=F) P(시공|S=F) P(시공|S=F) P(시공|S=F) P(ㄱㄱ|S=F)

      • 일반메일 가능성: 0.6 × (2/24) × (2/24) × (2/24) × (7/24) = 0.0001012
    • 결과값에 따라, 해당 메일은 스팸메일로 판단된다.

언더플로우

  • 메일에 존재하는 단어가 많을 경우 가능성이 0으로 수렴한다.

    • 0~1 사이의 확률값을 계속 곱하다보면 결과값이 0으로 수렴하기 때문이다.
    • 너무 0에 가까워지면 컴퓨터 연산의 특성상 정확도가 떨어진다. → 언더플로우
  • Log를 활용하여 개선 가능하다.

    • 우리는 결국 확률을 대소비교 하고 싶은 것이다.
    • Log는 단조증가함수이기 때문에, A < B 라면 log(A) < log(B) 와 동일하다.
    • Log를 사용하게 되면 곱셈 이였던 수식은 로그간 덧셈으로 바뀐다.
      • Log(ABC) = Log(A) + Log(B) + Log(C)
  • 로그를 사용하여 다시 계산해보면?

    • 메일 내용 : 롤 접속 ㄱㄱ

    • 스팸: log(P(S=T)) + log(P(롤|S=T)) + log(P(접속|S=T)) + log(P(ㄱㄱ|S=T))

      • (-0.92) + (-2.35) + (-1.95) + (-3.04) = -8.26
    • 일반: log(P(S=F)) + log(P(롤|S=F)) + log(P(접속|S=F)) + log(P(ㄱㄱ|S=F))

      • (-0.51) + (-1.57) + (-1.57) + (-1.23) = -4.88
    • 결과값에 따라, 헤당 메일은 일반 메일로 판단된다.

Comments