Natural Language Processing Theory : 텍스트 전처리와 토큰화(Text Preprocessing & Tokenization)
텍스트 전처리(Text Preprocessing)
자연어 처리란?에서 자연어 처리는 텍스트를 토큰의 나열로 받아 처리한다고 설명했습니다. 그러나 수집한 텍스트는 그대로 쓸 수 없습니다. HTML 태그가 섞여 있고, 같은 단어가 대소문자나 띄어쓰기만 다르게 적혀 있으며, 분석에 도움이 되지 않는 기호와 공백이 흩어져 있습니다.
텍스트 전처리(Text Preprocessing)는 이러한 원시 텍스트를 모델이 다루기 좋은 형태로 정리하는 과정입니다. 컴퓨터 비전에서 전처리 알고리즘이 이미지의 크기와 색상을 맞추는 역할을 했다면, 텍스트 전처리는 표기의 흔들림을 잠재우고 처리 단위를 정하는 역할을 합니다.
전처리의 품질은 이후 모든 단계의 상한을 정합니다. 같은 단어가 서로 다른 표기로 흩어져 있으면 모델은 그것들을 서로 다른 단어로 학습하므로 데이터가 사실상 쪼개지는 효과가 생깁니다. 반대로 지나친 전처리는 의미를 지웁니다. 어디까지 정리하고 어디부터 남길지는 과제에 따라 달라지며, 그 기준을 세우는 것이 전처리의 핵심입니다.
정제와 정규화(Cleaning & Normalization)
정제(Cleaning)는 텍스트에서 분석 대상이 아닌 것을 제거하는 작업입니다. 웹에서 수집한 텍스트의 HTML 태그와 URL, 이메일 주소, 반복된 공백과 줄바꿈, 깨진 문자 등이 대상입니다. 주로 정규 표현식(Regular Expression)으로 패턴을 지정해 걸러 냅니다.
정규화(Normalization)는 같은 뜻의 서로 다른 표기를 하나로 통일하는 작업입니다. 영어에서는 대소문자 통일이 대표적이며, “Apple”과 “apple”을 같은 단어로 묶습니다. 다만 회사 이름 “Apple”과 과일 “apple”처럼 대소문자가 뜻을 가르는 경우도 있으므로 무조건 적용할 수는 없습니다.
숫자, 날짜, 금액처럼 값 자체보다 유형이 중요한 표현은 특수 토큰으로 바꾸기도 합니다. “3,000원”과 “5,000원”을 모두 <NUM>원으로 바꾸면 어휘 수가 줄어들고 모델이 가격이라는 패턴에 집중할 수 있습니다. 반대로 숫자의 크기가 중요한 과제라면 이 변환은 정보를 지우는 일이 됩니다.
한국어에서는 “ㅋㅋㅋㅋㅋ”와 “ㅋㅋ”처럼 반복 문자의 길이를 통일하거나, “됬다”를 “됐다”로 고치는 맞춤법 교정, 전각 문자와 반각 문자의 통일 등이 정규화에 속합니다. 소셜 미디어 텍스트일수록 이러한 흔들림이 커서 정규화의 효과도 큽니다.
- Tip : 정제와 정규화는 되돌릴 수 없는 작업입니다. 원본은 반드시 따로 보관하고, 전처리 규칙은 코드로 남겨 두어야 나중에 기준을 바꿀 때 처음부터 다시 적용할 수 있습니다.
불용어 제거(Stopword Removal)
불용어(Stopword)는 문장에 매우 자주 등장하지만 그 자체로는 의미를 거의 담지 않는 단어를 뜻합니다. 영어의 “the”, “a”, “is”, “of”와 한국어의 조사 “은/는”, “이/가”, “을/를”, 접속사 “그리고”, “그러나” 등이 대표적입니다.
문서의 주제를 분류하거나 핵심어를 뽑는 과제에서는 불용어가 어휘의 상당 부분을 차지하면서도 구분에 도움이 되지 않으므로, 이를 제거하면 연산량이 줄고 중요한 단어가 두드러집니다. 전통적인 통계 기반 방법에서 불용어 제거는 거의 필수적인 단계였습니다.
그러나 불용어가 언제나 쓸모없는 것은 아닙니다. “not”을 제거하면 “not good”이 “good”이 되어 감성 분석의 결과가 뒤집히고, 조사를 제거하면 “철수가 영희를”과 “철수를 영희가”의 구분이 사라집니다. 문법 구조가 중요한 과제에서 불용어는 의미를 나르는 뼈대입니다.
딥러닝 모델은 문맥 전체를 보고 각 단어의 중요도를 스스로 학습하므로, 불용어를 미리 제거하지 않는 것이 일반적입니다. 불용어 제거는 모델이 무엇을 할 수 없는지를 보완하는 수단이었던 셈이며, 모델이 그 일을 할 수 있게 되면서 역할이 줄어들었습니다.
- Tip : 불용어 목록은 언어와 과제에 따라 다릅니다. 범용 목록을 그대로 쓰기보다, 데이터에서 등장 빈도가 가장 높은 단어들을 직접 살펴보고 과제에 맞춰 목록을 조정하는 것이 좋습니다.
어간 추출과 표제어 추출(Stemming & Lemmatization)
하나의 단어는 문장 안에서 여러 형태로 나타납니다. 영어의 “run”은 “runs”, “running”, “ran”으로 변하고, 한국어의 “먹다”는 “먹었다”, “먹는”, “먹히다”로 변합니다. 이들을 서로 다른 단어로 취급하면 같은 뜻의 데이터가 흩어지므로, 하나의 기본형으로 모으는 작업이 필요합니다.
어간 추출(Stemming)은 단어의 접사를 규칙에 따라 기계적으로 잘라 내어 어간(Stem)을 남기는 방법입니다. 영어의 포터 스테머(Porter Stemmer)가 대표적이며, “-ing”, “-ed”, “-s” 같은 접미사를 정해진 순서로 제거합니다. 빠르고 단순하지만 결과가 실제 단어가 아닐 수 있습니다. “studies”는 “studi”가 되고, “university”와 “universe”가 같은 어간으로 묶이는 오류도 생깁니다.
표제어 추출(Lemmatization)은 사전과 품사 정보를 참고해 실제로 존재하는 기본형인 표제어(Lemma)를 찾는 방법입니다. “ran”의 표제어는 “run”, “better”의 표제어는 “good”이 됩니다. 어간 추출보다 정확하지만 사전과 품사 분석이 필요해 느리고, 품사를 잘못 판단하면 표제어도 틀립니다.
한국어는 용언의 어간에 어미가 붙고, 체언에 조사가 붙으며, 그 과정에서 형태가 변하는 불규칙 활용이 많아 접사를 잘라 내는 단순한 어간 추출이 거의 통하지 않습니다. 그 대신 다음 절에서 다룰 형태소 분석(Morphological Analysis)이 표제어 추출의 역할까지 함께 수행합니다.
- Tip : 어간 추출과 표제어 추출은 검색이나 통계 기반 분류에서 어휘 수를 줄이는 데 효과적이었습니다. 반면 딥러닝 모델은 “run”과 “running”의 차이도 정보로 사용하므로, 서브워드 토큰화가 보급된 뒤로는 거의 적용하지 않습니다.
토큰화(Tokenization)
토큰화(Tokenization)는 텍스트를 처리의 기본 단위인 토큰(Token)으로 나누는 작업입니다. 모델은 텍스트를 글자 그대로 읽지 않고, 토큰마다 번호를 붙인 뒤 그 번호의 나열로 받아들입니다. 그러므로 무엇을 하나의 토큰으로 볼 것인지가 모델이 언어를 바라보는 해상도를 결정합니다.
토큰의 단위는 크게 세 가지입니다.
단어 토큰화(Word Tokenization): 띄어쓰기와 구두점을 기준으로 단어 단위로 나눕니다. 직관적이고 각 토큰이 의미를 가지지만, 어휘가 매우 커지고 처음 보는 단어를 처리하지 못합니다.문자 토큰화(Character Tokenization): 글자 하나하나를 토큰으로 삼습니다. 어휘가 작고 처음 보는 단어도 글자로 쪼개 표현할 수 있지만, 토큰 하나에 의미가 거의 없고 문장이 매우 길어져 학습이 어렵습니다.서브워드 토큰화(Subword Tokenization): 자주 쓰이는 단어는 통째로, 드문 단어는 더 작은 조각으로 나눕니다. 두 방식의 장점을 절충한 것으로, 현재 대부분의 딥러닝 모델이 사용합니다.
토큰화의 결과로 모든 토큰의 목록인 어휘 사전(Vocabulary)이 만들어지며, 각 토큰은 이 사전에서의 번호로 바뀝니다. 사전에 없는 토큰은 OOV(Out of Vocabulary) 또는 미등록어(Unknown Word)라 하며, 보통 <UNK>라는 하나의 특수 토큰으로 뭉뚱그려집니다. 미등록어가 많을수록 모델이 읽지 못하는 부분이 늘어나므로, 토큰화 방식의 선택은 곧 미등록어를 어떻게 줄일 것인가의 문제입니다.
단어 토큰화의 한계
영어는 띄어쓰기로 단어가 나뉘므로 단어 토큰화가 자연스러워 보이지만, 실제로는 여러 결정이 필요합니다. “don’t”는 “do”와 “n’t”로 나눌지 하나로 둘지, “New York”은 두 단어인지 한 단어인지, “state-of-the-art”의 하이픈은 어떻게 다룰지가 모두 선택의 문제입니다.
더 큰 문제는 어휘의 크기입니다. 단어 단위로 나누면 수십만 개의 서로 다른 단어가 등장하고, 그중 대부분은 몇 번 나오지 않습니다. 모델은 토큰마다 벡터를 하나씩 학습해야 하므로 어휘가 클수록 매개변수가 늘어나며, 몇 번 나오지 않은 단어의 벡터는 제대로 학습되지 않습니다.
한국어는 여기에 띄어쓰기가 단어의 경계가 아니라는 문제가 더해집니다. “학교에”와 “학교를”은 띄어쓰기 기준으로는 서로 다른 단어이지만, 실제로는 “학교”에 다른 조사가 붙은 것입니다. 띄어쓰기로 나누면 조사와 어미의 조합 수만큼 어휘가 폭발하며, 띄어쓰기 자체가 자주 틀리는 언어이기도 합니다.
형태소 분석(Morphological Analysis)
한국어의 전통적인 해결책은 형태소 분석(Morphological Analysis)입니다. 띄어쓰기 대신 의미의 최소 단위인 형태소로 나누고 각 형태소의 품사를 함께 붙입니다. “학교에 갔다”는 “학교/명사 + 에/조사 + 가/동사 + 았/어미 + 다/어미”로 분석됩니다.
형태소 분석기는 사전과 품사 전이 확률을 사용해 문장을 가장 그럴듯한 형태소 열로 나눕니다. “나는”이 “나/대명사 + 는/조사”인지 “날/동사 + 는/어미”인지는 문맥을 보아야 알 수 있으므로, 단순한 사전 검색이 아니라 문장 전체의 확률을 따지는 과정이 필요합니다. 국내에서는 Mecab, Okt, Komoran, Kiwi 등이 널리 쓰입니다.
형태소 분석은 어간 추출과 표제어 추출의 역할을 겸하며, 조사와 어미를 분리해 내므로 “학교”라는 명사가 어떤 조사와 붙든 같은 토큰으로 모입니다. 다만 사전에 없는 신조어나 고유명사는 잘못 쪼개지기 쉽고, 분석기마다 품사 체계가 달라 결과를 호환하기 어렵습니다.
- Tip : 형태소 분석기는 속도와 정확도의 균형이 서로 다릅니다. 대량의 텍스트를 빠르게 처리해야 한다면 Mecab 계열이, 신조어와 띄어쓰기 오류에 강해야 한다면 사전 확장이 쉬운 분석기가 유리합니다. 어느 쪽이든 데이터의 일부를 직접 분석해 보고 고르는 것이 좋습니다.
서브워드 토큰화(Subword Tokenization)
서브워드 토큰화는 토큰의 단위를 사람이 정하지 않고 데이터에서 통계적으로 학습합니다. 자주 함께 나타나는 글자 묶음은 하나의 토큰이 되고, 그렇지 않은 묶음은 더 작은 조각으로 남습니다. 결과적으로 “학교”처럼 흔한 단어는 통째로 하나의 토큰이 되고, “학교에서처럼”과 같은 드문 조합은 “학교 + 에서 + 처럼”으로 쪼개집니다.
이 방식의 가장 큰 장점은 미등록어가 원리상 사라진다는 점입니다. 어떤 단어든 더 작은 조각으로, 최악의 경우 글자 하나까지 쪼갤 수 있으므로 어휘 사전에 없는 단어도 조각의 조합으로 표현됩니다. 어휘 크기는 보통 수만 개로 고정하며, 이는 단어 토큰화보다 훨씬 작으면서도 문자 토큰화보다 토큰 하나에 담긴 의미가 큽니다.
BPE(Byte Pair Encoding)
BPE(Byte Pair Encoding)는 원래 데이터 압축 알고리즘이었으며, 2016년 기계 번역에 적용되면서 서브워드 토큰화의 표준이 되었습니다. 동작은 매우 단순합니다.
- 모든 단어를 글자 단위로 쪼개고, 각 글자를 초기 어휘로 둡니다.
- 말뭉치 전체에서 가장 자주 인접해 나타나는 토큰 쌍을 찾습니다.
- 그 쌍을 하나의 새 토큰으로 합치고 어휘에 추가합니다.
- 어휘가 목표 크기에 도달할 때까지 2~3을 반복합니다.
예를 들어 “low”, “lower”, “lowest”가 자주 나오는 말뭉치라면 “l + o”가 먼저 합쳐지고, 이어 “lo + w”가 합쳐져 “low”가 하나의 토큰이 됩니다. “est”와 “er”도 각각 자주 나타나므로 토큰이 되어, “lowest”는 “low + est”로 표현됩니다. 합치는 순서는 그대로 병합 규칙(Merge Rule) 으로 저장되며, 새 문장은 이 규칙을 같은 순서로 적용해 토큰화합니다.
WordPiece와 SentencePiece
WordPiece는 BPE와 거의 같지만 합칠 쌍을 고르는 기준이 다릅니다. 단순히 가장 자주 나오는 쌍이 아니라, 두 토큰을 합쳤을 때 말뭉치의 가능도(Likelihood)가 가장 크게 증가하는 쌍을 고릅니다. 각각은 드물지만 함께 나올 때는 거의 항상 붙어 있는 쌍이 우선되며, BERT 계열 모델이 사용합니다. 단어 중간에 오는 토큰 앞에 ##을 붙여 표시하는 것이 특징입니다.
BPE와 WordPiece는 모두 띄어쓰기로 먼저 단어를 나눈 뒤 단어 안에서 조각을 찾습니다. 그러므로 띄어쓰기가 불규칙한 한국어나 띄어쓰기가 아예 없는 일본어·중국어에서는 그 전제가 흔들립니다.
SentencePiece는 이 문제를 띄어쓰기를 특별 취급하지 않는 것으로 해결합니다. 공백을 ▁라는 일반 문자로 바꾼 뒤 문장 전체를 하나의 문자열로 보고 조각을 학습하므로, 언어에 따른 전처리가 필요 없고 토큰 열을 원래 문장으로 완전히 복원할 수 있습니다. 내부 알고리즘으로 BPE와, 확률 모델로 조각을 고르는 Unigram 방식을 모두 지원하며, 다국어 모델과 대규모 언어 모델 대부분이 이 방식을 사용합니다.
- Tip : 서브워드 토크나이저는 학습한 말뭉치의 언어 분포를 그대로 반영합니다. 영어 위주의 말뭉치로 학습된 토크나이저는 한국어 한 글자를 여러 토큰으로 쪼개므로, 같은 뜻의 문장이라도 한국어가 영어보다 토큰 수가 두세 배 많아지며 이는 곧 처리 비용과 입력 길이 제한에 직접 영향을 줍니다.
토큰화 방식 정리
| 방식 | 토큰 단위 | 어휘 크기 | 미등록어 | 특징 |
|---|---|---|---|---|
| 단어 토큰화 | 띄어쓰기 단위 | 매우 큼 | 많음 | 직관적이지만 한국어에 부적합 |
| 문자 토큰화 | 글자 하나 | 매우 작음 | 없음 | 문장이 길어지고 토큰에 의미가 없음 |
| 형태소 분석 | 형태소 | 큼 | 있음 | 품사 정보 제공, 한국어 전통 방식 |
| BPE · WordPiece | 통계적 조각 | 수만 개 | 거의 없음 | 띄어쓰기 기준 전처리 필요 |
| SentencePiece | 통계적 조각 | 수만 개 | 거의 없음 | 언어 독립적, 완전 복원 가능 |
오늘날 딥러닝 기반 자연어 처리에서 전처리는 최소화하는 방향으로 바뀌었습니다. 불용어 제거나 어간 추출처럼 정보를 지우는 단계는 생략하고, 정제와 가벼운 정규화만 거친 뒤 서브워드 토크나이저에 맡기는 것이 일반적입니다. 모델이 충분히 크다면 표기의 흔들림도 데이터에서 스스로 학습하기 때문입니다.
그렇다고 전처리의 중요성이 사라진 것은 아닙니다. 토크나이저가 어떤 말뭉치로 학습되었는지, 내 데이터가 몇 개의 토큰으로 쪼개지는지, 미등록어나 이상한 분절이 얼마나 생기는지는 모델을 학습하기 전에 반드시 확인해야 합니다. 다음 강좌에서는 이렇게 만들어진 토큰을 모델이 계산할 수 있는 벡터로 바꾸는 방법을 다룹니다.
- Tip : 학습에 사용한 토크나이저와 추론에 사용하는 토크나이저는 반드시 같아야 합니다. 어휘 사전이나 병합 규칙이 조금이라도 다르면 같은 문장이 다른 번호 열로 바뀌어 모델이 전혀 다른 입력을 받게 됩니다.
- Writer by : 윤대희
댓글 남기기