text/Python

Word2Vec parameter 정리

hoonzii 2021. 2. 18. 16:23
반응형

회사 프로젝트를 위해 Word2Vec 알고리즘을 사용해야 했는데 그때 내가 알아본 것들을 정리 해보려고 한다.

여러 파라미터에 의해 Word2Vec model은 영향을 받는데 코드를 돌리기 전에

각 파라미터별 의미나 영향에 대해 한글로 어느정도 알고있으면

나처럼 맨땅에 헤딩하지 않고 조금더 편해지지 않을까 싶다.

물론 내가 잘못 조사하거나 틀렸을수도 있다.

이글을 읽는 사람은 참고정도만 해주면 감사하겠다.

물론 태클 역시 대환영이다.

 

내가 사용한 모듈은 테스트시 Python으로 진행( gensim.Word2Vec 모듈)

실제 서비스를 위해서는 Java로 진행 (dl4j.Word2Vec 모듈) 을 사용하였다.

두 모듈 다 어느정도 비슷한 파라미터를 가지고 있으나,

두 모듈만의 파라미터도 존재하니 꼭 본인이 직접 확인하기를 바란다.

 

정리 시작

 

1. size or Layer Size

- 벡터 차원 수

- 너무 작은 값이 아니라면, 학습의 경향이 달라지진 않는다. 적당히 큰 숫자면 충분하다.
(보통 논문이나, 실험에서는 100~300 값으로 설정해 사용하곤 한다.)

  (ref. stackoverflow.com/questions/26569299/word2vec-number-of-dimensions)

 

- gensim document의 따르면 (ref. radimrehurek.com/gensim/auto_examples/tutorials/run_word2vec.html#size)

" Bigger size values require more training data, but can lead to better (more accurate) models. "

 

- 전체 데이터의 unique vocab 수보다 벡터의 차원수가 크면 안된다는 의견

(ref. stackoverflow.com/questions/45444964/python-what-is-the-size-parameter-in-gensim-word2vec-model-class)

  - 과적합, one-hot encoding 과 비슷해지는 결과라고 말한다.

  - 좀더 자세한 논문 (ref. papers.nips.cc/paper/2018/file/b534ba68236ba543ae44b22bd110a1d6-Paper.pdf)

    - PIP Loss라는 개념을 제시해, 벡터의 성능을 측정했고 300차원까지는 성능이 좋아지다가 그 이후로 떨어지기 시작

 

- 이글을 적는 본인의 경우, 들어오는 데이터에 따라 사이즈를 가변으로 조절하게끔 만들었다.

데이터가 적을땐 size는 크게, 데이터가 많으면 size는 작게 (150~300 범위)

  (ref. datascience.stackexchange.com/questions/51404/word2vec-how-to-choose-the-embedding-size-parameter)

  - 해당 의견에 대해 다른쪽으로는, 차원수는 테스트 성능에 영향을 주기 보다는 훈련시간에 영향을 주는 요소일뿐이라 서술

 

- 당연한 얘기 이겠지만 벡터의 size가 클수록 더 큰 메모리를 사용

  (ref. stackoverflow.com/questions/46560861/relation-between-word2vec-vector-size-and-total-number-of-words-scanned)

 

- 적절한 차원수를 수식으로 계산하는 방법?

  (ref. stackoverflow.com/questions/48479915/what-is-the-preferred-ratio-between-the-vocabulary-size-and-embedding-dimension)

  - 단어 개수와 차원수 비율에 관한 질문

  - 차원수 = 단어갯수 ** 0.25

 

2. window

- window 는 훈련시 앞 뒤로 고려하는 단어의 개수 

   ex) “a little, (cat), sit, on”에서 "cat" 단어 기준 windows 는 2

- window 값이 커지면 단어의 학습 량이 증가 -> 계산량 증가, 단어의 의미적 정확도 증가

- window size 값에 따른 결과 차이

  Larger windows tend to capture more topic/domain information, Smaller windows tend to capture more about word itself (ref. stackoverflow.com/questions/22272370/word2vec-effect-of-window-size-used/30447723)

 

3. min count

- 최소 빈도수, 해당 빈도수보다 작게 등장한 단어의 경우 모델 학습에서 배제

- 값을 작게할 수록 몇번 안나온 단어들도 계산에 포함, 속도가 느려지고, 모델의 크기가 커진다

- 등장 빈도가 높은 단어는 높은 단어끼리 가깝고, 등장 빈도가 낮으면 낮은 단어끼리 가깝다

  (ref. lovit.github.io/nlp/2018/04/05/space_odyssey_of_word2vec/)

 

4. worker

- 모델을 만들때, 스레드 개수 지정

- 스레드가 많아질수록 모델 빌드 속도가 빨라진다.

- dl4j 의 경우, 처음에 maven을 사용하지 않고 직접 jar 파일을 하나씩 붙여서 사용했었다.

그때 당시 최신버전이 아닌걸 사용했었는데 스레드 개수가 많아질수록 CPU 사용량이 거의 100% 였다.

maven 사용하고 최신 버전으로 업데이트 하고 나니 20%~40%로 어느정도 준수해졌지만 개수 지정도 신경을 써야하는 변수다. 

- gensim 경우는 체크를 해보지 않아서 정확히는 알수 없으나, 아마 비슷할거 같다. 데이터가 많지 않다고 한다면

왠만하면 default 값으로 진행하는게 좋지 않을까 싶다.

 

5. Skip-gram or CBOW

- gensim 에서는 sg 값으로 설정 가능 (1일 경우 skip-gram, 0일 경우 CBOW)

- dl4j 에서는 설정이 가능하나, negative sample 개수를 지정할 경우 알아서 지정되는듯 했다

(본인은 따로 negative sample 개수말곤 설정하지 않았음)

- skip-gram : 해당 단어를 통해 주변단어를 예측

- CBOW : 주변 단어를 통해 해당 단어를 예측

 

- skip-gram의 경우 해당 단어의 업데이트양이 CBOW보다 많아 보통 skip-gram 이용

- 좀더 자세한 설명은 

Skip-gram: works well with small amount of the training data, represents well even rare words or phrases

CBOW: several times faster to train than the skip-gram, slightly better accuracy for the frequent words

(ref. towardsdatascience.com/an-implementation-guide-to-word2vec-using-numpy-and-google-sheets-13445eebd281)

- 해당 알고리즘에 대한 설명은 잘 서술되어 있는 블로그들이 많기 때문에...

 

6. Hiehierarchical softmax or Negative sampling

- gensim의 경우 hs 값으로 설정 가능 (1일 경우 hierarchical softmax, 0일 경우 negative sampling)

- hierarchical softmax(이하 hs) 의 경우 전체 단어를 업데이트 하지 않고, 트리구조의 weigth 생성후 weight 업데이트

  - binary tree로 구성, log2(word_갯수) 만큼 업데이트

  (ref. shuuki4.wordpress.com/2016/01/27/word2vec-%EA%B4%80%EB%A0%A8-%EC%9D%B4%EB%A1%A0-%EC%A0%95%EB%A6%AC/)

  (ref. analysisbugs.tistory.com/184)

  (ref. building-babylon.net/2017/08/01/hierarchical-softmax/)

 

- negative sampling(이하 ns) 의 경우 전체 단어를 업데이트 하지 않고, 특정 단어를 뽑아 업데이트 하기때문에 속도면에서 이점

  - window 변수 만큼 주변단어와 기준단어를 거리가 "가깝게", 나머지 단어중 ns 개수 만큼 무작위로 뽑아 거리가 "멀게" 업데이트

- ns vs hs performance compare

  (ref. shuuki4.wordpress.com/2016/01/27/word2vec-%EA%B4%80%EB%A0%A8-%EC%9D%B4%EB%A1%A0-%EC%A0%95%EB%A6%AC/)

 

7. negative sample

- negative sampling 사용시 샘플링 할 단어의 갯수 지정, 보통 5~20 

- 각 단어별로 주변 window 단어와 해당 단어와 상관없는(negative) 단어 5개 (값을 5로 지정 했을 경우) 를 보고 해당 단어 및 주변 단어를 업데이트

- negative sample 값이 클수록 업데이트 해야하는 단어가 늘어나므로 계산 속도에 영향을 미침

- 본인은 구현할때 역시 데이터 사이즈에 따라 가변하게끔 사용했다 (2~5)

 

8. ns_exponent

- negative sampling 사용시 샘플링 비율 -> 0~1 사이 값을 가지고, 1은 빈도수에 비례해서, 0은 모든 단어 동일하게 랜덤하게 뽑는 형식 , 보통 0.75 로 설정해 사용

- 어떤 값으로 설정했을때, 결과가 좋은지에 대한 논문

  (ref. arxiv.org/abs/1804.04212)

   - 값이 0.75 일 경우 결과가 좋은 경우가 많았으나, 수행하는 일에 따라 값을 조정해봐야 한다고 결론

 

9. CBOW mean

- CBOW 방법을 설정했을때 사용되는 parameter, cbow 방법 으로 벡터 생성시 주변 단어 벡터를 합산할지, 평균을 낼지에 대한 parameter

- 본인은 CBOW 방법을 사용하지 않아 결과값에 대한 영향은 모름

 

10. alpha

- 벡터 업데이트 시 learning rate (defalt 0.025)

- 이 변수값에 대해서는 기본값을 사용했었다.

word2vec도 아주 간단한 NN이라고 보이고 역시 backword연산시 얼만큼 업데이트 할지에 대한 learning rate를 신경쓰지 않을수 없지만 테스트할때, 사정상 체크하지 못한 변수이다.

 

11. min alpha

- min learning rate parameter, 학습이 진행 될수록 alpha 값이 min_alpha로 떨어진다. (default 0.0001)

- alpha - (alpha - min_alpha) * progress (progress는 0~ 1 사이 값)

  (ref. github.com/RaRe-Technologies/gensim/blob/c0e0169565116854993b22efef29e3c402ec6c69/gensim/models/word2vec.py#L1334)

- alpha 변수와 마찬가지로 해당 값 역시 체크하지 않고 기본값으로 나뒀다.

 

12. seed

- 워드 벡터의 초기화를 위한 parameter, 단어+str(seed) 값을 해싱 -> 초기 단어 벡터 생성

- 해당 값은 사용 컴퓨터(32/64 비트, OS) 에 따라 초기화 값이 달리질 수 있다

  (ref. stackoverflow.com/questions/34831551/ensure-the-gensim-generate-the-same-word2vec-model-for-different-runs-on-the-sam)

- 본인의 경우, 해당값은 특정 상수로 고정해 사용했다. 테스트 할때 동일한 데이터에 대해 동일한 초기값으로 벡터가 만들어지길 원했기 때문이다.

 

13. hashfxn

- seed를 이용해 word를 해싱하는 함수가 os나 컴퓨터 사양에 영향을 받을 수 있으니, 사용자가 정의한 해쉬 함수를 사용하게끔 parameter 지정

  (ref. stackoverflow.com/questions/34831551/ensure-the-gensim-generate-the-same-word2vec-model-for-different-runs-on-the-sam)

- dl4j 에도 존재하는지 안하는지 글을 작성하는 시점에서는 기억이 안난다. 하지만 gensim, dl4j 에서 사용하지 않았기 때문에 각자 테스트에 맞게끔 조절하면 될듯하다.

 

14. max vocab size

- 벡터를 만들 단어 갯수를 제한 (빈도순으로)

- 저빈도 단어의 경우 모델에서 제외시키겠다는 의미

- 본인의 경우 min count 이상의 모든 단어를 필요로 했기 때문에, 사용하지 않았다.

 

15. max final vocab

- 빈도 순 단어 내림차순 정렬 후 정렬된 단어중 max_final_vocab index 자리의 단어 빈도와 min_count중 큰 값을 min_count로 지정

- 한마디로 min count를 치환, 단어 마지노선을 상향하겠다는 의미

- gensim에선 기본값 None, dl4j에선 없었던걸로 기억한다.

  (ref. github.com/RaRe-Technologies/gensim/blob/c0e0169565116854993b22efef29e3c402ec6c69/gensim/models/word2vec.py#L541)

 

16. sample (sub-sample)

- 전체 데이터에서 많이 등장하는 단어는 그만큼 학습 기회가 많으므로 이런 학습량을 확률적인 방식으로 줄이기 위한 변수

- p(단어 w) = 1 - root(t / freq(단어 w)) t 는 사용자 정의 -> 0.00001 권장

- 빈도가 높은 단어의 경우 학습에서 제외, 반대로 빈도가 낮은 단어의 경우 학습 기회가 올때 빼놓지 않고 학습

- 학습량을 줄여 전체 계산 속도를 높힌다

  (ref. ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/30/word2vec/)

 

17. iter or iteration

- 반복횟수, 전체 데이터를 몇번 반복해서 보고 업데이트 할건지에 대한 변수

- 이부분은 벡터 모델의 학습시간, 품질에 영향을 많이 끼치는 변수이다.

- 게다가 gensim의 iter와 dl4j 의 iter 값의 의미가 조금 다르다. 

  (gensim의 iter와 dl4j의 epoch 이 같은 의미, dl4j의 iter는 한 batch를 몇번 볼지에 대한 변수)

- dl4j에 대해서 예시로 서술하자면 

 

dl4j epoch, iter 로직 예시

이런 로직으로 흘러간다. 

 

18. trim rule

- 단어 제거 규칙 명시 parameter , 해당 규칙이 사용자에 의해 정의 되면 해당 규칙으로 단어를 제거

- gensim 기본 값으로 None( None = min_count 값 이하의 단어는 버리기)

- dl4j 에서는 딱히 못본것 같다... (꼭 확인해보기를 바람)

 

19. sorted vocab

- 값이 1 인 경우 단어를 인덱싱 하기 전에 등장 빈도 내림차순으로 소팅한 뒤에 인덱싱 

  -> 차후 메모리 문제로 단어 몇개만 가져와야할 경우, 등장 빈도 상위 순으로 가져오기 위함

- gensim 에선 지원, dl4j 에서는 없었던거 같음(파라미터가 없을뿐 내부적으로는 알아서 진행했을수도...)

 

20. batch word or batch size

- 모델 구성시 한번에 읽을 단어수

- gensim의 경우, 기본값 10000. 10000이상 설정 불가능 (greater than 10000 cython will be truncated)

  (ref. www.programmersought.com/article/2792230175/)

- dl4j 에서도 설정이 가능

- 본인의 경우 2048로 설정했으나, 역시 데이터 크기에 따라 가변적으로 변하게끔 설정

- 위 epoch 로직에 의해서 한번에 보는 batch size가 결과에 영향을 미침

  (값이 클수록 좀더 정확해지는 현상...)

 

21. compute loss

- 값이 True 이면 모델을 업데이트 하는 동안 손실계산 값을 저장

- gensim 에서는 설정가능, dl4j에서는 찾아보지 않아서 알수없음

  (하지만 있을 것으로 예상, word2vec 진행과정과 결과를 가시화 해서 볼수있는 모듈 지원이 있기때문에...)

 

 

대충  Word2Vec에 사용되는 파라미터를 정리 해보았다.

아래는 dl4j 파라미터 추가 정리 이다.

하지만 사용하지 않았다!

****************************************************

dl4j Word2Vec parameter (not used)

1. stopwords

- 모델 업데이트 중에 무시해야할 단어 지정 가능

 

2. useAdagrad

- 학습 과정의 최적화에 쓰이는 기법 중 하나

- 업데이트 횟수에 따른 가중치 변화에 차등을 주는 방법

  - 많이 업데이트되는 단어의 경우 가중치 변화량을 줄이고, 적게 업데이트 되는 단어의 경우 가중치 변화량을 늘린다.

  - 같은 데이터가 여러번 학습되는 word2vec 같은 모델에 적합

  (ref. twinw.tistory.com/247)

 

3. usePreciseMode / usePreciseWeightInit
- true로 설정할 경우, 초기 단어 벡터가 단어 자체에서 파생. 단어가 가진 속성 값을 통해서 벡터를 초기화

- 파라미터가 의미하는 바가 정확히 무엇인지 모르겠어서 default로 사용

 

4. useUnknown

- UNK 단어를 사용할지 말지 

 

5. unknownElement

- UNK 단어로 어떤 단어를 사용할건지

 

6. useVariableWindow

- 가변 window 크기를 사용. 이 경우 모든 배치는 미리 정의 된 창 크기 중 하나를 사용하여 처리.

- 매개변수로 (int...)사용 하는걸 보니 정수형 배열을 입력으로 받음

 

7. enableScavenger

- 모델 생성중에 주기적으로 단어를 버린다

  - 찾았을때, document가 없어서 사용x

반응형