버티의 블로그

[자연어처리 #01] Text Preprocessing 본문

전공 공부/자연어처리

[자연어처리 #01] Text Preprocessing

ㅤ버티ㅤ 2024. 6. 23. 15:14
728x90
화분에 예쁜 꽃이 피었다.

이 문장을 토큰화하면 다음과 같이 해야한다. 아래 처럼 명사/조사 사이나 어간/어미 사이도 분리해야한다.

화분(명사) + 에(조사) + 예쁘(어간) + -ㄴ(어미) + 꽃(명사) + 이(조사) + 피(어간) + 었(어미) + 다(어미)

 

이런식으로 컴퓨터가 자연어를 효과적으로 처리할 수 있도록 전처리 과정을 거쳐야 한다.

 

Pre-Processing

텍스트 전처리 과정은 크게 3가지 단계가 있다.

 

1) Tokenization

  • 문장을 형태소 단위로 자른다. 
  • 주어진 문장에서 의미 부여가 가능한 단위를 찾는다.
  • 표준화 토큰화 방법인 Treebank Tokenization이 있다.
  • 문장 의미별로 나누는 문장 토큰화도 존재한다.
  • 한국어는 토큰화가 어렵다. Ex) 필요하다면 -> 필요(명사) + 하(접미사) + 다면(어미)

2) Cleaning & Stemming

 

  • Cleaning : 데이터를 사용 목적에 맞춰 노이즈를 제거한다.
    • 즉 중요한 단어만 남기고 필요 없거나 출현 횟수가 적은 단어를 제거한다.
    • 대명사나 관사도 대부분 제거한다.
    • 주로 nltk 라이브러리의 불용어(stopword)를 가져와 사용한다.
  •  Stemming : 형태가 다른 단어들을 동일한 형태로 맞춰준다.
    • 어간 추출(Stemming) : 품사 정보 포함X
      Ex) having -> hav, is -> is
    • 표제어 추출(Lemmatization)  : 단어의 품사 정보를 포함, 그래서 품사 별로 의미가 다를땐 필수닫.
      Ex) having -> have, is -> be

3) Encoding

  • 추출한 단어를 숫자나 벡터 형태로 바꾼다
  • 정수 인코딩
    • 기본 방법 : 1부터 시작하여 처음 보는 단어마다 번호를 부여하고 번호를 +1, 기존 단어는 기존 번호를 사용
    • 빈도수 정렬 : 등장 횟수가 많은 단어에 앞쪽 번호를 부여, 파이썬의 dict와 enumerate 활용
  • One-hot 인코딩 : 각 단어의 범주가 있으면 해당 범주 위치에만 1을 나머지는 0으로 채워 사용
    • 저장공간 문제가 발생 가능
  • Word2vec 인코딩 : 단어의 유사성을 인코딩에 반영하여 유사한 단어끼리 모여있게 한다 (자세한건 다음장)
  • 인코딩 후 필요에 따라 Zero-padding 진행
    • 문장들의 길이를 가장 긴 문장 길이에 맞춰주기 위해 부족한 공간에 0을 채운다.

TF-IDF

단어들의 중요한 정도를 가중치로 매기는 방법

  • f(t, d) : 문서 d에서 특정 단어 t의 등장 횟수

  • df(t) : 특정 단어 t가 등장한 문서의 수
  • N : 총 문서의 수

N-gram

n이라는 수를 정해서 기준 단어의 앞/뒤로 n만큼만 고려하는 방법

  • Unigram (1-gram) : 단어 하나 또는 문자 하나로 구성된 시퀀스
    "I am happy" -> ["I", "am", "happy"]
  • n-gram : n개의 연속된 단어 또는 문자로 구성된 시퀀스
    n=2인 경우 "I am happy" -> ["I am", "am happy"]

Similarity

두 벡터의 유사도를 판단하여 문장이 유사한지 파악하는 방법

 

1) Cosine Metric

A = [1, 1, 0], B = [1, 0, -1]라면
두 벡터의 내적은 1*1 + 1*0 + 0*(-1) = 1 -> 분자
norm A와 norm B의 곱은 {1^2 + 1^2 + 0^2}^(1/2) * {1^2 + 0^2 + (-1)^2}^(1/2) = 2^(1/2) * 2^(1/2) = 2
따라서 Cosine Similarity는 1/2

 

이를 문장 유사도에 활용하기 위해, 각 단어의 등장 횟수를 벡터화시켜서 구한다.

1) I love apple.
2) Apple is delicious which i love too.
3) I want a delicious food, but not an apple.
4) I am developer.

 

이렇게 문장이 되어 있을 때 불용어를 제거한 다음 빈도를 체크해본다.

love apple delicious food apple developer
1 1 0 0 0 0
1 1 1 0 0 0
0 1 1 0 1 0
0 0 0 0 0 1

 

이제 문장 간 유사도를 몇개 구해보면 다음과 같다.

  • similarity(1, 2) : 2/6^(1/2)
  • similarity(2, 4) : 0/3^(1/2)
  • similarity(1, 3) : 1/6^(1/2)

따라서 문장 1, 2가 유사도는 높고, 문자 2, 4는 유사도가 낮은걸 볼 수 있다.

 

2) Euclidean Metric

두 벡터 사이의 직선 거리를 이용하는 방법, 크기가 작을수록 유사도가 높다

 

3) Levenshtein Distance

 

단어 사이의 거리를 나타내는 대표적인 척도인데, A를 B로 바꾸기 위한 최소 횟수이다. 이 횟수가 적으면 바꿀 필요가 적은 것이므로 문장 간 유사도가 높다고 볼 수 있다.

  • 단어 삽입, 단어 삭제, 단어 변경

그럼 아래에서 1번 문장을 2번 문장으로 바꾸려면 삽입을 1번, 삭제를 1번, 변경을 3번 해야된다.

1) 유사도나   분석   할까요
2) 얼마   나   분석이될까요