flask+ TF-IDF で、AIチャットボットをweb画面で作成する。自然言語処理(6)
index:
概要
以前の、slackチャット対応のAI チャットボット機能の
関連となります。web画面 UIを自作して、
自然言語処理とwebサービスを使用する例となります。
UI面は、BotUI のJSライブラリを使用しています。
web画面
デモの、操作画面となります。
処理など
Vue.js の変数(二重括弧)は、
flaskの レンダリング処理で、正常に動作しない為。
V ディレクティブ等を使用しています。
<html> <head> <link href="{{ url_for('static', filename='botui/build/botui.min.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='botui/build/botui-theme-default.css') }}" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/vue/latest/vue.min.js"></script> <script src="https://unpkg.com/botui/build/botui.min.js"></script> <script src="{{ url_for('static', filename='axios.min.js') }}?A2"></script> </head> <body> <h1>Bot UI test:</h1> <div class="botui-app-container" id="botui-app" style="height :400px;"> <bot-ui></bot-ui> </div> <!-- form --> <center> <div id="app"> <!-- msg :<span v-text="message"></span> --> 入力: <input size="30" name="intext" v-model="message" /> <button @click="addItem">質問する</button> </div> </center> <br /> </body> <script> //console.log("#then-aaa"); var botui = new BotUI('botui-app') // id of container // new Vue({ el: '#app', data: { message: '', }, created:function(){ console.log("#create-1122"); }, methods: { update() { this.message = 'Vue.js'; }, addItem() { console.log(this.message ); // botui.message.add({ human: true, content: this.message }); // var params = new URLSearchParams(); params.append('intext', this.message ); axios.post('./test3', params) .then(response =>{ console.log(response.data ); // botui.message.add({ content: response.data }); }); this.message=''; }, } }); </script> <script src="{{ url_for('static', filename='app_chat.js') }}?B1"></script> <!-- --> </html>
参考のページ
keras YOLO3 で、物体検知
index:
概要
以前の、keras 画像認識に関連した内容で、 YOLO3 物体検知
する例となります。
環境
python : 3.5.2
keras
YOLO3
準備
紹介記事が、複数ありましたので。
概要のみです
https://github.com/qqwweee/keras-yolo3
yolo3 の、コピー
・学習済ファイルのコピー、yolov3.weights
wget https://pjreddie.com/media/files/yolov3.weights
・keras読み込み、変換処理
model_data/yolo.h5 が、作成されます。
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
手順
python yolo_video.py --image
評価する、jpg等画像ファイル名の入力
・結果を、ファイルに保存する場合、
yolo_video.py
の、detect_img を、下記修正を追加すると可能でした。
https://github.com/kuc-arc-f/keras-yolo3-test/blob/master/yolo_video.py
# def detect_img(yolo): while True: img = input('Input image filename:') try: image = Image.open(img) except: print('Open Error! Try again!') continue else: r_image = yolo.detect_image(image) #r_image.show() import cv2 cv2.imwrite("out.jpg", np.asarray(r_image)[..., ::-1]) r_image.show() yolo.close_session()
その他
上記の、関連等に記載がありますが。
tiny版もあるので、容量小さめの weights ファイル
をコピーして、評価できましたが。
認識精度は、落ちそうでした。
参考の設定
keras LSTM で、文章自動生成を行う。 自然言語処理(5)
index:
処理など
参考ページと、ほぼ同じですが。
形態素解析は、 janome を使用しています。
・前処理、
before.py 、改行とかの削除
・学習
・評価
モデルを、ロードして。評価
学習データの、一部の文章を指定
その後は、文章の自動生成が可能でした。
#pred for diversity in [0.2]: # diversity は 0.2のみ使用 print('----- diversity:', diversity) generated = '' text= get_token("どんなつまらない仕事でも楽しんでやるのだ") sentence = text[start_index: start_index + maxlen] generated += "".join(sentence) print(sentence ) print('----- Generating with seed: "' + "".join(sentence)+ '"') sys.stdout.write(generated) for i in range(400): x_pred = np.zeros((1, maxlen, len(chars))) for t, char in enumerate(sentence): x_pred[0, t, char_indices[char]] = 1. preds = model.predict(x_pred, verbose=0)[0] next_index = sample(preds, diversity) next_char = indices_char[next_index] generated += next_char sentence = sentence[1:] # sentence はリストなので append で結合する sentence.append(next_char) sys.stdout.write(next_char) sys.stdout.flush() print()
評価の結果
どんなつまらない仕事でも得てももしそう事件ということを君はよくわかっている。 部屋の窓をそのときには言葉を、この注意をてで、――それに君を言うとおり、 証人たちは荒々しい声については意見が一致しているのに、あの鋭い、 あるいは一人の証人の言うところによれば耳ざわりな、声に関してはひどい意見のものであるたにちがいない。 窓はそこから出るときにしめて行ったのだろう。 その後、猩々は人自身の証人が『鋭いというよりも耳ざわりなものであった。 耳ざわりな声で――鋭いというよりも耳ざわりなものであった。鋭い声とは言えぬ。 荒々しい声のほうの数語は聞きとれた。それはフランス人の言葉だった。 女の声ではないことは確かだ。言った言葉は聞きとれなかった。鋭い声の言葉はわからなかった。 早くて死体た見つかっで、 被害者二人がまだこのときの通り人まだ少しのただ音のレスパネエ夫人を僕と家にうししを すっかりデュパンがこのあとをほうてのだが)、猩々のたぶんの想像に得られた我々と 部屋の扉を押しあけたときとのあいだの時間については、 証人の言うと鋭い声のものではないがこのパリでは動物はその他考えている ――が『彼はこのこの事件についてはまだなにを錠はかかっていなかった。 その建物には四階のほかにはどこにも家具がないようであった。 このフランス人は一人の数人の殺人をフランス語て部屋そしてにあいだにデュパン君と書いてぬというしまっと君を、 それから想像デュパンのつづけた「私」 デュパンがこのあとのほうは言葉を、 非常に低い調子で、非常に静かに言っ
・とりあえず、読めなくない程度の文章を
自動生成して、くれました。
・学習 epochs =60で、
google colab で、25分程、
作業PCですと、数時間かかりそうでしたが。
django + nginx + uwsgi の設定 #django
index:
設定方法
django プロジェクト作成、
アプリの追加等は、省略します。
前回の例と、ほぼ同じです。
nginx conf、追加
# upstream django { server 127.0.0.1:8001; } # server { listen 80; location / { uwsgi_pass django; include /home/pi/work/django/django1/uwsgi_params; } }
https://github.com/kuc-arc-f/django_nginx/blob/master/nginx_conf/django.conf
・uwsgi_paramsは、
プロジェクトのパスとなります。(後述します)
・ /etc/nginx/sites-available に、
conf 追加します。
・ /etc/nginx/conf.d/
に、上記のリンク追加します。
=>既に、confがある場合、削除しておきます。
・nginx 再起動
sudo service nginx stop
sudo service nginx start
uwsgi の設定
・uwsgi_params
プロジェクト内に、配置
uwsgi_param QUERY_STRING $query_string; uwsgi_param REQUEST_METHOD $request_method; uwsgi_param CONTENT_TYPE $content_type; uwsgi_param CONTENT_LENGTH $content_length; uwsgi_param REQUEST_URI $request_uri; uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; uwsgi_param REMOTE_PORT $remote_port; uwsgi_param SERVER_PORT $server_port; uwsgi_param SERVER_NAME $server_name;
https://github.com/kuc-arc-f/django_nginx/blob/master/django1/uwsgi_params
・uwsgi の起動
uwsgi --socket :8001 --module django1.wsgi
表示の確認、
http://ip/test1/
表示されます。
参考のページ
Slackチャットから、flask+ TF-IDF の応答を出力する。自然言語処理(4)
index:
概要
前回の、自然言語処理の関連となります。
slackチャットからの、入力文章を webhook経由で
AI/機械学習サーバからの応答を出力する例となります。
webhookは、aws EC2 ubuntu16です。
slack app設定は、トリガー単語を検出する。
カンタンな手法で、AI側を起動しています。
・構成の概要は、
Slack入力(質問)
=> Skack appトリガー検出
=> webhook (aws EC2)呼ぶ
=> nginx+ uWSGI 経由で flask 接続
=> 入力文章から、TF-IDFで、学習済みの入力文章
の類似文章を探す
=> 出力された、入力文章のindex番号から
応答文章を、引き当てる
=> Slackへ、結果送信
みたいな、流れですね
参考
https://www.sejuku.net/blog/74469
slack appの、追加方法など
・slack appで、
「Outgoing WebHooks」を追加
(発信Webフック )
・webhook の登録
=>EC2 のエンドポイントを指定。
・トリガー誤の登録( 例は、Bot: にしています。)
処理など
__init__.py
class VectBase: # def __init__(self): from flaskr.include.nlp_predict import NlpPredict self.pred=NlpPredict() #ans=self.pred.answers #print("ans-len=", len(ans)) tokens=self.pred.get_data() #print(tokens ) ret= self.pred.train(tokens ) self.vectorize= self.pred.get_vectorize() print("#end-load-vectorize") # def predict(self, text ): text=self.pred.predict(text ) #print(text ) return text # app = Flask(__name__) app.config['JSON_AS_ASCII'] = False vect=VectBase()
起動時に、学習処理して。
API応答速度は、高速にできるような形にしています。
( 文章の、件数が多い場合は。遅くなるかもしれませんが )
・webhook
views.py
@app.route('/test2', methods=['GET', 'POST']) def test2(): print("test2") # print(len(request.form )) ret="sorry, nothing response." if(len(request.form ) > 0): text=request.form['text'] print(text ) ret=vect.predict(text ) #print(ret ) dic = {"text" : ret } return jsonify(dic)
slackから、入力文を受信。
ML評価処理、結果の出力
flask + nginx + uwsgi, の設定
index:
概要
前回の、flask関連となりますが。
nginx + uwsgi と連携し、flask 活用する例となります。
環境
python 3.5
flask
nginx
uwsgi
インストールなど
nginx:
sudo apt-get install nginx
確認、
sudo service nginx status
停止、起動など
sudo service nginx stop
sudo service nginx start
sudo service nginx restart
設定など
上記の、参考ページ
を参考していますので。ほぼ同様ですが
Nginxの設定
/etc/nginx/conf.d/ 、にconf追加
myapp.conf
# server { listen 80; location / { include uwsgi_params; uwsgi_pass unix:///tmp/uwsgi.sock; } }
=> スペースが含まれる場合、エラーになりましたので。
タブを使用しています。
https://github.com/kuc-arc-f/flask_myapp/blob/master/nginx_conf/myapp.conf
sockファイルの場所など、適宣きめてます。
/etc/nginx/sites-enabled/ に、リンク設定有る場合は、けします。(rm )
チェック、
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
successful が、でれば。OKです。
起動しときます。
sudo service nginx start
uwsgi
インストール:
pip3 install uwsgi
flask の起動ファイルを、作成
app.py
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run(host='localhost', debug=True)
uwsgi コマンドで、起動します。
=> ブラウザで、設置IP を開くと、 Hello world でます。
uwsgi --socket /tmp/uwsgi.sock --module app --callable app --chmod-socket=666
=> uwsgi コマンドが、実行できない場合。
pip3 インストールに、パス設定が不足している場合は。追加します。
export PATH=$PATH:~/.local/bin/
・設定ファイルからの起動
uwsgi --ini myapp.ini
=>iniファイルからの、起動ができるようです。
TF-IDF+ janome で、類似文章の抽出。 自然言語処理(3)
index:
処理
・前処理、学習
# encoding: utf-8 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import numpy as np from janome.tokenizer import Tokenizer # def get_token(text): t = Tokenizer() tokens = t.tokenize(text) word = "" for token in tokens: part_of_speech = token.part_of_speech.split(",")[0] if part_of_speech == "名詞": word +=token.surface + " " if part_of_speech == "動詞": word +=token.base_form+ " " if part_of_speech == "形容詞": word +=token.base_form+ " " if part_of_speech == "形容動詞": word +=token.base_form+ " " return word words1="利用人数は何人ですか?" words2="契約期間は、ありますか?" words3="オープンソースですか?" words4="オンライン決済は、可能ですか?" words5="製品価格、値段はいくらですか?" #words= get_token(words1 ) #print(words ) #quit() words =[] words.append(words1 ) words.append(words2 ) words.append(words3 ) words.append(words4 ) words.append(words5 ) #print(words ) tokens=[] for item in words: token=get_token(item) tokens.append(token) # #print(tokens ) docs = np.array(tokens) vectorizer = TfidfVectorizer(use_idf=True, token_pattern=u'(?u)\\b\\w+\\b') print(tokens) #quit() vecs = vectorizer.fit_transform(docs )
・評価
fit_transformで、学習した結果を。
適当な、文章で cos類似度の計算
類似度の高い、文章を抽出
入力配列から、index 番号を出力
類似度の高い、文章の出力
str="利用人数は?" #str="契約期間" #str="価格は?" instr = get_token(str ).strip() print("instr=", instr ) x= vectorizer.transform( [ instr ]) #print( "x=",x) num_sim=cosine_similarity(x , vecs) print(num_sim ) index = np.argmax( num_sim ) print("word=", words[index]) print()
テスト
['利用 人数 何 人 ', '契約 期間 ある ', 'オープン ソース ', 'オンライン 決済 可能 ? ', '製品 価格 値段 いくら '] instr= 利用 人数 [[ 0.70710678 0. 0. 0. 0. ]] word= 利用人数は何人ですか?
=> 正しく、抽出できました。
追加している。
文章の数が少ないですが、ある程度。判定処理は
正しいようです。
データセットに、応答分を追加しておくと
会話の応答出力も、出力できそうですね。