딥러닝 챗봇 정리

2022. 2. 19. 16:10

Chap 3. 토크나이징

 

토큰: 가장 기본이 되는 단어 -> 토큰 단위로 정보를 나눔

KoNLPy : 한국어 자연어처리 라이브러리 (형태소를 토큰 단위)

Kkma: 한국어 형태소 분석기 (분석 품질 좋음)

from konlpy.tag import Kkma
kkma=Kkma()
text="와, 진짜 학교 가기 싫다."

morphs=kkma.morphs(text)
print(morphs)

#형태소, 품사태그
pos=kkma.pos(text)
print(pos)

#명사 추출
nouns=kkma.nouns(text)
print(nouns)

 

Komoran: 자바로 개발한 한국어 형태소 분석기 (사용자 사전 관리 용이)

 

Chap4. 임베딩

자연어를 숫자나 벡터 형태로 변환 (단어 임베딩만 해봄)

 

원-핫 인코딩: 단어를 숫자 벡터로 변환

from konlpy.tag import Komoran
import numpy as np

komoran=Komoran()
text = "이 컴퓨터는 포맷이 필요해."

#명사 추출
nouns=komoran.nouns(text)
print(nouns)

#단어 사전 구축
#단어별 인덱스 부여
dics={}
for word in nouns:
    if word not in dics.keys():
        dics[word]=len(dics)

print(dics)

nb_classes=len(dics)
targets=list(dics.values())
one_hot_targets=np.eye(nb_classes)[targets]
print(one_hot_targets)

이 문장의 noun은 컴퓨터/ 포맷/ 필요 3가지다.

각각 인덱스를 부여해서 dics에 저장한다. 각 단어 당 한 번씩만 저장한다.

원-핫 벡터는 numpy의 eye()를 이용하여 만든다. eye()는 단위행렬을 만들어준다. 

 

sparse representaiton이다. 단어 간 유사성이 표현되지 않음

->distributed representation ( dense representation)

 

Word2Vec (계산량 줄어들었음)

1. CBOW : context word를 이용하여 타깃 단어를 예측

2. skip-gram: 하나의 타깃 단어를 이용해 주변 단어를 예측

 

:  Gensim 패키지 사용

 

from gensim.models import Word2Vec
from konlpy.tag import Komoran
import time

#네이버 리뷰 데이터 읽어오기
def read_review_data(filename):
    with open(filename,'r',encoding='UTF8') as f:
        data=[line.split('\t') for line in f.read().splitlines()]
        data=data[1:] #헤더는 빼고 저장
    return data

start=time.time()

print('1) 말뭉치 데이터 읽기 시작')
review_data=read_review_data('./ratings.txt')
print(len(review_data))
print('1) 말뭉치 데이터 읽기 완료 : ',time.time()-start)

#문장 단위로 명사만 추출
print('2) 형태소에서 명사만 추출')
komoran=Komoran()
docs=[komoran.nouns(sentence[1]) for sentence in review_data]
print('2) 형태소에서 명사만 추출 완료 : ',time.time()-start)


#Word2Vec 모델 학습
print('3) Word2Vec 모델 학습')
model = Word2Vec(sentences=docs, vector_size=200, window=4, min_count=2, sg=1)
print('3) Word2Vec 모델 학습 완료 : ',time.time()-start)

# 모델 저장
print('4) 학습된 모델 저장 시작')
model.save('nvmc.model')
print('4) 학습된 모델 저장 완료: ', time.time() - start)

# 학습된 말뭉치 개수, 코퍼스 내 전체 단어 개수
print("corpus_count : ", model.corpus_count)
print("corpus_total_words : ", model.corpus_total_words)

 Word2Vec()의 parameter 중에 size를 vector_size로 바꿈 

잘 동작함

from gensim.models import Word2Vec

# 모델 로딩
model = Word2Vec.load('nvmc.model')
print("corpus_total_words : ", model.corpus_total_words)

# 단어 유사도 계산
print("일요일 = 월요일\t", model.wv.similarity(w1='일요일', w2='월요일'))
print("안성기 = 배우\t", model.wv.similarity(w1='안성기', w2='배우'))
print("대기업 = 삼성\t", model.wv.similarity(w1='대기업', w2='삼성'))
print("일요일 != 삼성\t", model.wv.similarity(w1='일요일', w2='삼성'))
print("히어로 != 삼성\t", model.wv.similarity(w1='히어로', w2='삼성'))

# 가장 유사한 단어 추출
print(model.wv.most_similar("안성기", topn=3))
print(model.wv.most_similar("시리즈", topn=3))

실제로 유사한 단어를 잘 찾아내는지 확인해보기

음... 일요일이랑 삼성의 유사도가 무시할 수 없는데😥

아무튼 실제로도 유사한 단어들이 그렇지 않은 단어들에 비해 유사도가 높게 나왔다.

유사한 단어 추출도 괜찮은 결과이다.

 

Chap 5.  텍스트 유사도

 

문장은 단어들의 묶음이기 때문에 하나의 벡터로 묶에서 문장간의 유사도를 계산할 수 있다.

QnA 챗봇을 개발하는 것이 목적이기 때문에 통계적인 방법을 이용해보자.

 

n-gram 유사도 : 문장에서 n개의 단어를 토큰으로 사용

 

2-gram 유사도 계산하기

from konlpy.tag import Komoran

# 어절 단위 n-gram
def word_ngram(bow, num_gram):
    text = tuple(bow)
    ngrams = [text[x:x + num_gram] for x in range(0, len(text))]
    return tuple(ngrams)

# 음절 n-gram 분석
def phoneme_ngram(bow, num_gram):
    sentence = ' '.join(bow)
    text = tuple(sentence)
    slen = len(text)
    ngrams = [text[x:x + num_gram] for x in range(0, slen)]
    return ngrams

# 유사도 계산
def similarity(doc1, doc2):
    cnt = 0
    for token in doc1:
        if token in doc2:
            cnt = cnt + 1

    return cnt/len(doc1)

sentence1 = '6월에 뉴턴은 선생님의 제안으로 트리니티에 입학하였다'
sentence2 = '6월에 뉴턴은 선생님의 제안으로 대학교에 입학하였다'
sentence3 = '나는 맛있는 밥을 뉴턴 선생님과 함께 먹었습니다.'

komoran = Komoran()
bow1 = komoran.nouns(sentence1)
bow2 = komoran.nouns(sentence2)
bow3 = komoran.nouns(sentence3)

doc1 = word_ngram(bow1, 2)
doc2 = word_ngram(bow2, 2)
doc3 = word_ngram(bow3, 2)

print(doc1)
print(doc2)
print(doc3)

r1 = similarity(doc1, doc2)
r2 = similarity(doc3, doc1)
print(r1)
print(r2)

doc3,doc1은 유사하지 않은 문장이므로 유사도가 0이 나오는 것은 당연하다.

 

코사인 유사도: 두 벡터 간 코사인 각도를 이용해 유사도 측정

 

 

Chap 6:  챗봇 엔진에 필요한 딥러닝 모델

케라스: 신경망 모델을 구축할 수 있는 고수준 API 라이브러리

 

인공 신경망: 뉴런을 수학적으로 모방 (예전에 배워서 알고있음)

 

y=(w0x0+w1x1+w2x2)+b

 

입력값과 가중치를 곱해서 더한 다음 bias 로 결과값 조정

 

step function: 그래프 모양이 계단식

-> 결과가 너무 극단적(0or1)

->sigmoid function ->exp함수는 연산 비용이 크다

 

ReLU(연산비용 크지 않아 학습 속도 빠름)

 

back propagation: 오차가 줄어드는 방향으로 가중치를 역방향으로 갱신

 

 

BELATED ARTICLES

more