반응형
반응형


단어 임베딩(Word Embedding)이란 텍스트를 구성하는 하나의 단어를 수치화하는 방법의 일종이다.

텍스트 분석에서 흔히 사용하는 방식은 단어 하나에 인덱스 정수를 할당하는 Bag of Words 방법이다. 이 방법을 사용하면 문서는 단어장에 있는 단어의 갯수와 같은 크기의 벡터가 되고 단어장의 각 단어가 그 문서에 나온 횟수만큼 벡터의 인덱스 위치의 숫자를 증가시킨다.

즉 단어장이 "I", "am", "a", "boy", "girl" 다섯개의 단어로 이루어진 경우 각 단어에 다음과 같이 숫자를 할당한다.

"I": 0
"am": 1
"a": 2
"boy": 3 
"girl": 4

이 때 "I am a girl" 이라는 문서는 다음과 같이 벡터로 만들 수 있다.

[11101]

단어 임베딩은 하나의 단어를 하나의 인덱스 정수가 아니라 실수 벡터로 나타낸다. 예를 들어 2차원 임베딩을 하는 경우 다음과 같은 숫자 벡터가 될 수 있다.

"I": (0.3, 0.2)
"am": (0.1, 0.8)
"a": (0.5, 0.6)
"boy": (0.2, 0.9) 
"girl": (0.4, 0.7)

단어 임베딩이 된 경우에는 각 단어 벡터를 합치거나(concatenation) 더하는(averaging, normalized Bag of Words) 방식으로 전체 문서의 벡터 표현을 구한다.

Feed-Forward 신경망 언어 모형 (Neural Net Language Model)

이러한 단어 임베딩은 신경망을 이용하여 언어 모형을 만들려는 시도에서 나왔다. 자세한 내용은 다음 논문을 참고한다.

V개의 단어를 가지는 단어장이 있을 때, 단어를 BOW 방식으로 크기 V인 벡터로 만든 다음 다음 그림과 같이 하나의 은닉층(Hidden Layer)을 가지는 신경망을 사용하여 특정 단어 열(word sequence)이 주어졌을 때 다음에 나올 단어를 예측하는 문제를 생각해 보자. 입력과 출력은 모두 BOW 방식으로 인코딩되어 있다.

이미지 출처: "word2vec Parameter Learning Explained", Xin Rong

입력 x가 들어가면 입력 가중치 행렬 WT이 곱해져서 은닉층 벡터 h가 되는데 x가 one-hot-encoding 된 값이므로 h 벡터는 입력 가중치 행렬 W의 행 하나가 된다.

h=WTx=viT

여기에서 i는 입력 벡터 x 의 값이 1인 원소의 인덱스이다. 즉, BOW 단어장에서 i번째 단어를 뜻한다.

벡터 h는 다시 출력 가중치 행렬 WT와 곱해져서 출력 벡터 y가 된다.

y=WTh

출력 가중치 행렬 W의 j번째 열을 vj라고 하면 출력 벡터 y의 j번째 원소의 값은 다음과 같다.

yj=vjTh

가중치 행렬을 갱신하는 최적화 공식을 살펴본다. 자세한 유도과정은 논문을 참조한다.

우선 출력 가중치 행렬의 갱신 공식은 다음과 같다.

vj(new)=vj(old)ηejh=vj(old)ηejviT

이 식에서 η는 최적화 스텝 사이즈, ej는 출력 오차가 된다. 이 공식에 따르면 벡터 vj는 vj 방향으로 수렴해 간다. 즉, i번째 단어와 j번째 단어가 연속하는 관계라면 vj가 vi와 유사한 위치로 수렴한다는 뜻이다.

다음으로 입력 가중치 행렬의 갱신 공식은 다음과 같다.

vi(new)=vi(old)ηkejwik

이 공식에 따르면 벡터 vi는 여러 vk 벡터의 가중합으로 수렴해 간다. 이렇게 단어간의 관계에 의해 i번째 단어를 뜻하는 vi의 값들이 연관성을 가지게 되는데 이 vi 벡터 값을 해당 단어에 대한 분산 표현 (distributed representation) , 벡터 표현 (vector representation) 또는 단어 임베딩 (word embedding)이라고 한다.

이미지 출처: https://www.tensorflow.org/versions/master/tutorials/word2vec/index.html

CBOW (Continuous Bag of Words) Embedding

위의 방식은 하나의 단어로부터 다음에 오는 단어를 예측하는 문제였다. 이러한 문제를 단어 하나짜리 문맥(single-word context)를 가진다고 한다.

CBOW (Continuous Bag of Words) 방식은 복수 단어 문맥(multi-word context)에 대한 문제 즉, 여러개의 단어를 나열한 뒤 이와 관련된 단어를 추정하는 문제이다. 즉, 문자에서 나오는 n개의 단어 열로부터 다음 단어를 예측하는 문제가 된다. 예를 들어

the quick brown fox jumped over the lazy dog

라는 문장에서 (thequickbrown) 이라는 문맥이 주어지면 fox라는 단어를 예측해야 한다.

CBOW는 다음과 같은 신경망 구조를 가진다. 여기에서 각 문맥 단어를 은닉층으로 투사하는 가중치 행렬은 모든 단어에 대해 공통으로 사용한다.

이미지 출처: "word2vec Parameter Learning Explained", Xin Rong

Skip-Gram Embedding

Skip-Gram 방식은 CBOW 방식과 반대로 특정한 단어로부터 문맥이 될 수 있는 단어를 예측한다. 보통 입력 단어 주변의 k개 단어를 문맥으로 보고 예측 모형을 만드는데 이 k 값을 window size 라고 한다.

위 문장에서 window size k=1인 경우,

  • quick -> the
  • quick -> brown
  • brown -> quick
  • brown -> fox

과 같은 관계를 예측할 수 있어야 한다.

이미지 출처: "word2vec Parameter Learning Explained", Xin Rong

word2vec

word2vec은 CBOW 방식과 Skip-Gram 방식의 단어 임베딩을 구현한 C++ 라이브러리로 구글에 있던 Mikolov 등이 개발하였다.

파이썬에서는 gensim이라는 패키지에 Word2Vec이라는 클래스로 구현되어 있다. nltk의 영화 감상 corpus를 기반으로 Word2Vec 사용법을 살펴보자.

우선 단어 임베딩을 위한 코퍼스를 만든다. 코퍼스는 리스트의 리스트 형태로 구현되어야 한다. 내부 리스트는 하나의 문장을 이루는 단어 열이 된다.

from nltk.corpus import movie_reviews
sentences = [list(s) for s in movie_reviews.sents()]
sentences[0]
[u'plot',
 u':',
 u'two',
 u'teen',
 u'couples',
 u'go',
 u'to',
 u'a',
 u'church',
 u'party',
 u',',
 u'drink',
 u'and',
 u'then',
 u'drive',
 u'.']

다음으로 이 코퍼스를 입력 인수로 하여 Word2Vec 클래스 객체를 생성한다. 이 시점에 트레이닝이 이루어진다.

from gensim.models.word2vec import Word2Vec
%%time
model = Word2Vec(sentences)
CPU times: user 12.2 s, sys: 400 ms, total: 12.6 s
Wall time: 7.33 s

트레이닝이 완료되면 init_sims 명령으로 필요없는 메모리를 unload 시킨다.

model.init_sims(replace=True)

이제 이 모형에서 다음과 같은 메서드를 사용할 수 있다. 보다 자세한 내용은 https://radimrehurek.com/gensim/models/word2vec.html 를 참조한다.

  • similarity : 두 단어의 유사도 계산
  • most_similar : 가장 유사한 단어를 출력
model.similarity('actor', 'actress')
0.87472425755991945
model.similarity('he', 'she')
0.85470770334392587
model.similarity('actor', 'she')
0.21756392610362227
model.most_similar("villain")
[(u'hero', 0.7978197932243347),
 (u'doctor', 0.7952470779418945),
 (u'actress', 0.7806568145751953),
 (u'performer', 0.775442361831665),
 (u'charming', 0.7602461576461792),
 (u'impression', 0.7583950757980347),
 (u'commoner', 0.7538788318634033),
 (u'janitor', 0.7536816000938416),
 (u'dude', 0.7528475522994995),
 (u'genius', 0.7506694793701172)]

most_similar 메서드는 positive 인수와 negative 인수를 사용하여 다음과 같은 단어간 관계도 찾을 수 있다.

he + (actress - actor) = she

model.most_similar(positive=['actor', 'he'], negative='actress', topn=1)
[(u'she', 0.2471558153629303)]

이번에는 네이버 영화 감상 코퍼스를 사용하여 한국어 단어 임베딩을 해보자.

import codecs

def read_data(filename):
    with codecs.open(filename, encoding='utf-8', mode='r') as f:
        data = [line.split('\t') for line in f.read().splitlines()]
        data = data[1:]   # header 제외
    return data

train_data = read_data('/home/dockeruser/data/nsmc/ratings_train.txt')
from konlpy.tag import Twitter
tagger = Twitter()

def tokenize(doc):
    return ['/'.join(t) for t in tagger.pos(doc, norm=True, stem=True)]

train_docs = [row[1] for row in train_data]
sentences = [tokenize(d) for d in train_docs]
from gensim.models import word2vec
model = word2vec.Word2Vec(sentences)
model.init_sims(replace=True)
model.similarity(*tokenize(u'악당 영웅'))
0.6062297706048696
model.similarity(*tokenize(u'악당 감동'))
-0.0041346659756955097
from konlpy.utils import pprint
pprint(model.most_similar(positive=tokenize(u'배우 남자'), negative=tokenize(u'여배우'), topn=1))
[(여자/Noun, 0.6258430480957031)]

더 많은 한국어 코퍼스를 사용한 단어 임베딩 모형은 다음 웹사이트에서 테스트해 볼 수 있다.


반응형
반응형
gensim.models.Word2Vec.train 


 Update the model’s neural weights from a sequence of sentences (can be a once-only generator stream). For Word2Vec, each sentence must be a list of unicode strings. (Subclasses may accept other examples.)
문장의 시퀀스에서 모델의 신경 가중치를 업데이트하십시오 (한 번만 생성기 스트림 일 수 있음). Word2Vec의 경우 각 문장은 유니 코드 문자열 목록이어야합니다. 서브 클래스는 다른 예를 받아들이는 일이 있습니다.

 To support linear learning-rate decay from (initial) alpha to min_alpha, either total_examples (count of sentences) or total_words (count of raw words in sentences) should be provided, unless the sentences are the same as those that were used to initially build the vocabulary.
(초기) alpha에서 min_alpha까지의 선형 학습 률 감소를 지원하려면, 문장이 처음 빌드에 사용 된 것과 같지 않으면 total_examples (문장의 수) 또는 total_words (문장의 원시 단어의 수)가 제공되어야합니다 어휘.






import gensim

sentences = [["my", "name", "is", "jamie"], ["jamie", "is", "cute"]]
model = gensim.models.Word2Vec(sentences)


#----------------------------------------------------------------------

sentences_vocab = SentenceReader('corpus.txt')
sentences_train = SentenceReader('corpus.txt')

model = gensim.models.Word2Vec()
model.build_vocab(sentences_vocab)
model.train(sentences_train)

#----------------------------------------------------------------------

class SentenceReader:

    def __init__(self, filepath):
        self.filepath = filepath

    def __iter__(self):
        for line in codecs.open(self.filepath, encoding='utf-8'):
            yield line.split(' ')


#----------------------------------------------------------------------

model.save('model')
model = gensim.models.Word2Vec.load('model')


model.most_similar(positive=["한국/Noun", "도쿄/Noun"], negative=["서울/Noun"], topn=1)
# [("일본/Noun", 0.6401702165603638)]


#----------------------------------------------------------------------

import multiprocessing

config = {
    'min_count': 5,  # 등장 횟수가 5 이하인 단어는 무시
    'size': 300,  # 300차원짜리 벡터스페이스에 embedding
    'sg': 1,  # 0이면 CBOW, 1이면 skip-gram을 사용한다
    'batch_words': 10000,  # 사전을 구축할때 한번에 읽을 단어 수
    'iter': 10,  # 보통 딥러닝에서 말하는 epoch과 비슷한, 반복 횟수
    'workers': multiprocessing.cpu_count(),
}
model = gensim.models.Word2Vec(**config)


#----------------------------------------------------------------------

...


반응형
반응형
구분일정대상시행처
구분일정대상시행처

3월

2017년 3월 9일 (목)

고등학교 1, 2학년

서울특별시교육청
(경기, 광주 미실시)

고등학교 3학년

서울특별시교육청

4월

2017년 4월 12일 (수)

고등학교 3학년

경기도교육청

6월

2017년 6월 1일 (목)

고등학교 1, 2학년

부산광역시교육청
(서울, 세종 미실시)

고등학교 3학년 - 대수능 모의평가

한국교육과정평가원

7월

2017년 7월 12일 (수)

고등학교 3학년

인천광역시교육청

9월

2017년 9월 6일 (수)

고등학교 1, 2학년

인천광역시교육청
(경기, 세종 미실시)

고등학교 3학년 - 대수능 모의평가

한국교육과정평가원

10월

2017년 10월 17일 (화)

고등학교 3학년

서울특별시교육청

11월

2017년 11월 22일 (수)

고등학교 1, 2학년

경기도교육청

시행지역 및 일정은 각 지역교육청 및 시행처 사정에 따라 변경 될 수 있습니다.


반응형
반응형

 Wordcloud 만들기 


from collections import Counter
from konlpy.tag import Twitter
import pytagcloud
 
f = open('blog_data.txt')
data = f.read()
 
nlp = Twitter()
nouns = nlp.nouns(data)
 
count = Counter(nouns)
tags2 = count.most_common(40)
taglist = pytagcloud.make_tags(tags2, maxsize=80)
pytagcloud.create_tag_image(taglist, 'wordcloud.jpg', size=(900, 600), fontname='korean', rectangular=False)
 
f.close()



반응형
반응형

파이썬에 내장되어 있는 함수 join, split을 이용해 문자열(String)을 리스트(List)로 변환하는 방법입니다. 

Join 함수는 리스트를 특정 구분자를 포함해 문자열로 변환해 주는 함수입니다. 

Split함수는 문자열을 특정 구분자를 기준으로 나누어 리스트로 변환해 주는 함수입니다.

리스트(List)를 특정 구분자를 포함해 문자열(String)으로 변환


animals = ['사자', '코끼리', '기린', '원숭이', '바나나원숭이']


print ",".join(animals)

# >> 사자,코끼리,기린,원숭이,바나나원숭이 


print "\n".join(animals)

# >> 사자

# >> 코끼리 

# >> 기린 

# >> 원숭이

# >> 바나나원숭이


print "/".join(animals)

# >> 사자/코끼리/기린/원숭이/바나나원숭이

문자열(String)을 특정 '구분자'를 기준으로 리스트(List) 로 변환

animal_string = "/".join(animals)

# >> 사자/코끼리/기린/원숭이/바나나원숭이


animal_split = animal_string.split("/")

print animal_split

# >> ["사자", "코끼리", "기린", "원숭이", "바나나원숭이"]





...

반응형
반응형
여행 서비스도 모바일 퍼스트 

 http://www.bloter.net/archives/284358

글로벌 애드테크 기업 크리테오가 유로모니터와 파트너십을 통해 2017년 2월 온라인으로 여행 상품을 검색·구매한 200명의 국내 여행객들을 대상으로 온라인 소비자 설문조사를 했다.

연구 결과에 따르면, 2016년 한국 온라인 여행 상품 거래 5건 중 1건이 모바일을 통해 이루어졌다. 모바일 여행 판매는 계속해서 증가할 것으로 예상된다. 본 연구는 여행 업계와 온라인 여행사가 여행자들의 구매를 극대화하는데 필요한 최적의 디지털 전략을 채택하도록 돕기 위해 진행됐으며, 온라인 여행 환경과 한국인의 여행 검색 및 구매 행동을 분석했다.


여행 상품·예약에도 단연 모바일 대세


보고서는 모바일을 통한 여행 매출이 급증하고 있으며, 온라인을 통한 여행 매출 성장을 앞지르고 있다는 점을 보여준다. 모바일 여행 매출은 2011년에서 2016년까지 연평균 59%의 성장률을 기록했으며, 2020년까지 모바일 판매량이 온라인 전체 예약 판매량의 절반에 이를 것으로 예측했다.

여행 예약에도 모바일이 대세다. 모든 연령대에 걸쳐 스마트폰은 여행 옵션 검색에 가장 많이 사용되는 기기로 43%의 응답자가 검색에 모바일 앱이나 웹을 가장 많이 사용한다고 답변했다. 데스크톱과 노트북이 각각 36%와 20%를 차지해 뒤를 이었다.


그 중에도 앱의 선호도가 특히 높게 나타났다. 모바일 사용자의 77%가 여행 옵션 검색에 앱을 활용한다고 답했다. 세대별로 비교했을 때, 밀레니엄 세대에서 특히 앱 선호도가 높은 것으로 나타났다. 밀레니엄 세대들의 38%가 다른 플랫폼보다 앱을 통해 여행 옵션 검색할 정도로 모바일 앱을 가장 많이 사용한다.


반면, X세대 및 베이비붐 세대는 여행 제품이나 서비스의 온라인 검색을 위해 데스크톱을 사용한다고 답변했다. 데스크톱과 노트북 대신 모바일을 통한 검색을 선호한다고 답한 응답자 중 32%가 편리성을 이유로 손꼽았으며, 74%가 이동성을 주요 이유로 선택했다.


검색은 모바일, 예약은 데스크톱


여행에 대한 검색 역시 주로 모바일로 이루어진다. 하지만 실제 여행을 예약하는 데는 데스크톱이 가장 많이 사용한다. 데스크톱은 예약에 사용되는 기본 기기로, 데스크톱에서 발생하는 온라인 여행 판매는 전체의 38%, 모바일은 31%, 노트북은 26%를 차지했다.

데스크톱을 통한 예약을 선호하는 이유로 ‘큰 화면으로 구매하는 것이 편리함'(45%)과 ‘작은 화면에서는 많은 개인 정보를 입력하기 어려움'(36%)을 꼽았다. 반면, 모바일을 통한 예약을 선호하는 이유로는 ‘어디에서나 예약할 수 있음'(62%)과 ‘데스크톱과 노트북보다 편리함'(35%)이라는 답변이 많았다.


이 외 크리테오는 연구 결과를 통해 구매에 영향을 미치는 요인에 대한 핵심 사항을 다음과 같이 정리했다.


  • 온라인 예약을 하는 주요 요인은 편리성이다. 84%의 응답자가 온라인을 통한 예약의 선호 이유로 시간 절약(51%), 제품 비교의 용이성(44%), 전화 및 실제 예약 대비 편리함(38%) 등을 선택했다.
  • 다음으로 중요한 온라인 예약 이유는 가격이다. 응답자의 35%가 온라인을 통한 여행 상품 구매가 가격 측면에서 더 나은 거래를 제공한다고 믿는다.
  • 온라인 여행 구매의 절반은 숙박 및 항공 구매인 것으로 나타났다.
  • 온라인 구매 시 한국인은 온라인 여행 가격 비교(58%)를 통해 예약을 진행하며, 가격 측면에서 나은 선택권을 제공하기 때문(60%)이라고 응답했다.


한국 구매자의 89%가 리타깃팅 광고를 본 적 있으며, 62%가 광고를 클릭해 본 적 있다고 답변했다.

크리테오 이정은 부장은 “한국의 경우 온라인 구매가 활성화되고, 간편한 결제 서비스가 확산되고 있다”라며 “여행 시장에서의 온라인 구매가 점점 보편화되면서 여행업계 및 OTA는 맞춤 마케팅에 더 많은 투자를 해야 하며, 이를 위해서는 다양한 디바이스를 사용하는 경우에도 일관되며 개인 연관성이 높은 쇼핑 경험을 제공해야 할 것”이라고 말했다.



...


반응형

+ Recent posts