영어 vs 한국어 문장 나누기(토큰화) 핵심 차이점
결론부터 말하면, 문장을 의미 단위로 나눌 때 영어는 '띄어쓰기'가 기준이 되는 반면, 한국어는 '형태소'가 기준이 됩니다. 그 이유는 두 언어의 구조적 특성이 다르기 때문입니다.
1. 영어: 띄어쓰기 중심의 분리 (Spacing is Key)
영어는 띄어쓰기 단위로 단어를 구분해도 대부분 그 단어가 독립적인 의미를 가집니다.
- you / going / to / be / there / today
물론 슬라이드의 예시처럼 gonna를 going to로 바꾸는 등의 정규화는 필요하지만, 기본적인 의미 단위는 띄어쓰기로 충분히 나눌 수 있습니다. 이를 '어절(Word)' 단위 토큰화라고 하며, 영어는 이 방식이 매우 효과적입니다.
시험 Point: 영어 문장 나누기의 기본 단위는? 띄어쓰기로 구분된 단어(어절)
2. 한국어: 형태소 중심의 분리 (Morpheme is Key)
한국어는 띄어쓰기만으로 의미를 제대로 파악하기 어렵습니다. 왜냐하면 한국어는 교착어(agglutinative language), 즉 조사, 어미 등이 명사나 동사 어간에 붙어서 문법적 기능을 하는 언어이기 때문입니다.
슬라이드의 예시를 봅시다: "한나가 책을 보았다."
이 문장을 띄어쓰기로만 나누면 ["한나가", "책을", "보았다"] 세 개의 덩어리(어절)가 나옵니다. 하지만 컴퓨터가 '한나가'와 '한나는'을 다른 단어로 인식하면 안 되겠죠? 진짜 의미를 알기 위해선 더 작은 단위인 **형태소(morpheme)**로 쪼개야 합니다.
형태소란? 의미를 가지는 가장 작은 말의 단위입니다.
"한나가 책을 보았다"는 다음과 같이 형태소로 나눌 수 있습니다. 한나 / 가 / 책 / 을 / 보 / 았 / 다
이 형태소들은 슬라이드에서 설명하는 두 가지 기준으로 다시 분류할 수 있습니다.
- 1) 혼자 쓸 수 있는가? (의존성)
- 자립 형태소: 혼자서도 의미를 가지며 쓰일 수 있는 형태소.
- 의존 형태소: 다른 말에 붙어야만 의미를 가지는 형태소.
- 예시: 가, 을(조사), 보(동사 어간), 았, 다(어미)
- 2) 실질적인 의미가 있는가? (의미 여부)
- 실질 형태소: 구체적인 대상이나 동작처럼 실질적인 의미를 나타내는 형태소.
- 형식(문법) 형태소: 문법적인 기능을 하는 형태소.
- 예시: 가(주격 조사), 을(목적격 조사), -았-(과거 시제), -다(종결 어미)
시험 Point: 한국어 문장 나누기의 기본 단위는? 의미를 가진 가장 작은 단위인 형태소(morpheme). 띄어쓰기 단위인 어절만으로는 부족하다.
최종 요약
| 구분 |
영어 |
한국어 |
| 언어 특성 |
굴절어 |
교착어 |
| 분리 기준 |
띄어쓰기 (어절) |
형태소 |
| 이유 |
단어 자체가 독립적인 의미를 가짐 |
명사, 동사에 조사, 어미가 붙어서 의미가 확장됨 |
| 예시 |
I love you → I / love / you |
나는 너를 사랑해 → 나 / 는 / 너 / 를 / 사랑하 / 아 |
토큰화(Tokenization) 완벽 정복
1. 토큰(Token)과 토큰화(Tokenization)란 무엇인가?
- 토큰 (Token): 자연어 처리(NLP)에서 의미를 가지는 최소 분석 단위입니다. 문장을 잘게 쪼갰을 때 나오는 각각의 조각이라고 생각하면 쉽습니다.
- 토큰화 (Tokenization): 주어진 문장이나 문서를 토큰(Token) 단위로 나누는 작업 전체를 말합니다. 컴퓨터가 텍스트를 이해하기 위한 가장 첫 번째 단계입니다. 이 작업을 수행하는 도구를 **토크나이저(Tokenizer)**라고 부릅니다.
2. 토큰의 단위: 무엇을 기준으로 쪼개는가?
토큰의 기준은 언어의 특성이나 분석 목적에 따라 달라집니다.
- 영어: 띄어쓰기 단위로 나눠도 큰 문제가 없어 주로 **어절(Word)**을 토큰으로 사용합니다.
- "I love you" → ['I', 'love', 'you']
- 한국어: '은', '는', '를' 같은 조사와 어미가 붙어있기 때문에, 어절 단위로 나누면 의미 분석이 어렵습니다. 따라서 **형태소(Morpheme)**를 토큰으로 주로 사용합니다.
- "나는 너를 사랑해" → ['나', '는', '너', '를', '사랑하', '아']
슬라이드의 예시(sentence.split())는 영어를 어절 단위로 분리하는 가장 간단한 토큰화 방법을 보여줍니다.
코드 예시 (어절 단위 분리):
sentence = "Thomas Jefferson began building Monticello at the age of 26."
# .split()은 띄어쓰기를 기준으로 문장을 나눕니다.
tokens = sentence.split()
# 결과: ['Thomas', 'Jefferson', 'began', ..., '26.']
이렇게 생성된 토큰들의 집합(중복 제거)을 **어휘집(vocabulary 또는 lexicon)**이라고 부릅니다.
3. [핵심] 토큰에 대한 중요한 관점 (주의사항)
시험에서 가장 중요하게 이해해야 할 부분입니다.
- 언어학적 의미 vs. NLP에서의 의미
- 전통 언어학: 토큰을 '최소 의미 단위' (예: 형태소)로 엄격하게 정의합니다.
- 자연어 처리 (NLP): 토큰을 **'분석을 위한 최소 연산 단위'**로 정의합니다. 즉, 모델이 처리하기 편하게 인위적으로 나눈 단위라는 의미가 더 강합니다.
- 토큰의 단위는 고정되어 있지 않다
- NLP에서 '토큰'은 꼭 어절이나 형태소만을 의미하지 않습니다. 분석 목적에 따라 다음과 같이 다양한 단위를 토큰으로 사용할 수 있습니다.
- 문장 단위 (Sentence Tokenization): 하나의 문서를 여러 문장 토큰으로 나눔
- 어절 단위 (Word Tokenization): 문장을 띄어쓰기 기준으로 단어 토큰으로 나눔
- 형태소 단위 (Morpheme Tokenization): 단어를 의미를 가진 최소 단위인 형태소 토큰으로 나눔
- 하위 단어 단위 (Subword Tokenization): preprocessing을 pre와 processing으로 나누는 것처럼, 단어보다 더 작은 단위로 토큰을 나눔 (최신 모델에서 주로 사용)
시험 Point: 자연어 처리(NLP)에서 토큰이란? **"텍스트를 쪼개어 컴퓨터가 연산하기 쉽게 만든 단위"**를 의미하며, 그 기준은 어절, 형태소, 하위 단어 등 목적에 따라 유연하게 달라질 수 있다.
최종 요약
- 토큰화란? 문장을 **분석의 최소 단위(토큰)**로 쪼개는 작업.
- 영어 토큰화: 주로 어절(띄어쓰기) 단위.
- 한국어 토큰화: 주로 형태소 단위.
- NLP에서의 토큰: 언어학적 최소 의미 단위라기보다는, 컴퓨터의 연산을 위한 실용적인 최소 단위이며, 그 기준은 분석 목적에 따라 달라질 수 있다.
규칙 기반 토큰화(Rule-based Tokenization) 완벽 정복
1. 규칙 기반 토큰화란?
규칙 기반 토큰화는 이름 그대로, 사람이 직접 만든 명시적인 규칙에 따라 텍스트를 토큰으로 나누는 가장 단순하고 직관적인 방법입니다.
- 핵심 개념: "이런 규칙을 만나면 단어를 나눠라!"라고 미리 정해두는 것입니다.
- 대표적인 규칙:
- 공백/띄어쓰기 기준 분리: 가장 흔한 규칙입니다.
- 구두점 기준 분리: 쉼표(,), 마침표(.) 등을 기준으로 나눕니다.
- 파이썬 코드: sentence.split() 함수가 바로 공백을 기준으로 텍스트를 나누는 대표적인 규칙 기반 토큰화 도구입니다.
2. 장점과 단점
이 방법은 간단한 만큼 명확한 장단점을 가집니다.
👍 장점
- 매우 간단한 구현: split() 함수 하나로 구현될 만큼 매우 쉽고 빠릅니다.
- 소규모/정형 데이터에 적합: 데이터가 복잡하지 않고 규칙이 잘 통하는 경우 효과적입니다.
👎 단점
- 모든 규칙을 고려하기 어려움: 아포스트로피(')나 하이픈(-) 같은 예외적인 규칙을 모두 사람이 만들기는 거의 불가능합니다.
- 신조어/줄임말에 취약: "핵인싸", "어쩔티비" 같은 신조어가 등장할 때마다 계속해서 규칙을 수동으로 추가해줘야 합니다.
- 복잡한 언어에 취약: 조사가 발달한 한국어는 단순히 띄어쓰기로만 나누면 "철수가"와 "철수는"을 다른 단어로 인식하는 등 문제가 발생합니다.
- Out-of-Vocabulary (OOV) 문제 발생: 가장 치명적인 단점입니다. (아래에서 상세 설명)
3. [시험 핵심] OOV (Out-of-Vocabulary) 문제
OOV란, 내가 가진 어휘집(Vocabulary, Lexicon)에 없는 새로운 단어를 만나 처리할 수 없는 문제를 말합니다.
- 발생 원인: 규칙 기반 토큰화는 미리 만들어 놓은 단어 목록(어휘집)을 기준으로 토큰을 인식합니다. 이 목록에 없는 단어는 "처음 보는 단어"가 되어버립니다.
- 예시: 내 어휘집에 '서울', '한강', '맛집'은 있어도 '서울한강맛집'이라는 복합 명사나 '저메추(저녁 메뉴 추천)' 같은 신조어는 없을 가능성이 높습니다.
- 해결 방법: 보통 이런 단어들은 무시하거나, 하나의 특별한 토큰, 즉 <UNK> (Unknown) 토큰으로 모두 치환해버립니다. 하지만 이 경우 원래 단어가 가진 소중한 의미 정보를 잃어버리게 됩니다.
OOV 문제의 근본적인 해결책: 슬라이드의 핵심 메시지처럼, 사람이 미리 어휘집을 다 만들어두는 것은 한계가 명확합니다. 따라서 "데이터를 기반으로 컴퓨터가 동적으로 어휘집을 만들고 토큰화를 수행하자!" 라는 아이디어가 나오게 되었고, 이것이 바로 통계 기반 토큰화(BPE 등)의 시작입니다.
최종 요약
| 구분 |
내용 |
| 정의 |
**사람이 만든 규칙(띄어쓰기, 구두점 등)**으로 텍스트를 분할하는 방식 |
| 장점 |
구현이 매우 간단하고 빠름 |
| 단점 |
예외 처리의 어려움, 신조어에 취약, 한국어 같은 복잡한 언어에 부적합 |
| 가장 큰 문제점 |
OOV (Out-of-Vocabulary) 문제: 어휘집에 없는 단어는 의미를 잃고 <UNK> 토큰으로 처리됨 |
BPE (Byte Pair Encoding) 완벽 정복
1. 왜 서브워드(Subword) 토큰화가 필요한가? (제안 동기)
기존의 단어(어절) 단위 토큰화는 OOV(Out-of-Vocabulary), 즉 어휘집에 없는 희귀어나 신조어를 처리하지 못하는 치명적인 문제가 있었습니다.
서브워드 토큰화는 이 문제를 해결하기 위해 등장했습니다. 단어를 더 작은 단위인 **'서브워드(Subword)'**로 쪼개면, 처음 보는 단어라도 이미 학습한 서브워드들의 조합으로 표현할 수 있습니다.
- 예시: Abwasserbehandlungsanlage (독일어: 하수 처리장)
- 단어 단위로는 처음 보는 단어(OOV)일 수 있지만,
- 서브워드 단위 Abwasser / behandlungs / anlage 로 쪼개면 각각 '폐수', '처리', '시설'이라는 의미로 번역이 가능합니다.
2. BPE의 핵심 아이디어: 데이터 기반 압축
BPE는 원래 데이터 압축 기술에서 유래한 알고리즘으로, 가장 빈번하게 등장하는 글자 쌍(pair)을 찾아 하나로 합치는 작업을 반복합니다.
- Rule-based가 아닌 Data-driven: 사람이 규칙을 정하는 게 아니라, 주어진 텍스트 데이터의 통계적 특성을 바탕으로 컴퓨터가 스스로 토큰화 규칙(어휘집)을 만듭니다.
- 효율적인 표현:
- 자주 쓰이는 단어 (예: love)는 통째로 하나의 짧은 토큰이 됩니다.
- 드물게 쓰이는 단어 (예: hugging)는 hugg + ing 처럼 여러 개의 서브워드 토큰으로 나뉩니다.
- 결과: 고정된 크기의 어휘집으로도 모든 단어를 표현할 수 있게 되어 OOV 문제가 해결됩니다.
3. BPE 알고리즘의 작동 방식
BPE는 크게 **(1) 학습(어휘집 구축)**과 (2) 토큰화(분해) 두 단계로 나뉩니다.
1단계: 학습 - 서브워드 어휘집 만들기
이 단계는 어떤 글자 쌍을 합칠지에 대한 병합 규칙(merge rule) 목록을 만드는 과정입니다.
- 초기화: 모든 단어를 글자(character) 단위로 분해하고, 단어의 끝을 표시하는 특별 토큰(예: </w>)을 추가합니다.
- low, lower, lowest → l, o, w, </w>, l, o, w, e, r, </w>, l, o, w, e, s, t, </w>
- 빈도 계산: 텍스트 전체에서 가장 자주 등장하는 글자 쌍(pair)의 빈도를 계산합니다.
- 병합: 빈도가 가장 높은 쌍을 찾아 하나의 새로운 서브워드로 합칩니다.
- 만약 (e, s)가 가장 빈도가 높았다면, es라는 새로운 서브워드를 만들고 어휘집에 추가합니다.
- 반복: 2번과 3번 과정을 미리 정해둔 횟수(hyperparameter)만큼 반복합니다.
- l, o, w, e, s, t, </w> → lo, w, e, s, t, </w> → low, e, s, t, </w> → lowes, t, </w> ...
2단계: 토큰화 - 새로운 단어 분해하기
학습 단계에서 만든 병합 규칙들을 사용해, 새로운 단어가 들어왔을 때 서브워드로 분해합니다.
- 초기화: 새로운 단어도 일단 글자 단위로 분해합니다.
- lowest → l, o, w, e, s, t, </w>
- 규칙 적용: 학습된 병합 규칙을 우선순위대로 탐욕적(Greedy)으로 적용하여 가능한 가장 긴 서브워드를 만듭니다.
- 만약 (l,o)→lo, (lo,w)→low, (e,s)→es, (es,t)→est 순으로 규칙을 배웠다면, lowest는 low + est + </w> 로 토큰화됩니다.
- 최악의 경우(만약 어휘집에 글자조차 없다면): 그래도 분해가 안 되면 최종적으로는 글자 단위로 처리됩니다. (그래서 OOV가 거의 없음)
4. BPE의 장점과 단점
| 👍 장점 |
👎 단점 |
| OOV 문제 최소화: 희귀 단어, 신조어도 서브워드 조합으로 표현 가능 |
의미 왜곡 가능성: meaningless가 meaning+less가 아닌 mean+ingless처럼 의미와 무관하게 분해될 수 있음 |
| 데이터 기반 학습: 사람이 규칙을 만들 필요 없음 |
계산 오버헤드: 학습 과정에서 반복적인 계산이 오래 걸릴 수 있음 |
| 압축 효과: 자주 쓰는 단어는 짧게, 드문 단어는 길게 효율적으로 표현 |
하이퍼파라미터 의존: 병합 횟수나 어휘집 크기에 따라 성능이 달라짐 |
| 복잡한 형태소 분석 불필요 |
한국어 등 교착어에 한계: 형태소 구조가 복잡한 언어에서는 최적의 성능을 내기 어려울 수 있음 |
| GPT 개선: 모든 문자를 UTF-8 바이트로 변환하여 토큰화하면 모든 언어와 기호를 예외 없이 처리 가능 |
직관적 해석의 어려움: 분해된 토큰이 사람이 이해하기 어려울 수 있음 |
WordPiece 토큰화 완벽 정복 (BPE와 비교)
WordPiece는 BERT와 같은 구글의 언어 모델에서 주로 사용하는 서브워드 토큰화 방식입니다. BPE와 매우 유사하지만, 어떤 글자 쌍을 합칠지 결정하는 기준에서 결정적인 차이를 보입니다.
1. 핵심 아이디어: 무엇이 BPE와 다른가?
- BPE (Byte Pair Encoding): 단순히 텍스트에서 가장 자주 나오는 글자 쌍을 합칩니다. (단순 빈도수 기준)
- WordPiece: 글자 쌍을 합쳤을 때, 언어 모델의 확률(Likelihood)을 가장 높이는 쌍을 합칩니다. (확률 기반)
이게 무슨 의미일까요? WordPiece는 단순히 자주 등장하는 것을 넘어, 합쳤을 때 단어의 전체적인 완성도를 높이고 언어적으로 더 자연스러운 패턴이 되는 조합을 우선시합니다. 이 때문에 un-, -able, -ing 처럼 의미를 가진 접두사나 접미사가 하나의 토큰으로 생성되는 경향이 강합니다.
시험 Point: BPE와 WordPiece의 가장 큰 차이점은? 병합 기준이다. BPE는 '빈도수', WordPiece는 **'확률(Likelihood)'**을 기준으로 글자 쌍을 합친다.
2. WordPiece 알고리즘의 작동 방식
알고리즘의 전체적인 흐름은 BPE와 같지만, '병합 후보 탐색' 단계가 다릅니다.
1단계: 학습 - 서브워드 어휘집 만들기
- 초기화: 모든 단어를 글자(character) 단위로 분해합니다.
- 병합 후보 탐색: 현재 어휘집에 있는 모든 글자 쌍 조합에 대해, 그 쌍을 합쳤을 때 Likelihood가 얼마나 증가하는지를 모두 계산합니다.
- 병합: 계산된 Likelihood 증가량이 가장 높은 글자 쌍을 선택하여 하나의 새로운 서브워드로 합치고 어휘집에 추가합니다.
- 반복: 정해진 어휘집 크기가 될 때까지 2~3번 과정을 반복합니다.
2단계: 토큰화 - 새로운 단어 분해하기
BPE처럼, 학습된 규칙을 적용하여 가능한 가장 긴 서브워드 단위로 단어를 나눕니다.
- unaffordable → ['un', '##aff', '##ord', '##able']
여기서 ##는 매우 중요한 표시입니다.
3. BPE와의 최종 비교 및 특징 요약
| 구분 |
공통점 |
| 작동 방식 |
글자 단위에서 시작 → 자주 등장하는 쌍을 병합하여 어휘집 생성 → OOV 문제 해결 |
| 구분 |
차이점 |
BPE |
WordPiece |
| 병합 기준 |
💯 |
단순 빈도 (가장 많이 나온 쌍) |
확률(Likelihood) (합쳤을 때 가장 자연스러운 쌍) |
| 단어 경계 표시 |
📝 |
단어의 끝을 표시 (예: low</w>) |
단어의 시작이 아님을 표시 (예: low, ##er) |
WordPiece의 장점과 단점 (BPE 대비)
- 👍 장점: 확률 기반으로 병합하기 때문에, 접두사/접미사와 같이 언어학적으로 의미 있는 단위로 토큰이 생성될 가능성이 높습니다.
- 👎 단점: 모든 후보 쌍의 Likelihood를 계산해야 하므로 계산 비용이 높고 구현이 복잡합니다. 이 때문에 최근의 몇몇 모델들은 구현이 더 간단한 BPE를 다시 채택하는 경향도 있습니다.
한국어 토큰화 완벽 정복
1. 왜 한국어 토큰화는 어려운가?
영어는 띄어쓰기만으로 단어를 나눠도 되지만, 한국어는 교착어이기 때문에 문제가 복잡합니다. '학생'이라는 명사에 '이', '은', '을' 같은 조사가 붙고, '읽었다'는 '읽-', '-었-', '-다'처럼 어간과 어미가 결합합니다. 이 때문에 단순히 띄어쓰기로 자르면 의미 분석이 어려워, 특별한 접근법이 필요합니다.
한국어 토큰화에는 크게 형태소 분석기 기반 접근과 Subword 기반 접근, 두 가지 방식이 있습니다.
2. 접근법 (1): 형태소 분석기 기반 (언어학적 접근)
이 방식은 언어학적 지식을 활용해 문장을 **의미를 가진 가장 작은 단위인 '형태소'**로 분리하는 방법입니다.
- 작동 방식: 사람이 만든 문법 규칙(Rule-based)과 통계 모델(확률 모델)을 함께 사용하여 형태소를 분석합니다.
- 토큰화 예시:
- 학생이 책을 읽었다 → ['학생', '이', '책', '을', '읽', '었', '다']
- 👍 장점:
- 언어학적 해석 가능: 분리된 토큰(학생, 책 등)이 명확한 의미를 가져 사람이 직관적으로 이해하기 쉽습니다.
- 👎 단점:
- 느린 속도: 복잡한 문법 규칙을 적용해야 해서 속도가 느립니다.
- 일반화 어려움: 특정 분야(도메인)의 신조어나 은어에 취약하며, OOV(미등록 단어) 문제가 발생할 수 있습니다.
- 대표적인 분석기: Mecab-ko, Okt(Opean Korean Text), Komoran
3. 접근법 (2): Subword 기반 (데이터 중심 접근) - SentencePiece
이 방식은 언어학적 지식 없이, 데이터 자체의 통계적 특성만을 이용해 텍스트를 분리합니다. 대표적으로 SentencePiece가 있습니다.
SentencePiece의 핵심 아이디어
기존 BPE나 WordPiece는 먼저 텍스트를 띄어쓰기로 나눈 뒤 서브워드를 학습했습니다. 이 방식은 중국어나 일본어처럼 띄어쓰기가 없는 언어에서는 사용하기 어렵다는 문제가 있었죠.
SentencePiece는 이 문제를 해결하기 위해, 문장을 그냥 하나의 긴 글자 덩어리(Raw text)로 보고, 띄어쓰기(공백)까지도 일반 글자처럼 취급하여 토큰화 규칙을 학습합니다.
- 언어 독립적(Language-independent): 띄어쓰기 규칙에 의존하지 않으므로 어떤 언어에도 바로 적용할 수 있습니다.
- 공백 처리: 공백을 (언더바) 기호로 치환하여 단어의 경계를 표현합니다.
- 토큰화 예시:
- 학생이 책을 읽었다 → [' 학생', '이', ' 책', '을', ' 읽', '었다']
- 👍 장점:
- OOV 문제 해결: 희귀 단어나 신조어도 글자 단위로 쪼개서 표현할 수 있습니다.
- 빠른 속도: 복잡한 문법 분석 없이 통계적으로 처리하므로 속도가 매우 빠릅니다.
- 대규모 학습에 적합: 대용량 데이터로 학습할 때 뛰어난 성능을 보입니다.
- 👎 단점:
- 언어학적 해석 불가능: 읽었다처럼 토큰 자체가 직관적인 의미를 갖지 않는 경우가 많습니다.
- 주로 사용되는 모델: SentencePiece, KoBERT, KoGPT
최종 요약 (시험 핵심)
| 구분 |
형태소 분석기 기반 |
Subword 기반 (SentencePiece) |
| 핵심 원리 |
언어학적 지식 (문법 규칙) |
데이터 통계 |
| 분리 단위 |
형태소 (의미 단위) |
서브워드 (통계 단위) |
| 장점 |
결과 해석이 직관적 |
속도 빠름, OOV 해결, 범용성 높음 |
| 단점 |
속도 느림, 신조어 취약 |
결과 해석이 어려움 |
| 대표 예시 |
Mecab-ko, Okt, Komoran |
SentencePiece, KoBERT, KoGPT |
결론적으로, 직관적인 의미 분석이 중요하다면 형태소 분석기를, 대규모 데이터 처리와 모델 성능이 중요하다면 Subword 방식을 사용한다고 이해하시면 됩니다.
NLTK (영어) & KoNLPy (한국어) 토큰화 완벽 정복
NLTK와 KoNLPy는 각각 영어와 한국어 자연어 처리를 위한 대표적인 파이썬 라이브러리입니다. 이 라이브러리들을 사용하면 복잡한 토큰화와 품사 태깅을 손쉽게 수행할 수 있습니다.
1. NLTK를 이용한 영어 토큰화 및 품사 태깅
NLTK(Natural Language Toolkit)는 영어 텍스트 처리를 위한 강력한 도구 모음입니다.
- word_tokenize(): 문장을 단어(어절) 단위로 토큰화합니다. 단순히 띄어쓰기로 나누는 것을 넘어, 구두점(., ,)이나 's 같은 것도 의미 있는 단위로 분리해 줍니다.
- pos_tag(): 토큰화된 단어 목록에 대해 각 단어의 **품사(Part-of-Speech)**를 태깅합니다.
코드 예시 분석: "I am actively looking for Ph.D. students." 라는 문장이 있을 때,
- 단어 토큰화 결과: ['I', 'am', 'actively', ..., 'Ph.D.', 'students', '.']
- Ph.D.와 students를 각각의 토큰으로 잘 분리한 것을 볼 수 있습니다.
- 품사 태깅 결과: [('I', 'PRP'), ('am', 'VBP'), ..., ('students', 'NNS')]
- I는 PRP(대명사), am은 VBP(동사), students는 NNS(복수 명사)로 정확하게 품사를 찾아냅니다.
시험 Point: NLTK는 영어 문장을 단어(Word) 단위로 토큰화하고, 각 단어에 맞는 **품사(POS)**를 붙이는 데 사용됩니다.
2. KoNLPy를 이용한 한국어 토큰화 및 품사 태깅
KoNLPy는 한국어 자연어 처리를 위해 다양한 형태소 분석기를 모아놓은 라이브러리입니다. 슬라이드에서는 **Okt(Open Korean Text)**와 꼬꼬마(Kkma) 두 가지를 비교하고 있습니다.
주요 함수
- .morphs(): 문장을 형태소 단위로 토큰화합니다.
- .pos(): 문장을 형태소 단위로 나눈 뒤, 각 형태소에 품사를 태깅하여 튜플 (형태소, 품사) 형태로 보여줍니다.
- .nouns(): 문장에서 명사만 추출합니다.
형태소 분석기별 특징 비교
"열심히 코딩한 당신, 연휴에는 여행을 가봐요" 라는 문장을 두 분석기로 분석한 결과는 다릅니다. 이 차이점을 아는 것이 시험의 핵심입니다.
| 구분 |
Okt (Open Korean Text) |
꼬꼬마 (Kkma) |
| .morphs() (형태소 분석) |
['열심히', '코딩', '한', '당신', ...] |
['열심히', '코딩', '하', 'ㄴ', '당신', ...] |
| .pos() (품사 태깅) |
[('열심히', 'Adverb'), ('코딩', 'Noun'), ...] |
[('열심히', 'MAG'), ('코딩', 'NNG'), ('하', 'XSV'), ...] |
| .nouns() (명사 추출) |
['코딩', '당신', '연휴', '여행'] |
['코딩', '당신', '연휴', '여행'] (이 경우 결과 동일) |
| 특징 |
속도가 빠르고, 일반적인 소셜 미디어 글 등 정규화가 덜 된 텍스트 처리에 유용합니다. 비교적 간단하게 형태소를 분석합니다. |
분석 정확도가 높고, '하', 'ㄴ'처럼 매우 세밀하게 형태소를 분리합니다. 학술적인 분석이나 정확성이 중요할 때 주로 사용됩니다. |
결론 및 시험 Point:
- KoNLPy는 한국어 문장을 형태소 단위로 분석하는 라이브러리입니다.
- Okt는 속도가 빠르고 범용적으로 쓰기 좋습니다.
- Kkma는 정확성이 높고 더 세밀하게 형태소를 분리합니다.
- 어떤 형태소 분석기를 사용하느냐에 따라 토큰화 결과와 품사 태깅 결과가 달라질 수 있다는 점을 반드시 기억해야 합니다.
텍스트 후속 처리 완벽 정복
토큰화가 끝난 후, 모델의 학습 효율과 성능을 높이기 위해 토큰들을 한 번 더 정제하는 과정을 거칩니다. 주요 후속 처리 방법으로는 불용어 제거, 어간 추출(Stemming), **표제어 추출(Lemmatization)**이 있습니다.
1. 불용어(Stopwords) 제거
불용어란, 문장에 자주 등장하지만 분석에 큰 의미나 영향을 주지 않는 단어들을 말합니다.
- 정의: I, am, a, the, is, of 처럼 문법적인 기능을 하지만 핵심 의미는 없는 단어들입니다.
- 목적: 이런 단어들을 제거함으로써, 모델이 정말 중요한 단어에만 집중할 수 있도록 데이터의 노이즈를 줄이고 계산 효율을 높입니다.
- 작동 방식: 라이브러리(예: NLTK)에 미리 정의된 불용어 목록을 불러와, 토큰화된 문장에서 해당 단어들을 걸러내는 방식으로 작동합니다.
코드 예시 분석: "Family is not an important thing. It's everything." 이라는 문장에서,
- 제거 전: ['Family', 'is', 'not', 'an', 'important', ...]
- is, not, an, it's 등 불용어 제거 후: ['Family', 'important', 'thing', '.', "'s", 'everything', '.']
2. 어간 추출 (Stemming)
어간 추출은 단어에서 접사(접두사/접미사)를 잘라내고 단어의 핵심 부분인 **어간(Stem)**만 남기는 작업입니다.
- 정의: 형태학적 분석을 단순화하여, 단어의 어미를 기계적인 규칙에 따라 잘라내는 것입니다.
- 특징: 언어학적 지식을 고려하지 않고 단순히 규칙에 기반해 접사를 제거합니다. 이 때문에 결과물이 실제 사전에 없는 단어일 수 있습니다. (예: having → hav)
- 대표 알고리즘: 포터 알고리즘 (Porter Algorithm)
코드 예시 분석: ['formalize', 'allowance', 'electricical']
- 어간 추출 후: ['formal', 'allow', 'electric']
- formalize에서 -ize를, allowance에서 -ance를 잘라내 어간만 남깁니다.
3. 표제어 추출 (Lemmatization)
표제어 추출은 단어의 문법적인 형태(시제, 단/복수 등)를 고려하여 원형, 즉 **표제어(Lemma)**를 찾는 작업입니다.
- 정의: 단어의 **사전 등재형(기본형)**을 찾아냅니다.
- 특징: 품사(POS) 정보를 활용하여 문맥에 맞는 정확한 원형을 찾으므로 어간 추출보다 정교합니다. (예: am, are, is → be)
4. [시험 핵심] Stemming vs. Lemmatization 비교
두 방법의 차이를 아는 것이 시험의 핵심입니다.
| 구분 |
어간 추출 (Stemming) |
표제어 추출 (Lemmatization) |
| 핵심 원리 |
규칙 기반으로 접사 제거 |
사전 기반으로 단어 원형 찾기 |
| 언어학적 고려 |
❌ 고려하지 않음 |
✅ 고려함 (품사 정보 활용) |
| 결과물 |
사전에 없는 단어일 수 있음 (hav) |
사전에 있는 단어 (have) |
| 예시 am |
am |
be |
| 예시 having |
hav |
have |
| 속도/정확도 |
속도는 빠르지만, 정확도는 낮음 |
속도는 느리지만, 정확도는 높음 |
5. 한국어에서의 유의점
한국어에서 어간/표제어를 추출할 때는 불규칙 활용 때문에 더 복잡합니다.
- 규칙 활용: 어간의 모습이 변하지 않고 어미만 바뀜 (예: 잡다 → 잡고, 잡으니)
- 불규칙 활용: 어미가 붙을 때 어간의 모습이 바뀜 (예: 긋다 → 긋고, 그어서, 그어라)
이처럼 긋-이 그-로 바뀌는 불규칙 용언 때문에, 단순히 접미사를 잘라내는 규칙 기반 방식(Stemming)은 한국어에 적용하기 어렵고, 정교한 형태소 분석이 필수적입니다.
1. 후속 처리 (Post-processing) 최종 요약
후속 처리는 토큰화된 텍스트를 모델 학습에 더 적합한 형태로 만들기 위해 한 번 더 가공하는 단계입니다.
후속 처리 기법 비교 (시험 핵심)
| 기법 |
정의 |
예시 |
장점 |
단점 |
| 불용어(Stopwords) 제거 |
의미 정보가 거의 없는 단어(is, the, 은, 는 등)를 제거 |
is, the 제거 |
차원 축소, 효율 향상 |
의미 손실 가능성 (뉘앙스 사라짐) |
| 어간 추출(Stemming) |
단순 규칙으로 단어의 접사를 잘라 어간만 남김 |
studies → studi |
효율 향상 |
결과가 실제 단어가 아닐 수 있음 |
| 표제어 추출(Lemmatization) |
사전과 품사 정보를 활용해 단어의 **기본형(원형)**을 찾음 |
Studies (동사) → study |
실제 단어 도출 |
속도가 느림 |
⚠️ 현대 NLP에서의 중요도
슬라이드의 노란색 하이라이트가 핵심입니다. 위에서 설명한 후속 처리 기법들은 주로 전통적인 NLP 모델에서 사용되었습니다. BERT, GPT와 같은 최신 대규모 언어 모델(LLM)은 문맥을 스스로 파악하는 능력이 뛰어나기 때문에, 이러한 후속 처리를 잘 사용하지 않습니다. 오히려 불용어를 제거하거나 단어를 원형으로 바꾸면 문장의 미묘한 뉘앙스가 사라져 모델의 성능이 저하될 수 있습니다.
2. 정규 표현식 (Regular Expression) 완벽 정복
정규 표현식(Regex)은 복잡한 문자열 속에서 특정한 패턴을 찾아 처리하기 위해 사용하는 강력한 형식 언어입니다.
주요 기능
- 검색(Search): 이메일 주소, URL, 전화번호처럼 일정한 규칙을 가진 문자열을 찾아냅니다.
- 추출(Extract): 문자열에서 숫자만, 혹은 특정 부분만 잘라냅니다.
- 치환(Replace): 주민등록번호 뒷자리를 *로 바꾸는 것처럼, 특정 패턴을 다른 문자로 바꿉니다.
핵심 문법 (이것만은 꼭 외우세요!)
| 기호 |
설명 |
기호 |
설명 |
| . |
아무 문자 1개 (줄바꿈 제외) |
\d |
숫자 [0-9] |
| * |
앞 문자가 0번 이상 반복 |
\D |
숫자가 아닌 것 [^0-9] |
| + |
앞 문자가 1번 이상 반복 |
\w |
문자, 숫자, _ [a-zA-Z0-9_] |
| ? |
앞 문자가 0번 또는 1번 등장 |
\W |
문자, 숫자, _가 아닌 것 |
| [] |
괄호 안의 문자 중 하나 (e.g., [abc]) |
\s |
공백 문자 (띄어쓰기, 탭 등) |
| [^] |
괄호 안의 문자를 제외한 나머지 |
\S |
공백이 아닌 것 |
Python re 모듈 주요 함수
| 함수 |
설명 |
| re.findall(패턴, 문자열) |
패턴과 일치하는 모든 부분을 찾아 리스트로 반환 |
| re.search(패턴, 문자열) |
문자열 전체를 검색하여 첫 번째로 일치하는 객체를 반환 |
| re.sub(패턴, 바꿀문자, 문자열) |
패턴과 일치하는 부분을 다른 문자로 치환 |
| re.split(패턴, 문자열) |
패턴을 기준으로 문자열을 분리하여 리스트로 반환 |
정규 표현식을 이용한 토큰화 예시
정규 표현식은 토큰화를 더 정교하게 만드는 데 사용될 수 있습니다.
- RegexpTokenizer("[\w]+")
- 의미: \w(문자, 숫자)가 +(1번 이상 반복)되는 패턴을 하나의 토큰으로 간주합니다.
- 결과: 문장에서 구두점('.`)은 모두 버리고 오직 단어와 숫자만 추출합니다.
- RegexpTokenizer("\s+", gaps=True)
- 의미: \s (공백)이 +(1번 이상 반복)되는 패턴을 **토큰을 나누는 기준(gaps)**으로 삼습니다.
- 결과: split() 함수처럼 공백을 기준으로 문장을 토큰화합니다.