기계 번역에 많이 사용된다는 모델입니다.
encoder와 decoder 두 개의 rnn을 사용합니다.

장점
학습된 모델로 문장을 만들기 때문에 인공지능에 걸맞는 방법입니다.
단점
문법적으로도, 문맥적으로도 올바르지 않은 값들을 출력하여 성능을 기대하기 힘듭니다.
대화형 챗봇 설계의 과제 를 참고하여 방향을 다시 생각해 보았습니다.
저희의 최종적인 목표는 자연어 처리에 지나치게 의존하지 않으며, 좁은 주제(명확한 주제)를 가지고 api를 제공하는 챗봇입니다.
챗봇은 대략 다음과 같은 로직에 의해서 진행됩니다.
명사 추출 -> 의도 파악 -> 재질문(필요한 정보가 부족하면) -> api 호출
명사 추출을 위해서 konply라는 형태소 분석기를 사용할 계획입니다. 하지만 문제가 하나 있습니다. ‘아이오아이 너무 좋아’ 라는 문장을 konlpy를 이용하여 형태소 분석을 해봅시다.
다음과 같은 결과가 나옵니다.
[('아이오', 'NNP'), ('아이', 'NNP'), ('너무', 'MAG'), ('좋', 'VA'), ('아', 'EC')]
‘아이오아이’가 하나의 명사로 분석되지 않습니다. 이를 방지하기 위해 사용자의 사전파일을 만들어 추가합니다.
#ex.py
from konlpy.tag import Komoran
komoran = Komoran()
komoran = Komoran(userdic='./user_dic.txt')
sentence = "아이오아이 너무 좋아"
print(komoran.pos(sentence))
#user_dic.txt
아이오아이 NNP
이후 결과는 이렇습니다.
[('아이오아이', 'NNP'), ('너무', 'MAG'), ('좋', 'VA'), ('아', 'EC')]
이제 명사 추출은 무섭지 않습니다.
컴퓨터가 어떤 단어를 인지하기 위해서는 수치적으로 표현할 수 있어야합니다. 결국 본질은 숫자 라는 겁니다. [‘고양이’, ‘개’, ‘아이스크림’]를 one-hot encoding 방식으로 표현해보겠습니다.
[1,0,0]
[0,1,0]
[0,0,1]
그런데 문제가 있습니다. ‘고양이’ 와 ‘개’는 유사한 단어고, ‘아이스크림’은 상대적으로 거리가 멀지만 이를 표현하기 힘듭니다.
그래서 제시된 방법이 word2vec입니다.
의미 자체를 다차원 공간에서 벡터화 하여 나타냅니다.

단어를 벡터화 시키는 다른 방법으로 페이스북이 개발한 FastText가 있습니다. word2vec과 FastText의 차이는 word2vec은 단어를 쪼개지 않지만 FastText는 하나의 단어에도 여러 단어가 존재하는 것으로 간주합니다. 노이즈가 많은 데이터에서도 좋은 성능을 보입니다.
우리의 목표는 wiki.ko.vec을 이용하여 문장을 벡터로 만드는 것입니다.
from gensim.models import KeyedVectors
model = KeyedVectors.load_word2vec_format('wiki.ko.vec')
print(model["불고기"])
출력된 결과는 이렇습니다.
[-0.23874 -0.022833 -0.73434 0.27491 -0.28145 -0.1756
0.055664 -0.16552 0.2394 -0.36278 0.01085 0.2478
-------------------------------생략----------------------------
-0.30549 0.26683 -0.66633 0.13036 -0.039943 -0.09051
0.14524 0.1615 0.40904 0.10204 0.42441 -0.35892 ]
char cnn은 오류가 발생하여 사용할 수 없었습니다. 텐서플로우 버전 문제라고 하는데 1.7.1에서 1.6.0, 1.4.0 cpu 버전까지 시도했지만 오류가 발생했습니다.
Traceback (most recent call last):
File "train.py", line 48, in <module>
FLAGS._parse_flags()
File "/home/shin/.local/lib/python3.6/site-packages/tensorflow/python/platform/flags.py", line 84, in __getattr__
wrapped(_sys.argv)
File "/home/shin/.local/lib/python3.6/site-packages/absl/flags/_flagvalues.py", line 632, in __call__
name, value, suggestions=suggestions)
absl.flags._exceptions.UnrecognizedFlagError: Unknown command line flag 'pre_trained'
fastText의 분류기능을 이용하여 문장의 의도를 알아내 봅시다.
File: pizza.train
__label__order 불고기 피자 주문할 수 있을까요?
__label__order 피자 한판 주문이요.
__label__order 치즈 피자 가능할까요?
__label__order 치즈 피자 한판 주문합니다.
__label__order 치즈 피자 두판 부탁합니다.
__label__order 불고기 피자 한판이요.
__label__price 불고기 피자 얼마인가요?
__label__price 치즈 피자 얼망인가요?
__label__price 불고기 피자 가격이 어떻게 되나요?
__label__price 치즈 피자 가격이?
모델 만들기
./fasttext supervised -input pizza.train -output model_pizza
피자 주문과 가격 조회를 다음과 같이 선언했습니다.
__label__order
__lbael__price
File: test.txt
불고기 피자 한판 주문이요.
예측값 출력
./fasttext predict model_pizza.bin test.txt
__label__order
의도(주문)을 잘 출력합니다. 아직은 데이터셋이 부족하지만 여러 의도에 맞는 데이터셋을 제작하고 수집하면 더 좋은 결과가 나올 듯합니다.