[Study, NLP] Text Classification : Preprocessing_1 (Tokenization)

minbrass·2025년 3월 15일

Study_NLP

목록 보기
2/4
post-thumbnail

1. Text Classification


Text Classification은 주어진 텍스트 데이터를 사전에 정의된 범주로 자동으로 분류하는 자연어처리 작업의 핵심 분야 중 하나이다.

텍스트 분류의 주요 목표는 입력된 텍스트의 의미적, 구조적 정보를 기반으로 적절한 class(=category)를 예측하는 것이다.

우리가 왜 Text Classification를 해야하냐면, 특히나 정보가 범람하고 있는 SNS 플랫폼 및 다양한 커뮤니티의 시대에 효율적으로 우리에게 필요한 정보와 불필요한 정보를 필터링할 수 있기 때문이다.

Sentiment analysis(문서나 문장의 감정 분석), Document categorization(문서 분류), Spam detection(스팸메일/문자 필터링)은 물론이거와, 아동에게 유해한 홈페이지나 정보를 필터링하고, 우리에게 유익한 정보만을 선별하는 등의 활동까지 Text Classification을 통해 진행할 수 있다.



2. Preprocessing의 목적과 필요성


텍스트 데이터는 본질적으로 비정형적(unstructured)이며, 중복 데이터, 불필요한 정보, 문법적 오류 등이 포함될 가능성이 높다. 따라서 이러한 raw text를 머신러닝 모델이 더 잘 분류하기 위해서는 크게 두 단계가 중요하다.

1) 첫 번째로는 Text Preprocessing과 적절한 방식의 Tokenization이 필요하다. 이는 텍스트를 컴퓨터가 이해할 수 있는 방식으로 전환하는 방법이다.

2) 두 번째로는, 그 후에 사용될 분류 알고리즘(로지스틱 회귀, 딥러닝 신경망 등)과 feature 추출방법(TF-IDF, Word2Vec 등)을 설계하고 적용하는 과정이다.

특히나 우리는 preprocessing에 대한 것을 먼저 살펴볼 것인데, 이 전처리과정의 효과에 대해서 간단하게 알아보고 넘어가자.

  • 노이즈 제거

SNS나 웹 문서에는 수많은 잡음(노이즈)이 포함될 수 있다. 예컨대, 오탈자, 과도한 구두점, 특수문자, 혹은 불필요한 HTML 태그 등이 모델의 분류 정확도를 떨어뜨린다. 이를 제거하거나 단순화함으로써 모델이 진짜 중요한 텍스트 정보에 집중할 수 있게 한다.

  • 정규화(Normalization) 과정

소문자 변환, 불필요한 공백 제거, 숫자나 기호의 통일된 표현 등은 텍스트를 일관성 있게 만들어준다. 예를 들어, ‘apple’과 ‘Apple’이 같은 단어임을 모델이 인식하도록 하는 것이 대표적이다.

  • 불용어(Stopwords) 처리

‘the’, ‘of’, ‘is’ 등의 단어는 영문의 경우 통계적으로 자주 등장하면서도 실제 의미 구성에는 크게 기여하지 않을 수 있다. 이러한 단어를 제거하면 모델이 중요한 토큰에 더 집중하도록 만들 수 있다.

이 외에도 다양한 필요로 되어지는 전처리 과정을 통해 Text classification의 효율을 높일 수 있다.



3. Tokenization


3.1. Tokenization이란?

Tokenization은 원본 텍스트를 더 작은 단위인 '토큰(token)'으로 나누는 작업이다.

Token: 자연어에서 의미를 갖는 최소 구성 단위. 의미가 없이 분리되어있다면 token이라 할 수 없다.

이 토큰들은 일반적으로 단어(word)나 부분적인 단어(sub-word), 아니면 문자(character)로 구성된다. 우리는 토큰화를 수행함으로써

1. 컴퓨터가 처리할 수 있는 형태로 문장을 변환

  • 자연어는 사람에게는 친숙한 형태이지만, 머신러닝이나 딥러닝 모델에 직접적으로 활용하기에는 구조적인 정보가 부족하다. 토큰화를 통해 문장을 일정한 토큰단위로 나누게되면, 각 단위를 벡터로 표현할 수 있게 된다.

    즉, Deep Learning Model이 우리가 사용하는 자연어를 쉽게 이해할 수 있도록, 컴퓨터언어(숫자)로 변환해주는 과정이라고 생각하면 쉽다.

2. 분석 및 통계적 처리에 용이함

  • 텍스트 내 빈도 정보나 단어 간의 상관관계 등 문장 내 통계적인 정보를 보다 명확하게 추출할 수 있게 된다.

3. 불필요한 노이즈 최소화

  • 제대로된 Tokenization 과정을 거치면, 의미적으로 연관되지 않은 부분까지 한 번에 묶이는 case 등을 줄여 노이즈를 최소화 할 수 있게 된다.

직관적으로 이해해보자!

딥러닝 모델에게 당신이 아래의 문장을 학습시키려고 한다.

"나는 네가 참 좋다."

이 문장을 통으로 학습시키는 것이 유리할까, 아니면 Tokenization을 거친 후에 학습시키는 것이 유리할까?

(얼마나 쪼갤지, 어떻게 쪼갤지 그 정도에 대한 논의는 차치하더라도,) "나는", "네가", "참", "좋다" 로 쪼개어 학습하는 것이, 딥러닝 모델이 각 단어의 의미와 상관관계를 직접적으로 이해하고 학습하는데 더 도움이 될 거라고 예측해 볼 수 있을 것이다.


3.2. Sentence Tokenization

문장 토큰화(Sentence Tokenization)는 주어진 텍스트를 문장 단위로 분리하는 것을 말한다.

제일 간단히 생각하기로는 문장부호 기준으로 ‘.’, ‘?’, ‘!’ 등을 만날 때 문장을 구분하면 될 것이다.

"나는 AI가 좋다. AI가 변화시킬 세상은 어떤 세상일까? 참 기대가 된다."

-> "나는 AI가 좋다."
-> "AI가 변화시킬 세상은 어떤 세상일까?"
-> "참 기대가 된다."

아래와 같은 예외사항이 존재한다.

  • 약어(줄임말)인 경우: 예) “Dr.”, “Mr.”, “U.S.” 등
  • 따옴표, 괄호 등이 혼재된 경우
  • 문장 부호가 사실상 문장을 구분하지 않는 경우(이모지나 특수 문자 등)

"나는... 아마 Ph.D.까지는 하지 않을까 싶은데? Dr. Kim에게 조언을 들어보려고."

-> "나는..."
-> "아마 Ph."
-> "D."
-> "까지는 하지 않을까 싶은데?"
(후략)

절대적인 구두점만을 기준으로 한다면 다음과 같은 엉망진창 대잔치가 펼쳐질 것이다. 따라서 우리는 이러한 예외를 명심해야한다.

문장 토큰화는 본격적인 단어 수준의 분석에 앞서, 텍스트의 구조를 이해하는 차원에서 중요한 역할을 한다. 예를 들어, 뉴스 기사나 사설에서 각 문장은 서로 다른 주제를 다룰 수도 있으므로, 문장 단위로 구분해 놓으면 이후 단어 수준 토큰화 및 분석을 보다 체계적으로 진행할 수 있다. 특히 매거진 같이 다양한 주제의 글이 혼재되어있는 형태의 글에서는 문장 토큰화가 분석에서의 효율성을 크게 높여줄 수 있다.

하지만 문장 토큰화가 모델 학습에 있어 큰 역할을 하지는 않는다. 하나의 문장을 하나의 feature로 대응시켜 표현하게 된다면, 무한 가지의 문장이 존재하는 만큼 무한가지의 feature가 요구될텐데, 이는 현실적으로 불가능하기 때문이다. 그리고 우리는 가성비/시성비 있는 방식을 찾기위해 tokenization을 행하고 있는 것인데, 오히려 엄청난 비효율이 야기될 수 있을 것이다.

다양한 오픈소스 라이브러리에서 문장 토큰화를 제공하는데, NLTK(Natural Language Toolkit)의 sent_tokenize가 가장 대표적인 문장 토큰화 패키지이다. 한국어의 경우에는 형태소 분석기(예: KoNLPy, MeCab-ko 등)를 활용하기도 하며, 문장 부호와 공백 정보 및 특수한 어미 처리를 함께 고려해야 한다.

from nltk.tokenize import sent_tokenize
text = "Proper tokenization makes model learning easier. So tokenization is an essential process."
sentences = sent_tokenize(text)
print(sentences)

# ['Proper tokenization makes model learning easier.', 'So tokenization is an essential process.']

3.3. Word Tokenization

Word Tokenization(단어 단위 토큰화)은 문장을 개별적인 단어 단위로 분리하는 방식이다.
영어의 경우 공백(스페이스)을 기준으로 분할하는 방식이 일반적이지만, 한국어나 일본어처럼 띄어쓰기 개념이 명확하지 않은 언어에서는 추가적인 형태소 분석이 필요하다. 흔히 언급되는 이슈들은 다음과 같다.

  • 불규칙한 표기: 영어의 경우 아포스트로피(‘)를 포함하는 단어(예: “don’t”, “it’s”)를 어떻게 분리할지 결정해야 한다.

  • 다양한 언어적 특성: 독일어, 프랑스어 등은 한 단어 내에 여러 의미가 붙을 수 있어 단순 공백 기반 분리는 의미적 손실을 일으킬 수 있다.

  • 언어 고유의 특징: 한국어, 일본어, 중국어 등의 언어는 공백만으로 단어를 분리하기 어려우며, 형태소 단위로 분석해 주어야 문맥을 정확히 파악할 수 있다.

한국어를 예로 들면, “자동차가 달린다”에서 “자동차 + 가 + 달리 + ㄴ다”처럼 하나의 어절을 의미 단위(형태소)로 나누어야 문장 내 문법적 역할을 제대로 반영할 수 있다. 이를 위해 KoNLPy, MeCab-ko, Kkma 등 다양한 형태소 분석기들이 개발되어 널리 활용되고 있다.

from nltk.tokenize import word_tokenize
text = "Proper tokenization makes model learning easier. So tokenization is an essential process."
words = word_tokenize(text)
print(words)
# ['Proper', 'tokenization', 'makes', 'model', 'learning', 'easier', '.', 'So', 'tokenization', 'is', 'an', 'essential', 'process', '.']

하지만 여전히 구두점 처리, 복합어 분석, 문맥 유지의 어려움 등의 문제를 지니고 있다.


3.4. Character Tokenization

문자 토큰화(Character Tokenization)는 모든 텍스트를 문자 단위로 분리하는 방식이다. 예를 들어 “NLP”은 [“N”, “L”, “P”] 와 같이 분리된다. (따라서 일반적인 경우 한국어는 자음 14개, 모음 10개(총 24개)로 분리되고, 이 외에도 쌍자모와 복자모도 독립적인 자음 모음 개수로 인지하여 처리하는 경우도 있다. 그렇기에 Vocab의 사이즈 자체는 작다는 장점이 있지만, 모델 예측 시간이 과도하게 오래걸릴 수 있다는 단점이 있다.)

이 방식은 언어별로 복잡한 전처리 과정을 피할 수 있다는 장점이 있지만, 단어의 의미 단위(형태소, 어근)를 놓칠 위험이 커진다. 또한, 매우 긴 시퀀스(sequence)를 다뤄야 할 수 있으며, 이를 모델이 처리하기 위해서는 더 높은 파라미터 수가 요구될 수도 있는 것이 문제점이다. (이 점은 비용이 급증하기 때문에, 치명적일 수 있다!)

그럼에도 불구하고 최근 LLM(대규모 언어 모델, large-scale language model)은 모든 가능한 입력 문자들을 처리해야 하므로, 뒤에서 설명할 Sub-word Tokenization 기법과 함께 적절히 혼합된 형태나, byte-level 단위 접근법 등을 채택해 문자 단위 정보까지 고려하는 방향으로 진행되고 있으며, 현재까지도 계속해서 발전하고 있다.

text1 = "NLP"
text2 = "안녕"

tokens1 = list(text1)
tokens2 = list(text2)

print(tokens1)
# ['N', 'L', 'P']
print(tokens2)
# ['ㅇ', 'ㅏ', 'ㄴ', 'ㄴ', 'ㅕ', 'ㅇ']

3.5. Sub-word Tokenization

3.5. Sub-word Tokenization
서브워드 토큰화는 Word Tokenization과 Character Tokenization의 절충안으로, 언어적 의미와 희소성 문제를 균형 있게 처리할 수 있는 방법이다. 특히 희귀 단어(내용의 희소성이나, 사용빈도의 희소성 등을 포함)가 많거나, 접사·어근이 다양하게 조합되어 단어가 생성되는 언어에서 유용하다.

sub-word의 예시:
1. "밤공기" -> "밤" + "공기"
2. "replay" -> "re" + "play"

아래의 세 개의 방법은 대표적인 서브워드 토큰화 기법이다.

  • Byte Pair Encoding(BPE)
    * 자주 등장하는 바이트 쌍(byte pair)을 반복적으로 병합(merge)하여 토큰 사전을 구성한다. 처음에는 모든 입력 문장을 문자 단위로 분할하고, 가장 빈도가 높은 문자 쌍을 단일 토큰으로 병합해가며 사전을 확장한다. BERT, GPT 계열 모델에서 널리 사용된다.

  • WordPiece
    * 구글의 텍스트 처리에서 주로 사용되는 알고리즘으로, BPE와 유사한 방식이다. 사전에 없는 희귀 단어가 등장해도 여러 서브워드로 분할하여 처리할 수 있으므로 OOV(Out-of-Vocabulary) 문제를 완화한다.

  • SentencePiece
    * 구글에서 제공하는 라이브러리로, 공백을 포함한 모든 텍스트를 일종의 단일 문자열로 취급한 후 BPE 혹은 Unigram Language Model 방식을 적용한다. 한국어같이 공백 기반 분할이 어려운 언어에서도 사용하기 수월하다.
    이러한 서브워드 토큰화 방식은 단어의 변형이나 접사 등의 특징을 유연하게 반영할 수 있으므로, 현재 많은 딥러닝 모델에서 사실상의 표준으로 사용되고 있다.


3.6. 최신 토큰화 기법

3.6.1. Contextualized Tokenization

최근 NLP 모델에서는 컨텍스트(Context)를 반영하는 토큰화 방식이 연구되고 있다. 전통적인 Tokenization 기법은 단어 자체의 형태에 집중하지만, BERT, GPT, T5 등의 모델에서는 문맥(Context)을 반영하여 동적인 토큰화를 수행한다.

  • FastText Embedding 기반의 Sub-word 모델
  • Transformer 기반 Dynamic Tokenization
  • Lexicon-free Tokenization (사전 없는 토큰화)

하지만 여기서는 너무 깊게 들어가지 않고 이 정도에서 마무리 하겠다. (나중에 다시 공부해보도록 하자.)



4. Reference


[1] oscar-cho: NLP - 01-02. Tokenization

[2] 딥 러닝을 이용한 자연어 처리 입문 / 02. 텍스트 전처리 / 02-01 토큰화(Tokenization)

[3] WordPiece tokenization - Hugging Face NLP Cource

[4] 텍스트 마이닝 #2 Text Preprocessing (1) ~ (2)

profile
인공지능 대학원 진학을 희망하는 학부생의 정리노트

0개의 댓글