토큰화 (Tokenization)

자연어 처리의 첫 번째 단계 - 텍스트를 기계가 이해할 수 있는 토큰으로 분할하기

토큰화는 자연어 처리의 첫 번째이자 가장 중요한 전처리 과정이다. 토큰의 개념부터 문장/단어/서브워드 토큰화까지 각 방법의 원리와 도전과제, 그리고 실무에서 사용되는 도구들을 종합적으로 다룬다.

Deep Learning
NLP
AI
저자

Kwangmin Kim

공개

2025년 01월 02일

1 내용 요약

토큰화의 핵심 개념: * 토큰(Token): 자연어 처리에서 텍스트를 처리 가능한 최소 단위로 나눈 것 * 토큰화(Tokenization): 연속된 텍스트를 의미 있는 단위(토큰)로 분할하는 과정 * 중요성: 텍스트를 구조화하고 표준화하여 후속 NLP 작업의 기반을 마련

토큰화의 주요 유형: * 문장 토큰화: 텍스트를 문장 단위로 분할 (마침표, 물음표 등 활용) * 단어 토큰화: 문장을 단어 단위로 분할 (공백, 구두점 등 기준) * 서브워드 토큰화: 단어를 더 작은 의미 단위로 분할 (BPE, WordPiece, SentencePiece)

주요 도전과제: * 복잡한 예외 상황: 약어, 특수문자, 이메일 주소, IP 주소 등의 처리 * 언어별 특성: 한국어 교착어 특성, 영어 축약형 등 * 도메인별 특수성: 소셜미디어 해시태그, 의학 용어 등 * OOV 문제: 어휘집에 없는 새로운 단어 처리

실무 권장 도구: * 영어: NLTK (TreebankWordTokenizer, sent_tokenize) * 한국어: KSS (문장분할) + KoNLPy (형태소분석) * 다국어: spaCy (산업용 고성능) * 딥러닝: Transformers 라이브러리 (서브워드 토큰화)

핵심 메시지: 직접 규칙을 구현하기보다는 검증된 도구를 활용하고, 언어와 도메인 특성에 맞는 적절한 전략을 선택하는 것이 중요하다.

2 토큰(Token)의 이해

  • 자연어 처리를 하다보면 여기저기서 토큰이란 단어가 빈번하게 관찰된다.
  • 토큰은 자연어 처리(NLP)에서 텍스트를 처리 가능한 최소 단위로 나눈 것을 의미한다.
  • 단어, 부분 단어, 구두점 등이 모두 토큰이 될 수 있다.
  • 토큰화(tokenization) 방식은 사용하는 언어 모델(GPT, BERT 등)에 따라 다르다.

2.1 영어의 토큰화

영어에서는 일반적으로 다음과 같은 방식으로 토큰화된다:

2.1.1 단어 기반 토큰화

"Hello, world!" → ["Hello", ",", "world", "!"]  # 4개 토큰

2.1.2 부분 단어 기반 토큰화

긴 단어나 복잡한 단어는 여러 토큰으로 분리될 수 있다:

"unbelievable" → ["un", "believ", "able"]  # 3개 토큰

2.2 한국어의 토큰화

한국어는 영어와 다른 토큰화 특성을 가진다:

2.2.1 음절 단위 토큰화

한국어는 주로 음절(글자) 단위로 토큰화된다:

"안녕하세요" → ["안", "녕", "하", "세", "요"]  # 5개 토큰

2.2.2 형태소 단위 토큰화

일부 모델은 형태소 단위로 분리하기도 한다:

"먹었습니다" → ["먹", "었", "습니다"]  # 3개 토큰
"데이터과학자" → ["데이터", "과학자"]  # 2개 토큰

2.2.3 혼합 문장의 예시

"안녕하세요! 반갑습니다." 
→ ["안", "녕", "하", "세", "요", "!", " ", "반", "갑", "습", "니", "다", "."]
# 약 13개 토큰

2.3 토큰 수와 글자 수의 관계

언어 토큰 수와의 관계 특징
영어 단어 수와 유사 1개 단어 ≈ 1-2개 토큰
한국어 글자 수와 유사 1개 글자 ≈ 1개 토큰
혼합 텍스트 복잡도에 따라 변동 언어별 규칙이 혼재

2.4 실무적 고려사항

2.4.1 한국어 텍스트의 토큰 수 예측

  • 간단한 추정: 글자 수 ≈ 토큰 수
  • 공백과 구두점: 추가 토큰으로 계산
  • 예시: “안녕하세요. 데이터 과학자입니다.” (약 17글자) → 약 17-20개 토큰

2.4.2 모델별 차이

  • GPT 계열: Byte Pair Encoding (BPE) 방식 사용
  • BERT 계열: WordPiece 방식 사용
  • 각 모델의 토크나이저마다 결과가 다를 수 있다

2.5 토큰 수 확인 방법

정확한 토큰 수를 확인하려면 사용하는 모델의 토크나이저를 직접 사용해야 한다:

# OpenAI GPT 모델 예시
import tiktoken

encoding = tiktoken.encoding_for_model("gpt-4")
text = "안녕하세요. 데이터 과학자입니다."
tokens = encoding.encode(text)
print(f"토큰 수: {len(tokens)}")
  • 영어: 토큰 수 ≈ 단어 수 × 1.3배 정도
  • 한국어: 토큰 수 ≈ 글자 수 × 1배 정도
  • 정확한 계산: 사용 모델의 토크나이저로 직접 확인 필요

토큰 수는 LLM API 비용 계산, 입력 제한 관리 등 실무에서 중요한 지표이므로, 대략적인 추정 방식을 알아두면 유용하다.

3 토큰화(Tokenization)의 개요

이제 토큰이 무엇인지 이해했으니, 토큰화 과정에 대해 본격적으로 알아보자.

  • 토큰화는 자연어 처리에서 가장 기본이 되는 전처리 과정이다.
  • 연속된 텍스트를 컴퓨터가 이해할 수 있는 의미 있는 단위(토큰)로 분할하는 작업을 의미한다.

3.1 토큰화의 정의와 목적

토큰화란 기계에게 어느 구간까지가 문장이고 단어인지를 알려주는 과정이다. 인간은 자연스럽게 문장의 구조를 이해하지만, 컴퓨터는 명시적으로 경계를 정해줘야 한다.

3.1.1 주요 목적

  • 구조화: 비구조화된 텍스트를 구조화된 형태로 변환한다.
  • 표준화: 일관된 처리 단위를 제공한다.
  • 효율성: 후속 NLP 작업의 효율성을 향상시킨다.
  • 의미 보존: 언어의 의미를 최대한 보존하면서 분할한다.

3.2 토큰화의 종류

토큰화는 분할 단위에 따라 여러 가지 방법으로 분류할 수 있다.

3.2.1 문장 토큰화 (Sentence Tokenization)

텍스트를 문장 단위로 분할하는 과정이다.

한글 예시:

입력: "자연어 처리는 매우 흥미로운 분야입니다. 컴퓨터가 인간의 언어를 이해하고 처리할 수 있게 만드는 기술이죠. 최근 딥러닝 기술의 발전으로 놀라운 성과를 보이고 있습니다. 특히 GPT나 BERT 같은 모델들이 주목받고 있어요."

출력: [
  "자연어 처리는 매우 흥미로운 분야입니다.",
  "컴퓨터가 인간의 언어를 이해하고 처리할 수 있게 만드는 기술이죠.",
  "최근 딥러닝 기술의 발전으로 놀라운 성과를 보이고 있습니다.",
  "특히 GPT나 BERT 같은 모델들이 주목받고 있어요."
]

영어 예시:

입력: "Natural language processing is a fascinating field of study. It combines linguistics, computer science, and artificial intelligence to help computers understand human language. Recent advances in deep learning have revolutionized this area. Models like GPT and BERT have achieved remarkable performance on various NLP tasks."

출력: [
  "Natural language processing is a fascinating field of study.",
  "It combines linguistics, computer science, and artificial intelligence to help computers understand human language.",
  "Recent advances in deep learning have revolutionized this area.",
  "Models like GPT and BERT have achieved remarkable performance on various NLP tasks."
]

주요 고려사항: - 마침표, 느낌표, 물음표 등의 문장 종결 부호 - 줄임말과 약어 처리 (예: “Dr.”, “etc.”) - 인용문 내의 문장 부호

3.2.1.1 문장 토큰화에 대한 고민

  • 문장 토큰화는 겉보기에는 간단해 보이지만, 실제로는 매우 복잡한 언어학적 문제들을 내포하고 있다.
  • 비전문가들은 마침표, 쉼표, 느낌표, 물음표만 있으면 문장을 쉽게 구분할 수 있다고 생각하지만, 현실은 그렇게 단순하지 않다.

1. 마침표의 다중 의미 딜레마

마침표가 항상 문장의 끝을 의미하는 것은 아니다. 동일한 기호가 완전히 다른 용도로 사용되는 경우가 빈번하다.

예시 1: 약어와 문장 종료의 혼재
"Dr. Smith earned his Ph.D. from MIT in 1995. He now works at NASA."

잘못된 분할:
- "Dr."
- "Smith earned his Ph."
- "D."
- "from MIT in 1995."
- "He now works at NASA."

올바른 분할:
- "Dr. Smith earned his Ph.D. from MIT in 1995."
- "He now works at NASA."

같은 마침표이지만 “Dr.”와 “Ph.D.”는 약어를 나타내고, 마지막 마침표만이 실제 문장의 끝을 의미한다.

2. 이메일 주소의 함정

예시 2: 이메일과 URL이 포함된 텍스트
"Contact john.doe@company.com for details. Visit www.company.com. Our office is open 9 A.M. to 5 P.M."

잘못된 분할:
- "Contact john."
- "doe@company."
- "com for details."
- "Visit www."
- "company."
- "com."
- "Our office is open 9 A."
- "M."
- "to 5 P."
- "M."

올바른 분할:
- "Contact john.doe@company.com for details."
- "Visit www.company.com."
- "Our office is open 9 A.M. to 5 P.M."

이메일 주소와 웹사이트 URL 내의 마침표들은 문장 구분자가 아닙니다.

3. 숫자와 소수점의 복잡성

예시 3: 숫자와 측정값
"The temperature reached 98.6°F yesterday. Sales increased by 15.7% this quarter. Our target is $1.5M."

잘못된 분할:
- "The temperature reached 98."
- "6°F yesterday."
- "Sales increased by 15."
- "7% this quarter."
- "Our target is $1."
- "5M."

올바른 분할:
- "The temperature reached 98.6°F yesterday."
- "Sales increased by 15.7% this quarter."
- "Our target is $1.5M."

소수점, 통화 표시, 백분율 등에서 사용되는 마침표는 문장 구분자가 아니다.

4. IP 주소와 기술 용어

예시 4: 기술 문서
"Connect to server 192.168.1.1 on port 8080. Use API version 2.3. Check logs at /var/log/app.log for errors."

잘못된 분할:
- "Connect to server 192."
- "168."
- "1."
- "1 on port 8080."
- "Use API version 2."
- "3."
- "Check logs at /var/log/app."
- "log for errors."

올바른 분할:
- "Connect to server 192.168.1.1 on port 8080."
- "Use API version 2.3."
- "Check logs at /var/log/app.log for errors."

IP 주소, 버전 번호, 파일 경로에서 사용되는 마침표들은 모두 문장 구분자가 아니다.

5. 인용문과 대화체의 복잡성

예시 5: 직접 인용문
'He said, "I don't think so. Maybe tomorrow?" Then he left.'

잘못된 분할:
- 'He said, "I don't think so.'
- 'Maybe tomorrow?"'
- 'Then he left.'

올바른 분할:
- 'He said, "I don't think so. Maybe tomorrow?" Then he left.'

인용문 내부의 문장 부호는 전체 문장의 구조를 고려해야 한다.

6. 줄임표와 생략 표현

예시 6: 줄임표의 혼란
"Well... I'm not sure. He seemed hesitant... maybe nervous? The meeting went on and on..."

문제점:
- "Well..."의 "..."는 망설임을 표현
- "hesitant..."의 "..."는 말끝을 흐림  
- "on and on..."의 "..."는 문장의 실제 종료

이런 경우 어디서 문장을 나눠야 할지 판단하기 어렵다.
  1. 이외에도, 다양한 유형의 문장 토큰화 문제가 있다.
  • 프로그래밍 코드가 포함된 텍스트
  • 시간과 날짜 표기법
  • 학술 논문과 참고문헌

결론적으로, 문장 토큰화는 단순한 규칙 기반 접근법으로는 해결되지 않는다. 다음과 같은 요소들을 종합적으로 고려해야 한다:

  • 문맥 정보: 주변 단어와 문장의 맥락
  • 도메인 지식: 의학, 법률, 기술 문서의 특수성
  • 언어적 규칙: 각 언어의 고유한 문법과 표기법
  • 의미론적 이해: 문장의 완결성과 논리적 구조
  • 다중 언어 처리: 코드 스위칭과 외래어 처리

이러한 복잡성 때문에 현대의 문장 토큰화 도구들은 기계학습 기반의 접근법을 사용하여 문맥을 이해하고 더 정확한 분할을 수행하려고 시도한다. 하지만 여전히 완벽한 해결책은 없으며, 지속적인 연구와 개선이 필요한 영역이다.

3.2.2 단어 토큰화 (Word Tokenization)

문장을 단어 단위로 분할하는 과정이다.

한글 예시:

입력: "자연어 처리는 매우 흥미로운 분야입니다. 컴퓨터가 인간의 언어를 이해하고 처리할 수 있게 만드는 기술이죠. 최근 딥러닝 기술의 발전으로 놀라운 성과를 보이고 있습니다. 특히 GPT나 BERT 같은 모델들이 주목받고 있어요."

출력: [
  "자연어", "처리", "는", "매우", "흥미로운", "분야입니다", ".", "컴퓨터가", "인간의", "언어를", "이해하고", "처리할", "수", "있게", "만드는", "기술이죠", ".", "최근", "딥러닝", "기술의", "발전으로", "놀라운", "성과를", "보이고", "있습니다", ".", "특히", "GPT나", "BERT", "같은", "모델들이", "주목받고", "있어요"
]

영어 예시:

입력: "Natural language processing is a fascinating field of study. It combines linguistics, computer science, and artificial intelligence to help computers understand human language. Recent advances in deep learning have revolutionized this area. Models like GPT and BERT have achieved remarkable performance on various NLP tasks."

출력: [
  "Natural", "language", "processing", "is", "a", "fascinating", "field", "of", "study", ".", "It", "combines", "linguistics", "computer", "science", "and", "artificial", "intelligence", "to", "help", "computers", "understand", "human", "language", ".", "Recent", "advances", "in", "deep", "learning", "have", "revolutionized", "this", "area", ".", "Models", "like", "GPT", "and", "BERT", "have", "achieved", "remarkable", "performance", "on", "various", "NLP", "tasks"
]

언어별 특성:

  • 영어
    • 공백을 기준으로 비교적 쉽게 분할 가능
    • 구두점 처리가 주요 과제
  • 한국어
    • 교착어 특성으로 복잡한 어미 변화
    • 공백만으로는 정확한 분할 어려움
  • 형태소 분석이 필요

3.2.2.1 단어 토큰화에 대한 고민

문장 토큰화와 마찬가지로, 단어 토큰화 역시 많은 복잡한 문제들을 내포하고 있다.

1. 특수문자 처리의 딜레마

문장 내에서 단어를 어떻게 구분할까? 느낌표나 어포스트로피 같은 특수문자가 들어갔을 때 문제가 발생한다.

예시:
"I can't believe it!" 

처리 방법 1: ["I", "can't", "believe", "it!"]
처리 방법 2: ["I", "can", "'", "t", "believe", "it", "!"]
처리 방법 3: ["I", "cannot", "believe", "it"]

어떤 방법이 정답일까? 각각 장단점이 있어 선택하기 어렵다.

2. 동일한 의미, 다른 토큰화 결과

의미가 동일한 문장들에 대해서 띄어쓰기 단위로 단어를 나눠본다면, 같은 의미이지만 컴퓨터는 다르게 취급한다.

문장 1: "He is a hero."
문장 2: "He is a hero?"
문장 3: "He is a hero!"

토큰화 결과:
문장 1: ["He", "is", "a", "hero."]
문장 2: ["He", "is", "a", "hero?"]  
문장 3: ["He", "is", "a", "hero!"]

의미가 동일함에도 전부 다른 결과를 얻는다. herohero?hero! 왜냐하면 컴퓨터가 인식하기에는 전부 다른 단어들이기 때문이다.

3. 특수문자 제거의 부작용

특수 문자가 토큰화에 방해가 된다고 해서 모든 특수 문자를 제거하는 규칙을 넣는다면?

원본: "He has a Ph.D in computer science."
특수문자 제거 후: "He has a Ph D in computer science."

토큰화 결과:
원본: ["He", "has", "a", "Ph.D", "in", "computer", "science", "."]
제거 후: ["He", "has", "a", "Ph", "D", "in", "computer", "science"]

Ph.DPh D - 특수 문자 제거로 인해 본래 의미를 상실하는 경우가 발생한다.

4. 더 복잡한 사례들

- "U.S.A" vs "USA" vs "U S A"
- "don't" vs "do not" vs "dont"  
- "New York" vs "New-York" vs "NewYork"
- "COVID-19" vs "COVID 19" vs "COVID19"
- "machine-learning" vs "machine learning"

각각은 같은 의미를 담고 있지만, 토큰화 결과는 완전히 다르다.

5. 언어별 특수성

한국어:
"안녕하세요" vs "안녕 하세요" vs "안녕하 세요"
"먹었습니다" → ["먹", "었", "습니다"] vs ["먹었습니다"]

영어:
"state-of-the-art" → ["state", "of", "the", "art"] vs ["state-of-the-art"]

결론: 섬세한 규칙 설계의 필요성

  • 단어 토큰화 작업은 상당히 섬세한 규칙을 설계해야만 한다.

  • 단순히 공백으로 나누는 것으로는 해결되지 않으며, 다음과 같은 요소들을 종합적으로 고려해야 한다:

  • 도메인 특성: 의학, 법률, 소셜미디어 등

  • 언어 특성: 형태소, 문법 구조

  • 목적: 번역, 감정분석, 검색 등

  • 일관성: 동일한 규칙의 지속적 적용

이러한 복잡성 때문에 최근에는 서브워드 토큰화 방법들이 주목받고 있다.

3.2.3 서브워드 토큰화 (Subword Tokenization)

단어보다 작은 단위로 분할하는 방법으로, 최근 딥러닝 모델에서 널리 사용된다.

3.2.3.1 Byte Pair Encoding (BPE)

가장 빈번하게 등장하는 문자 쌍을 반복적으로 병합하는 방법이다.

과정: 1. 모든 단어를 문자 단위로 분할 2. 가장 빈번한 문자 쌍 찾기 3. 해당 쌍을 하나의 토큰으로 병합 4. 원하는 어휘 크기까지 반복

예시:

초기: ["l", "o", "w", "e", "s", "t"]
1단계: ["lo", "w", "e", "s", "t"]    # "l"+"o" 병합
2단계: ["low", "e", "s", "t"]        # "lo"+"w" 병합
3단계: ["low", "es", "t"]            # "e"+"s" 병합
최종: ["low", "est"]                 # "es"+"t" 병합

3.2.3.2 WordPiece

Google에서 개발한 방법으로, BERT 등에서 사용된다.

특징: - 가능도(likelihood)를 최대화하는 방향으로 병합 - “##” 접두사로 서브워드 표시

예시:

"playing" → ["play", "##ing"]
"walked" → ["walk", "##ed"]

3.2.3.3 SentencePiece

언어에 독립적인 토큰화 방법이다.

특징: - 공백도 특수 문자로 처리 - 다양한 언어에 적용 가능 - 전처리 없이 raw text 직접 처리

3.3 토큰화 도구와 라이브러리

  • 앞서 살펴본 토큰화의 복잡성과 다양한 예외 상황들을 고려할 때, 개발자가 직접 상세한 규칙을 만들어 구현하려 하지 말고 이미 잘 개발되고 검증된 패키지들을 사용하는 것이 현명한 접근법이다.
  • 기존에 검증된 패키지로 처리 불가한 예외적인 부분들만 커스터마이징해서 처리하면 된다.

3.3.1 영어 토큰화 도구

3.3.1.1 단어 토큰화: TreebankWordTokenizer

Penn Treebank 코퍼스의 토큰화 규칙을 따르는 검증된 도구이다.

from nltk.tokenize import TreebankWordTokenizer

tokenizer = TreebankWordTokenizer()
text = "He said, \"I can't believe it's working!\" Dr. Smith agreed."
tokens = tokenizer.tokenize(text)
print(tokens)
# ['He', 'said', ',', '``', 'I', 'ca', "n't", 'believe', 'it', "'s", 'working', '!', "''", 'Dr.', 'Smith', 'agreed', '.']

장점: - 축약형을 적절히 분리 (“can’t” → “ca”, “n’t”) - 인용문 처리 ( 와 ’’ 로 변환) - 약어 보존 (“Dr.” 유지) - 수십 년간 검증된 규칙

3.3.1.2 문장 토큰화: NLTK Sentence Tokenizer

from nltk.tokenize import sent_tokenize

text = "Dr. Smith earned his Ph.D. from MIT. He works at NASA. Contact him at john.doe@company.com."
sentences = sent_tokenize(text)
print(sentences)
# ['Dr. Smith earned his Ph.D. from MIT.', 'He works at NASA.', 'Contact him at john.doe@company.com.']

특징: - 약어 목록을 내장하여 문맥 고려 - 이메일 주소 내 마침표 구분 - 다양한 언어 지원

3.3.2 한국어 토큰화 도구

3.3.2.1 문장 토큰화: KSS (Korean Sentence Splitter)

한국어 문장 분할에 특화된 고성능 라이브러리이다.

import kss

text = "안녕하세요. 제 이메일은 user@domain.co.kr입니다. 연락 주세요!"
sentences = kss.split_sentences(text)
print(sentences)
# ['안녕하세요.', '제 이메일은 user@domain.co.kr입니다.', '연락 주세요!']

장점: - 한국어 특화 규칙 - 이메일, URL 등 특수 패턴 인식 - 높은 정확도와 빠른 처리 속도

3.3.2.2 단어 토큰화: KoNLPy 생태계

from konlpy.tag import Okt, Komoran, Hannanum

# Okt (Open Korean Text)
okt = Okt()
text = "아버지가방에들어가신다"
tokens = okt.morphs(text)
print(tokens)
# ['아버지', '가', '방', '에', '들어가', '신다']

# Komoran
komoran = Komoran()
tokens = komoran.morphs(text)
print(tokens)
# ['아버지', '가', '방', '에', '들어가', '시', 'ㄴ다']

3.3.3 다국어 및 고급 토큰화 도구

3.3.3.1 spaCy

산업 수준의 NLP 라이브러리

import spacy

# 영어
nlp_en = spacy.load("en_core_web_sm")
doc = nlp_en("Dr. Smith's email is john@company.com. He earned his Ph.D. in 1995.")
sentences = [sent.text for sent in doc.sents]
tokens = [token.text for token in doc]

# 한국어 (spacy-korean)
nlp_ko = spacy.load("ko_core_news_sm")
doc = nlp_ko("안녕하세요. 저는 데이터 과학자입니다.")
sentences = [sent.text for sent in doc.sents]

특징: - 다양한 언어 지원 - 빠른 처리 속도 - 통합된 NLP 파이프라인 - 산업 환경에 최적화

3.3.3.2 Transformers 토크나이저

최신 딥러닝 모델에서 사용되는 서브워드 토큰화이다.

from transformers import AutoTokenizer

# BERT 토크나이저
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
text = "Hello, I can't believe it's working!"
tokens = tokenizer.tokenize(text)
print(tokens)
# ['hello', ',', 'i', 'can', "'", 't', 'believe', 'it', "'", 's', 'working', '!']

# 한국어 BERT
tokenizer_ko = AutoTokenizer.from_pretrained("klue/bert-base")
text = "안녕하세요. 한국어 토큰화입니다."
tokens = tokenizer_ko.tokenize(text)
print(tokens)
# ['안녕', '##하세요', '.', '한국어', '토큰', '##화', '##입니다', '.']

3.3.4 도메인별 특화 도구

3.3.4.1 소셜미디어: TweetTokenizer

from nltk.tokenize import TweetTokenizer

tknzr = TweetTokenizer(strip_handles=True, reduce_len=True)
text = "@user This is sooooo cool! 😊 http://example.com #NLP"
tokens = tknzr.tokenize(text)
print(tokens)
# ['This', 'is', 'sooo', 'cool', '!', '😊', 'http://example.com', '#NLP']

3.3.4.2 의학/과학 텍스트: SciSpaCy

import spacy
import scispacy

nlp = spacy.load("en_core_sci_sm")
text = "The patient has a temperature of 101.5°F. Administer 2.5mg of medication."
doc = nlp(text)
sentences = [sent.text for sent in doc.sents]

3.3.5 언어별 권장 도구 조합

3.3.5.1 영어

# 실용적인 영어 처리 파이프라인
from nltk.tokenize import sent_tokenize, TreebankWordTokenizer

def process_english_text(text):
    # 1. 문장 분할
    sentences = sent_tokenize(text)
    
    # 2. 단어 토큰화
    word_tokenizer = TreebankWordTokenizer()
    tokenized_sentences = []
    for sentence in sentences:
        words = word_tokenizer.tokenize(sentence)
        tokenized_sentences.append(words)
    
    return sentences, tokenized_sentences

3.3.5.2 한국어

# 실용적인 한국어 처리 파이프라인
import kss
from konlpy.tag import Okt

def process_korean_text(text):
    # 1. 문장 분할
    sentences = kss.split_sentences(text)
    
    # 2. 형태소 분석
    okt = Okt()
    tokenized_sentences = []
    for sentence in sentences:
        morphs = okt.morphs(sentence)
        tokenized_sentences.append(morphs)
    
    return sentences, tokenized_sentences

3.3.6 성능과 정확도 비교

3.3.6.1 처리 속도 (상대적 비교)

  • spaCy: 매우 빠름 (산업용)
  • KSS: 빠름 (한국어 특화)
  • TreebankWordTokenizer: 보통
  • KoNLPy: 보통-느림 (정확도 높음)

3.3.6.2 정확도 (도메인별)

  • 일반 텍스트: spaCy, NLTK
  • 소셜미디어: TweetTokenizer
  • 학술/의학: SciSpaCy
  • 한국어: KSS + KoNLPy

3.3.7 선택 기준

3.3.7.1 프로젝트 요구사항별 선택

  1. 프로토타이핑: NLTK (간편함)
  2. 제품 환경: spaCy (속도와 안정성)
  3. 한국어 중심: KSS + KoNLPy
  4. 딥러닝 모델: Transformers 토크나이저
  5. 특수 도메인: 도메인별 특화 도구

3.3.7.2 실무 권장사항

# 범용적인 다국어 처리 환경 구축
import spacy
import kss
from transformers import AutoTokenizer

class UniversalTokenizer:
    def __init__(self):
        self.en_nlp = spacy.load("en_core_web_sm")
        self.bert_tokenizer = AutoTokenizer.from_pretrained("bert-base-multilingual-cased")
    
    def tokenize_sentences(self, text, language='auto'):
        if language == 'ko':
            return kss.split_sentences(text)
        elif language == 'en':
            doc = self.en_nlp(text)
            return [sent.text for sent in doc.sents]
        else:
            # 자동 언어 감지 로직
            return self._auto_detect_and_tokenize(text)
    
    def tokenize_for_model(self, text):
        return self.bert_tokenizer.tokenize(text)

3.3.8 결론

  • 토큰화는 복잡한 언어학적 문제이므로, 수년간 연구되고 검증된 도구들을 활용하는 것이 가장 효율적이고 안정적인 접근법이다.
  • 각 도구의 특성을 이해하고 프로젝트의 요구사항에 맞는 적절한 조합을 선택하는 것이 성공적인 NLP 프로젝트의 첫걸음이다.

3.4 토큰화의 도전과제

3.4.1 언어별 특성

한국어: - 어미 변화가 복잡 - 띄어쓰기 규칙이 일관되지 않음 - 복합어 처리 어려움

영어: - 축약형 처리 (예: “don’t”, “I’m”) - 하이픈으로 연결된 단어 - 대소문자 처리

3.4.2 도메인별 특수성

소셜미디어: - 이모티콘과 이모지 - 해시태그와 멘션 - 비표준 언어 사용

의학/법률 텍스트: - 전문 용어 - 약어와 기호 - 정확성이 중요

3.4.3 Vocabulary

  • Vocabulary란 텍스트를 토큰화하고, 고유한 토큰들로 이루어진 집합으로 쉽게 말해 기계가 알고있는 단어들의 집합이다.
  • 기계가 텍스트를 처리하기 위해서는 이를 숫자 형태로 변환하는 과정이 필요하다.
  • 이를 위해 먼저 텍스트를 토큰화하고, 토큰을 숫자로 매핑하는 과정이 필요하다.
    1. 텍스트를 의미 있는 단위인 토큰으로 분할하고(토큰화),
    2. 각 고유 토큰에 숫자(정수 인덱스 등)를 부여하여 어휘집(Vocabulary)을 구축한 후,
    3. 이 어휘집을 바탕으로 원래의 토큰 시퀀스를 숫자 시퀀스로 변환하는 단계를 포함합니다.
  • 이렇게 매핑된 숫자를 통해 기계가 텍스트를 이해할 수 있도록 한다.

3.4.4 Out-of-Vocabulary (OOV) 문제

문제: - 모델이 학습한 어휘집(Vocabulary)에 포함되지 않은 단어가 입력으로 들어올 때 발생 - 이는 특히 다음과 같은 경우에 문제가 된다: - 새로운 단어: 신조어, 기술 용어, 브랜드 이름 등 - 오타 및 비표준 표현: 사용자의 입력 실수나 비공식적인 언어 사용 - 다양한 언어적 변형: 복합어, 축약형, 방언 등 - OOV 단어가 포함된 문장을 제대로 이해하지 못하거나, 잘못된 예측을 할 수 있다.

해결 방안: - 서브워드 토큰화 사용 - 최근 가장 널리 사용되는 방법 중 하나로, 다양한 자연어 처리 모델에서 효과적으로 활용되고 있다. - 이 방법들은 단어를 더 작은 의미 단위로 분할하여 처리하므로, 새로운 단어가 등장하더라도 부분적으로 이해할 수 있다. - 문자 단위 처리 - 단어를 문자 단위로 분할하여 처리하는 방법도 있다. - 이는 모든 단어를 개별 문자로 분해하여 처리하므로, OOV 문제를 근본적으로 해결할 수 있다. - 그러나 이 방법은 문맥 이해가 어려워질 수 있다. - 사전 확장 - 지속적으로 어휘집을 업데이트하여 새로운 단어를 포함시키는 방법. - 이는 시간이 지남에 따라 어휘집을 확장하여 OOV 문제를 줄일 수 있다.

3.5 평가 메트릭

3.5.1 어휘 크기 (Vocabulary Size)

  • 모델의 메모리 사용량과 직결
  • 너무 크면 비효율적, 너무 작으면 표현력 부족

3.5.2 압축률 (Compression Rate)

  • 원본 텍스트 대비 토큰 수의 비율
  • 효율적인 표현을 위해 중요

3.5.3 의미 보존도

  • 토큰화 후에도 원래 의미가 유지되는 정도
  • 정성적 평가가 주로 사용됨

3.6 실제 적용 사례

3.6.1 기계 번역

  • 다국어 처리를 위한 공통 서브워드 어휘
  • 언어 간 토큰 정렬

3.6.2 감정 분석

  • 감정을 나타내는 키워드 보존
  • 이모티콘과 특수 문자 처리

3.6.3 질의응답 시스템

  • 질문과 답변의 일관된 토큰화
  • 개체명 인식과의 연계

3.7 최신 동향

3.7.1 다국어 토큰화

  • mBERT, XLM-R 등 다국어 모델
  • 언어별 특성을 고려한 통합 토큰화

3.7.2 적응형 토큰화

  • 도메인별 최적화
  • 동적 어휘 확장

3.7.3 신경망 기반 토큰화

  • 학습 가능한 토큰화
  • End-to-end 학습

3.8 결론

  • 토큰화는 자연어 처리의 첫 단계이자 전체 성능을 좌우하는 중요한 과정.
  • 언어의 특성과 도메인의 요구사항을 고려하여 적절한 토큰화 방법을 선택하는 것이 중요.
  • 최근에는 서브워드 토큰화가 주류가 되었지만, 여전히 각 방법의 장단점을 이해하고 상황에 맞게 적용하는 것이 필요.

Subscribe

Enjoy this blog? Get notified of new posts by email: