문서 분석 시스템은 말 그대로 문서를 분석해서 유용한 정보를 얻어내는 시스템입니다. 문서의 내용을 분석해서 분류하거나, 문서의 주제를 추출하거나, 문법 분석을 해서 문장 구조를 파악하거나, 고유명사를 추출하는 등의 용도로 사용합니다. 문서 데이터는 다른 데이터보다 구하기 쉽고 종류도 굉장히 많습니다. 내용에 관계없이 대량의 텍스트가 필요하다면 웹페이지, 잘 정리된 백과사전 자료는 위키백과, 사용자 간의 사회활동 정보는 트위터, 상품에 대한 평가는 쇼핑몰 댓글에서 얻을 수 있습니다. 이렇게 많은 문서 데이터가 존재하는 이유는 인테넷에서의 소통이 대부분 텍스트를 통해 이루어지기 때문입니다. 따라서 문서의 내용을 분석하여 결과를 활요하면 경쟁에서 우위를 확보하거나 통찰력을 얻을 수 있기 때문에 최근 들어 쇼핑몰, 인터넷방송사, 정부기관, 포털사이트 등 다양한 분야에서 문서 분석 시스템을 사용합니다.
하지만 3.1.1절 '텍스트 데이터'에서 말했듯이 문서 분석에서 좋은 성능을 얻기란 생각보다 쉽지 않습니다. 문서의 의미라는 것은 중의적일 때도 있고, 단어가 배열된 순서에 따라 달라지며, 의미가 미묘하게 다른 단어들이 많아서 각각을 구분하기도 어렵기 때문입니다.
이런 어려움을 이겨내고 텍스트의 복잡한 의미를 파악하는 방법에 대해 알아보도록 하겠습니다.(실제 구현은 11장에서 다룹니다.) 이장에서 다루는 내용은 다음과 같습니다.
- 문서 분류 시스템 만들기
- 토픽 모델링
- 문법 분석
- 단어 임베딩
5.1 문서 분류 시스템 만들기
문서 분로(document classification, document categorization)는 말 그대로 문서를 분류하는 것이 목적입니다. 예를 들어 문서를 항목별로 분류하기(도서관에서 책 분류하기), 제품 리뷰로 상품에 대한 긍정/부정 의견 판단하기(sentiment analysis), 문서 내용을 보고 사람과 봇 중 누가 생성했는지 판단하기 등을 들 수 있습니다. 이 절에서는 일상에서쉽게 접할 수 있는 스팸 필터를 머신러닝을 이용해서 만들어 보겠습니다(실제 코드는 11장에서 다룹니다)
5.1.1 문서 분류에 많이 사용하는 피처
문서는 어떤 기준으로 분류할까요? '문서 내요을 분석해서 분류해야지'라고 생각했다면 반은 맞춘 겁니다. 문서에서는 내용, 글쓴이, 서식, 문서 구조, 문서 길이 등 여러가지 피처를 얻을 수 있는데, 그중 문서 내용이 가장 기본이 됩니다.
5.1.1.1 단어 빈도 피처
문서 내용을 완벽하게 이해하는 머신러닝 시스템은 아직 존재하지 않습니다. 그래서 간단한 모델을 이용하여 약간은 부정확하지만 적당한 수준의 시스템을 만든 후 많은 문서로 학습시켜 조금씩 더 나은 좋은 결과를 만들어 내는 방식이 주로 사용됩니다.
이러한 간단한 모델에 사용되는 피처의 예로는 단어 빈도(word frequency, term frequency)를 들 수 있습니다. 이 피처는 문서에서 단어가 얼마나 자주 나오는지 측정해서 문서 내용을 팡가하는 방법입니다. 예를 들어 문서에 축구와 관련된 단어가 자주 등장한다면 그 문서를 축구와 관련된 문서라고 여기는 것입니다. 단어 빈도는 단어가 문서에서 얼마나 나오는지 계산한 후 문서 전체 단어 숫자로 나누어 그 비율을 계산합니ㅏㄷ. 물론 단어가 단순히 몇 번 출현하는지 세는 단어 카운팅(word counting)방식도 많이 사용하지만, 이 방식은 한 문서가 길고(즉, 많은 단어로 이루어져 있고) 다른 문서가 짧은 경우(즉, 적은 단어로 이루어져 있을 경우)공정한 비교가 어렵기 때문에 횟수보다는 빈도를 더 많이 사용합니다. 때로는 단어의 존재 여부만 체크하는 단어 출연(word occurrence)도 유용합니다(단순히 문서를 긍정 또는 부정으로 평가할 때 의외로 좋은 성능을 보여 줍니다).
엄밀하게 정의하면 단어 빈도 피처는 다음과 같습니다.
i 번째 단어 빈도 피쳐 = i 번째 단어가 문서에 나타난 횟수/문서의 총 단어수
즉, 단어 빈도 피처는 가능한 모든 단어(보통 단어집vocabulary이라고 부릅니다)의 개수만큼의 피처를 가지며 각각의 값은 단어가 문서에 나타난 횟수와 문서의 총 단어 수로 결정됩니다.
5.1.1.2 TF-IDF
단어 빈도 피처의 한가지 문제점은 단어 하나하나의 중요도가 동일하기 때문에 빈도수가 높은 단어를 상대적으로 중요하다고 오인할 수 있습니다. TF-IDF(Term-Frequency Inverse-Document Frequency)단어를 이용하면 단어의 희귀도를 고려해서 피처를 생성할 수 있습니다.
단어의 중요도는 어떻게 결정할까요? 다음과 같은 문서가 있다고 합시다.
11살 생일을 몇칠 앞둔 어느 날 해리에게 초록색 잉크로 쓰여진 한 통의 편지가 배달된다. 그 편지의 내용은 다름 아닌 해리의 11살 생일을 맞이하여 전설적인 '호그와트 마법학교'에서 보낸입학 안내장이었다..(이하 생략)
이 문서에서 가장 많이 나오는 단어는 '해리'이므로 해리가 가장 주용한 단어인 것 처럼 보입니다. 하지만 해리포터 시리즈의 각 편을 다룬 기사를 구분하는 데 과연 해리라는 단어가 유용할까요?
예를 들어 해리포터 시리즈를 다룬 기사 3편에 대해 각각 단어 수를 세어봤더니 [표5-2]와 같은 결과를 얻었다고 합시다.
표5-2 기사에 따라 다르게 등장하는 단어 수에 대한 예
기사1 기사2 기사3
해리 132 98 103
호그와트 90 95 55
지팡이 0 120 55
성물 0 0 49
세 기사 모두에서 '해리'라는 단어가 가장 많이 등장하므로, 이 세 기사를 서로 구분하는데 해리는 별로 중요하지 않습니다. 반면 '성물'은 가사 3과 나머지 기사를 구분하는데 쓰일 수 있습니다. 이런 식으로 각 단어가 문서(여기서는 기사)를 구분하는데 얼마나 중요한지 고려하는 피처가 바로 TF-IDF입니다. 여기서 TF는 앞서 설명한 단어 빈도(Term-Frequency)를 뜻하고 IDF는 역문서 빈도(Inverse Document Frequency)를 뜻합니다.
TF-IDF=단어 빈도 * 역문서 빈도
단어 빈도는 5.1.1.1절 '단어 빈도 피처'에서 설명했듯이 단어가 나온 횟스를 문서 전체에 나온 단어 수로 나눈 값입니다. 역문서 빈도는 다음과 같습니다.
가능한 모든 단어 중 I번째 IDF피처 = log( 전체 문서수/i번째 단어가 나타나는 무서 수)
[표 5-2]에서 성물은 한번 나왔기 때문에 IDF가 log(3/1)= 0.477, 해리는 모든 문서에서 나왔기 때문에 log(3/3)=0.000이 됩니다. 많은 문서에 흔하게 등장하는 단어의 IDF가 낮다는 것을 알 수 있습니다. 각 단어의 IDF 는 다음표와 같습니다.
IDF 피처값
해리 log(3/3) = 0.000
호그와트 log(3/3) = 0.000
지팡이 log(3/2) = 0.176
성물 log(3/1) = 0.477
그렇다면 TF도 계산해서실제로 TF-IDF를 구해보도록 합시다. 문서 1에서 해리의 TF는 132/(132+90) = 0.595고 IDF는 0이므로 TF-IDF는 0입니다. 마찬가지로 호그와트의 TF-IDF도 0입니다. 지팡이와 성물의 TF는 0이므로 문서1의 TF-IDF 피처는 [0,0,0,0]입니다. 문서 3의 TF피처가 [0.393, 0.210, 0.210, 0.187]이므로 각각에 IDF를 곱한 TF-IDF는 [0,0,0.210*0.176, 0.198 * 0.477]= [0,0,0.037, 0.0094]입니다.
TF-IDF 피처는 이렇게 중요한 단어에 강조를 주어 문서를 구분하는데 도움을 줍니다.
전체적으로 자주 나오지 않는 단어의 로그값이 너무 작아서 IDF가 예외적으로 커지는 것을 막기 위해 IDF에 약간 변형을 주어 사용하기도 합니다. 바로 log를 취하기 전에 1을 더해서 다음과 같이계산하는 방법입니다.
스무딩된 IDF피처 = log(1 + 전체문서수/i번째 단어가 나타나는 문서수)
5.1.1.3 토픽 또는 군집에 기반한 피처
지금까지는 단순희 단어 출현 횟수를 세거나 그 중요도를 고려해서 피처를 정하는 방법을 알아 보았습니다. 단어외에 더 큰 의미 단위를 이용해보면 어떻까요? 예를 들어 단어들을 군집한 후 각 문서에 나타나는 단어가 어떤 군집에 해당되는지, 혹은 각 문서가 어떤 토픽으로 구성되는지 파악한 다음 그 토픽들이 가지는 중요도를 계산해서 피처를 만드는 방법을 생각해 볼 수 있습니다.
여기서는 이러한 방법의 문서에서 피처를 만들 수 있다는 정도만 언급하겠습니다. 자세한 내용은 5.2절'토픽 모델링'에서 다룹니다.
5.1.2 피처를 이용해서 실제로 분류하기
5.1.1절 '문서 분류에서 많이 사용하는 피처'에서는 문서에서 피처를 뽑아보았으며, 그를 통해 문서를 어떤 고정된 길이의 숫자로 변환시켰는데, 여기서는 그것을 이용해서 문서를 어떻게 분류할 수 있는지 이양기 해보겠습니다.
문서를 피처로 변환한 후에는 피처를 분휴할 수 있는 먼신러닝 기법을 사요하면 됩니다. 이 절에서는 대표적인 문서 분류 기법인 로지스틱 희귀와 SVM에 대해 살펴보겠습니다.(물론 결정 트리등 거의 모든 분류 깁버을 사요할 수 있습니다.)
5.1.2.1 로지스틱 회귀
로지스틱 회귀는 2.1.2절 '간단한 모델'에서 잠깐 소개햇던 선형 회귀 모델에 로지스틱 함수를 적용해서 분류를 하는 기법입니다. 이 모델은 간단해서 구현이 쉬우며 좋은 성능을 내기 때문에 자주 사용됩니다. 로지스틱 회귀는 선형 회귀와 밀접한 연관관계를 가지고 있습니다.
선형 회귀는 2.1.2절 '간단한 모델'에서도 잠깐 소개를 했었느데요, 주어진 입력과 출력 사이에 선형 관계가 존재한다는 가정을 합니다. 주어진 피처(xi)에 따라 다음과같이 정의됩니다.
선형 회귀는 간단하지만 학습이 빠르고 모델이 단순함에도 불구하고 좋은 성능을 보이므로굉장히 널리 쓰입니다. 하지만 주어진 입력에 따라 연속적인 산술값을 출력하는 회귀 기법이기 때문에 분류를 할 때는 약간 변형시켜 사용해야 합니다. 이 변형을 위해 로지스틱 함수를 이용합니다.
로지스틱 함수는 선형 회귀의 연속적인 숫자값을 확률값으로 변환합니다. 이를 이용해서 결과가 어떤 분류에 해당하는지와 해당 하지 않는 지 알 수 있습니다.(이항 분류라고 합니다.) 옐르 들어 입력 데이터의 로지스틱 회귀 값이 0.5보다 크면 분류 1에 속하고, 0.5보다 작으면 분류 0에 속한다는 것을 알 수 있습니다.
좀 더 복잡한 로지스틱 회귀에는 다항 로지스틱 회귀가 있습니ㅏㄷ. 이를 소프트맥스 회귀라고 부릅니다.(딥러닝에서 스프트맥스 회귀라는 표현을 더 많이 사용합니다.) 다항 로지스틱 회귀는 다음과같이 정의되며, 이항 로지스틱 회귀와 굉장히 비슷하다는 것을 알 수 있습니다.
수식이 조금 복잡하게 보일텐데,간단히 설명하면 모든 가능한 항목에 대해 선형 회귀를 수행한 다음 소프트맥스 함수에 통과시킨 겁니다. 소프트맥스 함수는 로지틱스 함수의 확장판으로 생각하면 되는데, 여러 개의 선형 회귀 값을 가지고 각각을 0 부터 1까지 변환시킨다고 생각하면 됩니다.
예를 들면 항목 A에 대한 파라미터 (Wa)가 벡터로 [3, -1]이고, 항목 B에 대한 파라미터(Wb)가[5,2], 항목 C에 대한 파라미터(Wc)가 [-1,10]인 예를 생각해 봅시다. 각각의 항목에 대한 W와 입력의 벡터곱에 exp를 취한 값으로 해당 항목의 확률을 계산합니다. 그러므로 만일 입력(x)이 [1,1]이면 다음과 같이 계산됩니다.
- 항목 A: exp(3*1 + -1*1)= 7.4
- 항목 B: exp(5*1 + 2*1) = 1096.6
- 항목 C: exp(-1*1 + 10 *1) = 8103.1
각각의 항목에 대한 확률은 각각의 값을 전체 합(7.4 + 1096.6 + 8103.1 = 9707.1)으로 나눈 값입니다.
- 항목 A가 맞을 확률: 7.4/9707.1 = 0.0008
- 항목 B가 맞을 확률: 1096.6/9707.1 = 0.1191
- 항목 C가 맞을 확률: 8103.1/9707.1 = 0.8801
이렇게 문서를 피처로 변환시켜서 그것을 입력으로 계산하면 각 항목에 속할 확률값이 나옵니다. 그중 가장 높은 확률을 가지는 항목이 문서의 분류값이 됩니다.
5.1.2.2 SVM
SVM은 문서 분류 문제에 사용하는 표준적인 분류 모델입니다. 로지스틱 회귀가 확률을 로지스틱 함수를 사용해서 모델링한다면 SVM은 확률을 직접 계산하지 않고 데이터가 어떤 '경계선'을 넘지 않는지 검사하는 분류합니다. 결과적으로 SVM은 확률값이 아닌 분류값을 출력합니다.
'경계선'에 대해 좀 더 이야기 하겠습니다(경계선의 머신러닝 공식 용어는 결정 경계선(decision boundary입니다). 데이터가 피처값에 의해 어떤 공간에 분포하고 있다고 합시다. 여기서 한 데이터에 피처 값이 두개 주어졌을 때를 생각해 봅시다.
5.1.2.3 그 외에 만히 쓰이는 분류 방법
로지스틱 회귀와 SVM이 문서 분류에 굉장히 널리 사용되지만, 결정 트리나 그레디언트 부스티드 트리 등의 모델도 많이 사용됩니다. 일단 5.1.1절 '문서 분류에서 만힝 사용하는 피처'에서다룬 것처럼 문서를 피처로 변환합니다. 그리고 나서 앞서 소개한 몇 가지 유명한 머신러닝 모델중 성능이 잘 나오는 것을 고르면 됩니다.
문서에서 좋은 피처를 뽑는 것과 좋은 모델을 찾는 것 중 어떤 것이 더 중요한지 궁금할 것입니다. 사실 정답은 없지만(정확하게는 데이터에 따라 다릅니다). 우선 단어 빈도나 TF-IDF피처로 시작해서 몇 가지 머신러닝 기법을 시도해 보는 것이 좋을 것 같고, 분류가 잘되지 않는 문서를 직접 보면서 어떤 피처가 분류에 도움이 될지 생각해 보는 것이 좋을 것 같습니다.
5.2 토픽 모델링
토픽 모델링은 문서에 존재하는 토픽을 추출하는 기법입니다. 토픽은 문서의 주제를 뜻하는데, 문서 분석의 경우 어떤 단어가 특정하게 분포하는 것을 토픽이라고 합니다. 옐르 들어 스포츠에 대한 단어가 다른 단어보다 많이 나오면 그 문서의 토픽은 스포츠와 관련되었다고 볼 수 있고, 연예인에 대한 단어가 많이 나오면 연예인과관련되었다고 볼수 있습니ㅏㄷ.
토픽 모델링은 문서가 토픽들로부터 생성된 단어로 이루어진다고 가정합니다.
- 문서에는 여러 토픽이 각각의비중을 가지고 존재합니다.
- 토픽마다 단어의 분포가 달라집니다.
- 문서를 작성할 때 토픽의 비중에 따라 토픽을 고라가면서 단어를 뽑습니다.
문서가 토픽에 기반하여 생성된다고 가정하면 문서 내용을 단순히 단어가 아니라 토픽이라는 큰 의미 단위를 통해 파악할 수 있습니다. 예를 들어 어떤 문서는 스포츠 토픽과 연예인 토픽을 7:3으로 썪었고, 또 다른 문서는 과학과 기술을 8:2로 썩였다고 판단할 수 있는 거죠. 그리고 일반적으로 토픽에 따라서 단어가 나오는 비율만 달라질 뿐 단어의 순서는 고려하지 않습니다.
이렇게 토픽을 가정하고 이를 문서를 분석하는 머신러닝 기법을 토픽 모델링이라고 합니다. 이 절에서는 토픽 모델링에 가장 유명한 LDA에 관해 알아보도록 하겠습니다.
5.2.1 LDA
LDA는 확률모델을 통해 문서의 토픽과 토픽에 분포하는 단어들을 분석합니다. 이전에도 말했듯이 LDA는 잠재 디리클레 할당이라는 뜻인데, 문서 안의 토픽 하나하나 디리클레 분포를 따르며, 문서를 그런 토픽에 할당한다는 의미에서 이렇게 부릅니다.
LDA에서는 하나하나의 문서가 다음 과정을 거쳐 생성된다고 가정합니다.
1. 문서에 단어가 몇 개 있는지 결정합니다.
2. 문서마다 토픽이 어떻게 분포되어 있는지, 토픽마다 단어 분포가 어떤지 디리클레 분포(Dirichlet distribution)에 따라 정의합니다.
3. 문서의 제일 첫 단어부터 끝 단어까지 다음 과정을 거칩니다.
a. 현재 위치의 단어가 어떤 토픽과 관계있는지 정합니다.
b. a에서 정한 현재위치의 토픽에 따라 단어의 분포를 결정하고 그 중에서 가장 높은 확률의 단어를 선택합니다.
간단히 요약하면, 문서가 어떤 토픽을 가질 확률, 각 위치의 단어가 어떤 토픽에 해당할지의확률, 그 토픽에 따라 단어가 어떤 확률로 생성될지 정의해서 문서를 활률 모델로 설명한 것으로 볼수 있습니다.
이제부터 LDA가 어떤 일을 하는지 구체적인 예제를 살펴보겠습니다. 다음은 LDA 논문에 수록된 내용으로, LDA를 이용해서 AP통신 기사에서 토픽을 추출한 것입니다.
이렇게 LDA를 통해 각 토픽이 어떤 단어들로 이루어져 있는지, 문서가 어떤 토픽을 가지는지 알 수 있습니다. 추출한 토픽 정보를 이용해서 5.1.1.3 절 '토픽 또는 군집에 기반한 피처'에서 설명한 것처럼 분류에 사용될 피처를 만들기도 하고, 문서 분석을위해 토픽 자체를 사용하기도 합니다. 또한 이러한 토픽을 이용해서 문서를 요약하거나 군집화하기도 합니다.
여기서는 토픽 모델링을 문서에 적용했는데, 문서 데이터와 비슷한 양상을 보이는 데이터가 있다면 토픽 모델링을 적용해서 내용을 간추리는데 도움이 될 수도 있습니다. 예를 들어 한 사용자의 쇼핑 정보를 문서로 간주하고 구매 항목을 단어로 취급하면 여러 상품을 토픽처럼 묶어서 분석할 수 있습니다.
5.3 문법 분석
문법분석은 문서의 문법 구조를 분석해서 내용을 파악하는 기법입니다. 문법을 분석해서 파악하기 때문에 단순히 단어 수만 세서 파악할 때보다 내용을 좀 더 정확하게 파악할 수 있습니다. 같은 단어를 사용하더라도 문법 구조에 따라 의미가 정반대가 되기도 하고, 대명사가 지칭하는 단어가 달라질 수 있기 때문입니다.
물론 앞서 잠시 이야기 했듯이 문서를 하나하나 완벽하게 분석하는 ㅣㅇㄹ은 어렵습니다. 문법 분석은 아직 완전히 풀린 문제로 보기 어렵고, 현존하는 기술로는 아직 단어 중심의 분석만큼 큰 규모의 분석을 하기 어렵습니다. 그렇기 때문에 문서의 뜻을 광의적으로 파악하는 문제보다 문장 하나의 뜻을 세부적으로 파악하는 것이 결정적인 역할을 하는 경우에만 적용합니다. 옐르 들어 신문기사를 분류하는 문제보다는 채팅 메시지를 보고 그것이 긍정인지 부정인지 파악하는 것을 생각해 볼 수 있습니다.
이 절에서는 두 가지 대표적인 문법 분석방법에 대해 알아보겠습니다. 첫 번째는 문서 내의 각 단어의 품사를 파악하는 품사 태깅(POS :Part of Speech Tagging)문제고, 두 번째는 각 단어가 어떤 의미 단위에 속하는지(옐르 들어 장소인지 사람인지)파악하느 고유명사 추출(NER: Named Entity Recognition)입니다.
5.3.1 품사 태깅
품사 태깅 문제는 주어진 문서에서 각 단어의 품사(주어, 목적어, 형용사 등)를 파악하는 것입니다. 보통 문서 전체에서 품사를 한번에 파악하기보다는 각 문장의 품사를 파악하는 것이 일반적입니다. 다음 문장을 읽으면서 단어들의 품사를 어떻게 결정하느지 생각해 봅시다.
The brown fox jumps over the lazy dog.
위 문장은 'The'로 시작합니다. 이 단어는 항상 관사로 상요되므로 뒤에 오는 단어가 명사임을 알 수 잇습니다. 그다음에 나온 단어는 'brown'인데, 이 단어는 형용사나 명사로 사용되며, 다음에 명사가 나왔기 때문에 이 명사를 수식하는 형용사로 쓰였다는 것을 아 수 있습니다. 그 다음에 'fox'라는 명사가 나오면서 이 명사절은 끝납니다. 문장 구조에서는 명사절 뒤에 동사가 나옵니다. 여기서 'jumps'가 그 역할을 하고 있습니다. 이런 식으로 문장을 끝까지 처리하면 다음과 같은 문법 트리를 얻게 됩니다.
(주어(명사구 The brown fox)
(동사 jumps
(전치사 over
(명사구 the lazy dog))))
POS 태깅 문제를 푸는 과정을 살펴보면 현재 단어와 이전 단어에 따라 품사가 결정 된다는 것을 알 수 있습니다. 이런 방식의 문제를 2.1.4.1절 '순차 모델'에서 잠깐 다루었는데, 바로 순차 모델링(sequential modeling)입니다. 품사 태깅에 순차 모델을 이용하면 문자으이 첫 단어부터 마지막 단어까지 단어 하나하나가 입력으로 들어가고, 모델의 상태를 순차적으로 업데이트해가며 문장 구조를 분석합니다.
이런 순차 모델링의 가장 대표적인 기법으로는 CRF와 최근 많이 쓰이는 딥러닝 기법인 RNN과 그중에서도 유며안 LSTM(Long Short-Term Memory)이 있습니다. 이어서 RNN과 LSTM을 간단히 소개하겠습니다.
5.3.1.1 RNN
2.1.4.1절 '순차 모델'에서 순차 모델을 설명하면서 잠깐 RNN의 정의에 대해 살펴봤습니다. 여기서는 그 정의에 좀 더 살을 붙여보겠습니다.
RNN을 사용한 POS 태깅의 경우 앞서 설명했듯이 순서를 가지는 데이터(여기서는 문장에서의단어들)를 앞에서부터 하나씩 읽어나가면서 품사 예측을 수행합니다. x는 문장의 단어의 각 단어들의 피처가 됩니다. 간단하게 전체 단어집에서 명 몇번째 단어에 해당하는지 생각할 수 있겠고요, 복잡하게는 사전에서 이 단어에 어떠한 뜻이 있는지 혹은 어떤 품사들을 가질 수 있는지에 대한 정보를 담을 수 있습니다. 출력 y는 모델이 예측한 품사입니다. h는 문장의 첨음부터 단어를 하나씩 보면서 전에 어떤 단어들이 모델의 입력으로 들어왔는지 기억하는 부분입니다. 즉,각 단어를 하나씩 보면서 바로 직전의 상태(ht-1)와 현재 단어(xt)를 가지고 현재 상태(ht)를 업데이트 합니다.
순서에 입각한 RNN의 학습은2장에서 예로 든 순서가 없는 모델보다 약간 더 복잡합니다. 순서가 없는 경우에는 입력 x와 출력y의 한 쌍이 다른 입출력과 독립적이기 때문에 각각의입출력에 대해 최적화를 했었는데, RNN의 경우에는 현재 단어와 지단 단어가 h를 통해 연결되기 때문에 한 문장 안의단어들은 함께 연관되어 학습되어야 합니다.(문장끼리는 보통 독립적이라고 생각합니다.) 이 학습을 위해서는 보통 경사하강법을 시간에 따라 거슬러 올라가면서 계산하는 방법(Backpropagation Though Time)을 많이 사용하며, 보통 이 방법은 라이브러리에 구현되어 있기 때문에 직접 작성하기 보다는 구현된 라이브러리를 활용하면 됩니다.
학습 방법에 대해 굳이 설명을 한 이유는 RNN이 가지고 있는 한계점에 대해 설명을 하고 싶었기 때문입니다. RNN은 문장이길어져서 단어 간의 연관관계가 멀리 떨어져 있을 때 제대로 모델링하지 못하는 문제가 있습니다. 이론적으로는 내부에 존재하는 표현형(h)과 연관관계가 멀리 떨어져 있더라도 제대로 모델링할 수 있어야 합니다. 하지만 앞서 언급한 '시간에 따라 거슬러 올라가며 계산하는 방법'으로 멀리 떨어져 있는 단어의 정보가 제대로 전달되지 않는 문제가 있습니다. 이 문제를 소멸하는 1차 미분값(vanishing gradient)이라고 부릅니다. 나열된 순서를 거슬러 올라가며 1차 미분값을 계산하다보면 그 값이 점점 작아져서 정보가 잘 전달되지 않습니다. 그렇기 때문에 문장이 길어지면 연관관계를 잘 모델링 하지 못해서 원하는 성능을 얻지 못하는 문제가 있게 되는 것입니다.
이 문제를 해결하고자 등장한 것이 LSTM(long Short-Term Memory)입니다. 물론 LSTM 모델이 앞서 설명한 기본적인 RNN보다 훨씬 더 복잡하기 때문에 학습이 어려워서 항상 잘 동작하는 것은 아니지만 멀리 떨어진 연관관계를 모델링하는 데는 탁월한 성능을 보여줍니다.
지금까지는 간단한 RNN모델만 이야기 했는데, [그림 5-6]처럼 직전 표현형만 고려하는 것을 넘어 두 단계 이전 표현형을 고려하는 등의 시도가 있습니다. 간단한 RNN 구조를 층층이 쌓아서 더 복잡한 연관관계를 학습하려는 시도인데, 보통 딥러닝이라고 불리는 모델은 이러한 복잡한 구조를 많이 사용합니다. 2.1.4 절 '구조가 있는 모델'에서 설명한 것처럼 구조가 복잡할수록 데이터가 많아야 제대로 동작합니다.
5.3.1.2 LSTM
LSTM은 RNN 모델 중 하나로 RNN기본 모델의 단점을 해결하고자 고안되었습니다. 가장 기본적인 차이점은 전에 가지고 있던 정보를 계속 가지고 갈지 혹은 잊을지 판단하는 신경망 구조가 들어 있다는 것입니다.
[그림 5-7]을 보면 [그림 5-6]과 비슷하게 문장의 흐름(xt-1, xt, xt+1)에 따라 각 단어가 입력으로 들어가고 각각에 해당하는 출력(yt-1, yt, yt+1)이 있습니다. 하지만 [그림 5-6]과는 다르게 상태를 저장하는 부분에 복잡한 박스가 있습니다.
이 박스는 입력과 현재까지의상태를 이용해서 내부에 가지고 있던 정보를 업데이트할지 잊을지 판단합니다. 문장을 앞에서부터 보다가 내용이 어느정도 정리된 것 같다고 판단되면 지금까지의 상태 정보를 잊고 새로 입력된 단어가 별로 유용하지 않으면 지난 단계까지의 상태를 많이 기억하고 업데이트를 조금만 합니다. 그리고 이 상태를 C(셀cell)라고 불리는 곳에 저장합니다.
이러한 선택적인 업데이트와 기억방식은 박스의 특별한 구조 때문인데, 자세한 동작 방식은 다음과 같습니다. 앞서 설명한 것처럼 C는 상탯값, W는 모델의매개변수를 뜻합니다.
1. 맨 왼쪽 첫번째 구조는 망각 게이트(forget gate)라 불리는데, 지금까지 기억했던 상태와 현재 입력에 파라미터를 곱해서 상태를 잊을지 말지 정합니다.
ft = Q(Wforget[Ct-1, Xt])
2. 그다음 구조는 입력 게이트(input gate)인데, 상태와 현재 입력을 가지고 얼마나 기억할지 정합니다.
it = Q(Winput[Ct-1, xt])
3. 그리고 그다음 상태를 앞에서 설명한 RNN과 비슷하게 추측합니다.
Ct =tanh(Wcell[Ct-1, Xt])
4. 이렇게 3가지를 계산하고 나면 망각을 얼마나 하고(항목 1) 업데이트를 얼마나 할지(항목2) 어떤 값을 업데이트할지(항목 3) 정해서 업데이트 합니다.
Ct = ft*Ct-1 + itCi
5. 실제 출력은 현재 상태(Ct)와 입력을 이용해서 결정합니다.
y = Q(Wy[Ct, xt])
수식 때문에 햇갈린다면 한글로 된 설명 부분만 이해해도 됩니다. 기본 RNN과 비슷한게, 내부에 어떤 상태가 있고(C, RNN의 h와 동일하지만 LSTM에서는 주로 셀이라고 부릅니다), 전 상태와 현재 입력에 따라 현재 상태를 얼마나 기억할지, 얼마나 업데이트할지, 무엇을 업데이트 할지 파라미터로 정합니다.
LSTM학습은 파라미터들이 어떻게 기억하는지, 출력을 어떻게 내는지에 대한 손실함수를 만들고(보통 교차 엔트로피를 많이 사용합니다) 경사하강법을 응용한 방법으로 학습을 수행합니다. 이걸 직접 구현하기는 복잡하므로 라리브러리에 주어진 기본 구현을 사용하면 됩니다.
[그림 5-7]은 광장히 단순화한 모델이며, 실제 사용할때는 구조가 훨씬 더 복잡해집니다. 옐르 들어 망각 게이트나 입력만 고려하는 것이 아니라 전 단계의 출력값까지 교려하거나, 아니면 몇 단계 전의 입력을 고려하기도 합니다. 또한 입력과 출력 사이에 LSTM박스를 하나만 두는것이 아니라 박스를 층층이 쌓아서 더 복잡한 학습에 사용합니다(보통 딥러링은 이렇게 복잡한 구조를 지칭합니다.) 반면 LSTM의 망각과 입력 게이트를 묶어서 망각하는 만큼 기억을 하는 GRU(Gated Recurrent Unit)같은 약간 더 간단한 모델도 있습니다.
이렇게 LSTM을 이용하면 RNN보다 더 복잡하고 멀리 떨어진 연관관계를 모델링할 수있습니다.LSTM은 POS 태깅 문제에도 사용되지만, 음성 데이터처럼 시간에 따라 변화하는 데이터를 분석하느데도 많이 사용됩니다.
5.3.2 고유명사 추출(NER)
구글 어시스턴트, 시리, 아마존 에코 등 대화형 봇이 유행입니다. 이런 봇들이 대화에서 장소나 시간 정보를 발견하면 일정을 만들어주는 머신러닝 시스템을 만든다고 생각해봅시다. 그렇다면 문장에서 어떤 부분이 장소고 어떤 부분이 시간인지 추측해야겠지요? 이런일을 가능하게 해주는 것이 바로 NER(Named-Entitiy Recognition)입니다. NER은 텍스트에서 인물, 조직, 장소, 일정 등을찾아내는 문법 분석 방법입니다. 책이나 웹 페이지에서 이름, 장소, 주소, 제품명을 인식하는 데 사용할 수 있습니다.
NER은 POS 태깅 문제와 몇 가지 비슷한 성질을 가집니다. 첫 번째로 품사 문제 때처럼 사전정보를 사용하면 많은 도움이 됩니다(유명한 사람의 이름이나 장소 같은 고유명사가 특히 중요합니다.) 두번째로 품사 문제를 풀 때와 마찬가지로 앞뒤에 나열된 단어에 따라 영향을 받습니다. 예를 들어'정문 앞에서 만나자'라는 부분이 있다고 합시다. 이때 '에서 만나자'라는 표현은 장소와 연관성이 있기 때문에 '정문 앞'에 해당하는 단어가 장소사전에 등록되어 있지 않더라도 장소일 확률이 높습니다.
이 절에서는 앞서 설명한 RNN이나 LSTM모델을 이용해서 어떻게 NER문제를 푸는지 알아보겠습니다. 또한 참고로 머신러닝 기법을 사용하지 않고서도 어떻게 NER문제를 풀 수 있는지에 대해서도 살펴보겠습니다.
5.3.2.1 순차 모델을 사용한 NER(RNN/LSTM)
NER도 머신러니의 순차 모델을 많이 사용합니다. 예를 들어 LSTM과 같은 순차 모델에 입력으로 NER 문제에 도움이 되는 장소사전이나 품사를 넣고, 출력값으로 NER 항목들을 주어서 학습하는 방식입니다. NER 항목은 필요에 따라 여러가지를 생각할 수 있지만 일반적으로 '장소, 일정, 인물, 해당 항목 없음' 이런 식으로 분류를 만들어 학습을 진행하면 됩니다.
다음 절에서 설명하겠지만 이 방식의 가장 큰 문제는 문장 하나하나마다 순차 모델을 돌려야 하므로 속도가 그렇게 빠르지는 않아서 문서를 대규모로 분석하기에는 시간이 많이 소요된다는 것입니다.
5.3.2.2 머신러닝은 아니지만 NER에 사용되는 기법
NER은POS태깅 문제와 약간 다르게 큰 규모의문서 분석에서도 종종 사용됩니다. 옐르 들어 소셜 네트워크나 포털사이트에서 사용자가 신문 기사를 포스팅하면 기사에 나오는 장소나 인물에 자동으로 링크를 만들어 주는 시스템을 생각할 수 있습니다.
물론 향휴에는 머신러닝의 발전으로 RNN이나 LSTM도 이런 큰 규모의 문제를 잘 처리할 거라 생각합니다. 하지만 머신러닝을 이용하지 않고 정규표현식을 이용해서 처리하는 방법도 있다는 점을 알려드립니고 싶습니다. 예를 들어 \d\d\d\d-\d\d\d\d-\d\d\d\d와 같이 숫자 3개, 4개,4개가 '-'로 연결되어있다면 전화번호일 확류이 굉장히 높습니다. 앞서 말씀드린 인물사전, 장소사전과 적절한 정규표현식을 사용하면 순차 모델을 사용하는 것보다 정확도나 발견 확률이 떨어지지만 빠르게 대규모 분석이 가능합니다.
5.4 단어 임베딩 학습-word2vec
컴퓨터로 단어의 의미를 나타내는 방법은 크게 이산표현(discrete representation)과 분산표현(distributed representation)이 있습니다.
쉽게 설명하자면 이산표현은 그 단어 자체를 이요하며 의미를 나타내는 것입니다. 옐르 들어 고양이라는 단어가 있다면 사전을 이용하여 단어를 정의하는 것이죠, 따라서 이산표현에서 단어 하나의 의미는 말뭉치에 든 모든 단어 수를 벡터 크기로 하는 원-핫 인코딩 벡터(3.3.2절'카테고리 데이터 표준화'참조)로 표현합니다.
이와 달리 분산 표현은 한 단어의 주변 단어를 이용해서 의미를 표현합니다. 즉, 분산 표현에서는 고양이는 '귀엽다', '야옹거린다'라는 주변 단어로 의미가 정해집니다. 이러한 분산 표현은 사전에 정의되지 않은 새로운 단어도 표현할 수 있으므로, 더 많은 단어를 분석에 이용할 수있습니다. 분산 표현을 이용하면 단어 하나는 실숫값으로 이루어진 벡터가 되는데, 이를 단어 임베딩(word embedding)이라고 합니다.
이산 표현과분산 표현의 예는 다음과 같습니다.
- 이산 표현
고양이 = [0,0,0,....1,0,0](원-핫 인코딩 벡터. 하나의 항만 1이 됩니다.)
여기서 벡터의 길이는 말뭉치 안의 단어(어휘집의 크기) 수가 됩니다.
- 분산 표현
고양이= [1.281, -2.321, 4.509,....3.212]
여기서 벡터의 길이는 사용자가 지정한 길이가 됩니다.
word2vec은 뉴럴넷을 이용하여 분산 표현을 학습하는 모델입니다. 이러한 시도는 오랫동안 있어왔지만 2013년에 소개죈 word2vec이 계산이 빠르고 간단해서 널리 쓰이므로, 이 책에서는 word2vec에 대해 자세히 살펴보겠습니다.
word2vec은 단어가 주어지면 그 단어와 주변 단어가 같이 일어날 확률을 구합니다.
word2vec의 목적 함수로는 스킵-그램과 COW가 있습니다.
- 스킵-그램(skip-gram):단어 하나(xt)를 받아서 그 주변에 같이 나타날 확률이 높은 단어들(context)을 구합니다. 즉, p(context|xt)를 구합니다.
- COW(continuous bag or words): 주변 단어들(context)을 받아서 그 단어들과 같이 나타날 확률이 높은 단어(xt)를 구합니다. 즉p(xt|context)를 계산합니다.
그림으로 나타내면 다음과 같습니다.
word2vec 은 한 단어wc가 주어졌을 때 그 주변에 단어가 존재하면 0, 그렇지 않으면 1로 하는 원-핫 인코딩을 생성해서 학습합니다. 예를 들어 '귀여/운 태비 고양이/가 고등어 통조림 앞/에서 야옹/하고 울/었/다'라는 문장을 앞뒤 두 단어를 이용하여 word2vec을 학습할때, 고양이를 중앙 단어로 입력받으면 (고양이, 태비)는 1, (고양이, 울)은 0이 되겠죠.
이 책에서는 의미적인 유사성을 얻기 위해 자주 사용하는 스킴-그램의 목적 합수를 살펴보겠습니다.
현재의 단어를 wt, 학습에 사용할 위도우 크기(주변 단어의 수+1)를 2m+1이라고할때, 스킴-그램의 목적은 다음의확률을 최대로 하는 파라미터의 집합 Q를 찾는 것입니다.
댓글 없음:
댓글 쓰기