BoW : Bag of Words
BoW: Bag of Words
BoW는 자연어 즉, 텍스트(text)를 처리하는 방법 중에 하나로 간단하고 이해하기 쉬운 방법중 하나입니다. 짧게 말하면 단어가방(Bag of Words)를 가지고 문장을 표현하는 방법 입니다.
왜, BoW가 필요한가?
컴퓨터는 0과 1밖에 모릅니다. 0 또는 1일 표시할 수 있는 이진수에서 1자리를 bit 비트라고 합니다. 그래서 1비트는 1자리 2비트는 2자리입니다. 8비트를 1바이트(byte)라고 하고 1,000바이트를 1KB(킬로바이트)라고 합니다. 1,000 KB를 1MB(메가바이트), 1,000 MB를 1GB(기가바이트) 라고합니다. 이처럼 컴퓨터에서 정보를 처리하는 단위는 비트 입니다. 그런데 NLP에서 다루고자 하는 것은 텍스트(text) 데이터 입니다. 물론 텍스트 데이터도 컴퓨터에서는 비트로 저장되고 처리되지만 언어적인 특성을 고려한 상태에서의 저장이 아니라 문자 자체로의 저장입니다. 예를 들면 비트로 저장시에는 주어, 동사, 목적어, 보어 등 문법적인 언어적인 내용을 저장하지 않습니다. 단지, 예를 들면 'ㄱ'은 '11100011 10000100 10110001' 로 저장합니다. 뒤에 'ㅏ' (11100011 10000101 10001111) 와 합쳐서 '가'를 저장하고 표현할 뿐입니다. 이처럼 기본적인 컴퓨터에서 문자의 표현을 위한 데이터가 아니라 자연어 정보의 표현을 위한 데이터가 필요합니다. 그래야 이것을 이용해서 모델에서 사용할 수 있습니다. 이처럼 자연어를 모델이 다룰 수 있는 형태로 표현하는 방법중하나가 BoW 입니다. 예를 들어보겠습니다. 다음과 같은 문장이 있습니다. " 나는 사과를 좋아합니다." 이 문장을 어떻게 표현 할 수 있을까요? 여러가지 방법이 있지만 BoW로 표현할 수 있습니다.
BoW는 무엇인가?
BoW는 텍스트를 표현하는 방법 중 하나로 단어 가방(Bag of Words)을 이용하여 문장 또는 문서를 표현하는 방법입니다. 단어 가방에는 단어들이 들어있고 문장은 어떤 단어가 몇번 사용되었는지를 가지고 표현하는 방법입니다.
BoW 예시
여러분은 오늘 막 입학한 유치원생 이라고 생각해 봅시다. 유치원 단어 놀이 시간이 돌아왔다고 가정해 보시지요. 단어 놀이는 단어 가방에서 단어가 적힌 카드들을 넣어 두었다가 꺼네서 문장을 만드는 놀이입니다. 단어 가방 안에 '나는', '사과를', '좋아합니다', '바나나를', '정말'이라는 단어가 각각 쓰여진 총 5개의 단어 카드가 들어 있습니다.
이 단어 가방에서 "나는 사과를 좋아합니다"라는 문장을 만들기 위해서는 어떤 카드를 몇개 뽑아야 할까요? 네, '나는', '사과를', '좋아합니다' 각각 1개씩 있으면 됩니다. 이것을 기호로 표시해보면 다음과 같습니다. {'나는': 1, '사과를': 1, '좋아합니다': 1} 한번 더 해보시지요. 이번에는 "나는 정말 정말 바나나를 좋아합니다"를 만들어 보겠습니다. 결과는 순서와 상관없이 다음과 같이 표현할 수 있습니다. {'나는': 1, '정말': 2, '바나나를': 1, '좋아합니다': 1}
단어 가방는 단어가 중복되어 들어있지 않습니다. 그래서 각 단어에 순번을 할당하면 순번만으로도 어떤 단어인지를 알수 있습니다. 즉, 1번 카드에는 '나는'이 적혀있고, 2번카드에는 '사과를'이라고 적혀있다고 생각할 수 있습니다. 그러면 단어 가방에는 다음과 같이 들어있다고 할 수 있습니다. {0: '나는', 1: '정말', 2: '바나나를', 3: '좋아합니다', 4: '사과를'}
이러한 단어 가방을 이용하여 "나는 사과를 좋아합니다" 문장을 하나의 표현하면 [1, 0, 0, 1, 1] 으로 표현할 수 있습니다. 왜냐하면 첫번째 자리는 '나는'이고 문장내에 '나는'이 한번 있으므로 1로 표시됩니다. 두번째 자리는 '정말'을 의미하는데 문장에 해당 단어가 없으므로 0으로 표시합니다. 세번째 자리는 '바나나를'의미하는데 표현하려는 문장에 '바나나를'이 없으므로 0입니다. 네번째 자리는 '좋아합니다'의 자리인데 문장중에 있으므로 1로 표시됩니다. 마지막 다섯번째 자리는 '사과를'을 의미하고 문장에 '사과를'이 있으므로 1로 표시합니다. 같은 방법으로 두번째 예시 문장인 "나는 정말 정말 바나나를 좋아합니다."를 BoW로 표현하면 [1, 2, 1, 1, 0]이 됩니다.
이처럼 단어 가방을 이용하여 문장을 표시하는 방법이 Bag of Words(BoW) 방법입니다. 예시의 간단한 설명을 위해서 문장을 그대로 이용했는데 자세한 분석을 위해서 형태소 분석을 통해 단어를 분리하여 단어 가방에 넣을 수 있습니다.(예: 나, 는, 바나나, 를, 좋아, 합니다.)
장점 및 단점
위의 예에서 보신 것처럼 BoW는 문장내에서 단어의 순서나 위치를 고려하지 않습니다. 그냥 출현 횟수만을 관리합니다. 그래서 주어, 동사, 목적어 등 위치에 따른 의미 파악이 안되고 앞뒤 단어와의 관계를 고려한 분석이 안됩니다. 그래서 여러 뜻을 가진 단어나 동의어를 파악하거나 활용하지 못합니다. 그리고 새로운 단어의 표현을 위해서는 단어 가방에 단어를 추가하고 다른 문장들에도 표현을 변경해 주어야합니다. 그래서 잦은 단어추가가 필요한 곳에는 적합하지 않습니다.(물론 데이터 양이 적으면 사용가능하고요 이러한 단점을 보완하기 위해 Dummy word를 임의로 추가하거나 해싱 트릭 hashing trick을 이용할 수도 있지만 문제를 완전히 해결하지는 못합니다. ) 그대신 구조가 간단해서 처리 속도가 빠르고 이해하기 쉽습니다. 그래서 문제를 머신러닝으로 풀수 있는지 없는지를 빠르게 검증하고자 하는 단계에서 많이 사용되는 방법입니다.
Python 구현 코드
from konlpy.tag import Kkma
sentence = "나는 정말 정말 바나나를 좋아합니다."
def print_bow(sentence):
kkma = Kkma()
pos = kkma.pos(sentence)
bow = {}
for word in pos:
try:
bow[word[0]] += 1
except KeyError:
bow[word[0]] = 1
print("BoW 표현: ", bow)
print("단어 개수: ",len(bow))
print_bow(sentence)
output 실행 결과
BoW 표현: {'나': 1, '는': 1, '정말': 2, '바나나': 1, '를': 1, '좋아하': 1, 'ㅂ니다': 1, '.': 1}
단어 개수: 8
유사하지만 조금 더 복잡하고 정교한 표현이 가능한 TF-IDF 도 많이 쓰입니다.
https://bigdatamaster.tistory.com/147
Bag of Words 를 이용한 어플리케이션이라고 할 수 있는 워드클라우드에 대해서는 아래의 링크를 참고해주세요.
https://bigdatamaster.tistory.com/99