NLP Basic
이름이 멋져서 손을 들고 시작하게 된 자연어처리 AI 프로젝트. 바닥부터 시작하는 딥러닝2의 내용을 많이 참고했다. 좋은 책이다.
자연어 처리란?
- 사람이 일상적으로 쓰는 언어를 자연어라고 한다. 반대의 개념으로는 형식어가 있다.
- 비교적 자유롭게 사용할 수 있는 자연어에 반해 형식어에는 엄격한 규칙이 있다. 수학 공식, 프로그래밍 언어 등이 이에 해당된다.
- 자연어 처리란 컴퓨터에게 자연어를 이해시키는 것이다. 컴퓨터가 자연어를 이해하면 번역, 문장 생성, 문장 요약, 문장 분류, 질의응답 등 다양한 작업을 빠르게 할 수 있다.
- 자연어를 처리하기 위해서는 우선, 자연어를 컴퓨터가 인식할 수 있는 디지털 형태로 표현해야 한다.
- 자연어는 문장들로 구성되어 있고, 문장들은 단어들로 구성되어 있으므로, 결국 단어를 디지털 형태로 표현해야 한다. 주로 벡터를 이용해 표현한다.
자연어 처리에서 단어와 토큰
- 자연어를 처리하기 위해서는 단어를 벡터로 표현해야한다고 했다. 그러기 위해서는 일단 문장 내에서 단어를 잘라내야 하는데, 단어의 기준이 모호하다. 어떤 기준으로 잘라내야 할까?
- 띄어쓰기 기준으로 자른다면 간편하지만, 단어 하나에 여러 의미가 포함되므로 처리가 부정확해질 수 있다.
- ‘나는 인공지능이 싫다’라는 문장을 ‘나는/인공지능이/싫다’로 자른다면, ‘인공지능이’라는 단어는 ‘인공’+’지능’+’이’ 의미를 모두 포함한다. 따라서 각각의 의미를 분리해서 처리하고자 하는 경우에는 부적합하다.
- 형태소나 글자 단위로 자른다면 각 단어는 고유한 의미를 갖겠지만, 잘라내기 까다롭고 단어의 종류가 많아져 처리가 복잡해질 수 있다.
- ‘나는 인공지능이 싫다’라는 문장을 ‘나/는/인공/지능/이/싫다’로 자른다면, ‘인공’과 ‘지능’의 의미를 구분해 처리할 수 있다. 또한 ‘는’과 ‘이’와 같이 조사도 구분해서 처리할 수 있다. 그러나 구분할 필요가 없는 경우에는 단어만 많아지고 복잡해질 뿐이다.
- 따라서 단어를 잘라내는 적절한 기준을 세워야 하고, 이는 처리하고자 하는 목적에 부합해야 한다.
- 기준을 갖고 문장을 단어로 잘라주는 녀석을 토크나이저(tokenizer)라고 한다.
- 토크나이저를 통해 잘라낸 단어를 토큰(token)이라고 한다. 결국 벡터로 표현하여 자연어 처리에 이용하는 대상은 토큰이다.
- 의미를 갖는 단위라는 의미에서 ‘단어’라는 용어를 사용하고, 잘려진 단위라는 의미에서 ‘토큰’이라는 용어를 사용하도록 하겠다. 실체는 같다.
워드피스(word piece) 토크나이저
- 문장 내에 여러번 출현했음에도 분리되지 않는 글자 뭉치를 하나의 토큰으로 판단한다.
- ‘나는 과학자이자 수학자입니다’라는 문장에서 ‘학자’라는 글자 뭉치는 2번 출현했음에도 ‘학’과 ‘자’로 분리되지 않았다. 따라서 ‘학자’는 하나의 토큰이 된다.
- 많은 문장을 학습하여 글자 뭉치의 맵을 생성한다.
- 생성해 둔 글자 뭉치의 맵을 참고하여 입력된 문장을 자른다. 입력된 글자 뭉치가 맵에 없으면 한 글자씩 자른다.
- 단어를 자르는 기준이 언어의 종류에 무관하므로 여러 언어에 공통으로 사용할 수 있으나, 성능은 떨어질 수 있다.
그램(gram)
- 문맥을 표현하기 위해 사용한 토큰의 갯수이다.
- ‘인공지능 은 재미있다 그리고 지루하지 않다’라는 문장에서 ‘인공지능’의 문맥을 표현하려고 할 때, 1개의 토큰을 사용하면, ‘인공지능’이 ‘재미있다’인지 ‘지루하지’인지 알 수 없다. 최소 2개의 토큰은 사용해야 ‘재미있다’와 ‘지루하지’+’않다’로 ‘인공지능’의 문맥을 파악할 수 있다.
- 몇개의 토큰을 사용했느냐에 따라 bi-gram, tri-gram, n-gram으로 부른다.
통계에 기반해 단어를 벡터로 표현
- 어떤 단어의 의미는 주변 단어들, 즉 맥락에 의해 결정된다는 가설이 분포 가설이다.
- ‘나는 인공지능이 싫다’라는 문장에서 ‘인공지능’은 내가 싫어하는 대상이다. ‘나는’과 ‘싫다’라는 맥락이 ‘인공지능’의 의미를 결정한다. 더 많은 문장에서 ‘인공지능’의 맥락을 확인할수록 ‘인공지능’의 의미는 뚜렷해진다.
- 분포 가설에 따라 단어를 주변(앞/뒤)에 출현하는 단어들로 표현한다. 이를 분산 표현이라고 하며 벡터로 나타낸다.
- ‘나는 인공지능이 싫다 나는 사람이 좋다’를 분산 표현하여 벡터로 나타내면
- 단어를 주변에 출현하는 단어들로 표현했으므로, 주변에 출현하는 단어들이 비슷하면 그 단어들은 맥락적으로 비슷한 단어이다.
- ‘나는 출퇴근할 때 버스를 탄다.’ ‘너는 출퇴근할 때 지하철을 탄다.’에서 ‘버스’와 ‘지하철’은 주변 단어가 비슷하기 때문에 맥락적으로 비슷한 단어이다.
- 두 단어가 맥락적으로 얼마나 비슷한지는 두 단어 벡터의 내적을 구하면 알 수 있다. 관계가 없을 수록 0에 가까운 값이 나온다.
- 그런데 단순히 단어의 앞/뒤에 출현하는 단어라고 해서 항상 그 단어의 맥락을 표현하는 것은 아니다.
- ‘I love the tuned engine sound’에서 ‘the’는 ‘love’나 ‘tuned’와 크게 관계가 없다. 반면 ‘engine’은 ‘tuned’이나 ‘sound’와 관계가 있다. 어떤 차이가 있을까? ‘the’는 ‘love’나 ‘tuned’와 동시에 출현할 확률이 적지만, ‘engine’은 ‘tuned’이나 ‘sound’와 동시에 출현할 확률이 높다. 즉, 단어들의 동시 출현을 고려하면 더 정확하게 단어들의 관계를 표현할 수 있다.
- 단어의 수가 많아지면 분산 표현된 단어 벡터의 차원수가 증가하기 때문에 연산에 부담이 된다. SVD 등을 사용해 차원을 축소한다.
- 통계에 기반해 단어를 벡터로 표현하려면 모든 텍스트 데이터가 미리 확보되어 있어야 한다. 따라서 확장이나 변경에 취약하다.
추론에 기반해 단어를 벡터로 표현(word2vec)
- 분포 가설 이용한다는 점은 통계적 방법과 동일하다.
- 주변(앞/뒤) 단어를 주고, 중간 단어를 추론하도록 학습 시킨다. 이 모델을 CBOW(Continuous Bag of Words)라고 한다.
- ‘나는 인공지능이 싫다 나는 사람이 좋다’에서 ‘인공지능이’를 나타내는 벡터를 얻기 위해 ‘나는’과 ‘싫다’를 모델에 입력하여 ‘인공지능이’를 추론하도록 학습시킨다.
- 학습 후, 주변(앞/뒤) 단어를 모델에 통과시키면, 중간 단어가 될 수 있는 단어들의 확률을 알 수 있다.
- 학습 후 얻은 입력 가중치의 행렬은 각 단어들의 분산 표현이라고 볼 수 있다.
- 중간 단어를 주고 주변(앞/뒤) 단어를 추론하도록 학습시킬 수도 있다. 이 모델을 skip-gram이라고 한다.
- 일반적으로 skip-gram이 CBOW보다 성능이 더 좋다.
- 텍스트 데이터를 점진적으로 확보하여 점진적으로 학습 시킬 수 있으므로 확장/변경에 유연하다.
- 단어 간 유사성을 너머 복잡한 관계도 표현이 가능하기 때문에 king - man + woman = queen과 같은 유추 문제도 풀 수있다.
추론 기반 + 통계 기반
- Glove
- 통계 기반 정보를 손실 함수에 도입해 미니배치 학습을 시킨다.
문장을 벡터로 표현
- 문장을 고정길이 벡터로 표현하여 전이학습(분류, Seq2Seq 등)의 데이터로 사용한다.
- bag of words
- 문장을 구성하는 각 단어(word2vec)의 단순 합으로 표현한다.
- 문장 = 단어의 합 = 단어들이 순서없이 섞여있는 가방
- 단어의 순서가 고려되지 않아 문장 표현으로 부적절하다.
- 언어모델
- 단어의 순서가 고려된 언어모델을 만들면, 고정길이 벡터로 표현된 문장을 얻을 수 있다.
언어모델
- 순서대로 나열된 단어들(문장) 뒤에 이어질 단어를 주어주고, 해당 단어를 추론하도록 학습한다. 단어들의 순서를 고려한 모델이기 때문에 문장을 적절히 표현할 수 있다.
- 데이터의 순서가 반영되는 RNN(Recurrent Neural Network)을 사용하여 언어모델을 만들 수 있다.
- 학습 후, 순서대로 나열된 단어들(문장)을 모델에 통과시키면, 이어질 단어들의 확률을 알 수 있다.
- 성능은 퍼플렉서티(perplexity)로 평가한다.
- 문장 뒤에 이어질 수 있는 단어의 후보 수를 표현한다.
- 이어질 수 있는 단어의 후보 수가 적으면, 모델이 이어질 단어를 더 명확하게 제시한다는 뜻이므로 좋은 성능을 갖고 있다고 말할 수 있다.
- 확률에 기반해 문장 뒤에 이어질 자연스러운 단어를 추론할 수 있다. 즉, 문장 생성이 가능하다.
- word2vec과는 달리 순서가 고려됨
- 언어 모델 : 나는 인공지능이(0.99), 인공지능이 나는(0.02)
- word2vec : 나는 인공지능이(0.99), 인공지능이 나는(0.99)
RNN(Recurrent Neural Network)
- 이전 데이터의 신경망 처리 출력값/가중치를 다음 데이터의 신경망 처리 입력으로 사용
- you say good bye and i say hello
- you → RNN → you의 가중치(분산 표현), you의 출력
- say, you의 가중치, you의 출력 → RNN → say의 가중치, say의 출력
- say의 가중치, say의 출력에는 you의 특징(you의 가중치, you의 출력)이 반영됨
- you say good bye and i say hello
- 이전 데이터의 특징이 반영되므로 순서가 고려됨
- 순서가 고려되어야 하는 시계열 데이터(문장, 음성 등)의 신경망 처리에 사용
seq2seq
- 순서가 있는(시계열/시퀀스) 데이터를 다른 형태의 순서가 있는(시계열/시퀀스) 데이터로 변환한다.
- 번역 : 한국어 문장 → 영어 문장
- 음성인식 : 음성 → 문장
- 챗봇 : 문장 → 문장
- 데이터 → 인코더 → 인코딩된 데이터 → 디코더 → 원하는 데이터
- LSTM을 이용한 한국어 문장 → 영어 문장 번역
- peeky 디코더
- 인코더의 출력인 고정길이 벡터 h를 디코더의 각 시계열 데이터에 모두 사용한다.
- h를 디코더의 첫번째 시계열 데이터에만 사용하는 것보다 성능 좋다.
어텐션
- LSTM 인코더의 문제점
- 문장이 길면 고정길이 벡터 h의 문장 표현력이 떨어진다.
- 입력-출력 시계열 데이터들 간 대응관계가 있음에도 불구하고, h가 출력 시계열 데이터 모두에게 동일하게 영향을 미친다.
- 입력-출력 시계열 데이터들 간의 대응관계(서로에게 주목하는 정도)를 고려하기 위해 어텐션을 사용한다.