자연어처리(NLP) 17일차 (Text Classification)

정민수
6 min readJun 20, 2019

--

2019.06.20

출처 : https://wikidocs.net/book/2155

핵심키워드

  • Text Classification
  • May-to-One Problem

케라스를 이용한 텍스트 분류 개요(Text Classification using Keras)

이번 챕터에는 케라스로 인공 신경망을 이용한 텍스트 분류와 인공 신경망 외에도 텍스트 분류 방법으로서 자주 언급되는 나이브 베이즈 분류기를 통해서 텍스트를 분류해본다.

3) 로이터 뉴스 분류하기 챕터부터 뒤의 다른 챕터까지는 데이터가 이미 왠만큼 전처리가 돼있고, 또 비교적 짧은 코드로 분류 작업이 이루어지기 때문에 어쩌면 이해하는 데 혼란이 있을 수 있다. 그렇기 때문에 딥 러닝을 이용해서 텍스트 분류가 수행될 때, 어떤 작업과 구성으로 진행되는지 간단히 미리 정리해보기로 한다.

1. 훈련 데이터에 대한 이해

앞으로 배우게 될 텍스트 분류 작업은 지도 학습(Supervised Learning)에 속한다. 지도 학습의 훈련 데이터는 레이블이라는 이름의 미리 정답이 적혀있는 데이터로 구성되어있다. 쉽게 비유하면, 기계는 정답이 적혀져 있는 문제지를 열심히 공부하고, 향후에 정답이 없는 문제에 대해서도 정답을 예측해서 대답하게 되는 메커니즘이다.

예를 들어 스팸 메일 분류기의 훈련 데이터 같은 경우에는 메일의 내용과 해당 메일이 정상인지, 스팸 메일인지 적혀있는 레이블로 구성되어있다. 아래와 같은 형식의 데이터가 약 20,000개 있다고 가정해보자.

20,000개의 행을 가진 이 데이터는 메일의 내용을 담고 있는 텍스트 데이터와 이 데이터가 스팸 메일인지 아닌지가 적혀있는 레이블, 두 가지 열로 이뤄져있다. 기계는 이 20,000개의 데이터를 학습하게 되는데, 만약 데이터가 깔끔하고 모델 또한 잘 설계되어져 있다면 이제 학습이 다 된 이 모델은 훈련 데이터에서는 없었던 어떤 텍스트 데이터가 왔을 때 레이블을 예측해낼 수 있게 된다.

2. 훈련 데이터와 테스트 데이터

위에서는 20,000개의 데이터를 전부 훈련에 사용한다고 했지만 사실 갖고 있는 모든 데이터를 전부 훈련에 사용하는 것보다는 테스트 용으로 일부는 남겨 놓는 것이 바람직하다. 예를 들어서 20,000개의 데이터에서 18,000개의 데이터는 훈련용으로 사용하고, 2,000개의 데이터는 테스트용으로 보류한 채 훈련을 시킬 때는 사용하지 않을 수 있다. 그리고 나서 18,000개의 데이터로 모델이 훈련되면, 이제 보류해뒀던 2,000개의 테스트 데이터에서 레이블은 보여주지 않고 모델에게 맞춰보라고 요구한 뒤, 정확도를 확인해볼 수 있다. 2,000개의 데이터에도 레이블이 있으므로 모델이 실제로 정답을 얼마나 맞추는지 정답률을 계산하게 된다.

뒤에 나오게 될 예제에서는 갖고 있는 데이터에서 분류하고자 하는 텍스트 데이터의 열을 X, 레이블 데이터의 열을 y라고 명명한다. 그리고 이를 훈련 데이터(X_train, y_train)와 테스트 데이터(X_test, y_test)로 분리한다. 모델은 X_train과 y_train을 학습하고, X_test에 대해서 레이블을 예측하게 된다. 그리고 모델이 예측한 레이블과 y_test를 비교해서 정답률을 계산하게 된다.

3. 단어에 대한 인덱스 부여

앞서 워드 임베딩 챕터에서 단어를 밀집 벡터(Dense Vector)로 바꾸는 워드 임베딩에 대해서 배운 바 있다. 8챕터와 9챕터에서 설명했지만, 케라스의 Embedding()은 단어 각각에 대해 정수가 맵핑된 입력에 대해서 임베딩 작업을 수행할 수 있게 해준다.

단어 각각에 숫자 맵핑, 인덱스를 부여하는 방법으로는 2챕터의 정수 인코딩 챕터에서와 같이 단어를 빈도수 순대로 정렬하고 순차적으로 인덱스를 부여하는 방법이 있다. 로이터 뉴스 분류하기와 IMDB 리뷰 감성 분류하기 챕터에서도 이 방법을 사용했으며, 해당 챕터에서 사용할 데이터들은 이미 이 작업이 끝난 상태이다.

등장 빈도순대로 단어를 정렬하여 인덱스를 부여했을 때의 장점은 등장 빈도수가 적은 단어의 제거이다. 예를 들어서 25,000개의 단어가 있다고 가정하고, 해당 단어를 등장 빈도수가 높은 순서로 1부터 25,000까지 인덱스를 부여해보겠다고 하자. 이렇게 되면 등장 빈도수 순대로 등수가 부여된 것과 다름없기 때문에 전처리 작업에서 1,000을 넘는 인덱스를 가진 단어들을 제거시켜버리면 등장 빈도수 상위 1,000개의 단어만 남길 수 있다.

4. RNN으로 분류하기

# 실제 RNN 은닉층을 추가하는 코드
model.add(SimpleRNN(hidden_size, input_shape=(timesteps, input_dim))

텍스트 분류 관점에서 앞서 배운 RNN 코드의 timesteps와 input_dim을 해석해보면 다음과 같다. (위의 코드에서는 SimpleRNN을 사용했지만, RNN의 변형인 LSTM이나 GRU도 아래의 사항은 동일하다.)

hidden_size : 출력의 크기(output_dim)

timesteps : 시점의 수 = 각 문서에서의 단어 수.

input_dim : 입력의 크기 = 각 단어의 벡터 표현의 차원 수.

5. RNN의 다-대-일(Many-to-One) 문제

텍스트 분류는 RNN의 다-대-일(Many-to-One) 문제에 속한다. 즉, 텍스트 분류는 모든 시점(time-step)에 대해서 입력을 받지만 최종 시점의 RNN 셀만이 은닉 상태를 출력하고, 이것이 출력층으로 가서 활성화 함수를 통해 정답을 고르는 문제가 된다.

이 때 두 개의 선택지 중에서 정답을 고르는 이진 분류(Binary Classification) 문제라고 하며, 세 개 이상의 선택지 중에서 정답을 고르는 다중 클래스 분류(Multi-Class Classification) 문제라고 한다. 이 두 문제에서는 각각 문제에 맞는 다른 활성화 함수와 손실 함수를 사용할 것이다.

이진 분류의 문제의 경우 출력층의 활성화 함수로 시그모이드 함수를, 손실 함수로 binary_crossentropy를 사용한다. 반면, 다중 클래스 문제라면 출력층의 활성호 함수로 소프트맥스 함수를, 손실 함수로 categorical_crossentropy를 사용한다. 또한, 다중 클래스 분류 문제의 경우에는 클래스가 N개라면 출력층에 해당되는 밀집층(dense layer)의 크기는 N이어야 한다. 즉, 출력층의 뉴런 수도 N개 여야 한다.

이번 챕터에서는 스팸 메일 분류하기와 IMDB 리뷰 감성 분류하기 문제가 이진 분류 문제에 해당되며, 로이터 뉴스 분류하기 문제가 다중 클래스 문제가 된다.

--

--

정민수
정민수

No responses yet