A guide to creating a chatbot with Rasa stack and Python.
2편에서는 앞서 만든 봇을 슬랙에 배포하는 실습을 진행해본다. 진행에 앞서 1편을 미리 읽어보고 넘어오길 권해드린다.
Rasa Stack 과 파이썬을 활용한 슬랙 챗봇 만들기 (1) A guide to creating a chatbot with Rasa stack and Python
Rasa Installations
1편과는 달리 여기서는 최신 버전의 Rasa Core 를 설치할 것이다. 아나콘다 등을 활용하여 가상환경을 만든 뒤 실습을 진행하길 권해드린다.
우분투 18.04 아나콘다 설치하기 How To Install the Anaconda Python Distribution on Ubuntu 18.04
아나콘다 가상환경을 생성한 후 활성화시킨다.
(base) founder@hilbert:~$ conda create --name rasabot python=3.6
Collecting package metadata: done
Solving environment: done
==> WARNING: A newer version of conda exists. <==
current version: 4.6.3
latest version: 4.6.4
Please update conda by running
$ conda update -n base -c defaults conda
## Package Plan ##
environment location: /home/founder/anaconda3/envs/rasabot
added / updated specs:
- python=3.6
The following packages will be downloaded:
package | build
---------------------------|-----------------
libedit-3.1.20181209 | hc058e9b_0 188 KB
pip-19.0.1 | py36_0 1.8 MB
python-3.6.8 | h0371630_0 34.4 MB
setuptools-40.8.0 | py36_0 647 KB
------------------------------------------------------------
Total: 37.1 MB
The following NEW packages will be INSTALLED:
ca-certificates pkgs/main/linux-64::ca-certificates-2019.1.23-0
certifi pkgs/main/linux-64::certifi-2018.11.29-py36_0
libedit pkgs/main/linux-64::libedit-3.1.20181209-hc058e9b_0
libffi pkgs/main/linux-64::libffi-3.2.1-hd88cf55_4
libgcc-ng pkgs/main/linux-64::libgcc-ng-8.2.0-hdf63c60_1
libstdcxx-ng pkgs/main/linux-64::libstdcxx-ng-8.2.0-hdf63c60_1
ncurses pkgs/main/linux-64::ncurses-6.1-he6710b0_1
openssl pkgs/main/linux-64::openssl-1.1.1a-h7b6447c_0
pip pkgs/main/linux-64::pip-19.0.1-py36_0
python pkgs/main/linux-64::python-3.6.8-h0371630_0
readline pkgs/main/linux-64::readline-7.0-h7b6447c_5
setuptools pkgs/main/linux-64::setuptools-40.8.0-py36_0
sqlite pkgs/main/linux-64::sqlite-3.26.0-h7b6447c_0
tk pkgs/main/linux-64::tk-8.6.8-hbc83047_0
wheel pkgs/main/linux-64::wheel-0.32.3-py36_0
xz pkgs/main/linux-64::xz-5.2.4-h14c3975_4
zlib pkgs/main/linux-64::zlib-1.2.11-h7b6447c_3
Proceed ([y]/n)? y
Downloading and Extracting Packages
libedit-3.1.20181209 | 188 KB | ##################################### | 100%
python-3.6.8 | 34.4 MB | ##################################### | 100%
setuptools-40.8.0 | 647 KB | ##################################### | 100%
pip-19.0.1 | 1.8 MB | ##################################### | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
# $ conda activate rasabot
#
# To deactivate an active environment, use
#
# $ conda deactivate
(base) founder@hilbert:~$
(base) founder@hilbert:~$ source activate rasabot
(rasabot) founder@hilbert:~$
(rasabot) founder@hilbert:~$ mkdir rasabot
(rasabot) founder@hilbert:~$ cd rasabot
(rasabot) founder@hilbert:~/rasabot$
(rasabot) founder@hilbert:~/rasabot$ python -m pip install rasa_nlu[spacy]
(rasabot) founder@hilbert:~/rasabot$ pip show rasa_nlu
Name: rasa-nlu
Version: 0.14.3
Summary: Rasa NLU a natural language parser for bots
Home-page: https://rasa.com
Author: Rasa Technologies GmbH
Author-email: hi@rasa.com
License: Apache 2.0
Location: /home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages
Requires: six, gevent, numpy, matplotlib, coloredlogs, requests, klein, future, typing, ruamel.yaml, cloudpickle, simplejson, jsonschema, tqdm, scikit-learn, boto3, packaging
Required-by:
Rasa Core (https://rasa.com/docs/core/installation/)
(rasabot) founder@hilbert:~/rasabot$ python -m pip install -U rasa_core
(rasabot) founder@hilbert:~/rasabot$ pip show rasa_core
Name: rasa-core
Version: 0.13.2
Summary: Machine learning based dialogue engine for conversational software.
Home-page: https://rasa.com
Author: Rasa Technologies GmbH
Author-email: hi@rasa.com
License: Apache 2.0
Location: /home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages
Requires: pydot, slackclient, tensorflow, flask-cors, questionary, python-socketio, keras-preprocessing, rocketchat-API, scipy, jsonpickle, tqdm, python-dateutil, rasa-core-sdk, pykwalify, ruamel.yaml, colorhash, fakeredis, apscheduler, pymongo, flask, typing, redis, numpy, scikit-learn, requests, packaging, webexteamssdk, coloredlogs, networkx, mattermostwrapper, twilio, fbmessenger, pytz, rasa-nlu, jsonschema, pika, terminaltables, keras-applications, gevent, python-telegram-bot, flask-jwt-simple, colorclass
Required-by:
(rasabot) founder@hilbert:~/rasabot$ python -m spacy download en_core_web_md
Collecting en_core_web_md==2.0.0 from https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.0.0/en_core_web_md-2.0.0.tar.gz#egg=en_core_web_md==2.0.0
Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.0.0/en_core_web_md-2.0.0.tar.gz (120.8MB)
100% |████████████████████████████████| 120.9MB 129.7MB/s
Installing collected packages: en-core-web-md
Running setup.py install for en-core-web-md ... done
Successfully installed en-core-web-md-2.0.0
Linking successful
/home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages/en_core_web_md
-->
/home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages/spacy/data/en_core_web_md
You can now load the model via spacy.load('en_core_web_md')
(rasabot) founder@hilbert:~/rasabot$ python -m spacy link en_core_web_md en --force;
Linking successful
/home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages/en_core_web_md
-->
/home/founder/anaconda3/envs/rasabot/lib/python3.6/site-packages/spacy/data/en
You can now load the model via spacy.load('en')
Ngrok 은 멀티플랫폼 터널링, 리버스 프록시 소프트웨어로 인터넷에서 로컬 구동 네트워크 서비스로의 안전한 터널링을 생성해준다. 간단히 말해서 인터넷에서 로컬 앱에 접근할 수 있도록 해준다는 것이다.
1) ngrok 사이트에서 로그인 후 적절한 파일을 다운로드받는다.
2) $ unzip /path/to/ngrok.zip 을 통해 파일압축을 해제한다.
3) $ ./ngrok <authtoken> 형식으로 계정에 접속한다.
4) ngrok 압축을 푼 디렉토리로 이동하여 $ ngrok <authtoken> 이라고 콘솔에 입력한다. 토큰 정보는 여기서 확인할 수 있다.
(rasabot) founder@hilbert:~/src$ ./ngrok authtoken 4xWEiEVWgkoJnSfyLEDgd_2bMEHLSdzQsa2dFU4LzDh
Authtoken saved to configuration file: /home/founder/.ngrok2/ngrok.yml
5) 다음과 같이 포트 번호를 지정해 서비스를 시작한다.
(rasabot) founder@hilbert:~/src$ ./ngrok http 5004
Session Status online
Account 홍 길 동 (Plan: Free)
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://dhidjid78.ngrok.io -> localhost:5004
Forwarding https://dhidjid78.ngrok.io -> localhost:5004
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
(rasabot) founder@hilbert:~/rasabot$ python nlu_model.py
Fitting 2 folds for each of 6 candidates, totalling 12 fits
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done 12 out of 12 | elapsed: 0.2s finished
{'intent': {'name': 'mood_unhappy', 'confidence': 0.5305762770479238}, 'entities': [{'start': 40, 'end': 43, 'value': 'shibes', 'entity': 'group', 'confidence': 0.9894194765511979, 'extractor': 'ner_crf', 'processors': ['ner_synonyms']}], 'intent_ranking': [{'name': 'mood_unhappy', 'confidence': 0.5305762770479238}, {'name': 'goodbye', 'confidence': 0.1254236380112934}, {'name': 'mood_great', 'confidence': 0.10182979881087542}, {'name': 'inform', 'confidence': 0.09953166268980061}, {'name': 'greet', 'confidence': 0.07776521429451069}, {'name': 'mood_affirm', 'confidence': 0.04546210008854246}, {'name': 'mood_deny', 'confidence': 0.01941130905705334}], 'text': 'I am sad, plased send me a picture of a dog'}
(rasabot) founder@hilbert:~/rasabot$
(rasabot) founder@hilbert:~/rasabot$ python -m rasa_core_sdk.endpoint --actions actions
2019-02-19 09:00:02 INFO __main__ - Starting action endpoint server...
2019-02-19 09:00:02 INFO rasa_core_sdk.executor - Registered function for 'action_retrieve_image'.
2019-02-19 09:00:02 INFO __main__ - Action endpoint is up and running. on ('0.0.0.0', 5055)\
(rasabot) founder@hilbert:~/rasabot$ python dialogue_management_model.py
Processed Story Blocks: 100%|███| 12/12 [00:00<00:00, 3103.25it/s, # trackers=1]
Processed Story Blocks: 100%|███| 12/12 [00:00<00:00, 511.91it/s, # trackers=11]
Processed Story Blocks: 100%|███| 12/12 [00:00<00:00, 293.16it/s, # trackers=17]
Processed Story Blocks: 100%|███| 12/12 [00:00<00:00, 276.09it/s, # trackers=14]
Processed actions: 470it [00:00, 12279.86it/s, # examples=382]
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
masking (Masking) (None, 5, 24) 0
_________________________________________________________________
lstm (LSTM) (None, 32) 7296
_________________________________________________________________
dense (Dense) (None, 15) 495
_________________________________________________________________
activation (Activation) (None, 15) 0
=================================================================
Total params: 7,791
Trainable params: 7,791
Non-trainable params: 0
_________________________________________________________________
Epoch 1/100
470/470 [==============================] - 1s 2ms/step - loss: 2.5890 - acc: 0.3043
Epoch 2/100
470/470 [==============================] - 0s 299us/step - loss: 2.3293 - acc: 0.4957
Epoch 3/100
470/470 [==============================] - 0s 302us/step - loss: 2.0503 - acc: 0.4979
Epoch 4/100
470/470 [==============================] - 0s 342us/step - loss: 1.8383 - acc: 0.4979
Epoch 5/100
470/470 [==============================] - 0s 315us/step - loss: 1.7796 - acc: 0.4979
Epoch 6/100
470/470 [==============================] - 0s 311us/step - loss: 1.7170 - acc: 0.4979
Epoch 7/100
470/470 [==============================] - 0s 351us/step - loss: 1.6711 - acc: 0.4979
Epoch 8/100
470/470 [==============================] - 0s 339us/step - loss: 1.6139 - acc: 0.4979
Epoch 9/100
470/470 [==============================] - 0s 351us/step - loss: 1.5845 - acc: 0.4979
Epoch 10/100
470/470 [==============================] - 0s 335us/step - loss: 1.5456 - acc: 0.4979
Epoch 11/100
470/470 [==============================] - 0s 333us/step - loss: 1.4948 - acc: 0.4979
Epoch 12/100
470/470 [==============================] - 0s 281us/step - loss: 1.4581 - acc: 0.4979
Epoch 13/100
470/470 [==============================] - 0s 325us/step - loss: 1.4139 - acc: 0.4979
Epoch 14/100
470/470 [==============================] - 0s 323us/step - loss: 1.3700 - acc: 0.5000
Epoch 15/100
470/470 [==============================] - 0s 376us/step - loss: 1.3357 - acc: 0.5043
Epoch 16/100
470/470 [==============================] - 0s 376us/step - loss: 1.3015 - acc: 0.5191
Epoch 17/100
470/470 [==============================] - 0s 207us/step - loss: 1.2591 - acc: 0.5404
Epoch 18/100
470/470 [==============================] - 0s 224us/step - loss: 1.2281 - acc: 0.5362
Epoch 19/100
470/470 [==============================] - 0s 209us/step - loss: 1.1905 - acc: 0.5617
Epoch 20/100
470/470 [==============================] - 0s 194us/step - loss: 1.1591 - acc: 0.5702
Epoch 21/100
470/470 [==============================] - 0s 186us/step - loss: 1.1229 - acc: 0.5830
Epoch 22/100
470/470 [==============================] - 0s 186us/step - loss: 1.0910 - acc: 0.5872
Epoch 23/100
470/470 [==============================] - 0s 218us/step - loss: 1.0473 - acc: 0.6191
Epoch 24/100
470/470 [==============================] - 0s 200us/step - loss: 1.0314 - acc: 0.6170
Epoch 25/100
470/470 [==============================] - 0s 203us/step - loss: 0.9916 - acc: 0.6426
Epoch 26/100
470/470 [==============================] - 0s 193us/step - loss: 0.9683 - acc: 0.6468
Epoch 27/100
470/470 [==============================] - 0s 196us/step - loss: 0.9296 - acc: 0.6745
Epoch 28/100
470/470 [==============================] - 0s 212us/step - loss: 0.9023 - acc: 0.6872
Epoch 29/100
470/470 [==============================] - 0s 212us/step - loss: 0.8729 - acc: 0.7149
Epoch 30/100
470/470 [==============================] - 0s 196us/step - loss: 0.8722 - acc: 0.6936
Epoch 31/100
470/470 [==============================] - 0s 191us/step - loss: 0.8239 - acc: 0.7340
Epoch 32/100
470/470 [==============================] - 0s 192us/step - loss: 0.8179 - acc: 0.7277
Epoch 33/100
470/470 [==============================] - 0s 195us/step - loss: 0.7904 - acc: 0.7532
Epoch 34/100
470/470 [==============================] - 0s 195us/step - loss: 0.7744 - acc: 0.7809
Epoch 35/100
470/470 [==============================] - 0s 190us/step - loss: 0.7499 - acc: 0.7532
Epoch 36/100
470/470 [==============================] - 0s 206us/step - loss: 0.7061 - acc: 0.7872
Epoch 37/100
470/470 [==============================] - 0s 215us/step - loss: 0.6891 - acc: 0.8085
Epoch 38/100
470/470 [==============================] - 0s 198us/step - loss: 0.7002 - acc: 0.7702
Epoch 39/100
470/470 [==============================] - 0s 208us/step - loss: 0.6630 - acc: 0.8000
Epoch 40/100
470/470 [==============================] - 0s 203us/step - loss: 0.6497 - acc: 0.8064
Epoch 41/100
470/470 [==============================] - 0s 197us/step - loss: 0.6276 - acc: 0.8021
Epoch 42/100
470/470 [==============================] - 0s 195us/step - loss: 0.6059 - acc: 0.8213
Epoch 43/100
470/470 [==============================] - 0s 207us/step - loss: 0.6136 - acc: 0.8106
Epoch 44/100
470/470 [==============================] - 0s 242us/step - loss: 0.5664 - acc: 0.8426
Epoch 45/100
470/470 [==============================] - 0s 196us/step - loss: 0.5551 - acc: 0.8489
Epoch 46/100
470/470 [==============================] - 0s 199us/step - loss: 0.5774 - acc: 0.8255
Epoch 47/100
470/470 [==============================] - 0s 206us/step - loss: 0.5429 - acc: 0.8319
Epoch 48/100
470/470 [==============================] - 0s 216us/step - loss: 0.5256 - acc: 0.8404
Epoch 49/100
470/470 [==============================] - 0s 235us/step - loss: 0.5075 - acc: 0.8574
Epoch 50/100
470/470 [==============================] - 0s 199us/step - loss: 0.5122 - acc: 0.8319
Epoch 51/100
470/470 [==============================] - 0s 196us/step - loss: 0.4940 - acc: 0.8404
Epoch 52/100
470/470 [==============================] - 0s 185us/step - loss: 0.4914 - acc: 0.8426
Epoch 53/100
470/470 [==============================] - 0s 189us/step - loss: 0.4816 - acc: 0.8383
Epoch 54/100
470/470 [==============================] - 0s 187us/step - loss: 0.4551 - acc: 0.8596
Epoch 55/100
470/470 [==============================] - 0s 186us/step - loss: 0.4444 - acc: 0.8617
Epoch 56/100
470/470 [==============================] - 0s 186us/step - loss: 0.4442 - acc: 0.8596
Epoch 57/100
470/470 [==============================] - 0s 192us/step - loss: 0.4378 - acc: 0.8660
Epoch 58/100
470/470 [==============================] - 0s 212us/step - loss: 0.4251 - acc: 0.8660
Epoch 59/100
470/470 [==============================] - 0s 201us/step - loss: 0.4228 - acc: 0.8638
Epoch 60/100
470/470 [==============================] - 0s 221us/step - loss: 0.4125 - acc: 0.8532
Epoch 61/100
470/470 [==============================] - 0s 191us/step - loss: 0.3825 - acc: 0.8596
Epoch 62/100
470/470 [==============================] - 0s 198us/step - loss: 0.3827 - acc: 0.8723
Epoch 63/100
470/470 [==============================] - 0s 203us/step - loss: 0.3824 - acc: 0.8681
Epoch 64/100
470/470 [==============================] - 0s 193us/step - loss: 0.3945 - acc: 0.8553
Epoch 65/100
470/470 [==============================] - 0s 188us/step - loss: 0.3741 - acc: 0.8532
Epoch 66/100
470/470 [==============================] - 0s 182us/step - loss: 0.3532 - acc: 0.8809
Epoch 67/100
470/470 [==============================] - 0s 200us/step - loss: 0.3518 - acc: 0.8787
Epoch 68/100
470/470 [==============================] - 0s 192us/step - loss: 0.3685 - acc: 0.8574
Epoch 69/100
470/470 [==============================] - 0s 201us/step - loss: 0.3623 - acc: 0.8596
Epoch 70/100
470/470 [==============================] - 0s 190us/step - loss: 0.3579 - acc: 0.8532
Epoch 71/100
470/470 [==============================] - 0s 218us/step - loss: 0.3455 - acc: 0.8638
Epoch 72/100
470/470 [==============================] - 0s 202us/step - loss: 0.3267 - acc: 0.8660
Epoch 73/100
470/470 [==============================] - 0s 191us/step - loss: 0.3212 - acc: 0.8872
Epoch 74/100
470/470 [==============================] - 0s 189us/step - loss: 0.3335 - acc: 0.8574
Epoch 75/100
470/470 [==============================] - 0s 196us/step - loss: 0.3117 - acc: 0.8766
Epoch 76/100
470/470 [==============================] - 0s 195us/step - loss: 0.3275 - acc: 0.8702
Epoch 77/100
470/470 [==============================] - 0s 197us/step - loss: 0.3208 - acc: 0.8745
Epoch 78/100
470/470 [==============================] - 0s 190us/step - loss: 0.3161 - acc: 0.8468
Epoch 79/100
470/470 [==============================] - 0s 193us/step - loss: 0.2953 - acc: 0.8787
Epoch 80/100
470/470 [==============================] - 0s 205us/step - loss: 0.3096 - acc: 0.8723
Epoch 81/100
470/470 [==============================] - 0s 188us/step - loss: 0.3079 - acc: 0.8532
Epoch 82/100
470/470 [==============================] - 0s 212us/step - loss: 0.3114 - acc: 0.8638
Epoch 83/100
470/470 [==============================] - 0s 216us/step - loss: 0.2918 - acc: 0.8723
Epoch 84/100
470/470 [==============================] - 0s 197us/step - loss: 0.2886 - acc: 0.8766
Epoch 85/100
470/470 [==============================] - 0s 186us/step - loss: 0.2954 - acc: 0.8745
Epoch 86/100
470/470 [==============================] - 0s 199us/step - loss: 0.2719 - acc: 0.8851
Epoch 87/100
470/470 [==============================] - 0s 197us/step - loss: 0.2785 - acc: 0.8787
Epoch 88/100
470/470 [==============================] - 0s 194us/step - loss: 0.2823 - acc: 0.8638
Epoch 89/100
470/470 [==============================] - 0s 194us/step - loss: 0.2840 - acc: 0.8723
Epoch 90/100
470/470 [==============================] - 0s 219us/step - loss: 0.2669 - acc: 0.8766
Epoch 91/100
470/470 [==============================] - 0s 191us/step - loss: 0.2617 - acc: 0.8894
Epoch 92/100
470/470 [==============================] - 0s 216us/step - loss: 0.2646 - acc: 0.8830
Epoch 93/100
470/470 [==============================] - 0s 191us/step - loss: 0.2688 - acc: 0.8830
Epoch 94/100
470/470 [==============================] - 0s 211us/step - loss: 0.2820 - acc: 0.8723
Epoch 95/100
470/470 [==============================] - 0s 204us/step - loss: 0.2520 - acc: 0.8915
Epoch 96/100
470/470 [==============================] - 0s 194us/step - loss: 0.2597 - acc: 0.8617
Epoch 97/100
470/470 [==============================] - 0s 199us/step - loss: 0.2509 - acc: 0.8830
Epoch 98/100
470/470 [==============================] - 0s 197us/step - loss: 0.2517 - acc: 0.8809
Epoch 99/100
470/470 [==============================] - 0s 193us/step - loss: 0.2446 - acc: 0.8809
Epoch 100/100
470/470 [==============================] - 0s 188us/step - loss: 0.2529 - acc: 0.8915
run_app.py 파일을 실행시켜 에이전트를 구동한다. 단, 실행 전에 해당 스크립트에 슬랙 토큰 정보가 정확히 들어가 있는지 확인한다.
OAuth & Permissons 의 2개의 토큰 정보 중 하단에 있는 Bot User OAuth Access Token 정보를 하단 스크립트 input_channel 정보에 입력한다.
input_channel = SlackInput('#your bot user authentication token')
run_app.py
from rasa_core.channels.slack import SlackInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
import yaml
from rasa_core.utils import EndpointConfig
nlu_interpreter = RasaNLUInterpreter('./models/nlu/default/current')
action_endpoint = EndpointConfig(url="http://localhost:5055/webhook")
agent = Agent.load('./models/dialogue', interpreter = nlu_interpreter, action_endpoint = action_endpoint)
input_channel = SlackInput('xoxb-514185865477-514638817877-ZlAUhYSuoydYHkl0oCrUU7MC' #your bot user authentication token
)
agent.handle_channels([input_channel], 5004, serve_forever=True)
https://<your_ngrok_url>/webhooks/slack/webhook
마지막으로, 다음 2개의 Workplace events 를 받기로 한다.
- app_mention : 누군가가 자기 이름을 호출했을 경우 봇이 반응하도록 한다
- message_im : 봇에게 DM (direct messages)을 보낼 수 있게 한다.
그리고 다음과 같이 run_app.py 파일을 실행한다.
(rasabot) founder@hilbert:~/rasabot$ python run_app.py
Let’s Talk
1) custom actions 서버가 구동중인지 확인한다
2) ngrok 가 5004번 포트에서 구동중인지 확인한다
3) Slack 인터페이스에서 봇과 대화한다
엄청나게 힘든 작업처럼 들릴지 몰라도 한 단계씩 따라하다보면 어느 순간 Zoe 라는 멋진 챗봇을 완성할 수 있을 것이다.
아래와 같이 3개의 터미널이 돌아가고 있다.
[원문] https://towardsdatascience.com/building-a-conversational-chatbot-for-slack-using-rasa-and-python-part-2-ce7233f2e9e7
'프로그래밍 Programming' 카테고리의 다른 글
서프라이즈 라이브러리를 활용한 추천시스템 구축 및 검증 Building and Testing Recommender Systems With Surprise, Step-By-Step (0) | 2019.03.02 |
---|---|
주피터랩 살펴보기 Jupyter Lab: Evolution of the Jupyter Notebook (0) | 2019.02.25 |
Rasa Stack 과 파이썬을 활용한 슬랙 챗봇 만들기 (1) A guide to creating a chatbot with Rasa stack and Python (0) | 2019.02.22 |
핀터레스트 위젯 빌더 Pintereest Widget builder (0) | 2019.02.16 |
웹사이트, 블로그에 핀터레스트 핀 넣기 (0) | 2019.02.16 |