티스토리 뷰

728x90

NLP 전처리 과정 & 단어 임베딩

 

1. Introduction

  • 자연어 데이터는 다른 데이터(Ex:이미지)와 달리 컴퓨터가 이해 할 수 있는 숫자로 변환해야만 한다.

  • 정제되지 않은 입력 데이터와 모델을 연결시켜줄 수 있는 파이프라인 과정을 구축해야할 필요가 있다.

그렇기 때문에 NLP가 다른 데이터를 다루는 분야보다 전처리 단계에서 까다롭게 느껴지는 이유 중 하나라고 생각한다.

 

즉, 자연어를 모델에 입력시킬 수 있는 파이프라인을 구축하는 단계(자연어 전처리)와 모델은 자연어를 어떻게 이해 할 수 있는 지에 대해 흐름을 파악하는 것이 이 글의 목표 -> 따라서 사용되는 알고리즘이나, 모델 구조의 개념들은 생략


2. 실험에 사용 된 목표 TASK

NLP Text Classification 문제

- 주어진 소설 속 문장뭉치 분석을 통한 저자 예측

 

https://www.dacon.io/competitions/official/235670/overview

 

소설 작가 분류 AI 경진대회

출처 : DACON - Data Science Competition

dacon.io

 


3. 데이터 전처리부터 모델에 입력까지의 과정

Step 1. 데이터 전처리 (Train+Vali+Test Data)

  • 말뭉치들을 Token화 하기 전, 가공하기 쉬운 형태로 만들어주는 과정

  • 처리할 TASK의 성격에 따라 전처리도 선택하여 적용하는 것이 필요

  1. 불필요한 문자 혹은 숫자 그리고 특수기호들을 제거 -> 정규식

  2. 불용어 제거

  3. 대 소문자 통일화

  4. 표제어 추출 (Lemmatization)

  5. 어간 추출 (Stemming)

  6. HTML 태그 제거 등..

-> 주어진 TASK에 맞게 전처리하는 것이 중요

 

Step 2. 데이터의 토큰화 (Train+Vali+Test Data)

  • 모델의 Input은 한 문장일수도 있고, 여러 개의 문장이 될 수도 있다.

  • 토큰화의 기준은 한 문장 속의 단어가 될수도 있고,

  • 여러 개의 문장 중 한 문장이 토큰화될 수도 있다. -> 문장 분류 TASK

  • 또한 여러 개의 문장을 문장 별로 토큰화 후 다시 단어 별 토큰화도 할 수 있다.

  • 모든 토큰화 과정은 TASK에 알맞게 토큰화 하는 것이 중요

-> 토큰화는 직접 구현, 라이브러리(Mecab, NLTK 등)을 사용하는 방법과 아예 Pre-trained 된 토큰화(라이브러리)를 사용하는 방법 등이 있다.

 

Step 3. 단어 사전 구축 1 (Train Data 기반)

  • 결국 우리의 말뭉치 데이터는 숫자로 표현해야한다. 

  • 이 과정의 첫 시작은 항상 ‘정수 인코딩’ 으로 부터 시작

  • 보통 토큰화 단계에서 얻은 단어들의 사전을 구축하여 빈도수 기준으로 인덱스를 정렬 후 맵핑시켜 정수 인코딩을 얻는다.

  • 따라서 이같은 과정을 진행시키기 위해 단어 사전 구축을 해야함

Step 4. 단어 사전 구축 2 (Special Token)

  • 주어진 TASK를 수행하기 위한 Special Token을 단어 사전에 추가한다.

  • 패딩(Padding)을 위한 토큰 <PAD> 

  • 입력의 Classification을 위한 토큰 <CLS> -> Classification을 위한 토큰

  • 단어 사전에 없는 단어를 표기하기 위한 토큰 <UNK>

  • 한 입력 내에서 문장들을 구별하기 위한 토큰 <SEP> -> 문장 구분을 위한 토큰

  • 입력의 끝을 알리는 토큰 <EOS>

-> 이외에도 주어진 TASK와 모델에 맞는 토큰을 임의로 생성할 수 있다.

 

Step 5. 정수 인코딩과 Model Input

  • 앞에서 구축한 단어 사전(Vocab)을 기반으로 입력 데이터들을 정수 인코딩

  • Batch Size에 맞게 정수 인코딩된 입력 데이터들을 길이를 기준으로 Bucketing 하여 모델의 Input에 넣어준다. 

  • Model Input은 Tensor Type으로 들어가고 Tensor는 Batch Size 만큼의 데이터의 길이가 모두 같아야 한다. (남는 길이에는 <PAD> 토큰이 들어감)

배치 별 최대 길이 기준으로 Bucketing한 예시

-> 그러나 정수 인코딩된 Data를 모델에 입력한다고 해서 모델은 단어를 이해할 수 없다. 지금까지의 과정만으로는 모델은 단순 스칼라값으로만 이해할것이다. 따라서 이 스칼라값으로 표현된 단어를 벡터로 표현해줘야한다.


4. 각 단어를 벡터로 표현하는 방법

Solution 1. 원-핫 인코딩

정수 인코딩을 벡터로 표현하기 위한 첫 번째 시도는 원-핫 인코딩(=원-핫 벡터)

하지만 많은 한계와 단점을 가지고 있음.

  • 메모리 문제 : 단어 사전의 크기를 차원으로 가지는 원-핫 벡터가 입력의 단어 수 만큼 필요 -> Batch Size까지 고려한다면 (B , L, len(Vocab))의 차원을 가짐

  • 표현력 부족 : 원-핫 벡터로는 각 단어 간의 유사도을 알 수 없음

Solution 2. 단어 임베딩

  • 원-핫 벡터의 메모리 적 한계를 보완 (차원 축소)

  • 단어 임베딩은 각 단어에 임의의 차원(Hyper Parameter)의 Feature로 표현할 수 있음

  • 각 단어들의 유사도를 벡터로 비교할 수 있게 되었음

-> 즉, 단어 임베딩으로 부터 단어들의 특징을 벡터로 표현할 수 있게 되었다


5. 단어 임베딩

1) 모델에서 임베딩 레이어의 위치

: NLP 모델의 시작에는 항상 Embedding Layer가 존재

 

2) 임베딩 레이어는 무엇을 학습할까?

*) 실험1. 사전 훈련되지 않은 Embedding Layer

-> 사전 훈련이 안된 임의의 값으로 초기화된 임베딩 레이어를 포함한 모델에 TASK를 수행시키면 어떤 결과를 얻을 수 있을까?

 

1) 모델1. Embedding Layer -> Linear Layer

실험에 사용된 Linear Model

 

2) 모델2. Embedding Layer -> GRU Layer

실험에 사용된 GRU Model

 

*) 실험1의 결과로 알 수 있는 점

  • 랜덤한 값들로 초기화된 Embedding Layer 임에도 불구하고 나름의 학습이 이루어졌다.

  • 하지만 이 Embedding Layer가 단어의 의미를 학습했다고는 할 수 없다.

  • 학습 데이터의 각 Label에 맞는 단어의 특징을 학습했다고 할 수 있다. (TASK에 맞는 나름 단어들의 유사도를 구함)

-> 따라서 실험1의 결과와 같이 빠르게 오버피팅이 일어남을 볼 수 있었다. (일반화 성능 부족)

-> 결국, NLP 모델의 일반화 성능을 끌어올리기 위해서 Embedding Layer의 의미있는 가중치를 설정해주는 것이 중요한 것으로 보인다.

 

-> 그렇다면 Embedding Layer 가중치를 어떤 값을 초기값으로 넣어주는 것이 좋을까?

 


6. Word2Vec

: Vocab내 단어들이 속한 학습 문장 속에서 각 단어 간 의미를 학습한 Embedding를 모델의 Embedding Layer에 넣기 위한 목적

(Word2Vec의 자세한 내용은 dev-hunmin.tistory.com/entry/Day-16-NLP-%EC%9E%90%EC%97%B0%EC%96%B4-%EC%B2%98%EB%A6%AC-1?category=1179221 에서 설명)

 

-> Word2Vec과 Task를 수행할 모델은 독립적이다.

-> 독립적인 Word2Vec 모델에서 Train Data를 통해 단어 간 의미를 Embedding 벡터에 학습시키고, Word2Vec 모델에서 학습된 Embedding 벡터들을 Task를 수행할 Embedding Layer의 가중치로 사용한다.

 

Word2Vec CBOW / Skip-Gram

- Word2Vec은 보통 Embedding Layer, Linear Layer로 구성하거나, 두개의 Embedding Layer로 구성하여 두 임베딩 가중치의 평균을 Task를 수행할 Model의 Embedding Layer 가중치로 사용한다.

 

*) 실험2. Word2Vec으로 사전 훈련된 Embedding Layer

-> 사전 훈련된 Word2Vec에서 구한 Embedding Layer로부터 Task를 수행하면 어떤 결과를 얻을 수 있을까?

 

1) 모델1. Embedding Layer -> Linear Layer

실험에 사용된 Linear Model

 

2) 모델2. Embedding Layer -> GRU Layer

실험에 사용된 GRU Model

 

*) 실험2의 결과로 알 수 있는 점

- 단어 간 의미를 사전 학습한 Embedding Layer를 통해 같은 환경에서 TASK를 수행한 결과, 실험 1과 다른 결과를 얻을 수 있었다.

 

  • 실험1에서는 빠르게 학습 데이터에 오버피팅 되는 경향을 보였으나, 실험2에서는 Train, Validation 데이터에 대해서 좀 더 밸런스 있게 증가하는 것을 볼 수 있었다. (오버피팅 해소, 일반화 성능 향상)
  • 실험1과 같이 Label에 대한 학습 데이터 Feature를 파악해 학습하는 것이 아닌 각 단어들의 의미의 유사도를 통해 TASK를 수행하였다.
  • 즉, NLP 모델에 각 단어들의 의미의 유사도를 학습한 Embedding Weight를 부여하는 것이 일반화 성능 개선에 효과가 있었음을 알 수 있다.

7. Word2Vec의 한계, 그리고 FastText의 등장

1) Word2Vec의 한계

  • 학습 단어 내에서 구축한 단어 사전에 없는 단어가 입력으로 들어올 시 OOV로 취급할 수 밖에 없다.
  • 슬라이딩 윈도우 기반으로 단어의 의미를 예측하는 것이므로 거리가 먼 단어들과는 자연스럽게 관계가 멀어진다.
  • 구축한 단어 집합에 등장 빈도가 낮은 단어는 임베딩 벡터를 학습할 기회가 적다.
  • (즉, 희소한 단어를 임베딩하기 어렵다는 문제)
  • 특히 OOV 관련된 문제는, Pre-trained 된 Word2Vec을 사용하더라도 구축된 사전에 없는 단어라면 임베딩 벡터를 부여할 수 없는 문제가 치명적이다.

2) FastText의 등장

  • 본래, Word2Vec의 치명적인 한계인 OOV 문제를 대응한 단어 임베딩 학습 방식

  • Facebook에서 개발한 FastText는 Word2Vec을 기본으로 한다. (단어의 의미를 학습하는 것은 같음)

  • 하지만 Word2Vec는, 단어 그자체로만 학습을 한 반면, Fasttext는 그 단어를 다시 n-gram 방식으로 sub-word로 쪼개, 부분 단어들도 임베딩한다.

-> 따라서, Sub-word 방식으로 OOV의 단어도 임베딩 벡터를 구할 수 있고, 희소한 단어의 임베딩 학습의 문제도 대응 할 수 있었다. (OOV의 단어임에도 부분 단어들의 임베딩의 평균으로 그럴싸한 임베딩 벡터를 얻을 수 있게 됨)

 

-> 또한, 동일한 학습 데이터에서 더 많은 정보를 활용할 수 있으므로 높은 성능을 기대할 수 있다.


8. 단어 임베딩 기반 알고리즘의 한계

  • 하지만 단어 임베딩 학습으로만은, 단어의 모든 의미를 모두 내포하고 있을 수 없다.
  • 결국 단어 임베딩은, 각 단어에 임베딩 벡터가 1:1 맵핑이 되는 것이므로 단어는 하나의 임베딩 벡터만을 가질 수 있다.

-> 예를 들면, 과일의 Apple, 회사의 Apple은 단어 임베딩에서는 같은 임베딩 벡터를 가지는 한계를 가진다.


9. Bert / GPT의 등장

  • Transformer의 일부 구조 그리고 Attention을 사용한 Self-Supervised Learning의 Bert와 GPT가 등장함

  • 본래 Word2Vec과 Fasttext는 단어 임베딩을 먼저 학습시켜 모델 임베딩 레이어에 Weight 값을 넣어준 반면에, Bert와 GPT는 모델 내에서 문장 속의 단어의 의미를 찾고 더 나아가, 문장과 문장의 예측을 스스로 학습한다.

  • 이 과정 속에서 Word2Vec, Fasttext의 한계에 모두 대응하고 각 단어, 더 나아가 문장의 의미까지도 모델이 확실히 학습할 수 있게 되었다.

  • 또 Special Token으로 많은 DownStream TASK에도 수행할 수 있도록 하였다.

*) 실험3. Pre-trained Bert Model

- 기존의 단어 임베딩의 한계를 모두 극복하고 뛰어난 성능을 자랑하는 Pre-trained Bert Model로 Task 수행하기

Pre-trained Bert Model 선언

 

-> 리소스 부족으로 Max length를 100으로 제한했음에도 불구하고 뛰어난 성능을 보인다.

 


10. Conclusion

  • NLP에서 데이터 전처리는 결국 Input data의 정수 인코딩을 위한 과정 (1.말뭉치들의 정제, 2.정제된 말뭉치들을 토큰화, 3.토큰화된 단어들의 사전 구축, 4.구축된 사전을 통해 정수 인코딩) 

  • 단어 임베딩은 각 단어들의 Feature를 벡터로 표현할 수 있게 만들어준다.

  • 임베딩 레이어는 기본적으로 모델의 가장 첫 레이어에 위치한다.

  • 정수인코딩된 Input이 임베딩 레이어를 지나면서 매핑되는 단어 별 벡터를 가진다.

  • 모델 TASK의 일반화 성능을 위해 임베딩 레이어를 사전 학습 시킬 수 있다. (Word2Vec, FastText 등) -> 사전 학습 방식에 따라 다르다(대부분 의미 파악하기)

  • 앞의 한계들을 모두 극복하고 모델 내부에서 학습하는 Self-Supervised Learning Model의 등장 (Bert, GPT 등)

11. Further Question

Q) 그렇다면 Word2Vec, FastText 보다 Bert, GPT 쓰는 것이 항상 유리할까요?


 

 

 

 

실험을 위해 작성된 코드는

https://github.com/hunmin-hub/DL_Tutorial/tree/main/DACON_Novel

 

hunmin-hub/DL_Tutorial

DeepLearning Tutorial. Contribute to hunmin-hub/DL_Tutorial development by creating an account on GitHub.

github.com

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함