(자연어처리/챗봇) 파이토치를 이용해 챗봇 만들기
다른 분들이 짜둔 챗봇 코드를 몇 종류 공부해봤는데, 이걸 하나씩 응용해보고 있어요.
첫번째로, 파이토치를 이용해 간단한 (영어) 챗봇을 구현한 분의 코드를 공부해보았습니다.
* 유튜브 강의: Chat Bot With PyTorch - NLP And Deep Learning
https://www.youtube.com/watch?v=RpWeNzfSUHw
* 깃허브 소스
https://github.com/python-engineer/pytorch-chatbot
train.py를 실행해서 훈련시킨 다음, chat.py를 실행해서 채팅을 하면 됩니다.
***
Let's chat! (type 'quit' to exit)
You: hello
Sam: Hey :-)
You: what do you sell?
Sam: We sell coffee and tea
You: coffee please
Sam: I do not understand...
You: will you take credit cards?
Sam: We accept VISA, Mastercard and Paypal
You: delivery?
Sam: I do not understand...
You: how long does delivery take?
Sam: Shipping takes 2-4 days
You: give me a joke!
Sam: Why did the hipster burn his mouth? He drank the coffee before it was cool.
You:
***
intents.json 파일에 대화가 심어져 있는데 몇 종류 되지 않습니다.
이것을 한글 채팅용으로 개조해보았습니다.
1) 일단 채팅 데이터를 많이 확보해서 intents.json 파일에 심어놓습니다. 데이터가 많아지니 json 포맷이 입력하기 불편하네요.
2) 두 번째는, NLTK는 영문용 전처리기이므로, 한국어 형태소 분석을 위해 Komoran을 사용했습니다. Mecab과 Khaiii를 사용해봤는데 성능은 비슷합니다. 특히 Khaiii는 단문의 경우 분석 능력이 약간 떨어질 수 있습니다. 그래서 konlpy에서 기본으로 제공하는, 하지만 성능은 준수한 Komoran을 사용했습니다.
다음에서 다운로드 받을 수 있습니다.
https://drive.google.com/file/d/1GuvISh2CL27NIoZL6qi71u3tbLidalDl/view?usp=sharing
hanchat_pytorch_simple.zip
drive.google.com
사용 방법은 동일합니다. 폴더 안에 data.pth가 있으면 제가 만들어둔 것인데, 훈련 없이 바로 채팅이 가능할 겁니다. 정석으로는, train.py로 훈련시키고, chat.py를 실행해 채팅을 합니다.
***
채팅 시작. 마치려면 'quit'이나 '끝'을 입력하세요
나: 안녕
로봇: 방가
나: 잘 지냈어?
로봇: 보고 싶었습니다.
나: 헉
로봇: 요즘 공기가 조금 좋아졌어요.
나: 그래
로봇: 마스크 답답하시죠?
나: 응
로봇: 날이 조금 풀렸어요
나: 아직이야
로봇: 요즘 공기가 조금 좋아졌어요.
나: 그렇긴 하지
로봇: 날이 조금 풀렸어요
나: 다른 이야기 없어?
로봇: 서울인구 모두가 동시에 외치면 무슨 말이 될까?................. 천만의 말씀
나: 천만 무 너진 지 오래야
로봇: 정말 비가 오면 좋죠
나: 그렇긴 해
로봇: 요즘 공기가 조금 좋아졌어요.
나: 비가 오려나
로봇: 그러게요
나: 라거 하나만 줘
로봇: 냉장고에서 직접 가져다 드세요.
나: 참이슬은 있나?
로봇: 처음처름, 참이슬, 진로가 있습니다.
나: 참이슬 하나
로봇: 네, 갖다 드릴게요.
나: 안주는?
로봇: 골뱅이무침, 해물누룽지탕, 해물떡볶이, 오뎅탕, 황도복숭아 있습니다.
나: 오뎅탕
로봇: 금방 갖다 드릴게요.
나:
***
위의 경우는 대화가 잘 풀린 경우이고, 잘 풀리지 않은 경우도 있습니다.
***
채팅 시작. 마치려면 'quit'이나 '끝'을 입력하세요
나: 안녕
로봇: 반갑습니다.
나: 잘 지냈어?
로봇: 방가 방가
나: 비가 왔으면 좋겠어
로봇: 좀 있다 비가 쏟아진대요.
나: 진짜?
로봇: 최근에 인상깊게 읽은 책 있습니까?
나: 무슨 생뚱맞은?
로봇: 최근에 재미있게 본 영화 있습니까?
나: 오늘 너무 덥다
로봇: 선풍기 틀어 드릴까요?
나: 에어컨 없어?
로봇: 요즘 관심 가는 거 있습니까?
나: 자꾸 엉뚱한 소리 할래?
로봇: 제가 잘못 알아들었어요
나: 귀가 어둡구나
로봇: 요즘 뭐하면서 지내셨어요?
나: 코딩
로봇: 오늘 날씨 좋네요.
나: 안 좋아. 너무 더워
로봇: 핫팩 여기 있어요.
나: 미쳤니... 핫팩은 겨울이지.
로봇: 우산 드릴까요?
나: 비가 안 오는데?
로봇: 핫팩 드릴까요?
나: 미쳤군...
로봇: 님을 위해 맛있는 똥과 차디찬 오줌을 준비했습니다. 드셔보세요.
나: 너 돌았구나
로봇: 우산도 없는데.
나: 비 안 온다니까.
로봇: 요.
나: 요?
로봇: 오늘 날씨 좋네요.
나: 너무 더워
로봇: 부채 부쳐 드릴까요?
나: 응.
로봇: 요즘 관심 가는 거 있습니까?
나: 인공지능?
로봇: 요즘 뭐하면서 지내셨어요?
나: 코딩
로봇: 날이 조금 풀렸어요
나: 아직 안 풀렸어
로봇: 고맙습니다.
나: 뭐가?
로봇: 정말 미안해요
나: 뭐가?
로봇: 제가 나쁜 놈이죠.
나: 그래 넌 나쁜 놈이야
로봇: 잘 지내셨어요?
나: 아니.
로봇: 오늘 날씨 좋네요.
나: 안 좋아.
로봇: 제가 옳은 말을 잘하죠.
나: 틀린 말을 많이 하는군.
로봇: 제가 옳은 말을 잘하죠.
***
다람쥐 쳇바퀴 돌 듯하는 대화다.
intents.json 파일을 들여다보면 알겠지만,
술을 몇 가지 종류로 나누고, '메뉴', '주문', '안주'까지 항목을 나눠서 대답한다.
마찬가지로, 날씨 중 비 항목도, 비 오기 전, 비 오는 중, 비 그치고...로 세분해서 구체적으로 대답한다.
구체적으로 대답하는 부분에서 성능이 조금 모자란다.
'나'와 '로봇'의 상태와 사실 관계를 기록하는 변수들이 필요해 보인다. 상대가 자극할 경우, 로봇이 욕을 버럭 할 경우가 있는데,
로봇의 화난 상태를 몇 단계로 나누어 점진적으로 대응할 필요가 있다.
마찬가지로, '나'가 현재 마실 것을 찾는 단계인지, 술을 마시고자 했는지, 술을 고르는 단계인지, 술을 주문한 후인지, 안주를 고르는 단계인지, 안주를 주문한 후인지...하는 구체적인 단계에 따라 로봇의 대응이 달라져야 하는데, 이런 부분을 시시콜콜하게 코딩해두면 딥러닝이 아니라 옛날 스타일 코딩이 되어 버린다.
가령, '나'의 기분 상태... '슬픔', '기쁨', '우울', '몽롱', 그리고 그 단계 (1, 2, 3단계)...
'나'의 직업, 이름, 나이, 성별, 이성친구 유무, 사는곳 등에 대한 정보를 대화를 통해 수집해서 그것에 대해 이야기를 나누게 하는 게 좋은데, 이것은 현재 제법 성능 좋은 챗봇들도 시도하지 못하는 것들이다.
아무튼 기분에 따라 맥주나 소주, 막걸리를 고를 수 있고 안주도 주문할 수 있으니, 그리고 시덥잖은 챗봇의 농담도 들을 수 있으니, 원작보다는 한결 나아진 셈이다.