https://hanglestocks.tistory.com/109
내가 시험공부하려고 만든 자연어처리-전처리 3탄(벡터화)
1. 벡터화(Vectorization)란 무엇인가? (정의 및 핵심 아이디어)가장 먼저 '벡터화'가 무엇인지 정확히 알아야 합니다.정의벡터화란 우리가 사용하는 자연어(예: 한국어, 영어 문장)를 컴퓨터가 이해
hanglestocks.tistory.com
🧠 1. 모든 것의 시작: 분포 가설 (Distributional Hypothesis)
카운트 기반 벡터화 방법을 이해하려면, 그 바탕에 깔린 핵심 철학인 **'분포 가설'**을 먼저 알아야 합니다.
정의
분포 가설이란 **"어떤 단어의 의미는 그 단어 주변에 함께 나타나는 단어들(문맥, context)에 의해 결정된다"**는 아이디어입니다. 즉, 끼리끼리 논다는 말처럼, 비슷한 단어는 비슷한 환경에서 등장한다는 뜻이죠.
- 핵심 아이디어: 비슷한 의미를 가진 단어는 비슷한 문맥에서 자주 등장한다.
- 예시: "wine"과 "와인"은 다른 언어지만, 두 단어의 주변에는 보통 '마시다', '포도', '레드', '화이트', '치즈' 등 유사한 단어들이 함께 나타납니다. 이를 통해 우리는 'wine'과 '와인'의 의미가 매우 비슷할 것이라고 추정할 수 있습니다.
카운트 기반 접근법의 단순화
여기서 카운트 기반 방법은 한 가지 단순한 가정을 합니다. "여기서 말하는 **문맥(context)**을 그냥 문서(document) 전체라고 보자!"
이 가정에서부터 모든 것이 시작됩니다. 이제 단어의 의미는 '그 단어가 어떤 문서에서 얼마나 자주 등장하는가'를 통해 파악할 수 있다는 아이디어가 탄생합니다.
🔢 2. 구현 방법: 카운트 기반 벡터화 (Count-based Vectorization)
위의 '분포 가설'을 실제 벡터로 구현하는 방법이 바로 '카운트 기반 벡터화'입니다.
정의
카운트 기반 벡터화는 단어의 의미를 그 단어의 출현 빈도(count) 분포를 기반으로 표현하는 방식입니다.
- 벡터 값의 의미: 벡터를 구성하는 각 숫자 값은 해당 단어(토큰)의 **출현 횟수(빈도)**를 직접적으로 의미합니다.
- 대표적인 모델: Bag-of-Words (BoW) 모델이 여기에 속합니다. BoW는 문서에 포함된 단어들의 순서는 무시하고, 오직 각 단어가 몇 번 등장했는지만을 세어 벡터로 만듭니다. 이 결과를 표로 나타낸 것을 **문서-단어 행렬(DTM, Document-Term Matrix)**이라고 합니다.
의미와 유사성 추론
이 방식을 사용하면 다음과 같은 추론이 가능해집니다.
- 텍스트의 의미: 특정 단어들의 출현 분포를 통해 텍스트 전체의 주제나 의미를 유추할 수 있습니다. (예: '농구', '선수', '득점'이라는 단어가 많이 등장하면 스포츠 관련 문서일 확률이 높다.)
- 텍스트 간 유사성: 두 문서에 등장하는 단어들의 분포가 비슷하다면, 두 문서는 서로 유사하다고 판단할 수 있습니다.
🎯 3. 벡터화의 지향점 (그리고 카운트 기반 방식의 한계)
그렇다면 이 카운트 기반 벡터화는 우리가 궁극적으로 원하는 '이상적인 벡터'를 만들어 냈을까요? '벡터화의 지향점'과 비교하며 평가해 보겠습니다.
벡터화의 이상적인 목표
- 벡터 공간의 효율적 사용: 단어(토큰)를 고차원 공간의 벡터로 매핑하여, 의미 관계를 공간상에 표현한다.
- 의미 유사도 표현: 비슷한 의미를 가진 단어는 벡터 공간에서 서로 가까운 벡터로 표현되어야 한다. 이를 통해 의미를 수학적으로 계산할 수 있어야 한다.
카운트 기반 벡터화의 평가 (★시험 핵심★)
- 어떤 것을 해결했나?
- 단순히 존재 여부만 표시하던 원핫 인코딩과는 달리, '등장 빈도'라는 통계적 정보를 벡터에 담아냈습니다. 이를 통해 문서의 주제를 파악하거나 문서 간의 유사도를 계산하는 데는 어느 정도 성공했습니다.
- 무엇이 여전히 문제인가? (한계점)
- 벡터 공간의 비효율성: 여전히 벡터의 차원은 전체 단어 사전의 크기와 동일하여 고차원이며, 대부분의 값이 0인 **희소 벡터(Sparse vector)**입니다. 이는 차원의 저주(Curse of Dimensionality) 문제를 그대로 가지고 있습니다.
- 의미 유사도 표현 실패: 가장 결정적인 한계입니다. 카운트 기반 벡터화는 '단어 자체'의 의미를 표현하지 못합니다. 예를 들어 '고양이'와 '강아지'는 의미가 매우 유사하지만, BoW 벡터 상에서는 이 두 단어 벡터 역시 서로 아무 관계가 없는(직교하는) 벡터일 뿐입니다. 단어 간의 의미적 유사성을 벡터 거리로 계산할 수 없습니다.
🎓 시험 대비 최종 요약
- 핵심 이론: 분포 가설 ("단어의 의미는 주변 단어로부터 나온다").
- 구현 방식: 분포 가설의 '문맥'을 '문서'로 단순화하여, 문서 내 **단어의 출현 횟수(count)**를 벡터 값으로 사용하는 것 (대표 예시: Bag-of-Words).
- 성과와 한계:
- 성과: 문서의 주제 파악 및 문서 간 유사도 계산이 가능해짐.
- 한계: 여전히 고차원/희소 벡터 문제를 가지며, 결정적으로 단어 간의 의미적 유사성을 벡터에 담아내지는 못했다.
이러한 한계 때문에, 이후에는 단어의 의미 자체를 저차원의 밀집 벡터(Dense Vector)에 담아내는 **TF-IDF(카운트 기반의 발전형)**나 예측 기반의 Word2Vec 같은 방법들이 등장하게 됩니다. 이 전체적인 흐름을 이해하는 것이 중요합니다!
Bag-of-Words (BoW)는 카운트 기반 벡터화의 가장 대표적인 모델입니다.
👜 1. Bag-of-Words (BoW)란 무엇인가?
개념 (The "Bag" Analogy)
**Bag-of-Words (BoW)**는 이름 그대로 텍스트를 **'단어들의 가방'**으로 취급하는 모델입니다. 문장에서 모든 단어를 꺼내 순서나 문법 구조는 다 무시하고 그냥 하나의 가방 안에 뒤죽박죽 섞어 넣는다고 상상해 보세요.
이 가방에서 우리가 관심을 갖는 것은 딱 하나, "어떤 단어가 몇 번 들어있는가?" 입니다.
- 핵심 아이디어: 텍스트를 단어(토큰)들의 집합으로 보고, 각 단어가 등장한 빈도(frequency) 정보만을 사용하여 텍스트를 숫자 벡터로 표현합니다.
- 무시하는 것 (🚨 시험 포인트!): 단어의 순서나 문법을 완전히 무시합니다. 예를 들어, "소년이 소녀를 사랑한다"와 "소녀가 소년을 사랑한다"는 의미가 전혀 다르지만, BoW 모델에게는 완전히 동일한 텍스트로 보입니다. (두 문장 모두 '소년', '소녀', '사랑한다'가 한 번씩 들어있기 때문이죠.)
- 결과: 텍스트는 최종적으로 각 단어의 빈도를 나타내는 **'토큰 빈도 벡터'**로 표현됩니다.
🛠️ 2. BoW 벡터 생성 과정 (Step-by-Step)
BoW 벡터(및 행렬)는 크게 두 단계로 만들어집니다.
1단계: 어휘집(Vocabulary) 구축 과정
먼저 전체 텍스트 데이터(코퍼스)를 기반으로 기준이 될 **어휘집(단어 사전)**을 만듭니다.
- 토큰화(Tokenization): 가지고 있는 모든 텍스트를 문장이나 단어 같은 토큰 단위로 쪼갭니다.
- 정제(Cleaning): 불필요한 기호(마침표, 쉼표 등)나 큰 의미가 없는 불용어(stopwords, 예: a, the, 은, 는)를 제거합니다.
- 고유 토큰 추출: 모든 텍스트에서 등장한 단어들의 중복을 없애고 고유한 단어들만 남깁니다. 이것이 바로 어휘집이 됩니다.
- 인덱스 부여: 어휘집에 있는 각 고유 토큰에 고유한 번호(인덱스)를 부여합니다.
- 예시:
- 문장1: "오늘 날씨가 좋아요" → ["오늘", "날씨", "좋다"]
- 문장2: "내일 날씨를 알려주세요" → ["내일", "날씨", "알려주다"]
- → 최종 어휘집: {"오늘": 1, "날씨": 2, "좋다": 3, "내일": 4, "알려주다": 5}
2단계: 문서-단어 행렬 (DTM) 생성
어휘집이 완성되면, 각 문장(문서)을 이 어휘집을 기준으로 벡터화하여 **문서-단어 행렬(Document-Term Matrix, DTM)**을 만듭니다.
- 행(row): 각 문장 또는 문서
- 열(column): 어휘집에 있는 모든 고유 토큰
- 값(value): 해당 문서(행)에 해당 토큰(열)이 등장한 횟수 (Term Frequency, TF)
- 예시 DTM:
| 토큰 | 오늘 | 날씨 | 좋다 | 내일 | 알려주다 |
| 문장1 | 1 | 1 | 1 | 0 | 0 |
| 문장2 | 0 | 1 | 0 | 1 | 1 |
- 결과 해석:
- 문장1의 BoW 벡터: [1, 1, 1, 0, 0]
- 문장2의 BoW 벡터: [0, 1, 0, 1, 1]
- 이제 각 문장은 어휘집의 차원(이 경우 5차원)을 갖는 숫자 벡터로 성공적으로 변환되었습니다!
👍👎 3. BoW의 장점과 한계 (★시험 핵심★)
| 장점 (Pros) | 단점 (Cons) |
| ✔️ 구현이 간단하고 이해하기 쉽다. | ❌ 단어 순서를 무시하여 문맥 정보를 잃는다. (가장 치명적!) |
| ✔️ 문서의 주제 분류에 효과적이다. (예: "선수, 경기, 골"이 많이 나오면 스포츠 문서) | ❌ 희소성(Sparsity) 및 고차원 문제: 단어 수가 많아지면 벡터가 매우 길어지고 대부분이 0으로 채워져 비효율적이다. (차원의 저주) |
| ❌ 단어의 의미적 유사성을 반영하지 못한다. ('강아지'와 '개'를 완전히 다른 단어로 취급) |
🎓 시험 대비 최종 요약
- BoW란? 단어의 순서는 무시하고, 오직 출현 빈도만으로 텍스트를 숫자 벡터로 만드는 방법.
- 핵심 결과물: 문서-단어 행렬 (DTM). 여기서 각 행은 하나의 문서를 나타내는 BoW 벡터.
- 가장 큰 특징이자 한계: 문맥 정보의 손실. "아버지가 방에 들어가신다"와 "아버지 가방에 들어가신다"를 구분하지 못함.
- 주요 용도: 간단하면서도 효과가 좋아 텍스트 분류, 스팸 메일 필터링, 토픽 모델링 등 넓은 범위의 기초 모델로 사용됨
🔄 1. BoW 모델 프로세스 요약 (Summary Flowchart)
먼저 BoW 모델이 어떻게 동작하는지 전체적인 흐름을 다시 한번 복습해 보겠습니다. 슬라이드의 요약 이미지는 이 과정을 매우 명확하게 보여줍니다.
- Corpus (코퍼스): 분석하고자 하는 텍스트 문서들의 모음에서 시작합니다.
- Tokenize (토큰화): 각 문서를 단어(토큰)와 같은 작은 단위로 나눕니다.
- Count Word Frequencies (단어 빈도수 계산): 전체 문서에서 고유한 단어들로 어휘집(Vocabulary)을 만들고, 각 문서에서 어휘집의 단어들이 몇 번씩 등장하는지 횟수를 셉니다.
- Encode the Data (데이터 인코딩): 위에서 계산한 빈도수 정보를 바탕으로, 각 문서를 숫자 벡터로 변환합니다. 이 결과물을 모아놓은 것이 바로 **문서-단어 행렬(DTM)**입니다.
이 네 단계를 거치면, 텍스트는 컴퓨터가 이해하고 계산할 수 있는 숫자 데이터(벡터)로 변환됩니다.
📏 2. BoW의 문제점과 해결책: 텍스트 길이 문제
기본적인 BoW 모델은 한 가지 중요한 약점을 가지고 있습니다. 바로 문서의 길이에 따라 단어의 중요도가 왜곡될 수 있다는 점입니다.
문제점: 긴 문서의 함정
- 문장1: 전체 단어 10개, "오늘" 1번 등장 → 출현 횟수: 1
- 문장2: 전체 단어 100개, "오늘" 10번 등장 → 출현 횟수: 10
단순히 등장 횟수(count)만 보면, 문장2에서 "오늘"이라는 단어가 문장1에서보다 10배나 더 중요해 보입니다. 하지만 문장2는 길이가 10배나 길기 때문에 "오늘"이 10번 등장한 것일 수 있습니다. 오히려 전체 문서에서 "오늘"이 차지하는 비중은 문장1(1/10)과 문장2(10/100)가 동일합니다.
이처럼 단순 카운트는 긴 문서에 있는 단어에 더 높은 가중치를 부여하여, 문서 간의 공정한 비교를 어렵게 만듭니다.
해결책: 정규화된 출현 횟수, TF (Term Frequency) 사용
이 문제를 해결하기 위해 **정규화(Normalization)**를 사용합니다. 즉, 각 단어의 등장 횟수를 그 단어가 포함된 문서의 전체 단어 수로 나누어 주는 것입니다. 이것을 바로 **단어 빈도(TF, Term Frequency)**라고 합니다.
TF(단어 t, 문서 d) = (문서 d에서 단어 t의 등장 횟수) / (문서 d의 전체 단어 수)
- 예시 DTM (TF 적용 후):
| 토큰 | 오늘 | 날씨 | 좋다 | 내일 | 알려주다 |
| 문장1 | 1/3 | 1/3 | 1/3 | 0 | 0 |
| 문장2 | 0 | 1/3 | 0 | 1/3 | 1/3 |
이렇게 TF를 사용하면, 각 벡터의 값은 문서 길이에 상관없이 해당 단어가 문서 내에서 차지하는 **상대적인 중요도(비중)**를 나타내게 됩니다. 따라서 문서 길이가 달라도 훨씬 공정하게 비교할 수 있습니다.
🛠️ 3. BoW의 활용 사례 (Use Cases)
BoW는 단순한 모델이지만, 그 효과가 뛰어나 여러 분야에서 널리 활용됩니다.
- 메일 필터링 (Spam Mail Filtering)
- 스팸 메일에는 'free', 'offer', 'money', 'win' 등의 단어가 일반 메일보다 훨씬 자주 등장합니다. BoW로 메일의 단어 빈도 벡터를 만든 후, 기계학습 모델을 통해 스팸 메일의 단어 분포 패턴을 학습시켜 스팸을 걸러낼 수 있습니다.
- 뉴스 카테고리 분류 (News Categorization)
- '선수', '경기', '골' 등의 단어가 많이 나오면 스포츠 기사로, '대통령', '국회', '선거' 등의 단어가 많으면 정치 기사로 분류할 수 있습니다. BoW는 문서의 주제를 파악하는 데 매우 효과적입니다.
- 감정 분석 (Sentiment Analysis)
- 영화 리뷰나 상품 후기에서 '최고', '추천', '만족' 같은 긍정적인 단어와 '최악', '실망', '별로' 같은 부정적인 단어의 빈도를 세어 해당 텍스트의 감정이 긍정적인지 부정적인지 판단할 수 있습니다.
- 정보 검색 (Information Retrieval) 및 주제 추론 (Topic Modeling)
- 사용자가 검색어를 입력했을 때, 검색어에 포함된 단어들의 빈도가 높은 문서를 찾아 보여주는 원리도 BoW에 기반합니다. 또한, 문서들의 단어 빈도 분포를 분석하여 해당 문서 집단의 주요 주제가 무엇인지 추론할 수도 있습니다.
🎓 시험 대비 최종 요약
- BoW 프로세스: **코퍼스 → 토큰화 → 빈도수 계산 → 인코딩(DTM 생성)**의 4단계를 거친다.
- 핵심 문제점: 문서 길이가 길수록 단어 빈도수가 부풀려져 중요도가 왜곡될 수 있다.
- 핵심 해결책: 단순 카운트 대신, 단어 횟수를 전체 단어 수로 나눈 **정규화된 값, 즉 단어 빈도(TF)**를 사용한다.
- 주요 활용 분야: 스팸 필터링, 뉴스 분류, 감정 분석 등 텍스트의 주제나 성격을 파악하는 대부분의 기초적인 자연어 처리 문제에 효과적으로 사용된다.
🛠️ 1. 직접 구현으로 원리 파악하기 (Manual Implementation)
이 코드는 외부 라이브러리 없이 기본적인 파이썬 문법만으로 BoW 모델의 핵심 로직을 처음부터 끝까지 만드는 과정을 보여줍니다. BoW의 동작 원리를 이해하는 데 가장 좋은 예제입니다.
코드 분석 (단계별)
- 데이터 준비 및 토큰화
- 분석할 4개의 문서를 리스트로 준비합니다.
-
Python
docs = ['먹고 싶은 사과', '먹고 싶은 바나나', '길고 노란 바나나 바나나', '저는 바나나가 좋아요'] # 실제 코드에서는 각 문서를 .split()으로 단어 리스트로 만듭니다. - 어휘집(Vocabulary) 생성
- 모든 문서에 있는 단어들을 모아 중복을 제거하여 고유한 단어의 집합, 즉 어휘집을 만듭니다.
- enumerate를 사용해 어휘집의 각 단어에 0부터 시작하는 고유한 정수 인덱스를 부여한 word_to_index 딕셔너리를 생성합니다. 이것이 단어와 숫자(벡터의 위치)를 연결하는 다리 역할을 합니다.
-
Python
# 모든 문서의 단어들을 하나로 합친 후, set으로 중복을 제거해 고유 단어만 추출 vocab = list(set(word for doc in docs for word in doc.split())) vocab.sort() # 순서를 보장하기 위해 정렬 # 단어에 고유 인덱스 부여 word_to_index = {word: i for i, word in enumerate(vocab)} - BoW 벡터 생성 함수 (make_bow)
- 이 함수가 BoW의 핵심 로직입니다.
- 먼저 어휘집의 크기와 동일한 길이의 0으로 채워진 리스트(bow)를 만듭니다.
- 입력된 문서(doc)의 단어들을 하나씩 확인합니다.
- word_to_index에서 해당 단어의 인덱스를 찾아, bow 리스트의 그 인덱스 위치에 있는 값을 1씩 더해줍니다.
- 모든 단어를 다 세면, 최종적으로 완성된 빈도수 벡터(bow)를 반환합니다.
- 이 함수가 BoW의 핵심 로직입니다.
-
Python
def make_bow(doc): # 1. 어휘집 크기의 0으로 채워진 벡터 생성 bow = [0] * len(vocab) # 2. 입력된 문서의 단어들을 하나씩 순회 for word in doc.split(): # 3. 단어의 인덱스를 찾아서 idx = word_to_index[word] # 4. 해당 인덱스의 값을 1 증가 (카운트) bow[idx] += 1 return bow - 실행 및 결과 확인
- 이 make_bow 함수를 모든 문서에 대해 실행하면 슬라이드 우측에 보이는 **BoW 행렬(DTM)**이 만들어집니다.
- 예를 들어, 3번째 문서 "길고 노란 바나나 바나나"의 벡터가 [1, 0, 2, 0, 0, 0, 0, 1]인 이유를 어휘집 ['길고', '먹고', '바나나', '사과', '싶은', '저는', '좋아요', '노란']과 비교해 보면,
- '길고'(0번 인덱스) 1번, '바나나'(2번 인덱스) 2번, '노란'(7번 인덱스) 1번 등장했음을 정확히 알 수 있습니다.
🚀 2. Scikit-learn으로 간단하게 구현하기
이번 코드는 머신러닝 라이브러리인 Scikit-learn의 CountVectorizer를 사용합니다. 실무에서 BoW 모델을 만들 때 사용하는 표준적인 방법입니다.
코드 분석 (단계별)
- CountVectorizer 불러오기 및 생성
- BoW 모델을 만들어주는 도구인 CountVectorizer를 불러와 객체를 생성합니다.
-
Python
from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer() - 학습 및 변환 (fit_transform)
- 이 한 줄이 위에서 직접 구현한 모든 과정을 알아서 처리해 줍니다.
- fit(): 입력된 docs 데이터를 분석해서 스스로 어휘집을 만들고 단어-인덱스 매핑을 학습합니다.
- transform(): 학습된 어휘집을 기준으로 docs 데이터를 BoW 행렬(DTM)로 변환합니다.
- **fit_transform()**은 이 두 과정을 한 번에 수행하는 편리한 메서드입니다.
- 이 한 줄이 위에서 직접 구현한 모든 과정을 알아서 처리해 줍니다.
-
Python
X = vectorizer.fit_transform(docs) - 결과 확인
- vectorizer.get_feature_names_out(): CountVectorizer가 학습한 어휘집(DTM의 열 순서)을 보여줍니다.
- X.toarray(): 생성된 X는 원래 메모리 효율을 위해 희소 행렬(sparse matrix) 형태로 저장되어 있습니다. .toarray()를 통해 우리가 눈으로 보기 쉬운 일반적인 행렬(Numpy 배열)로 변환하여 출력합니다.
- 출력된 어휘집과 BoW 행렬은 위에서 직접 구현한 결과와 완전히 동일한 것을 확인할 수 있습니다.
-
Python
print("어휘집:", vectorizer.get_feature_names_out()) print("BoW 행렬:\n", X.toarray())
🎓 시험 대비 최종 요약
| 구분 | 직접 구현 (Manual) | Scikit-learn (CountVectorizer) |
| 목적 | BoW의 동작 원리를 단계별로 이해하기 위함 | 실용적이고 효율적인 BoW 모델 구현을 위함 |
| 핵심 | word_to_index 딕셔너리 생성, for 루프를 통한 직접 카운팅 | fit_transform() 메서드 하나로 모든 과정 자동 처리 |
| 시험 Tip | 코드의 각 부분이 어휘집 생성, 인덱싱, 카운팅 중 어느 역할을 하는지 파악하는 것이 중요. | CountVectorizer, fit_transform, get_feature_names_out의 기능과 역할을 암기하는 것이 중요. |
결론적으로, 두 방법은 동일한 결과를 내지만, 원리 이해를 위해서는 직접 구현 코드를, 실제 문제 해결을 위해서는 Scikit-learn 코드를 알아두는 것이 좋습니다. 두 가지를 모두 이해하고 있으면 어떤 형태의 문제가 나와도 완벽하게 대비할 수 있습니다!
📉 Bag-of-Words (BoW)의 명확한 한계점
BoW는 구현이 간단하고 직관적이라는 장점이 있지만, 다음과 같은 4가지의 치명적인 약점을 가지고 있습니다.
1. 불용어 문제 (Stopword Problem) 🚮
- 설명: 텍스트에는 'the', 'a', 'is'나 한국어의 '은', '는', '이', '가'와 같이 자주 등장하지만 실제 의미에는 거의 기여하지 않는 단어들이 있습니다. 이를 **불용어(Stopword)**라고 합니다.
- BoW의 문제점: BoW는 오직 단어의 '빈도'만을 보기 때문에, 이 의미 없는 불용어들이 가장 중요한 단어인 것처럼 취급될 수 있습니다. 예를 들어, 어떤 문서의 BoW 벡터에서 '는'이라는 단어가 가장 높은 빈도수를 차지한다면, 이 벡터는 문서의 핵심 의미를 제대로 담고 있다고 보기 어렵습니다.
- 해결책: 일반적으로 BoW 모델을 만들기 전, 텍스트 전처리 단계에서 불용어를 미리 제거하는 작업을 거칩니다.
2. 순서 정보 손실 (Loss of Word Order) 🤷
- 설명: BoW의 가장 근본적이고 심각한 한계입니다. BoW는 단어를 '가방'에 담는다는 개념 때문에, 원래 문장에 있던 단어의 순서 정보를 완전히 무시합니다.
- 왜 문제인가?: 단어의 순서는 문장의 의미를 결정하는 핵심적인 요소입니다.
- (🚨 시험 단골 예시!)
- 문장 A: "개가 사람을 물었다"
- 문장 B: "사람이 개를 물었다"
- 이 두 문장은 의미가 완전히 반대입니다. 하지만 BoW의 관점에서는 두 문장 모두 {'개': 1, '사람': 1, '물었다': 1} 이라는 동일한 단어 구성을 가지므로, 완전히 똑같은 벡터로 변환됩니다. 즉, BoW는 이 두 문장을 전혀 구별하지 못합니다.
- 추가 문제: 부정(negation) 표현처럼 순서가 중요한 문맥을 파악하기 어렵습니다. 예를 들어, "이 영화는 전혀 재미있지 않다"에서 '전혀'와 '않다'의 관계를 이해하지 못하고 '재미있다'라는 단어의 존재만으로 긍정으로 잘못 판단할 수 있습니다.
3. 차원의 저주 (Curse of Dimensionality) 🌌
- 설명: BoW 벡터의 차원(길이)은 어휘집(Vocabulary)에 있는 고유 단어의 총개수와 동일합니다.
- 왜 문제인가?: 일반적인 텍스트 데이터(예: 뉴스 기사 모음)의 어휘집 크기는 수만 개에서 수십만 개에 달하는 경우가 흔합니다. 이는 단어 하나하나가 수만 차원의 벡터가 된다는 의미입니다.
- 결과:
- 계산 비용 증가: 차원이 클수록 모델이 계산해야 할 양이 기하급수적으로 늘어나 학습이 매우 느려집니다.
- 과적합(Overfitting) 위험: 데이터의 양에 비해 차원이 너무 크면, 모델이 훈련 데이터에만 과도하게 최적화되어 새로운 데이터에 대한 예측 성능이 떨어질 수 있습니다.
4. 희소 벡터 (Sparse Representation) 문제 💨
- 설명: 이 문제는 '차원의 저주'와 직접적으로 연결됩니다. 벡터의 차원은 수만 개로 매우 크지만, 하나의 문서에는 그중 극히 일부의 단어만 포함됩니다.
- 왜 문제인가?: 결과적으로 BoW 벡터는 대부분의 값이 0이고 몇 개의 값만 1 이상의 수를 갖는 **희소 벡터(Sparse Vector)**가 됩니다.
- 결과:
- 메모리 비효율성: 수많은 0을 저장하기 위해 엄청난 메모리 공간이 낭비됩니다. (물론 실제 구현에서는 이를 해결하기 위해 희소 행렬 자료구조를 사용하지만, 근본적인 비효율성은 존재합니다.)
- 정보 밀도 저하: 벡터 하나에 담긴 정보의 밀도가 매우 낮아, 모델이 의미 있는 패턴을 학습하기 어려워집니다.
🎓 시험 대비 최종 요약
| 한계점 | 핵심 내용 | 결과 및 영향 |
| 불용어 문제 | 의미 없는 단어(a, the, 은, 는)가 높은 빈도수를 차지함 | 벡터가 핵심 의미를 제대로 표현하지 못할 수 있음 |
| 순서 정보 손실 | 단어의 순서를 완전히 무시함 ("개가 사람을..." vs "사람이 개를...") | 문맥과 뉘앙스를 파악하지 못하고, 의미가 다른 문장을 동일하게 취급함 |
| 차원의 저주 | 어휘집 크기만큼 벡터 차원이 커짐 | 계산 비용이 급증하고 모델 성능이 저하될 수 있음 |
| 희소 벡터 | 벡터의 대부분이 0으로 채워짐 | 메모리 낭비가 심하고 정보 밀도가 낮음 |
이러한 명확한 한계점들 때문에, 자연어 처리 기술은 BoW를 개선한 TF-IDF, 그리고 더 나아가 단어의 순서와 의미를 모두 고려하는 Word2Vec, BERT와 같은 모델로 발전하게 되었습니다. 이 전체적인 흐름을 기억해두시면 시험에 큰 도움이 될 겁니다!
'코딩공부 > 자연어처리' 카테고리의 다른 글
| 시험공부를 하려고 만든 자연어처리 정리-전처리 3탄(벡터화)-TF한계와 TF-IDF (0) | 2025.10.08 |
|---|---|
| 내가 시험공부하려고 만든 자연어처리-전처리 3탄(벡터화) 벡터유사도 (0) | 2025.10.05 |
| 내가 시험공부하려고 만든 자연어처리-전처리 3탄(벡터화)-패딩 (0) | 2025.10.05 |
| 내가 시험공부하려고 만든 자연어처리-전처리 3탄(벡터화)-원핫인코딩 (0) | 2025.10.05 |
| 내가 시험공부하려고 만든 자연어처리-전처리 3탄(벡터화)-정수인코딩 (0) | 2025.10.05 |