출처 : https://arxiv.org/pdf/1607.01759.pdf

초록

위 논문은 텍스트 분류를 위한 간단하고 효과적인 baseline을 탐구한다. 우리의 실험은 fastText라는 빠른 text classifier가 학습과 평가에서 다른 딥러닝 분류기들과 비슷한 정확도를 보임과 동시에 속도가 빠름을 보여준다. 멀티 코어 CPU로 1억개의 단어들을 십분안에 학습할 수 있고 5000개의 문장들을 312000개의 클래스로 일분 안에 분류할 수 있다.

 

1. Introduction

텍스트 분류는 NLP에서 매우 중요한 작업이다(가령, 웹 검색, 정보 탐색, ranking and document classification 등) 최근에 신경망을 기반으로 한 모델들이 매우 인기있다. 이러한 모델들이 실전에서 좋은 성능을 보이긴 하지만, train과 test에서 상대적으로 느리며 매우 큰 데이터셋을 사용하기에 힘들다.

 한편, linear classifier은 텍스트 분류 문제에 대한 강력한 baseline으로 여겨진다. 그들의 단순함에도 불구하고, 올바른 feature들이 주어지면, 좋은 성능을 보여주며 매우 많은 corpus를 처리할 수 있는 가능성 또한 있다. 

 위 논문에서, 우리는 텍스트 분류의 맥락에서 많은 output 차원을 가진 거대 corpus를 scale할 수 있는 방법들을 탐구하고자 한다. 최근 효과적인 word representation learning에 감명받아, 우리는 rank constraint 와 fast loss approximation을 갖고 있는 linear model들이 최신 기술들과 비슷한 정확도를 보이며 10분 안에 1억개의 단어들을 학습할 수 있음을 보여주려 한다. 우리는 fastText를 tag prediction과 sentiment analysis 두가지 task에 활용하여 평가하고자 한다.

 

2. Model Architecture

문장 분류를 위한 간단하고 효율적인 baseline은 문장들을 bag of Words(boW)로 표현하고 linear classifier(가령, logistic regression 혹은 Support Vector Machine)에 학습시키는 것이다. 그러나, linear classifier들은 feature와 class 간에 파라미터를 공유하지 않기에, output차원이 클 때에는 일반화가 잘 이루어지지 않는다.(어떤 클래스들은 매우 작은 예시만을 갖기에) 이 문제를 해결하기 위한 일반적인 solution으로 linear classifier를 낮은 rank matrices로 분해하거나 multilayer-neural-networs를 사용하는 것이다.

 Figure 1은 rank constraint가 포함된 간단한 선형 모델을 보여준다. 첫번째 weight matrix인 A는 단어에 대한 look-up table이다. word representations들은 이후 text representation으로 평균화되는데, 그 이후에 linear classifier에 부여된다. Text representation은 잠재적으로 사용 가능한 hidden variable에 해당한다. 이 구조는 중간 단어가 label에 의해 대체되어 있는 cbow 모델과 비슷하다. 우리는 softmax 함수인 f를 이용하여 이미 정해진 classes에 대해 확률 분포를 계산하고자 한다. N documents의 셋에서 negative log likelihood를 각 클래스 별로 최소화하고자 한다. 이는 다음과 같다.

yn은 label, B와 A는 weighted matrix, xn은 n번째 document의 정규화된 bag of features에 해당한다.

이 모델은 multiple CPUs에서 동시적으로 학습되었으며 stochastic gradient descent와 lineary decaying learning rate를 이용하여 학습되었다.

 

2.1 Hierarchical Softmax

 클래스가 많을 때, linear classifier를 계산하는 것은 큰 비용이 든다. 정확하게 말하자면, 계산 복잡도는 O(kh)인데, 이때 k는 클래스의 개수를, h는 text representation의 차원의 수를 말한다. running time을 개선하기 위하여 hierarchical softmax를 사용한다. 학습 시에 계산 복잡도는 O(hlog2(k))로 떨어진다.

 Hierarchical softmax는 가장 그럴듯한 클래스를 찾는 test 시에도 유용하다. 각 노드는 루트에서 해당 노드로 오기까지 path의 확률로 연관된다. 만약 l+1 깊이의 노드가 부모 노드들이 n1, n2, .., nl 까지 있다면, 확률은 각 부모 노드의 확률을 모두 곱하는 것과 같다. 이는 자식 노드가 부모 노드보다 확률이 더 낮음을 의미한다. 깊이 우선 탐색으로 트리를 탐색하고 잎 노드 사이에서 최대 확률을 추적하여 작은 확률과 연관된 가지들은 버릴 수 있게 된다. (깊이 우선 탐색 : 자기 자신을 호출하는 순회 알고리즘으로 이웃 노드를 탐색하는 과정에서 가장 깊은 노드까지 탐색한 이후 backtracing 하며 방문하지 않은 노드 방문). 실제로, 우리는 test 시에 복잡도가 O(hlog2(k))로 감소하는 것을 발견했다. 이 접근은 binary heap(이진 힢)을 사용하여 T개의 top target들을 O(logT)의 복잡도로 계산할 수 있게 한다.

 

2.2 N-gram features

Bag of Words는 어순을 고려하지 않지만 단어의 어순을 고려하는 것은 컴퓨팅 비용이 비싸다. 대신, 우리는 bag of n-grams를 사용하여 주변 단어의 어순의 부분적인 정보를 고려할 수 있도록 하였다. 이 방법은 실전에서 매우 효율적이었고 어순을 사용하는 방법들과 견줄만한 결과를 성취해냈다. 우리는 hashing trick을 이용하여 n-gram을 빠르고 메모리 효율적으로 매핑하였고 bigram을 사용했을 때는 10M개의 bins와 Mikolov et al.에서 나온 해싱 함수와 동일한 함수를 사용했다.

 

3 Expremients

우리는 fastText를 두개의 다른 task 들에서 평가했다. 우선, 우리는 감정 분석의 문제에 대한 존재하는 텍스트 분류기들을 이것과 비교했다. 그리고 나서, 우리는 tag prediction dataset에 큰 output space로 스케일하는 능력을 평가했다. 우리의 모델이 Vowpal Wabbit library와 함께 실행될 수 있었고, 실전에서 우리의 실험은 적어도 2배에서 5배정도 빨랐다.

 

3.1 감정 분석 실험과 결과

기존의 모델들인 BoW, ngrams, ngrams TFIDF, char-CNN, char-CRNN, VDCNN 등의 모델들과 fastText를 비교하였고 결과적으로, 정확도는 char-CNN와 char-CRNN보다 살짝 높았고 VDCNN보다 살짝 낮았다. 더 많은 n-grams를 이용함으로써 정확도가 더욱 높아짐 또한 확인할 수 있었다. 또한, Tang et al(2015)의 방법들과 비교해봤을 때 fastText역시 경쟁력이 있음을 알 수 있었다. 또한 학습속도 역시 굉장히 빨랐다!

 

3.2 태그 예측

제목과 자막에 따라 태그를 예측하는 것에 초점을 맞추었고 Tagspace라는 모델(Convolution 기반)과 비교하였다. 결과적으로 속도도 더 빨랐고 더 정확했다! 

 

4.Discussion

 딥러닝 모델들이 최근 엄청난 인기를 얻고 있긴 하지만, 선형모델을 기반으로 한 Fasttext역시 성능이 그와 비슷한 반면 더욱 빨랐다. 

1. 도입

단어의 분산 표현은 자연어 처리에서 비슷한 단어들을 묶어 처리하게 함으로서 효율적인 결과를 만들어낸다. 최근에 고안된 Skip-gram model은 비정형 텍스트 데이터에서 많은 양의 단어를 양질의 단어 벡터로 표현하는 좋은 방법이다. 신경망을 활용한 이전의 연구와 달리 skip-gram model은 dense matrix multiplications를 포함하지 않아 효율적이다. 자연어 처리에서 신경망을 활용하는 방법은 언어적 관계와 패턴을 반영하고 연산과 같은 선형 변환으로 활용할 수 있기에 흥미롭다. 

해당 논문에서는 기존의 Skip-gram model을 발전시키는 몇가지 방향을 제안하고자 한다. 학습 과정에서 자주 나오는 단어들을 Subsampling 하는 것이 효율적일 수 있고 또한, 복잡한 hierarchical softmax 대신 Noise Contrastive Estimation(NCE)를 활용하여 더욱 효율적이고 양질의 vector representation을 도출할 수 있다.

또한, 자연어 처리에서 관용어 표현이 어려운데 단어 기반의 Skip-gram이 아닌 구 벡터를 활용하는 방안을 도입했다. 또한, Skip-gram Model을 도입함으로써 단어 벡터 표현에 연산을 가하는 것이 유용할 수 있음을 설명하려 한다.

 

2. Skip-gram Model

Skip gram 모델의 목표는 타겟단어 벡터를 이용하여 주변의 단어들을 예측하려는 것이다. 이 때, 문맥 단어의 사이즈(개수)에 해당하는 변수 C의 크기를 조정할 수 있는데 이를 늘리면 정확도는 더 높지만 더욱 많은 비용이 투입된다. Skip- Gram은 소프트맥스 활성화 함수를 사용하는데 많은 비용이 투입되기에 실용적이지 못하다.

 

2.1 Hierarchical Softmax : 해석하는데 오래 걸렷음 ㅠ

기존의 Full Softmax의 경우 모든 경우의 지수함수를 더한 후에 해당 결과의 지수함수에 나누는 것으로 확률의 역할을 함. 하지만 One-Hot vector의 차원이 큰 만큼, Full softmax를 이용할 경우 굉장히 많은 연산이 필요하다. 즉, 모든 지수함수를 합쳐야함. 이러한 비효율을 개선하기 위해 도입한 것이 Hierarchical Softmax이다. 

 

 

출처 : https://velog.io/@xuio/NLP-TIL-Negative-Sampling%EA%B3%BC-Hierarchical-Softmax-Distributed-Representation-%EA%B7%B8%EB%A6%AC%EA%B3%A0-n-gram

Hierarchical Softmax는 위의 그림처럼 이진트리의 형태로 구성된다. 트리의 leaf(맨 끝 노드)는 단어이며, 트리의 root에서부터 각 단어까지 도달하기 위하여 중간 노드는 벡터로 구성되어 있다. 이 벡터들을 거쳐 마지막 단어 노드 까지 도달하는 과정에서 각 단어별로 확률이 부여되는데 이를 최적화하기 위하여 Parameter들을 업데이트 하는 과정이다.

 

논문에서는 위의 수식으로 설명하는데 이 때, L(w)는 트리의 깊이, n(w,j)는 w라는 단어로 가기 위한 path 상에 놓인 j번째 노드를 일컫는다. ch(x)는 x의 자식노드를 말하며, [[ ]] 기호는 내용이 true이면 1을, False면 -1을 반환한다.  즉, 첫번째 단계부터 트리의 뒤에서 2번째 노드까지 w를 향한 j+1번째 노드가 j번째 노드의 자식 노드일 경우 j번째 노드의 벡터에 1을 곱한 후 input word와 내적을 하게 되며 만약, j+1번째 노드가 j번째 노드의 자식 노드가 아닐경우 j번째 노드의 벡터에 -1을 곱한 후 input word와 내적을 하게 된다. 이러한 결과를 sigmoid함수에 넣어 확률값으로 바꾼 후 각 단계마다 반복하여 확률을 얻게 된다.

 

이러한 방식은 단어에 대한 학습이 log(V)로 줄어든다는 큰 장점이 있다.

 

2.2 Negative Sampling

 

기존에 Hierarchical softmax를 대체하는 기법에는 Noise Contrastive Estimation (NCE)가 있다. NCE는 logistic regression의 방법으로 데이터에서 noise를 제거한다. NCE는 softmax의 log probablity를 최대화해주지만 Skip-gram 모델은 좋은 품질의 vector representation을 학습하는 데에 집중하기에, NCE에서 착안하여 Negative Sampling(NGE)를 모델링하여 이를 새로운 손실함수로 이용한다.

왼쪽은 Positive Sampling과 관련된 수식으로 해당 output의 확률을 최대화하고자 함. 오른쪽은 Negative Sampling에 관한 수식으로 해당 output이 될 확률을 최소화하고자 함.

 

Negative Samplinig은 Word2Vec의 CBOW와 Skip-Gram 모두 단어 개수가 많아질수록 계산 복잡도가 증가하기에 이러한 문제점을 해결하고자 고안되었다. Word2Vec은 역전파 과정에서 모든 단어의 임베딩 벡터값을 업데이트 한다. 만약, 중심단어가 '한국'이고 주변 단어가 '서울', '대구'와 같은 단어일 때, 별 관계없는 '게임', '변호사'와 같은 수많은 단어의 임베딩 벡터 값을 업데이트 하는 것은 비효율적이다.

Negative Sampling은 이러한 문제점에 착안하여 학습 과정에서 전체 단어가 아니라 일부 단어에 집중하도록 하는 방법이다.

현재 집중하고 있는 주변 단어가 '서울', '대구'일 때, 전체 단어 집합에서 주변 단어가 아닌 단어들 중에서 무작위로 '게임', '컴퓨터', '빵' 이라는 단어를 일부 가져온다. 이들 단어 집합을 이용하여 마지막 단계에서 각 단어가 주변 단어인지, 그렇지 않은지를 분류하는 이진분류 단계를 거친다. 

 

이를 구현하기 위해 우선 Sample 단어를 선정해야 한다. Sample 단어를 선정하는 기준은 전체 문장에서 자주 사용되는 단어에 높은 가중치를 부여하고 우선적으로 해당 단어를 선별한다. 

여기서 wi는 i번째 단어, f(wi)는 해당 단어의 출현 빈도를 말한다.

기존의 Skip-gram에서 사용되었던 중심단어의 주변 단어들에는 1을 라벨링해준다. 위의 확률을 이용하여 중심단어와 관계없는 단어들을 선택한 후 해당 단어들에는 0을 라벨링해준다. 이후 중심 단어에 대한 임베딩 테이블과 주변단어 혹은 관계없는 단어들의 임베딩 테이블을 만든 후 임베딩 벡터로 변환한다. 두 개의 임베딩 벡터들을 이용하여 중심단어와 다음 단어를 내적한 값을 모델의 예측값으로 이용하고 이를 라벨과의 오차만큼 역전파하여 임베딩 벡터값을 업데이트 하게 된다. 학습이 끝나면 중심단어에 대한 임베딩 테이블을 이용할 수 있다. (아마 주변 단어에 대한 임베딩 테이블은 관계없는 단어가 섞여 있기 때문에 이용하기 힘들기 때문일듯)

 

위 논문에서는 Sample을 선택하는 기준을 명시하는데, 학습 데이터 수가 적을 경우 Negative Sample의 수를 5~20개로 설정하는 것이 좋지만 큰 데이터에서는 2개에서 5개 사이의 Sample을 선택하는 것이 효율적이라고 한다.

 

Word2vec에서 성능은 CBOW < Skip-gram < Skip-gram with Neagtive Sampling이라 알려져 있다.

 

2.3 Subsampling of Frequent words

 

Corpora에서 가장 많이 등장하는 단어들(in, the, a 등)은 수백만번 등장할 수 있다. 이런 단어들은 덜 등장하는 단어들보다 정보를 반영하지 못한다. 또한, 빈번하게 등장하는 단어들의 벡터는 몇백번의 학습을 거쳐도 크게 변하지 않는다. 이를 활용하여 학습 시 각 단어는 다음과 같은 확률로 제거된다.

 

t는 threshold, f(wi)는 해당 단어의 빈도를 말한다.

위 식에 따르면 빈도가 높을 수록 제거될 확률이 커지게 된다. 

 

3 Empirical Results

 

Hierarchical Softmax, Noise Constrastive Estimation, Negative Sampling, subsampling을 평가하고자 한다. Analogical Reasoning Task를 수행하는데 가령 'Germany : Berlin - France: ??'와 같이 코사인 distance를 이용하여 대응되는 단어의 벡터를 찾고자 한다. 

Skip-gram 모델을 학습시키는 과정에서, 다양한 뉴스 기사들이 포함되어 있는 데이터셋을 썼으며 5번 이하의 빈도로 나타나는 단어들은 제거했다. 수행 결과를 살펴보면, Negative Sampling이 Hierarchical Softmax보다 analogical reasong task에서 우수한 성능을 보여주었으며 Noise Constrastive Estimation보다도 더 나은 성능을 보여주었다. 빈번한 단어들을 Subsampling하는 것은 학습 속도를 개선시켰으며 word respresentation을 더욱 정확하게 해주었다.

Skip - gram 모델의 linearity가 linear analogical reasoning에 더욱 적합하도록 벡터들을 만들었다고도 볼 수 있지만 다른 연구결과를 보면, standard sigmoidal recurrent neural networs(비선형성을 띤다고 알려진 모델)에서 학습된 벡터 역시 학습 데이터가 증가할수록 linear reasoing task에서 성능이 개선되었다. 이는 비선형모델 역시 단어를 linear 구조에 맞추어 표현할 수 있음을 보여준다.

 

4. Learning Phrases

 

많은 구들은 각 단어들의 의미의 단순한 합으로 표현될 수 없다. 구에 대한 벡터 표현을 학습하기 위해 다른 맥락에서 덜 빈번하게 등장하지만 특정 맥락에서 빈번하게 발견되는 벡터 표현를 찾는다. (가령, New York Times, Toronto Maple Leafs와 같은 구들. this is 와 다른 구들) 이러한 방법은 vocabulary의 크기를 키우지 않으면서 reasonable phrases를 형성할 수 있게 한다. 텍스트에서 phrases를 구분하기 위해 해당 논문에서 data-driven approach를 이용하여 unigram과 bigram counts를 기반으로 다음과 같은 점수를 이용하였다.

이 때, 델타는 매우 빈번하지 않게 등장하는 단어들로 이루어진 구들이 형성되지 않도록 제어하는 discounting coefficient이다. 논문에서는 2~4번의 pass를 넘어가면 threshold를 더욱 감소시켜 더 긴 phrases를 형성할 수 있도록 한다.

 

4.1 Phrase Skip-Gram Results

Hierarchical Softmax를 이용한 Huffman code가 subsampling을 함께 이용하여 비약적인 성능 상승과 더불어 1위를 차지 하였으며, NEG는 Phrase가 얼마나 등장해야 학습에 넣을지에 해당하는 수치인 k값에 민감하였다.

 

5. Additive Compositionality

위 논문에서는 Skip-gram모델로 학습된 word 와 phrase representation이 선형 구조를 띠며 이는 단순한 벡터 연산으로 정확한 analogical reasoning이 가능하게 만들었다. 흥미롭게, 우리는 Skip-gram representation이 다른 구조의 선형적 특징을 가짐을 알게 되었는데, 이는 단어들의 벡터 표현의 element-wise합(행렬 간 합)을 통해 의미적으로 단어를 결합하는 것을 가능하게 함을 말한다.

 이러한 새로운 특성은 학습 시 목적함수로 설명할 수 있다. 단어 벡터들은 Softmax nonlinearity에 대한 input들과 선형 관계를 갖는다. 단어 벡터들이 문장에서 주변 단어들을 예측하도록 학습되기에, 벡터들은 단어가 나타내는 맥락의 분포를 표현할 수 있게 된다. 이러한 값들은 output layer에서 계산되는 확률과 로그 연산으로 관련되어 있으므로, 두 단어 벡터의 합은 두 context distribution의 곱과 연관되어 있는 셈이다. 곱셈은 여기서 AND 연산으로 동작한다 : 두 단어 벡터와 높은 확률을 부여받은 단어들은 높은 확률을 가질것이며 다른 단어들은 낮은 확률을 가질 것이다. 예를 들어, Volga Rive이라는 구는 Russian 과 river 라는 단어와 함께 같은 문장에서 자주 나타난다면 관계에 대한 학습으로 두 단어 벡터의 합은 Volga River의 벡터에 가까운 특징 벡터를 갖게 된다.

'NLP' 카테고리의 다른 글

[논문리뷰] Bag of Tricks for Efficient Text Classification  (0) 2023.03.17
[논문 리뷰]NNLM(A Neural Probabilistic Language Model)  (0) 2023.03.02
Weekly NLP(~week9)  (0) 2023.02.06
BoW 모델 구현  (0) 2022.10.02
N-Gram 모델 구현하기  (0) 2022.09.29

논문 출처 : https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf

초록

statistical Language Modeling의 목표는 단어의 시퀀스에 대한 결합확률함수를 학습시키는 것임. 하지만 이는 모델의 테스트에 쓰이는 단어의 시퀀스는 다르기 때문에 발생하는 '차원의 저주' 때문에 어렵다. n-gram을 기반으로 전통적으로 성공적인 방법은 training 데이터에서 등장하는 짧은 중복 시퀀스들을 합쳐서 일반화를 하는 방법이다. 우리는 차원문제를 해결하기 위해 각 훈련 문장이 의미상으로 이웃하는 문장들의 exponential number를 모델에 전달할 수 있는 단어의 분산표현을 학습시키는 것을 제안한다. 이 모델은 (1) 각 단어의 분산 표현과 (2) 단어 시퀀스의 확률 함수를 동시에 학습한다. 이전에 한번도 나타나지 않은 단어들의 시퀀스들이 만약 이전에 학습된 문장의 단어들과 비슷한 단어들로 구성되었다면 높은 확률을 갖기에 일반화될 수 있다. 거대 모델들을 합리적인 시간 내에 학습시키는 것은 매우 어렵다. 우리는 신경망구조를 사용하여 실험을 하였는데 위의 방식으로 접근했을 때 향상된 n-gram model의 성능을 보여주었고 더 긴 문맥에서 이점이 있음을 발견했다.

 

1. 도입

- 차원의 저주는 모델의 학습을 어렵게 하는데 특히, 다양한 discrete random varaiables(문장 속 단어들 등) 사이에서 joint distribution(결합확률분포)을 모델링하려고 할 때 심하다. 예를 들어 사이즈가 10만인 Vocabulary의 10개의 연속적인 단어에 대해 joint distribution을 모델하려고 하면 100000^10-1 만큼의 파라미터가 필요하다. 연속 확률 분포라면 일반화가 더 쉽지만 이산 공간에서는 일반화의 구조가 명백하지 않다. 이러한 문제를 해결하기 위해 분산표현(distributed Representation)을 고안하였다. 분산 표현은 기존의 one-hot-vector 처럼 vocabulary size 전체를 벡터의 차원수로 두는 것이 아니라 훨씬 작은 m차원의 벡터로 표현하여 Dense vector로 나타낼 수 있게 한다. 이 때 분산표현은 이산분포가 아닌 연속 분포로서 smoothness 측면에서 효율적이며 벡터 간 유사도와 거리 계산이 가능하여 단어 간의 유사성을 표현하는 것이 가능하다.

어떤 문장에서 그 전에 나온 모든 단어들을 이용하여 다음 단어를 예측하는 것 보다 단어의 순서를 고려함과 동시에 가까운 단어들이 통계적으로 더욱 dependant하기에 이전의 n-1개의 단어들에 대한 조건부 확룔을 이용하는 것이 N-gram Model이다. 하지만 training 말뭉치에 없던 단어들의 조합이 새롭게 등장할 경우 이에 대하여서는 학습한 내용이 없기에 확률은 0이 된다. 이러한 문제를 해결하기 위해 더 작은 context를 살펴보거나 특정한 값을 더해 확률이 0이 되지 않게 하는 Smoothing 방법이 존재하지만 단어 간 유사성을 고려하기 위해 분산표현을 사용하였다.

 

2. A Neural Model

우선 Input layer에서는 n-1개의 단어들에 대한 One-hot-vector인 |V| x 1 크기의 벡터 w들과 |V| x m 크기의 행렬 C가 필요하다. 이 때 행렬 C는 Random initialized 행렬로서 이를 벡터 w와 곱함으로서 input layer의 결과물인 x가 도출된다. 이후 x는 Hidden layer와 Output layer를 다음의 식 처럼 거치게 된다.

 

y = b + Wx + U tanh(d + Hx)

 

W는 input layer와 output layer간의 direct connection을 만들 경우 weights 이며 b는 bias에 해당한다. U는 hidden layer에서 output layer로 갈 때의 weights, H는 hidden layer의 weights, d는 bias에 해당한다. 

 

이렇게 나온 y 는 각 output 단어에 대한 비정규화된 log-probabilites이기에 softmax 연산을 거치게 되고 이 결과들을 정답 테이블과 비교하여 back-propagation으로 학습이 이루어 진다. 이 때 확률적 경사하강법이 사용된다.

 

3. Parallel Implementation

 많은 계산을 효율적으로 하는 방법을 설명함. 최근에는 gpu의 성능이 좋아졌기에 넘어감.

 

import torch
import torch.nn as nn
import torch.optim as optim

def make_batch():
    input_batch = []
    target_batch = []
    
    for sen in sentences:
        word = sen.split() #공백을 기준으로 토큰화
        input = [word_dict[n] for n in word[:-1]] #제일 끝 요소 빼고 input으로 넣음
        target = word_dict[word[-1]] #causal language modeling으로 제일 마지막 단어를 예측하도록 하는 모델
        
        input_batch.append(input)
        target_batch.append(target)
        
    return input_batch, target_batch

#Model
class NNLM(nn.Module):
    def __init__(self):
        super(NNLM, self).__init__() #super():상위 클래스 상속
        self.C = nn.Embedding(n_class, m)
        self.H = nn.Linear(n_step * m, n_hidden, bias=False) #bias=False를 사용하면 parameter의 수가 감소하여 모델 단순화 가능
        self.d = nn.Parameter(torch.ones(n_hidden)) #nn.Parameter : nn.Module 안에 만들어진 tensor들을 보관가능
        self.U = nn.Linear(n_hidden, n_class, bias=False)
        self.W = nn.Linear(n_step*m, n_class, bias=False)
        self.b = nn.Parameter(torch.ones(n_class))
        
    def forward(self,X):
        X = self.C(X) #X = [batch_size, n_step, m]
        X = X.view(-1, n_step*m)
        tanh = torch.tanh(self.d + self.H(X))
        output = self.b + self.W(X) + self.U(tanh)
        return output
    
if __name__ == '__main__': #main함수의 선언, 시작을 의미한다
    n_step = 2 #step의 수, n-1 in paper
    n_hidden = 2
    m = 2 #embedding size
    
    sentences = ['i like dog', 'i love coffee', 'i hate milk']
    
    word_list = ' '.join(sentences).split()
    word_list = list(set(word_list))
    word_dict = {w: i for i,w in enumerate(word_list)}
    number_dict = {i:w for i, w in enumerate(word_list)}
    n_class = len(word_dict) #vocabulary의 단어 수
    
    model = NNLM()
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=.001)
    
    input_batch, target_batch = make_batch()
    input_batch = torch.LongTensor(input_batch)
    target_batch = torch.LongTensor(target_batch)
    
    #학습 시작
    for epoch in range(5000):
        optimizer.zero_grad()
        output = model(input_batch)
        
        #output : [batch_size, n_class], target_batch : [batch_size]
        loss = criterion(output, target_batch)
        if (epoch +1) % 1000 == 0:
            print('Epoch:', '%04d' % (epoch +1), 'cost =', '{:.6f}'.format(loss))
        
        loss.backward()
        optimizer.step()
        
    #Prediction
    predict = model(input_batch).data.max(1, keepdim=True)[1]
    
    #Test
    print([sen.split()[:2] for sen in sentences], '->', [number_dict[n.item()] for n in predict.squeeze()])

 

https://lovelydiary.tistory.com/419

 

ADP) 3-1. 전처리 3탄 (변수 변환; Feature Scaling 총정리 - 수치형/범주형)

지난 전처리 2탄에서 다룬 수치형 변수변환 방법들에 이어서, https://lovelydiary.tistory.com/417 ADP) 3-1. 전처리 2탄 (변수 변환; Feature Scaling 총정리 - 수치형/범주형) 변수변환 (Feature Scaling) 변수변환이

lovelydiary.tistory.com

위 사이트를 참고하여 범주형 변수를 다루는 방법과 주의할 점에 대해 정리해보겠다.

 

 

1. 결정트리를 기반을 두는 모델(RandomForest, GradientBoostingDecisionTree 등)에서는 레이블 인코딩으로 범주형 변수를 변환하는 것이 가장 편리하다. 가끔 타겟 인코딩이 편리할 대도 있지만 타겟 인코딩을 실행하게 되면 '데이터 정보 누출의 위험'이 있다!!

2. 원핫 인코딩의 경우 범주형 변수를 0 또는 1 값을 가진 하나 이상의 새로운 특성으로 바꾼 것으로 구현이 쉽고 가장 정확하고 온라인 학습이 가능하지만 계산이 비효율적이고 범주의 수가 증가할 경우 부적합하며 선형 모델 이외에는 적합하지 않다!!

 

나의 모델이 pd.get_dummies를 실행했을 때 오히려 성능이 떨어진 것은 위와 같은 이유일 듯하다.

따라서, 결정트리 기반의 모델을 실행할 때에는 레이블 인코더를 실행하는 것이 더욱 효율적일 듯 하다!

'ML' 카테고리의 다른 글

0210LGAimers  (0) 2023.02.10
LG Aimers 진행중,,  (0) 2023.02.08
LG Aimers 강의 정리  (0) 2023.02.01
K-최근접 이웃 알고리즘  (0) 2022.09.26
경사하강법  (2) 2022.09.23

One-hot-vectors : 단어를 Nx1 Column Vector로 표현

Scalar(스칼라) : 숫자

Vector(벡터) : 방향+숫자

Euclidean Space : Vector의 차원

 

Word Embedding (워드 임베딩) : 단어 간의 관계를 학습하여 Vector에 저장하는 모델

One-hot-vectors는 Vocabularary가 무한정 커질 수 있기에 비효율적이다. word2vec과 GloVe는 vocabulary의 차원을 낮추려고 함. word embedding은 단어 간의 관계 입력 + 차원 감소

- GloVe : 문장에 한 단어가 어떤 근처 단어들과 몇번을 같이 나오는지 세는 Co-Occurence matrix 활용.

- ex) 전체 Corpus에 40000개의 단어 존재. 40000x40000 Matrix를 만들고 붙어 있는 단어의 빈도수 마다 matrix의 숫자 증가. 이후 Singular Value Decomposition(SVD)를 활용하여 차원을 300x40000으로 감소.

 - Word2Vec : Continuous bow혹은 Skipgram알고리즘을 활용하여 단어 간의 관계 학습. cbow는 주변 단어가 주어졌을 때 타깃 단어를 예측하는 모델. Skipgram은 타깃 단어가 주어졌을 때 주변 단어를 예측하는 모델. 예측을 위해 Neural Network를 활용하고 Stochastic Gradient Descent(SGD)를 통해 학습한다. Input에는 Nx1 word embedding이 들어감.

 

BOW와 TF-IDF는 단어의 빈도수를 계산하여 N차원의 열벡터로 문장을 표현

Word Embedding은 GloVe 혹은 Word2Vec같은 알고리즘으로 벡터의 차원을 줄이고 N차원 공간의 하나의 점으로 바꾸어 표현

- Eucliedian Distance

- Cosine Similarity

- Cosine Distance = 1 - Cosine similarity

 

NLP에서는 단어의 빈도수를 다루기 때문에 Cosine similarity가 주로 많이 사용됨. 벡터들 간의 유사성을 계산할 때는 Cosine distance가 사용됨.

 

Text Classification

- Binary Classification : 긍정 혹은 부정으로 분류. Logistic Regression Classifier = Linear Regression+Sigmoid

- Feature Importance : 모델이 중요하게 생각하는 단어

 

Multinomial Naive Bayes Classifier

위의 P(c|d)는 베이즈 정리를 통해 변형될 수 있음.

 

NLP에서도 CNN 사용가능. word embedding은 단어를 column vector로 표현하지만 row vector로 변환하여 단어 순서대로 차례로 row vector들을 쌓음. 이후 1D 필터를 통해 학습. 이는 감정분석, 질문 유형 분석, 객관/주관 유형 분석에서 뛰어난 성능.

 

Pretrain worde embedding은 알고리즘을 이용하여 많은 데이터를 학습한 결과물. transfer learning이라고도 함. 

Object Localization : 단 하나의 object 위치를 Bounding box로 지정하여 찾음

Object Detection : 여러 개의 Object 들의 위치를 Bounding box로 지정하여 찾음

Object Segmentation : Detection보다 더 발전된 형태인 Pixel 단위로 Detection 수행

 

Object Detection은 Classification과 Regression을 동시에 수행해야 하며, 다양한 크기와 유형의 object가 섞여 있고, 짧은 시간 안에 명확하지 않은 이미지를 이용하여 수행해야 하며 데이터 셋 자체가 부족할 수 있다는 어려움이 있다.

 

Sliding Window : Window를 왼쪽 상단에서부터 오른쪽 하단으로 이동시키며 Object를 Detect하는 방식

Region Proposal : 영역 추정방식. 컬러, 무늬 등 유사한 특징을 가진 Region을 계층적 그룹핑 방식으로 계산 ex)Selective Search

 

Object Detection의 성능 평가 Metric

 - IOU : Area of overlap / Area of union

NMS : Detected된 Object의 Bounding box중에 비슷한 위치의 bounding box를 제거하고 가장 적합한 box 찾는 기법

 1. Bounding box별로 Confidence threshold 이하 bounding box는 먼저 제거

 2. 가장 높은 Confindence score를 가진 box 순으로 내림차순 정렬하고 아래 로직을 순차적으로 적용

  - 높은 confindece score를 가진 box와 겹치는 다른 box를 모두 조사하여 IOU가 특정 threshold 이상인 box는 제거

 3. 남아 있는 bounding box만 선택

 - mAP : 실제 object가 detected된 재현율의 변화에 따른 정밀도의 값을 평균한 성능 수치. AP는 한 개 오브젝트에 대한 성능 수치. mAP는 여러 오브젝트들의 AP값을 평균한 값

+ Recent posts