딥러닝을 이용해 크시 부적절 어휘 필터링하기

Share on facebook
Share on linkedin
Share on twitter
Share on email
지식을 공유하는 봇은 부적절한 어휘를 포함한 지식으로 타인에게 불쾌감을 줄 수도 있다. 이번 포스트에선 딥러닝을 통한 간단한 자연어처리로 부적절한 어휘를 필터링해본다.

목차

포스트 공유하기

Share on facebook
Share on linkedin
Share on twitter
Share on email

우리 팀 크레센도에서 서비스하고 있는 챗봇인 크시는 끝말잇기 등의 게임과 유저가 지식을 가르칠 수 있는 기능들이 있다. 단순하지만 매력있는 기능들로, 팀 크레센도에 가장 늦게 들어온 봇임에도 불구하고 선배라고 할 수 있는 슷칼봇의 이용자를 제쳐버린 귀여운 봇이다.

그런 용도가 아니야…

그런데 간혹, 지식을 가르치는 부분을 악용하는 유저가 있다. 크시의 지식은 지식을 가르친 한 서버에만 적용되는것이 아닌 크시의 모든 이용자가 열람할 수 있다. 이 점을 악용해 음란한 어휘나 폭력/혐오 발언 등을 가르쳐 제재되는 유저의 수가 생각보다 많다. 크시의 이용자 수가 적을땐 이를 관리자 몇분이 일일이 제재가 가능했지만, 이제는 너무 커버린(?) 크시는 소수의 관리자들만으론 커버가 불가능하다. 매일 신고 레포트가 넘쳐나 관리자들의 원성이 자자하다.

그렇다면, 컴퓨터가 자동으로 필터링하면 되지 않을까?

자동화시키는 것도 일

현재 크시의 전체 어휘 목록중, 제재가 필요한 명령어 유형은 다음과 같다.

  1. 음란한 발언
  2. 폭력적인 어휘 & 혐오발언
  3. 정치활동에 관련된 어휘
  4. 개인정보 노출

데이터셋 구축

프로젝트에 사용하는 머신러닝 모델을 학습시키기 위해선 데이터셋이 필요하다. 데이터 구축을 위해 다음과 같은 방법을 사용했다.

  1. 전체 데이터셋 약 220,000건 – 데이터셋 #0
  2. 10,000건 랜덤 추출 후 레이블링 (부적절한 어휘 약 220건) – 데이터셋 #1
    • 다만 레이블링의 퀄리티는 떨어짐
  3. 데이터셋 #1에 대한 Baseline 머신러닝 분류기를 만듦 – 분류기 A
    • 분류기 A에 대한 상세 성능은 다음 절 참고
  4. 분류기 A가 데이터셋 #0 중에서 부적절한 어휘라고 생각한 리스트를 뽑고, 사람이 그 중 분류기가 잘못 분류한 말에 대해 교정 작업 수행 – 데이터셋 #2
    • 분류기 A가 분류한 8,346건 중 1,000건 채점 (야한말 506건)
  5. 데이터셋 #1데이터셋 #2를 합침 – 데이터셋 #3
  6. 3~5의 과정(데이터 증강)을 2회 더 반복하여 최종 코퍼스 완성

위의 과정을 통해 총 11,846건(1,784건 부적절 어휘 : 약 15%)의 데이터셋을 확보했다.

전처리

필요한 데이터셋을 확보했다면, 전처리를 진행해야 한다. 전처리를 진행하지 않은 데이터는 논에서 방금 수확한 벼와 다를 게 없다. 전처리 과정을 거쳐야 데이터는 비로소 그 가치를 발할 수 있다.

본 프로젝트에서 전처리는 두가지 방법을 사용했다. 머신러닝과 딥러닝 두 방법을 사용했는데, 각각의 모델은 다른 전처리를 거친 데이터셋을 사용했다.

전처리 1 – 머신러닝 분류기

머신러닝 분류기에서 사용한 전처리 방법은 단순하다. 공백을 제거하고, 영어를 모두 소문자로 바꾸고, .가 반복되면 1개로 줄이면 끝. 따옴표가 반복되면 양성으로 잘못 예측하는 경우가 생겨 배제하였다.

ex) 안녕하세요...!! Ean 입니다! -> 안녕하세요.!!ean입니다!

머신러닝 방법은 unigram과 bigram을 사용했다.

  • 안녕하세요!!
    → (unigram) !
    → (bigram) 안녕 녕하 하세 세요 요! !!

순서가 뒤바뀌거나, 단어 사이에 새로운 글자가 들어가도 unigram 정보는 보존되며, unigram과 bigram을 포함해 총 52,679개의 토큰을 고려했다.

전처리 2 – 딥러닝 분류기

본 프로젝트에서 최종적으로 사용한 딥러닝 모델에서 사용한 전처리 방법이다. 우선 .을 포함한 2번 이상 반복되는 모든 단어를 2개로 줄인다. 이후 이를 자모단위로 분리한다. 문장을 자모단위로 분리하면 오타를 구분할 수 있게 된다. 없어라는 단어는 입력 순서만 잘못되어도 ㅓㅇㅄ어가 되며, 모델은 두 단어를 전혀 다른 문장이라 판단하게 된다. 이를 방지하기 위해 모델이 단어 단위가 아니라 자모 단위로 인식하게 하여 오타를 어느정도 무시할 수 있다.

ex) 안녕하세요...!! Ean 입니다! -> ㅇㅏㄴㄴㅕㅇㅎㅏㅅㅔ요..!! Ean ㅇㅣㅂㄴㄷㅏ!

해당 방법으로 특수문자, 한글, 영어등을 포함해 총 155개의 문자사전을 확보했으며, 사전에 없는 문자(OOV)와 패딩까지 157개의 토큰을 사용한다.

이후 one-hot-encoding과 padding과정을 거쳐 데이터를 완성했다.

분류기

프로젝트에 실험해본 여러가지 모델들이다. 모델 학습은 구글에서 제공하는 Colaboratory를 이용해 학습했다.

부적절 어휘 데이터셋은 Positive(부적절한) 데이터가 상당히 적은 비율을 차지한다는 특징이 있다. 따라서 약 22만건 상당의 전체 데이터에 대해 인퍼런스를 돌리고, 모델이 부적절하다고 판단한 데이터를 전수조사하는 방식으로 Precision을 구했다.

Negative(정상적인)로 추론한 데이터의 개수는 너무 많아서 False Negative를 세기에는 어려움이 있었고, 따라서 Recall은 비율이 아닌 상대적인 수치로 계산했다.

1. Baseline – 분류기 A

  • Logistic Regression + L2 regularization (C = 0.1)
  • 학습 데이터가 불균형하여 (부적절 어휘는 데이터 전체의 2%) 가중치 고려하여 학습
  • 이후에 실험할 모델들의 최소 성능 기준이 되는 모델

2. Model 5

  • SVM (Linear Kernel) + L2 regularization (C = 0.1)
  • Test Set Precision 0.8680, Recall ~ 4754

3. Model 6

  • SVM (Linear Kernel) + L1 penalty (C = 0.1)
  • Test Set Precision 0.6900, Recall ~ 6430

4. CNN base Model

  • Convolution Neural Network
  • Test Set Precision 0.6492, Recall ~ 7368

필터링 모델에서 가장 중요한 것은 Recall이다. 사용자 경험을 해치지 않도록 최대한 보수적일 필요가 있었고, Precision을 희생하더라도 Recall을 더 많이 가져가는 방향성이 맞다고 판단하여 이를 기준으로 적절한 모델을 선택해 배포 서버에 반영했다. 그리하여 최종적으론 CNN 기반의 딥러닝 모델을 사용하기로 결정하였다.

모델 구조

그렇다면 최종적으로 선택한 CNN 기반의 모델은 어떤 방식으로 예측을 하는걸까? 모델은 유저가 입력하는 키워드와 이에 반응하는 크시의 답변, 2개의 input을 개별로 입력받는다. 입력받은 데이터는 1D CNN layer로 개별적인 분석을 마친 후, 두개의 분석된 값을 연결(Concatenate)한다. 여기에 마지막 분석 이후 0~1사이의 결과를 출력하는 sigmoid 함수를 거쳐 최종적인 예측값을 출력한다. 간단한 구조이지만 만족할 만한 성능을 내는것을 확인할 수 있다.

활용방안

어느정도 그럴듯한 모델이 완성되긴 했으나, 잘못 예측하는 경우도 심심찮게 보인다. 필터링에 걸리는 대로 제재를 가하면 잘못된 유저가 피해받을 수 있으니, 유저의 신고나 관리자의 확인을 받도록 한다.

총평

몇주간 조금씩 시간을 들여 필터링 모델을 개발할 수 있었다. 거대한 모델이 아니기 때문에 CPU 환경에서도 충분히 돌릴 수 있는 것도 나름의 장점이라 할 수 있다. 앞으로 만들어질 데이터를 통해 더욱 발전할 수 있는 모델인 만큼, 조금 기다렸다 성과를 확인해 볼 수 있을 것이다.

물론 앞으로 보완해야할 점도 있다. 첫 학습이고 데이터가 부족한 만큼 성능이 떨어질 수밖에 없으며, 신고된 데이터를 다시 한 번 레이블링 해야한다는 것도 큰 과제이다.

이번 프로젝트가 관리자분들의 고통을 조금이나마 줄일 수 있을지를 기대하며, 모델의 성능을 더욱 향상할 수 있는 방법을 찾아봐야겠다.

목차

이안 (Ean)

이안 (Ean)

딥러닝을 공부하고 판타지소설을 사랑하는 고등학생 취준생입니다 🙂

더 둘러보기