doc2vec 훈련 파라미터 설명

Word2vec이 단어를 vector로 변경하는 word embedding 방식이라면 doc2vec은 문서를 vector로 변경하는 document embedding 방식입니다. Word2vec 방식을 문서에 대해서 확장하였기 때문에 기존의 word2vec의 장점을 그대로 가지며 훈련 방식도 word2vec의 cbow와 skip-gram과 유사한 distributed memory(dm)과 distributed bag of words(dbow)을 사용합니다.

주변의 단어들로 가운데 있는 단어를 유추하는 CBOW, 가운데 있는 단어로 주변 단어들을 유추하는 skip-gram

doc2vec 알고리즘 소개

논문 연결

Doc2vec에서는 paragraph id(document id)를 하나의 단어(paragraph token)처럼 사용해서 문서를 훈련 데이터로 사용합니다. paragraph id, paragraph vector, paragraph token 등 다양한 이름으로 불리지만 의미는 동일합니다.  

PV-DM 방식은 이런 paragraph vector 와 앞의 단어들을 사용해서 다음에 나오는 단어를 유추합니다.  window라는 정해진 사이즈의 단어들을 context로 한 단어씩 옆으로 이동하면서 훈련 데이터로 사용합니다. 같은 패러그래프에서 생성된 훈련 데이터에서는 하나의 패러그래프 벡터로 공유되기 때문에 패러그래프 벡터는 훈련시 문서의 주제를 잡아주는 memory 같은 역할을 하고 있습니다. 그래서 이 알고리즘의 이름 자체가 분산화된 메모리를 가진 패러그래프 벡터(paragraph vector Pragraph vector with distributed memory) 로 지어졌습니다.

PV-DBOW 방식은 위 방식에서 나오는 context 단어들을 사용하지 않고 paragraph id 만 가지고 이 패러그래프에서 나오는 단어를 랜덤하게 예측하는 방식을 사용합니다.  input은 패러그래프 벡터이고 output은 패러그래프에서 random하게 뽑인 단어들입니다.

 

doc2vec 훈련시 주요 파라미터

class gensim.models.doc2vec.Doc2Vec(documents=None,

 corpus_file=Nonedm_mean=Nonedm=1dbow_words=0,

 dm_concat=0dm_tag_count=1docvecs=None

docvecs_mapfile=Nonecomment=None,

 trim_rule=Nonecallbacks=()**kwargs)

document는 doc2vec 모델을 훈련시키기 위한 말뭉치(corpus) 입니다. taggeddocument 리스트를 생성해서 입력하면 됩니다. taggedDocument는 문서 별로 문서 tag, 문서 안의 단어들의 리스트로 구성됩니다.

dm은 doc2vec 훈련 알고리즘입니다. dm=1으로 설정하면 distributed memory(PV-DM)이 사용되고 그 외는 distributed bag of words( PV-DBOW) 알고리즘이 사용됩니다.  Distributed Representations of Sentences and Documents 페이퍼에서는 PV-DM 방식만 사용해도 대부분의 작업에 좋은 결과를 보였으나 PV-DBOW와 함께 사용하는 것을 추천한다고 합니다.

 


vector_size 는 임베딩 벡터의 크기입니다. 벡터 사이즈가 클수록 생성된 모델의 성능이 정교해지나 훈련 시간 및 메모리의 크기가 사이즈가 커진다는 단점이 있습니다. Glove 논문에 따르면 vector size가 커질수록 모델 성능이 좋아지는 것을 확인할 수 있습니다. vector 사이즈가 100까지 증가할 경우 가장 극적인 성능 향상을 보이고 그 이상의 사이즈일 경우 정확도 그래프가 완만하게 증가하는 것을 확인 할 수 있습니다.


alpha 는 learning rate 입니다.

window 는 훈련시 앞 뒤로 고려하는 단어의 개수입니다.  “a little, (cat), sit, on”의 windows 는 2 입니다.  window 사이즈가 커지면 훈련 결과로 나오는 word vectors의 성능이 높아지지만 대신 훈련 시간이 오래 걸린다는 단점이 있습니다. 보통 5에서 10 사이의 값이면 적당합니다.

min count 는 데이터에서 등장하는 단어의 최소빈도수입니다.  Word2Vec/Doc2vec 은 자주 등장하지 않은 단어에 대해서는 제대로 학습이 이뤄지지 않습니다. 또한 min_count 가 작으면 모델에 지나치게 많은 단어가 포함되어 모델의 크기가매우 커집니다.   10에서 100 사이의 값이면 적당할 것 같습니다.

negative 는 negative samples 의 개수입니다. 이 역시 기본값 쓰셔도 됩니다. 클수록 학습속도가 느려집니다. 하지만 지나치게 작으면 학습이 제대로 이뤄지지 않습니다.

그리고….

doc2vec 알고리즘은 일반적인 document embedding 방식으로 훌륭한 성능을 보여줍니다. 하지만 doc2vec 인코딩을 사용하기 위해서는 다량의 말뭉치를 준비하고 형태소 분석기를 사용하여 띄어쓰기를 하고 gensim 등 doc2vec 툴으로 훈련 시키는 등의 다량의 준비 작업이 필요합니다.

로보리포트 기계학습 서비스에서는 이런 준비 과정 없이 간단하게 클릭만으로 기계학습에 사용할 문서를 doc2vec 인코딩으로 변환하거나, 실험에 사용되는 단어 속성들을 word2vec 인코딩으로 변환하도록 준비 하고 있습니다.

저희 서비스에 관심있으신 분들은 로보리포트 사이트에 회원가입하고
(선택) 서비스 업데이트 정보 알람 수신 동의를 클릭하시면 해당 서비스가 업데이트 될 경우 이메일 알람을 받아볼 수 있습니다 : )

그리고 위키 문서 및 경제 뉴스에서 에서 훈련된 doc2vec 모델은 roboreport 오프소스로 이미 등록되어 있으니 이곳도 참조 부탁드립니다.

참고 문서들

https://radimrehurek.com/gensim/models/doc2vec.html

https://lovit.github.io/nlp/representation/2018/03/26/word_doc_embedding/

https://ronxin.github.io/wevi/

https://programmers.co.kr/learn/courses/21/lessons/1698

한국어 뉴스 데이터로 딥러닝 시작하기 – 1. 한국어 위키피디아 덤프 다운로드 받기

로보리포트에서는 자연어처리 오픈소스 저장소를 운영하고 있습니다. 그곳에서 연재했던 글들을 가져오고 이어서 글을 작성해보겠습니다.

한국어 뉴스 데이터로 딥러닝 시작하기 

뉴스 데이터를 이용하여 간단하게 딥러닝 알고리즘으로 classification 하는 과제를 수행해보고자 합니다.

 자연어를 처리하기 위해서는 단어나 문서를 vector로 변환을 해야 하는데 이러한 변환 과정을 word embedding이라고 합니다. 최근 deep learning에서는 word embedding을 위해서 word2vec, doc2vec 모델을 주로 사용하기 때문에 doc2vec 모델로 진행해보려고 합니다.

1. training data 수집 

doc2vec model 훈련을 위해서는 말뭉치 데이터가 필요합니다. 형태소 분석없이 공백 단위로 단어를 분리해서 훈련을 할 수 있지만 과거 제대로 띄어쓰기가 되어있을 경우 doc2vec 변환후 실험 성능이 더 좋은 기억이 있어 형태소 태깅된 데이터가 필요합니다. 일단 한국어 위키를 다운받아 형태소 태깅을 진행하려고 합니다. 

위키피디아는 정기적으로 덤프 파일로 릴리즈 합니다 . 언어마다 릴리즈 주기가 다르긴 하지만 한국어 덤프 파일은 한달에 한두번 릴리즈되고 있으니 참고하면 될 것 같습니다.  

한국어 위키 덤프 다운로드 사이트 바로가기

덤프 사이트에 직접 접속하려면 아래 주소로 가면 날짜별로 디렉토리가 있고 그 안에 덤프 파일들이 있습니다.


https://dumps.wikimedia.org/kowiki/

덤프 파일들 종류는 아래와 같습니다.

pages-articles.xml.bz2 – 일반 문서의 최신 버전만이 묶여 있고, 전체 편집 역사는 들어있지 않습니다. 대부분의 이용자는 이 파일을 이용하면 됩니다.

pages-current.xml.bz2 – 모든 문서의 최신 버전이 묶여 있습니다.

pages-full.xml.bz2/7z – 모든 문서(토론 포함)의 최신 버전이 묶여 있습니다.

pages-meta-history.xml.bz2 – 모든 문서의 모든 편집 내역이 묶여 있습니다.

abstract.xml.gz – 문서 요약을 묶어놓았습니다.

all_titles_in_ns0.gz – 문서 제목만을 묶어놓았습니다.

최신 버전의 문서만 필요하니 pages-articles.xml.bz2를 다운받습니다.

위키 데이터는 xml로 되어 있기 때문에 이 안에서 본문만 추출하기 위해서는 parsing이 필요합니다.

다음 포스팅에서는 위키 데이터 파싱하는 법을 이어서 설명하겠습니다.  

참고로 공백이나 형태소 단위로 토큰화된 한국어 위키 덤프 데이터 (문장만 포함)는 아래 github에 올려두었습니다.

앞으로 진행되는 다른 연재 자료들도 계속 추가할 예정이니 필요하신 분은 watch를 걸어주세요 : ) 

github 바로가기 

인공지능 분석 서비스 로보리포트

scikit-learn을 사용하여 부동산 가격 예측하기 – 4) linear regression 사용법

scikit-learn을 사용하여 부동산 가격 예측하기 실험 시리즈 네번째 포스팅입니다.이제 본격적인 실험에 들어갑니다. 

기계학습을 할 경우 실험 과제의 특성(분류화, 클러스터링 등)와 데이터의 속성 및 복잡도, 사이즈에 따라 적합한 학습방법을 선택해야 합니다. 이 실험에서는 데이터 개수와 속성 개수가 적으면서 실제 예측값이 나와야 하므로 싸이킷런에서 제공하는 가장 간단한 알고리즘인 선형 회귀(linear regression) 알고리즘을 사용해 보겠습니다. 나중에 개별 매물 평가 실험에서는 부동산 실거래가 데이터를 사용하여 신경망을 사용한 더 복잡한 기계학습을 사용해보려고 합니다.

이전 포스팅 내용 요약

이전 포스팅에서 속성 소개, 데이터 분석에 대해서 완료했습니다. 그 중 데이터를 읽어와서 pandas dataframe으로 저장한 이후에 이어서 실험을 하겠습니다.

dropna 함수로 속성에 빈 값이 있는 데이터는 실험에서 제거하였습니다.

실험 데이터는 2017년도 이전의 데이터는 훈련 데이터 셋으로, 2017년 이상의 데이터는 테스터 데이터셋으로 구성을 했습니다. 일반적인 fold validation으로 실험데이터를 구성하지 않은 이유는 예측 실험에서는 과거 데이터로 최근의 데이터를 예측하는 것이 중요하다고 생각하였기 때문입니다. 나중에 소개드릴 로보리포트 시계열 예측 서비스에서는 다양한 방식으로 실험 데이터를 구성하도록 지원하고 있습니다.

X_train.shape : (6356, 16) 
X_test.shape : (196, 16)

속성 소개하기

전체 16개의 속성이며 훈련 셋 크기는 6356개, 테스트 셋 크기는 196개 입니다. 참고로 실험 속성은 지역코드, 년도, 월, 빌딩 타입(아파트, 빌라 등), 매매가격 지수, 금리, 환율, 미분양 데이터 등입니다. 자세한 내용은 아래 표를 참조해 주세요.
그리고 target 속성은 다음달 주택 매매가격지수(tradeprice_sido_n1)를 설정했습니다.

region_cd 지역코드(시도)
year 연도
month
building_type 부동산타입
tradeprice_sido 매매가격지수(시도)
construction_realized_amount 건설기성액(백만원)
cd
cd(91일물)

spirit_deposit_rate

정기예금금리
exchange_rate 환율
composite_stock_price_index 종합주가지수
economy_growth 경제성장률
exchequer_bond_three 채3년
household_loan_all 가계대출액(전국)
mortgage_all 주택대출액(전국)
numberofnosells 미분양 가구수(시도)
unsalenum_c 공사완료후 미분양(민간,시도)

실험을 하기 위해 우선 Linear Regression 패키지를 import 합니다. 선형 회귀 알고리즘(linear regression)은 주어진 데이터 집합에 대해 종속 변수 Y 와 설명 변수 X와의 선형 관계를 모델링합니다. 쉽게 이야기해서 아래와 같이 실험 데이터에 가장 근사하게 매치하는 직선을 그린다고 생각하면 됩니다. y절편은 이 직선이 y축과 만나는 점을 의미하며 LinearRegression 클래스의 intercept_ 속성에 그 값이 저장됩니다.

표현식은 아래와 같습니다. 이중에서 베타는 weight, 상관계수 라고도 불리며 각 속성의 영향도를 의미합니다. 실험이 끝나면 훈련이 끝난 모델의 coef_ 속성에 값이 저장됩니다. intercept_ 속성은 항상 실수 값 하나지만, coef_ 속성은 각 입력 특성에 하나씩 대응되는 Numpy 배열입니다. 16개의 속성이므로 coef_ 속성 배열 사이즈도 16이 될 것 입니다.

선형회귀 실험

LinearRegression 함수 인자의 문는 아래를 참고하세요.

fit_intercept는 y 절편을 계산할지에 대한 설정입니다. 데이터를 표현하는 식이 원점을 지나가는 선이 최적화된 선이 아니라면 기본적으로 사용하는 것이 좋습니다. normalize는 regressors X를 정규화 시킬 것인지에 대한 옵션입니다. n_jobs 는 모델 계산에 사용될 작업 개수를 의미합니다. 데이터 개수가 작아 None으로 설정했습니다.

Linear Regression test file accuracy:0.904775830424
Out[12]:
array([ 2.41360754e-06, -1.43348218e-01, -6.30260362e-03, -9.82386414e-03, 9.78713133e-01, -9.70551425e-09, 2.54192891e-01, -1.51807329e-01, 1.58985085e-05, 5.78284319e-04, 1.10692957e-01, -6.18784363e-02, -5.71178866e-06, 1.41955024e-05, -1.97553459e-05, -4.99848193e-06])

sklearn은 기본적으로 fit 함수를 사용하여 훈련 데이터 셋에서 모델을 생성합니다. 그리고 score 함수를 사용해서 생성된 모델의 성능을 확인하고 predict 함수로 테스트 셋의 예측값을 생성합니다. 이 세가지 함수는 알고리즘의 종류와 관계 없이 대부분의 알고리즘에 존재합니다.

Score 함수에서 리턴하는 값은 R2 이며 결정계수, R-Square,
coefficient of determination 로도 불립니다. 결정계수는 모델의 전반적인 성능을 0~1까지의 숫자로 알려줍니다. 종속 변수와 독립 변수와의 상관도가 높을 수록 값은 1에 가까워 집니다. 실험에서 나온 결정계수의 스코어는 0.90으로 그럭저럭 높은 예측값을 보여줍니다. 그리고 coef_ 변수에는 각 속성들의 상관계수 값이 들어있습니다. 상관계수는 -1 에서 1까의 값을 가지며 -는 음의 영향력, +는 양의 영향력을 의미합니다. 부호와 상관없이 숫자의 절대값은 영향력의 크기를 의미합니다.

위 코드에서 속성의 순서에 따라 결정계수의 값이 배열로 들어있긴 하지만 속성과 연관해서 확인하기는 힘들어서 한글 속성 이름으로 변경하고 절대값이 큰 순서로 정렬해서 pandas dataframe으로 다시 확인해 보았습니다.

당연한 결과이지만 해당 월의 매매가격 지수가 0.9로 매우 강한 양의 상관관계를 보이고 그외 단기 금리인 cd와 0.25의 약한 양의 상관관계, 정기예금금리와는 -0.15의 약한 음의 관계, 연도와는 -, 경제성장률은 +의 매우 약한 상관 관계를 보여주고 있습니다. 그 외 나머지는 0.1 이하의 값으로 크게 상관관계가 없어보입니다. 미분양 데이터가 상관관계가 적어보이는 것은 약간 의아하지만 바로 다음달의 매매가격지수를 예측했기에 그럴 수도 있을 것 같습니다. 어느정도 시차를 두고 영향을 끼치는 속성들은 3개월후, 6개월후, 1년후 등으로 예측 시기를 변경해서 실험을 해보는 것도 의미가 있을 것 같습니다.

실험 결과 해석하기

다음은 테스트셋의 실제 값을 x축으로 예측 값을 y축으로 그래프를 그려보겠습니다. 원칙적으로 모든 예측 값이 실제 값과 일치하면 직선이 나올 것이고 모델의 성능이 좋지 않을 수록 흩어진 점들을 볼 수 있을 것입니다. 해당 실험은 아래와 같이 어느정도 직선에 가까운 모습을 보입니다.

mse = sklearn.metrics.mean_squared_error(Y_test, Y_pred)
print(mse)


0.100838171768

그리고 실제 값과 예측 값의 mean squared error를 구해보았습니다. mean squared error는 오차의 제곱의 평균값을 계산한 값으로 숫자가 적을 수록 예측값과 실제 값의 차이가 적은 것을 의미합니다. 0.1의 값이 나왔습니다.

그럼 지금까지 부동산 가격에 영향이 있을 것 같은 속성들을 일부 골라서 선형 회귀로 다음달의 부동산 지수를 예측하는 실험을 해 보았습니다. 처음 작성하는 실험 포스팅이라 최대한 자세하고 쉽게 적으려고 노력을 해보았습니다. 다음 포스팅에서는 각 알고리즘에 대한 설명 및 실험 관련 속성들에 대해서 간략하게 적어보도록 하겠습니다. 포스팅 연재를 읽어주셔서 감사합니다.

참고로 해당 포스팅의 실험 결과는 로보리포트 사이트에 지속적으로 업데이트 될 예정입니다. 관심 있으신 분은 방문 부탁드립니다 +_+

https://land.roboreport.co.kr

읽을만한 글들

linear regression : https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html

https://medium.com/@haydar_ai/learning-data-science-day-9-linear-regression-on-boston-housing-dataset-cd62a80775ef