반응형





신의 책상 위에는 이런 글이 쓰여 있다.
‘네가 만일 불행하다는 말을 하고 다닌다면 불행이 정말 어떤 것인지 보여주겠다.’
‘네가 만일 행복하다는 말을 하고 다닌다면 행복이 정말 어떤 것인지 보여주겠다.’
- 버니 S. 시겔

텍사스 대학교 제임스 페너베커 교수는 개인 블로그 3만 5천개와
학생들 에세이 1만 5천개를 분석해서 부정적인 단어들을 많이 사용하는 이들은
질병이나 외로움, 신경증이나 우울증에 시달릴 가능성이
더 높다는 사실을 발견했습니다.
반면 긍정적인 단어를 다채롭게 구사하는 이들은 직장 생활 뿐 아니라,
여가 활동에서도 더 성실하고 적극적이고 몸도 더 건강했다고 합니다.


반응형
반응형

Word2Vec 모델 만들기  sdc-james.gitbook.io/onebook/5./6.1./6.1.3.-word2vec

 

6.1.3. Word2Vec 모델 만들기

 

sdc-james.gitbook.io

 

다음 예제는 네이버 영화 리뷰를 정리해둔 Naver sentiment movie corpus v1.0(https://github.com/e9t/nsmc) 사용하여 Word Embedding Model (Word2Vec)을 빌드하는 것입니다.

일단 다음 명령으로 genism 라이브러리를 설치합니다. NLTK는 자연어 처리를 위해 광범위하게 쓰이는 Python library입니다.

(onebook) > pip install lxml
(onebook) > pip install utils
(onebook) > pip install paramiko
(onebook) > pip install nltk
(onebook) > pip install genism

다음은 https://github.com/e9t/nsmc 에서 Corpus를 다운로드 합니다.

Naver sentiment movie corpus는 3개의 파일로 되어 있습니다.

  • ratings.txt: All 200K reviews

  • ratings_test.txt: 50K reviews held out for testing

  • ratings_train.txt: 150K reviews for training

각 파일에 있는 Column 은 <영화 아이디, 영화 평, 영화 평점> 입니다.

위의 세개의 파일을 raw형태로 다운로드 합니다.

 

Onebook 가상환경 하단에 NLP라는 폴더를 만들고 다운받은 파일을 이동합니다. "NaverMovieWord2Vec.py" 파이썬 파일을 새로 만들고 프로그래밍을 시작하겠습니다.

일단 저장된 파일을 csv를 사용해서 읽겠습니다. CSV란 Comma-separated values의 약자로서 CSV 파일은 각 라인의 컬럼들이 콤마로 분리된 텍스트 파일 포맷입니다. CSV 파일을 읽기 위해서는 먼저 파이썬에 기본 내장된 csv 모듈을 import 합니다. 다음 .csv 파일을 오픈하고 파일객체를 csv.reader(파일객체) 에 넣으면 됩니다. csv.reader() 함수는 Iterator 타입인 reader 객체를 리턴하므로 for 루프를 돌며 한 라인씩 가져올 수 있습니다. CSV 파일과 비슷하지만, 콤마 대신 Tab으로 컬럼을 분리하는 파일포맷을 TSV 파일이라 합니다. TSV 파일은 컬럼 delimiter만 차이가 나므로, csv 모듈의 reader() 혹은 writer() 함수에서 delimiter='\t' 옵션만 지정해 주면 나머지는 CSV와 동일합니다. Naver sentiment movie corpus는 탭으로 구분되어 있으므로 TSV를 읽는 방식으로 읽습니다.

import csv

 f = open('ratings_train.txt', 'r', encoding='utf-8')
 rdr = csv.reader(f, delimiter='\t')
 r = list(rdr)
 print("Id=%s : Name=%s" % (r[0][0], r[0][1]))
 print("Id=%s : Name=%s" % (r[1][0], r[1][1]))
 print("Id=%s : Name=%s" % (r[2][0], r[2][1]))

 f.close()
 
# 결과 
Id=id : Name=document
Id=9976970 : Name=아 더빙.. 진짜 짜증나네요 목소리
Id=3819312 : Name=흠...포스터보고 초딩영화줄....오버연기조차 가볍지 않구나

이제 본격적으로 형태소 분석 코드를 넣어 보겠습니다. 여기서 'konlpy'의 여러 품사 태깅 클래스 중 'Twitter'를 사용했습니다. Konlpy의 Twitter은 Okt로 변경되었습니다.

실제 형태소를 분석한 결과는 다음과 같습니다.

[('재미', 'Noun'), ('잇다', 'Verb'), ('매우', 'Noun'), ('~~', 'Punctuation')]
[('진짜', 'Noun'), ('자다', 'Verb'), ('만들다', 'Verb'), ('수작', 'Noun')]
[('제발', 'Noun'), ('2', 'Number'), ('좀', 'Noun'), ('찍다', 'Verb'), ('.', 'Punctuation'), ('현기증', 'Noun'), ('나다', 'Verb'), ('말', 'Noun'), ('이에요', 'Josa')]
[('너무나도', 'Adverb'), ('따뜻하다', 'Adjective'), (',', 'Punctuation'), ('마음', 'Noun'), ('이', 'Josa'), ('따뜻하다', 'Adjective'), ('...', 'Punctuation'), ('한번', 'Noun'), ('쯤', 'Suffix'), ('자신', 'Noun'), ('을', 'Josa'), ('되돌아보다', 'Verb'), ('만들다', 'Verb'), ('영화', 'Noun')]

여기에서 “Josa”, “Eomi”, “'Punctuation”는 제외하고 처리해야 합니다. 전체 소스는 다음과 같습니다.

 import csv
 from konlpy.tag import Okt
 from gensim.models import word2vec

 #네이버 영화 코퍼스를 읽는다.
 f = open('ratings_train.txt', 'r', encoding='utf-8')
 rdr = csv.reader(f, delimiter='\t')
 rdw = list(rdr)
 f.close()

 #트위터 형태소 분석기를 로드한다. Twiter가 KoNLPy v0.4.5 부터 Okt로 변경 되었다.
 twitter = Okt()

 #텍스트를 한줄씩 처리합니다.
 result = []
 for line in rdw:
     #형태소 분석하기, 단어 기본형 사용
     malist = twitter.pos( line[1], norm=True, stem=True)
     r = []
     for word in malist:
         #Josa”, “Eomi”, “'Punctuation” 는 제외하고 처리
         if not word[1] in ["Josa","Eomi","Punctuation"]:
             r.append(word[0])
     #형태소 사이에 공백 " "  을 넣습니다. 그리고 양쪽 공백을 지웁니다.
     rl = (" ".join(r)).strip()
     result.append(rl)
     #print(rl)

 #형태소들을 별도의 파일로 저장 합니다.
 with open("NaverMovie.nlp",'w', encoding='utf-8') as fp:
     fp.write("\n".join(result))

 #Word2Vec 모델 만들기
 wData = word2vec.LineSentence("NaverMovie.nlp")
 wModel =word2vec.Word2Vec(wData, size=200, window=10, hs=1, min_count=2, sg=1)
 wModel.save("NaverMovie.model")
 print("Word2Vec Modeling finished")

위의 코드를 실행하면 종료 할 때까지 많은 시간이 걸립니다. 결과는 NaverMovie.model 파일입니다. 어미, 조사, 구두점을 제외하고 동사와 형용사는 기본형으로 학습하도록 입력 텍스트를 만들었습니다. 공백으로 구분된 텍스트 파일을 Word2Vec에 전달하고 생성된 모델을 save()로 저장했습니다.

 

이제 위에서 생성한 모델을 사용하여 단어 유사도를 확인해 보겠습니다.

 

다시 NaverMovieModelTest.py 라는 파일을 만들어 다음의 코드를 입력 해 봅니다.

from gensim.models import word2vec

model = word2vec.Word2Vec.load("NaverMovie.model")

print(model.most_similar(positive=["재미"]))

print(model.most_similar(positive=["최고"]))

위 코드의 수행 결과는 다음과 같습니다.

 

“재미”라는 단어와 유사한 단어들을 벡터로 나타낸 것입니다.

 

[('없슴', 0.6063779592514038), ('나용', 0.6040781736373901), ('지렁이', 0.5945030450820923), ('칙스', 0.5877454280853271), ('오랬', 0.5862023830413818), ('원도', 0.5712456703186035), ('잼', 0.5703416466712952), ('무것', 0.5685503482818604), ('푸시', 0.5684186816215515), ('유익', 0.5595628023147583)]

 

“최고”라는 단어와 유사한 단어들의 벡터는 다음과 같습니다.

 

[('꼽을', 0.6920815110206604), ('꼽는', 0.6835036873817444), ('최고다', 0.6749817132949829), ('단연', 0.6692216396331787), ('손꼽다', 0.6552967429161072), ('으뜸', 0.6476656198501587), ('하이스쿨', 0.6261676549911499), ('정치드라마', 0.6205614805221558), ('꼽겠다', 0.6203451156616211), ('였슴', 0.6191103458404541)]

 

 

 

models.word2vec – Word2vec 임베딩

radimrehurek.com/gensim/models/word2vec.html

 

Gensim: topic modelling for humans

Efficient topic modelling in Python

radimrehurek.com

 

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

 

실습으로 배우는 데이터 사이언스 - Gensim을 통해 벡터화 & t-SNE로 시각화

Gensim을 통해 벡터화 & t-SNE로 시각화 Word2Vec 모델을 학습 전처리를 거쳐 파싱된 문장의 목록으로 모델을 학습시킬 준비가 되었다. Gensim Word2Vec 모델의 파라메터 아키텍처 : 아키텍처 옵션은 skip-gra

programmers.co.kr

 

반응형
반응형

불화의 주범, 목소리.
귀엽고 예쁘다는 이야기를
목소리 톤을 높여 소리 지르듯 했을 때,
아기는 입을 삐죽거리며 칭얼대기 시작할 것이고
강아지는 슬금슬금 당신을 피해 달아날 것이다.
아기나 강아지는 말하는 내용이 무엇인지 전혀
알아듣지 못한다. 그러나 그 말을 전하는
목소리에서 말하는 사람의 감정을
느끼고 두려움을 갖는 것이다.


- 아놀드 베넷의《변화의 즐거움》중에서 -


* 말을 할 때는
단어의 선택도 중요하지만
말투와 목소리도 정말 중요한 것 같아요.
무심코 던진 돌에 개구리는 맞아 죽는다는 속담처럼
나의 불화에서 튕겨 나온 목소리가 누군가에게 돌이
되지 않도록 말을 하기 전 잠시 생각하는,
한숨 쉬는 습관을 가져야겠습니다.
 

반응형
반응형

남편은 
내게도 선생님이 되었다. 
출근할 적마다 숙제를 내주기 시작한 것이다. 
이를테면 사자성어 같은 것, 또는 어려운 단어 
같은 것. 그럼 난 살림하는 사이사이 열심히 외우고 
쓰고 익혔다. 공부 때문에 혼이 났다거나 야단이 났다거나 
한 적은 없다. 지금 내가 국한문 혼용이 자유자재인 건 
다 남편 덕이다. 뿐만 아니다. 자식들에게 늘 책을 
한 아름씩 안겨주면서 동시에 내게도 소설책을 
많이 갖다 주었다. 

- 서동필의《남의 눈에 꽃이 되어라》중에서 -


* '남편이 선생님이었다'는 아내의 고백,
많은 것이 눈에 보이듯 그려집니다. 남편 앞에서 
우등생처럼 좋은 학생이 되어주었던 그 아내는 아마도
그 자식들에게 더없이 훌륭한 선생님이 되었을 것입니다. 
자식들에게 한 아름씩 책을 안겨주면서 '남의 눈에 
꽃이 되라'는 말을 전해주는 '선생님'의 모습이 
큰 바위 얼굴로 다가옵니다.

반응형

'생활의 발견 > 아침편지' 카테고리의 다른 글

아버지가 되어 보니  (0) 2019.05.29
우리 아이의 잘못된 습관  (0) 2019.05.28
오월에서 유월 사이  (0) 2019.05.25
6,000년 된 기마의 기원  (0) 2019.05.24
거짓 반성과 후회  (0) 2019.05.23
반응형

동료 사무실에 가보니

“일이 잘못될 거 같으면 그렇게 될 수밖에 없다”고 쓰여 있었다.

나는 이 흔한 경구를 패배의 시인으로 해석했다.

나는 ‘그렇게 될 수밖에 없다’를 지우고

‘바로 잡아라’라고 크게 적었다. 새로운 간판은 이렇다.

‘일이 잘못될 거 같으면 바로 잡아라.’

- 피터 다이아맨디스, 싱귤레러티 대학 설립자


단어를 바꾸면 태도가 바뀝니다.

우리의 믿음은 우리가 사용하는 언어에 의해 형성되고

내가 사용하는 언어는 나의 믿음에 의해 형성됩니다.

“할 수 있다고 생각하든, 그렇지 않다고 생각하든 간에,

당신 생각이 옳다.”

헨리 포드의 명언입니다. 



...

반응형
반응형

핀란드 사람들은 

'자연에서 나를 치유하고 재충전하는 것'이 

중요한 휴식 방법이라고 믿고 있다. 이들에게 

'휴식'과 연관되는 단어를 떠올려보라고 한다면, 

아마 '코티지'일 것이다. 핀란드 사람들의 휴식 공간으로서 

절대 빠질 수 없는 것이 이 코티지다. 코티지란 일종의 

숲 속 산장이라 할 수 있는데, 꼭 부자들만 갖고 있는 

화려하고 특별한 별장이 아니다. 오히려 숲 속 

오두막집이라는 표현이 더 잘 어울린다.

가족 혹은 친척이 공동으로 

소유하는 경우가 많다.



- 나유리, 미셸 램블린의《핀란드 슬로우 라이프》중에서 -



...

반응형

'생활의 발견 > 아침편지' 카테고리의 다른 글

내 아이를 이렇게 키우고 싶었다  (0) 2017.10.12
박자와 강약, 쉼표와 리듬  (0) 2017.10.11
한글의 신비  (0) 2017.10.10
자연 그리고 조화  (0) 2017.10.10
  (0) 2017.10.10
반응형

오지다


https://namu.wiki/w/오지다


오지다를 잘 들어 보면 비속어처럼 들리기도 한데, 정작 뜻은 들리는 것과는 반대다. 

전라도 사투리로 사용됐을 때는 마음이 흡족하다이고, 급식체로 사용되는 오지다는 대단하다, 

굉장하다, 엄청나다 등의 감탄사로도 통하는데, 간간히 상대방을 비꼬는 용도로 사용되기도 한다. 

이 때문에 비속어라고 착각하는 경우가 많다.


 

...



반응형
반응형


단어 임베딩(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)]

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


반응형

+ Recent posts