Bag-of-Words

Bag-of-Words의 등장 배경

Bag-of-Words는 문서를 컴퓨터가 계산할 수 있는 숫자로 바꾸려는 초기 정보검색과 문서분류의 필요에서 나온 방법이다. 자연어의 의미를 깊이 이해하기 위해 처음부터 설계된 방법은 아니다. 문서에 어떤 단어가 얼마나 많이 등장하는지를 세면 문서의 주제나 성격을 어느 정도 구분할 수 있다는 실용적인 생각에서 출발했다.

예를 들어, 정치 관련 문서에는 ‘정부’, ‘선거’, ‘정당’ 같은 단어가 자주 등장하고, 경제 관련 문서에는 ‘시장’, ‘금리’, ‘기업’ 같은 단어가 자주 등장한다. 단어의 빈도만 보더라도 두 문서의 주제를 어느 정도 구분할 수 있다고 본 것이다.

Bag-of-Words는 당시의 계산 환경에도 잘 맞는 방법이었다. 규칙이 단순하고 구현이 쉬웠다. 복잡한 언어 지식이나 대규모 학습도 필요하지 않았다. 단어를 세고 행렬로 만들면 바로 통계 분석이나 머신러닝에 사용할 수 있었다. 그래서 문서 검색, 스팸 분류, 감성 분석, 초기 토픽 모델링과 같은 여러 분야에서 널리 사용되었다.

Bag-of-Words의 핵심 가정은 단어의 순서를 무시해도 문서의 주요 정보를 어느 정도 보존할 수 있다는 것이다. 긴 문서의 주제를 분류할 때는 이 가정이 어느 정도 작동한다. 정치 기사에는 정치 관련 단어가 반복되고, 스포츠 기사에는 경기와 선수 관련 단어가 반복되기 때문이다. 문장의 세부적인 의미보다 문서 전체의 주제를 파악하는 작업에서는 단어 빈도가 유용한 신호가 된다.

Bag-of-Words란

앞서 언급한 바와 같이, Bag-of-Words는 이름 그대로 문장을 ‘단어들의 집합(Bag)’ 으로 표현하는 방법이다. 여기서 Bag이라는 표현은 의도적으로 사용된 용어이다. 가방 안에 물건을 넣으면 순서는 중요하지 않고 어떤 물건이 몇 개 들어 있는지만 알 수 있듯이, Bag-of-Words 역시 문장에서 어떤 단어가 몇 번 등장했는가만을 기록한다. 단어가 어떤 순서로 등장했는지, 문장에서 어떤 역할을 하는지는 고려하지 않는다.

예를 들어 다음과 같은 두 문장이 있다고 하자.

나는 사과를 먹었다.
나는 배를 먹었다.

먼저 두 문장에 등장하는 모든 단어를 모아 Vocabulary(어휘 집합) 를 만든다. Vocabulary는 분석 대상이 되는 모든 문서에서 등장하는 고유한 단어들의 목록이다. 위의 예에서는 ‘사과’, ‘배’와 같은 단어들이 Vocabulary를 구성하게 된다. 이후 각 문장은 Vocabulary에 포함된 단어가 몇 번 등장했는지를 숫자로 기록한다. 이러한 표현을 Document-Term Matrix(DTM) 라고 한다.

예를 들어 첫 번째 문장은 ‘사과’가 한 번 등장하고 ‘배’는 등장하지 않으므로 [1, 0]으로 표현된다. 반대로 두 번째 문장은 [0, 1]이 된다. 결국 컴퓨터는 문장을 실제 문장이 아니라 이러한 숫자의 배열로 저장하고 계산하게 된다.

이 방법은 매우 단순하면서도 계산이 빠르기 때문에 오랫동안 자연어처리의 기본적인 표현 방식으로 사용되었다. 하지만 이 방식에는 근본적인 문제가 존재한다.

Bag-of-Words의 한계

첫째, Bag-of-Words는 단어의 순서를 잃는다. 예를 들어 다음 두 문장을 비교해 보자.

개가 사람을 물었다.
사람이 개를 물었다.

두 문장은 전혀 다른 의미를 가진다. 그러나 등장하는 단어의 종류와 개수는 같다. 따라서 Bag-of-Words에서는 두 문장에 등장하는 단어의 종류와 개수가 동일하기 때문에 동일한 벡터로 표현된다. 즉, 문장의 의미를 바꾸는 가장 중요한 정보인 단어의 순서(word order)가 완전히 사라진다.

둘째, 의미를 표현하지 못한다. 사람은 ‘사과’와 ‘배’가 모두 과일이라는 사실을 알고 있다. 따라서 “나는 사과를 먹었다.”와 “나는 배를 먹었다.”를 비슷한 의미의 문장으로 이해한다. 그러나 Bag-of-Words는 그렇지 않다. 사과는 서로 다른 단어로만 취급된다. 두 단어 사이의 의미적인 관계는 전혀 표현되지 않는다.

셋째, 동의어나 유사한 표현을 이해하지 못한다. 예를 들어 ‘자동차’와 ‘승용차’, ‘학생’과 ‘학습자’처럼 의미가 매우 비슷한 단어들도 Bag-of-Words에서는 완전히 다른 단어로 취급된다. 반대로 철자가 같으면 항상 같은 단어로 간주하기 때문에 문맥에 따라 의미가 달라지는 단어 역시 구분하지 못한다. 결국 컴퓨터는 단어의 철자만 비교할 뿐, 그 단어가 담고 있는 의미는 고려하지 못한다.

넷째, 희소 행렬(Sparse Matrix)이 만들어진다. 실제 연구에서는 수천 개에서 수십만 개에 이르는 Vocabulary가 만들어진다. 그러나 하나의 문서에는 그중 극히 일부의 단어만 등장한다. 따라서 대부분의 값은 0이 되고, 매우 크지만 대부분이 비어 있는 행렬이 만들어진다. 이러한 Sparse Matrix는 저장 공간과 계산 비용을 증가시킬 뿐만 아니라 데이터의 의미를 효과적으로 표현하지도 못한다.

Bag-of-Words는 문장을 숫자로 표현하는 데는 성공했지만 의미를 표현하는 데는 실패했다. 이것이 Bag-of-Words의 가장 근본적인 한계이다. 컴퓨터는 단어를 구분할 수는 있지만, 단어들이 서로 얼마나 비슷한 의미를 가지는지는 알 수 없다. 따라서 의미를 이해하는 자연어처리를 수행하기에는 한계가 있다.

Bag-of-Words의 의의

자연어처리의 발전 과정에서 Bag-of-Words는 언어를 처음으로 체계적인 숫자 벡터로 바꾼 중요한 단계로 볼 수 있다. 다만 이 벡터는 의미 벡터가 아니라 빈도 벡터이다. 이후 TF-IDF는 단어별 중요도를 반영했고, Word2Vec부터는 단어 사이의 의미적 관계를 벡터에 담기 시작했다. 이런 흐름에서 Bag-of-Words는 현대 Embedding의 직접적인 형태라기보다, 텍스트를 벡터로 표현한다는 기본 틀을 마련한 출발점이라고 볼 수 있다.