우리의 목적은 어떤 주어진 문장을 읽은 다음, 그 문장이 어떤 카테고리에 속하는 글인지를 판단하는 인공지능 카테고리 판별기를 개발하는 것. 분류할 카테고리는 인문과 경제, 과학으로 나누어진다.
각 카테고리의 글은 특징이 있으며, 사람은 그 글을 읽는 과정에서 해당 카테고리와 관련이 있는 단어나 독특한 표현을 무의식중에 느낄 수 있다. 또한 단어를 식별하고, 문장의 구조를 파악하며, 그 속에 담긴 의미를 이해하고, 그 글을 읽으면서 연상되는 여러 가지 정보들을 생각 할 수 있다.
자연어 처리의 핵심은
자연어는 어떻게 다루는가
컴퓨터로 무엇인가를 판별한다는 것은 프로그램상에서 수학적인 계산을 할 수 있다는 것. 자연어 처리는 어떻게 수학적으로 다뤄야 할까?
특징 추출과 학습 과정에서는 도대체 어떤 일이 벌어지는가
우리가 판별하려는 각 카테고리의 글들이 어떤 특징을 가지며, 그러한 특징이 어떻게 수학적으로 표현되고, 판별하는 프로세스는 어떻게 구현되는가.
정답률은 어느 정도로 나오는지
'인공'적으로 만들어진 지능으로 하여금 '자연'적으로 만들어진 언어를 처리하게 만들어야 하는 것은 매우 힘들다. 우리가 평소에 크게 의식하지 않고 자연어를 이해하는 과정을 수학적인 개념으로 구현할 수 있어야 한다. 우리가 인공지능을 구현하기 위해 프로그래밍을 하는 과정은 수학적인 개념을 표현하는 작업이기에, 우리가 하고 싶은 일을 수학적인 개념으로 만들어 낼 수 있어야 한다.
사람은 보통 자연어를 다음과 같이 처리한다 알려져 있으며, 이를 이용하고자 한다.
우리는 언어를 배울 때 하나의 문장을 명사와 동사, 형용사와 같은 품사들로 분해하며 이해한다. 이 과정을 형태소 분석이라고 한다. 정확하게 말하면 분해를 할 때 품사에만 국한하지 않고, 언어에서 의미를 갖는 최소 단위(형태소)까지 분해한다.
우리는 인공지능을 만들기 위해서 공부한다.
우리/는/인공지능/을/만들/기/위해서/공부/한다.
이때, 영어나 유럽 지역의 언어는 띄어쓰기를 하는 단위가 단어의 단위랑 거의 일치하기에 이러한 과정이 상대적으로 쉽다. 그러나 아시아 지역의 단어는 단어가 단어 단위로 깔끔하게 분해되지 않는 경우가 있기에 잘못 쪼개질 가능성이 있다. 이에 영어를 사용할 때보다 한국어 문장을 사용할 때 기술적인 난이도가 더 높아진다.
이에 형태소 분석을 할 때에는 해당 언어의 사전이 필요하다.
조각난 단어들 간의 관계를 찾는 과정. 산산조각난 단어들 중에서 어디서 어디까지가 주어이고, 술어인지, 명사구이고 동사구인지, 단어들 간의 관계를 파악해야 한다.
어떤 지문을 주고 글쓴이의 의도가 무엇인지, 글의 주제가 무엇인지, 그 글에 대한 올바른 답은 무엇인지와 같은 문제.
인공지능은 문장의 의미를 분석할 때 수학적인 개념으로 표현할 수 있어야 하는데, 이때 벡터의 개념을 이용한다. 이를 벡터 공간(vector space) 분석이라고 한다.
이는 어떤 문장에 포함된 단어 개수와 같은 정보들을 벡터를 사용함으로써 해당 문장의 특징을 수학적으로 표현하려는 접근 방법이다. 벡터를 사용하면 내적과 같은 수학적인 처리 및 코사인 유사도를 통한 문장 비교를 할 수 있다. 벡터 공간 분석에서는 문장을 고차원의 벡터로 추상화한 후 다양한 계산을 하게 되므로, 사람이 쉽게 직관적으로 이해할 수는 없다. 반면 컴퓨터에게는 이런 방법이 오히려 직관적이기에 자연어를 효과적으로 처리할 수 있다.
즉, 수많은 문장들로부터 특징을 추출하고, 각 문장들이 얼마나 비슷한가를 생각하는, 마치 사람이 자연어를 처리하는 것과 같은 과정을 모방할 수 있다.
단어를 분해하는 방법 중에는 N-gram 분석이 있다. 이는 '사전을 사용하는 데는 한계가 있고, 기계가 품사 분해를 정확하게 하는 것도 어렵기에 차라리 적당한 크기로 잘게 쪼개서 분석하자'라는 접근 방식. 이에 단어를 분해할 때 별다른 분석 없이 기계적으로 끊는데, 하나의 문장을 N개의 글자당 하나씩 뒤로 옮겨가면서 분할한다.
예) N=3
우리는 / 리는□ / 는□인 / □인공 / 인공지 / 공지능 / 지능을 / 능을□ / 을□만 /...
이때 □는 공백을 의미하고, 적용한 N-gram은 음절 단위 N-gram이다. 어절 단위 N-gram은 다음과 같은 결과가 나온다.
우리는 인공지능을 만들기 / 인공지능을 만들기 위해서 / 만들기 위해서 공부한다.
이러한 방법을 사용한다면, 일단 사전이 필요 없고 단어를 분할하는 처리 속도도 빠르다. 사전에 의존하지 않기 때문에 사전에 등록되지 않은 사람 이름이나, 전문 용어, 신조어, 약어와 같은 미등록 단어를 다룰 수 있으나 단어를 분할하는 방법이 너무 단순하다보니 의도한 단어가 아닌 것이 포함될 수도 있으며, 분할 후 데이터 양이 너무 많아질 수 있다.
인문과 경제, 과학 카테고리에서 '카테고리 판별기'를 만들기 위해 먼저 문장을 단어로 분해하고자 할때, 사용되는 데이터 세트는 인문과 경제, 과학과 같은 일반적인 카테고리의 글들이기에 사전에 없는 미등록 단어는 많지 않을 것으로 예상되어, N-gram 방식보다는 사전을 활용한 형태소 분석으로 진행할 것이다.
한국어의 형태소 분석에는 mecab-ko을 사용할 것이다. 이는 일본어용 mecab을 한국어의 특성에 맞게 수정한 것이다. 이를 한국어 형태소 분석에 사용하기 위해서는 사전인 mecab-ko-dic을 추가해야 한다.
이때, 헷갈리기 쉬운 문장이나 전후의 문맥으로부터 내용을 유추해야 하는 글은 형태소 분석을 하더라도 원하는 결과가 나오지 않을 수 있다.
문장에서 분해한 단어들 중에는 우리가 판별하려는 카테고리의 문장 특징과 관련 없는 정보도 다수 포함되어 있다. 이렇게 문장을 특징하는데 큰 영향을 주지 않는 단어들을 스톱워드(stop words)라고 부른다. 한국어의 '에', '에서', '를'이나, 영어의 'of', 'the' 등과 구두점이 있다. 이러한 것들을 처리해야 의미 있는 결과를 얻으면서 데이터 연산 과정을 줄일 수 있다.
하지만 경우에 따라서는 이러한 단어들이 문장의 특징을 결정할 수 있을 수도 있기에 스톱워드를 제거하지 않고 분석해야 할 수 있다. 가령 스톱워드를 제거하지 않은 데이터를 사용하면 테스트 데이터의 F값이 올라가지만, 학습 데이터나 테스트 데이터로 사용되지 않은 미학습 데이터로 검증을 하면 오히려 F값이 떨어질 수 있다.
과학책을 쓰는 과학자와 민문학책을 쓰는 인문학자가 있다고 가정하자. 그들이 쓴 글을 단어로 분해한 다음, 단어들 중 '법칙'과 '사상', 그리고 '가설'이라는 세 가지 단어가 등장하는 횟수를 세었을 때의 정보를 벡터 및 그래프로 표현하면 다음과 같은 결과가 나온다.
이러한 방법을 통해 과학자가 쓴 글과 인문학자가 쓴 글을 벡터 공간 안에 표현할 수 있다. 이러한 방법으로 다른 글의 정보를 벡터화 하여 이 공간에 배치하면, 그 글이 어느 쪽 벡터에 더 가깝거나 먼지를 코사인 유사도를 통해 알아낼 수 있다.
물론, 이 예시에서는 세 개의 단어(3차원)으로 분석을 했지만, '인문', '경제', '과학'이라는 세 개의 카테고리로 글을 분류하기 위해서는 훨씬 더 많은 단어(차원)이 필요할 것이다. 이 이 예와 같이 단어를 벡터의 열에 할당하고, 해당 단어의 출연 횟수를 요소로 만든 벡터를 Bag-of-words(BoW)벡터라고 부른다.
이러한 방법을 통해서 '글의 카테고리'라는 정보를 수학적으로 처리할 수 있다. 이러한 벡터의 연산은 비교적 간단한 사칙연산을 반복하는 일이 많기 때문에, 컴퓨터로 계산하기에 매우 용이하다.
여기서는 해당 글이 어떤 카테고리에 속하는 글인지를 판별하고자 한다. 보통 특정 카테고리에 속하는 글들은 해당 카테고리에서 자주 쓰이는 단어를 포함하고 있다거나 특유의 문체가 존재한다. 이렇게 어떤 기준에 대해 공통적이거나 특징을 잘 드러내는, 그래서 주목해야 하는 단어를 특징어라고 한다. 이러한 특징어가 포함된 글이 주어진다면, 해당 글의 카테고리를 추정하는 것은 어렵지 않다. 이에 특징어 리스트가 필요하다.
그러나 특징어를 쉽게 판별하기는 어렵다. 이에 특징어에 가중치를 부여하는 방법이 있다. 원래의 BoW에서는 단어의 출현 횟수만 세었지만, 이번에는 그러한 단어들 중 중요도가 높을 것 같은 특징어에는 숫자를 더 크게 만들어주고, 그다지 중요할 것 같지 않은 경우는 숫자를 더 작게 만들어 주도록 보정한다.
보정할 때는 가중치가 주어진 행렬을 곱하면 되는데, 이 과정을 통해 해당 글의 특징을 더 두드러지게 표현할 수 있는 벡터를 만들 수 있다.
가중치를 주는 방법으로는 TF-IDF(Term Frequency-inverse document Frequency)를 사용한다. TF의 의미는 특정 단어가 문서 안에서 얼마나 자주 나오는가, 즉 단어의 출현 빈도를 나타내는 지표이다. 이에 TF가 높다면 어떤 문서에서 특정 단어가 자주 나온다면(TF의 값이 커진다면) 그 단어는 문서에 대한 특징어가 될 수 있다는 의미이다. 반면 IDF는 특정 단어가 전체 문서상에 얼마나 자주 나오지 않는가, 즉 단어의 희소성을 나타내는 지표이다.
어떤 문서가 D개의 문장, N개의 단어로 구성되어 있을 때, TF와 IDF를 구하는 공식은 다음과 같다.
특정 단어 t가 n번 나올 때,
특정 단어 t를 포함한 문장이 d개 있을 때,
TF-IDF는 TF와 IDF를 곱하면 된다.
이때, IDF에서 사용하는 log의 밑은 1보다 큰 임의의 실수를 사용하나, 보통 상용로그를 사용한다.
카테고리를 판별할 수 있는 방법은 여러 가지가 있기에, 무조건 그 방법이 맞다고는 할 수 없다. 이에 다양한 판별 방법을 알아야 한다.
이때 문서의 유사도를 판단하는 방법은 다음과 같다.
다음과 같이 철학자가 쓴 글을 추가하여 새로운 BoW벡터를 만들었을 때, 이는 과학자의 벡터에 가까운지, 인문학자의 벡터에 가까울까.
글의 특징 정보를 담은 벡터는 3차원 벡터이기에 3차원 공간상의 점으로 표현할 수 있다. 이때 가장 간단한 유사도의 표현 방법으로는 유클리드 거리 방법과 벡터의 각도가 얼마나 비슷한지를 보고 코사인 유사도로 판단하는 방법이 있다.
여기서는 분류하기 애매한 것을 잘 가려낸다는 로지스틱 회귀(losgitic regression)을 이용하고자 한다. 이를 사용하면 유사도를 확률로 표현할 수 있어, 단순히 누가 쓴 글인지 비슷한가하는 막연한 답보다 좀 더 구체적인 정보를 얻을 수 있다.
로지스틱 회귀는 1이 될 확률이 p이고 0이 될 확률이 1-p인 이산확률분포를 사용하여 1이나 0의 값을 확률적으로 사용하는 방법으로, 이산확률분포로는 베르누이 분포(Brenoulli distribution)을 사용한다.
x가 실수 입력값이고 y={0,1}이 출력값일 때, 출력값은 반드시 0과 1 중 하나가 나온다. 이때, 출력값 y=1이 되는 조건부확률 p(y=1 | x;θ)는 다음과 같다. 이때 θ는 실수 파라미터이다.
이때,
은 로지스틱 함수(logistic function)로, 치역은 0에서 1이고 평균값은 0.5가 되는 함수이다. 시그모이드 함수와 동일하다.
이 함수의 정의역은 실수 전체로 θ>0 일 때 y=1이 될 확률 p(θ)가 0.5보다 커지는 특성이 있다. 이러한 특성은 어떤 대상은 분류(classfication)할 때 유용하게 활용할 수 있다. 예를 들어 θ=0인 지점을 경계로 하여, θ≥0 일 때는 y=1이라고 하여 어떤 클래스로 분류하고, θ<0일 때는 y=0이라고 하여 어떤 클래스로 분류하지 않는다고 판단할 수 있다. 즉, 학습 데이터로 쓸 데이터 세트가 1≤i≤m 만큼 주어졌다고 가정할 때, 다음과 같은 식이 성립한다.
목점 함수(objective function)을 구하기 위해 편의상 확률 표현을 다음과 같이 표현한다면,
목점함수 J(θ)를 최소로 만드는 θ를 구한다고 한다면, 다음과 같은 목적함수를 구할 수 있다.
보통은 J(θ)를 최소화할 수 있는 θ를 구하기 위해 이 함수를 전개해서 계산하는데, 이 경우에는 확률이 0과 1사이이고, y값이 결국 0 아니면 1값이 나오기에 다음과 같은 손실 함수 L(θ)로 바꿔서 계산하는 것이 훨씬 효과적이다. 이를 우리는 교차 엔트로피 오차함수(cross entropy)라고 부른다.
이 식에서 y는 0이나 1이기 때문에 결국 두개의 항 중 하나의 항이 0이 되어 수식이 간단해지는 효과가 있다.
이때 사용하는 로지스틱 회귀에서 사용하는 입력은 고차원의 BoW벡터이다. 또한 세 가지 카테고리를 위한 벡터는 12,800차원인데, 이는 결국 입력 벡터인 x와 파라미터인 θ도 12,800차원 벡터이기에 12,800개의 성분을 조정해야 하는 12,800차원 공간상의 최적화 문제를 풀어야 한다. 그러나 이러한 문제를 그대로 풀게 되면 과적합이 발생할 수 있어 정규화를 진행해주어야 한다. 이에 L2정규화를 통해 다음과 같이 식을 만들어준다.
이렇게 만들어진 로지스틱 회귀로 우리는 어떤 색깔이 흰색이냐, 검은색이냐 같은 이분법적인 확률판단이 가능하다. 그러나 우리가 하고 싶은 것은 '인문', '경제', '과학'와 같은 세 가지 카테고리에 대한 판별이므로, 출력이 y={0,1,2}같은 형태가 되어야 한다. 이런 경우는 다중 클래스 분류(multi class classification)에 해당하는데, 여러 개의 이진 클래스 분류(binary class classification)문제로 나누어서 해결해야 한다. 이에 y=i와 y≠i를 하나의 이진 클래스 분류 문제로 간주하고 확률 p(y=i | x;θ)를 i= 0, 1, 2의 경우에 대해 각각 구한 다음 p가 최대인 클래스로 판별하는 방법을 사용할 것이다.
카테고리 판별 모델을 만들기 위한 진행 과정은 다음과 같다.
이때, 모델을 평가하는 지표는 무엇을 사용해야 할까? 이전 회귀 문제에서는 결정계수를 사용했으나, 이번에는 정밀도(Precision)와 재현율(Re-call), 그리고 F값(F-value)을 사용한다. 이들을 알기 위해서는 다음에 대해 알아야 한다.
카테고리가 판별된 결과에 대해 평가를 해보면 다음과 같은 유형으로 분류할 수 있다. 이렇게 분류된 정보를 바탕으로 정확도, 정밀도, 재현율, 그리고 F값 같은 정보를 만들 수 있다.
정밀도
어떤 문서를 인문학 카테고리의 문서라고 판단했는데, 실제로도 그 문서가 인문학 카테고리의 문서가 맞을 때의 확률
재현율
인문학 카테고리의 문서를 카테고리 판별기에게 판별을 맡겼을 때, 그 문서가 인문학 카테고리의 문서라고 맞출 때의 확률
이때, 정밀도와 재현율은 사실 한 쪽의 지표가 높아지면 다른 쪽의 지표가 낮아지는 Trade off 관계를 보인다. 이러한 이유로 두 지표의 특징을 모두 가진 지표인 F값이 많이 사용된다. F값은 특히 질병의 발생률이나 조사 대상의 크기 등에 쉽게 좌우되지 않는 평가 척도이기에 활용도가 높다.
글 잘 읽었습니다~