初心者がナイーブベイズ分類器を作成する為の備忘録
やりたい事
ナイーブベイズ分類器を用いてツイートの内容が修造BOTとイチローBOTのどちらに分類されるかを識別する。
自分用の備忘録として纏めていますので、若干分かりづらい所があると思いますので悪しからず。
間違いがあれば指摘頂けると嬉しいです。
教師データ作成
Bag of Wordsを作成する
Bag of Wordsとは文書から抽出した単語の集合。
訓練用データを読み込んで、mecabで分かち書きし、
[ツイート][単語]の2次元配列を作成する。
こんな感じなる
[ [自分,絶対,駄目,人,全て], [自分,ない,人,目,バット] ]
訓練用データのBag of Wordsから教師データ(モデル)を作成する
教師データ作成では以下の情報を取得する。
P(Ci)=事前確率
教師データ作成の為に利用した全データのうちクラスCiの発生する確率。
各クラスの生起確率とも言う。
今回の識別器で扱うクラスは
それぞれ150件、合計300件を利用しているので事前確率は等しい事となる。
P(C1) = 150 / 300 = 1/2
P(C2) = 150 / 300 = 1/2
識別対象データのクラス識別する
識別対象データの特徴ベクトルを取得
今回の例だと識別対象のツイートから頻出単語上位5件を取得する。
取得した特徴ベクトルを特徴ベクトルxと呼ぶ事とする。
例)
[自分,明日,人,耳,バット]
観測データをベイズの定理に当てはめてそれぞれのクラスの事後確率を求める
P(Ci|x)=p(x|Ci)/p(x) * P(Ci)
以下の様に変形できる
P(x|Ci) * P(Ci)
p(x)とは特徴ベクトルxの生起確率、全てのクラスで共通なので無視できる。
例えば、特徴ベクトルxのC1クラスとC2クラスそれぞれの事後確率を比較する場合、
p(x|C1)/p(x) * P(C1)
と
p(x|C2)/p(x) * P(C2)
を比較する事となるが、p(x)はどちらでも共通の値(全文書で特徴ベクトルxの生起確率)なので無視できる。
なので
P(x|Ci) * P(Ci)
の式に当てはめて事後確率を求める。
P(Ci)=事前確率
訓練時に取得済み。
p(x|Ci)=尤度
特徴ベクトルが連続的なデータ(単語の出現回数)なので、多項分布モデルで分類する。
※単語が出たか出なかったか(0 or 1)のような離散的データならベルヌーイ分布モデル
観測データをx、分類クラスをCi(i=1,...,N)とし、書き直すと
=P(x|Ci)
=クラスCiに分類されたデータxの確率分布
=Ci の中でxが発生する確率(xがCiであることが尤もらしい度合い)。
イチローBOTの例で考えると、
イチローBOTのツイート全ての中で、特徴ベクトル[自分,ない,人,目,バット]が発生する確率。
P(x|Ci) = P( word1, word2, word3, ... | Ci)
と考えられる。
P(word_i | Ci)=単語の条件付き確率
各単語がイチローBOTのツイート全ての中で発生する確率「単語の条件付き確率」を求める。
P( word1, word2, word3, ... | Ci)
=P(word1 | Ci) * P(word2 | Ci) * P(word3 | Ci) ...
=特徴ベクトルxの単語の条件付き確率の積が尤度となる。
※注意
上記の式の変形では単語の出現確率の間に独立性を仮定して同時確率をそれぞれの確率の積で表しているが、
本来、単語の出現に独立性は成り立りたたない。
たとえば、「人工」と「知能」は共起しやすいし、「機械」と「学習」は共起しやすい。
これを無視して単語の出現は独立と無理矢理仮定して文書の確率を単語の確率の積で表して
単純化するのがナイーブベイズのナイーブたる所以。
P(word_i | Ci)=単語の条件付き確率
クラスCiでword_iが出現する確率。
例として、
イチローBOTでword_iが出現した単語数 / (イチローBOTで出現した全ての単語数 + 全文書のユニーク単語数)
クラスの識別
各クラスの事後確率を比較して、最も事後確率が大きいクラスが該当する。
(Map推定)
おわりに
mecabにmecab-ipadic-neologd辞書を追加する
環境
CentOS6
mecab-ipadic-neologdとは?
mecab標準のシステム辞書の拡張の為の新語辞書。
辞書は月に数回更新されており定期的に新語が追加されている。
※ipadicは2007年を最後に更新が止まっている
更新された辞書を反映する為には都度以下の作業(mecab-ipadic-NEologdのダウンロードと辞書変換)が必要になると思われる。
mecabのインストールはこちらから
toriaezu-engineer.hatenablog.com
手順
mecab-ipadic-NEologdをダウンロードする
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
解凍する。
解凍後のCSVファイル名はmecab-ipadic-NEologdの最終更新日みたい。
xz -dkv mecab-ipadic-neologd/seed/mecab-user-dict-seed.*.csv.xz mecab-ipadic-neologd/seed/mecab-user-dict-seed.20160915.csv.xz (1/1) 100.0 % 33.6 MiB / 422.0 MiB = 0.080 89 MiB/s 0:04
mecab用辞書に変換する。
ファイル名の日付は適宜変更する事
/usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/ipadic -u mecab-user-dict-seed.20160915.dic -f utf-8 -t utf-8 mecab-ipadic-neologd/seed/mecab-user-dict-seed.20160915.csv
辞書を移動
※別に移動しなくても後述の設定で辞書パスを指定すれば大丈夫です
cp -p ./mecab-user-dict-seed.20160915.dic /usr/local/lib/mecab/dic/
vi /usr/local/etc/mecabrc
ユーザー辞書追記
userdic = /usr/local/lib/mecab/dic/mecab-user-dict-seed.20160915.dic
辞書が反映されている事を確認
追加前
[root@localhost src]# echo "なのはちゃんかわいい" | mecab な 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ の 名詞,非自立,一般,*,*,*,の,ノ,ノ は 助詞,係助詞,*,*,*,*,は,ハ,ワ ちゃん 名詞,一般,*,*,*,*,ちゃん,チャン,チャン かわいい 形容詞,自立,*,*,形容詞・イ段,基本形,かわいい,カワイイ,カワイイ EOS
追加語
[root@localhost src]# echo "なのはちゃんかわいい" | mecab なのは 名詞,固有名詞,人名,一般,*,*,なのは,ナノハ,ナノハ ちゃん 名詞,接尾,人名,*,*,*,ちゃん,チャン,チャン かわいい 形容詞,自立,*,*,形容詞・イ段,基本形,かわいい,カワイイ,カワイイ EOS
設定ファイルに追記しなくてもmecabのオプションでユーザー辞書の指定が可能
echo "なのはちゃんかわいい" | mecab -u /usr/local/lib/mecab/dic/mecab-user-dict-seed.20160915.dic なのは 名詞,固有名詞,人名,一般,*,*,なのは,ナノハ,ナノハ ちゃん 名詞,接尾,人名,*,*,*,ちゃん,チャン,チャン かわいい 形容詞,自立,*,*,形容詞・イ段,基本形,かわいい,カワイイ,カワイイ EOS
python3でTwitter APIからデータを取得
環境
CentOS6
python3.5
手順
Twitterアカウント作成後、以下にアクセス。
※アカウント登録には電話番号のひも付けが必要
https://apps.twitter.com/
「Create New App」をクリック
web siteには「http://127.0.0.1」を入力しても大丈夫だった。
登録後、「Keys and Access Tokens」タブでAPI Keyが確認できる。
requests-oauthlibインストール
pip install requests-oauthlib
API Keyの管理は設定ファイルで管理する。
[twtter_api] consumer_key=***** consumer_key_secret=***** access_token=***** access_token_secret=*****
下記サイトを参考にAPI Key管理方法だけ変更して動いた。
【python】gunicornとfalconを使ってWSGIサーバを作成してみる
環境
CentOS6
python3.5.1
gunicorn19.6.0
falcon-1.0.0
はじめに
gunicornはPython製のWSGIサーバ。
WSGIサーバーとはWEBサーバーとWebアプリケーションをつなぐサーバ。
今回はwebアプリケーションにpythonのWEBフレームワークfalconを利用する。
前回の記事で導入したfalconアプリケーションを今回は利用する
toriaezu-engineer.hatenablog.com
手順
gunicornインストール
pip install gunicorn
インストール確認。
gunicorn -v gunicorn (version 19.6.0)
gunicorn起動
バックグラウンドプロセスで起動する。
gunicorn falcon_test:api &
起動時の引数は
gunicorn モジュール名:falcon.APIインスタンスの変数名
モジュール名は、pythonスクリプトファイル名の拡張子を省いたもの。
falcon_test.py
api = falcon.API()
起動してみる
※BGプロセスで起動
何かログ出た
gunicorn falcon_test:api [2016-09-15 20:09:08 +0900] [62160] [INFO] Starting gunicorn 19.6.0 [2016-09-15 20:09:08 +0900] [62160] [INFO] Listening at: http://127.0.0.1:8000 (62160) [2016-09-15 20:09:08 +0900] [62160] [INFO] Using worker: sync [2016-09-15 20:09:08 +0900] [62234] [INFO] Booting worker with pid: 62234
curlでアクセスしてみる
gunicornで起動するとfalconアプリケーションで指定したポートは無効になるみたい。
gunicornのデフォルトのポート8000でアクセスする。
curl http://localhost:8000/test_api?key=TEST {'USER-AGENT': 'curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2', 'HOST': 'localhost:8000', 'ACCEPT': '*/*'} {"title": "WebAPIテスト", "tags": [{"バージョン": [], "name": "テスト"}, {"name": "request", "TEST": []}]}
アクセス出来た。
停止するには、プロセス番号を特定してkill
2つプロセスあるけど・・
ps ax|grep gunicorn 62676 pts/0 S 0:00 /root/.pyenv/versions/3.5.0/bin/python3.5 /root/.pyenv/versions/3.5.0/bin/gunicorn falcon_test:api 62750 pts/0 S 0:00 /root/.pyenv/versions/3.5.0/bin/python3.5 /root/.pyenv/versions/3.5.0/bin/gunicorn falcon_test:api
pkill
pkill gunicorn [2016-09-15 20:13:47 +0900] [62676] [INFO] Handling signal: term [2016-09-15 20:13:47 +0900] [62750] [INFO] Worker exiting (pid: 62750) [2016-09-15 20:13:47 +0900] [62676] [INFO] Shutting down: Master
停止してる事を確認
[root@localhost falcon]# ps ax|grep gunicorn 63106 pts/0 S+ 0:00 grep gunicorn
パット見、falconだけの起動時と何も変わらない。
と思ったら、起動時のオプションで色々指定できるみたい。
参考
http://docs.gunicorn.org/en/stable/settings.html
ポート番号指定して起動
gunicorn -b localhost:4000 falcon_test:api &
workerプロセス4つで起動
2~4の間で指定
gunicorn -w 4 falcon_test:api &
4プロセス起動してる
pstree -a|grep gunicorn | |-grep gunicorn | |-gunicorn /root/.pyenv/versions/3.5.0/bin/gunicorn -w 4 falcon_test:api | | |-gunicorn /root/.pyenv/versions/3.5.0/bin/gunicorn -w 4 falcon_test:api | | |-gunicorn /root/.pyenv/versions/3.5.0/bin/gunicorn -w 4 falcon_test:api | | |-gunicorn /root/.pyenv/versions/3.5.0/bin/gunicorn -w 4 falcon_test:api | | `-gunicorn /root/.pyenv/versions/3.5.0/bin/gunicorn -w 4 falcon_test:api
デーモンプロセスで起動
これ指定すれば&はいらないや。
gunicorn -D falcon_test:api
workerのスレッド数
2-4 x CPUコア数の間で指定
gunicorn --threads 2 falcon_test:api
workerの最大コネクション数
gunicorn --worker-connections 100 falcon_test:api
タイムアウト値、ワーカーが指定した秒数応答無い場合、自動的に再起動されます。
合ってるか怪しい
gunicorn -t 30 falcon_test:api
カレントディレクトリを指定
webアプリケーションのpythonがある場所を指定したりする
gunicorn --chdir /work/falcon/ falcon_test:api
pidファイルを作成
gunicorn -p /tmp/gunicorn.pid falcon_test:api
こんな感じでプロセスIDが出力される
cat /tmp/gunicorn.pid 64695
アクセスログ出力
gunicorn --access-logfile /tmp/gunicorn_access.log falcon_test:api
cat /tmp/gunicorn_access.log 127.0.0.1 - - [15/Sep/2016:22:35:13 +0900] "GET /test_api?key=TEST HTTP/1.1" 200 117 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
エラーログ出力
gunicorn --error-logfile /tmp/gunicorn_error.log falcon_test:api
cat /tmp/gunicorn_error.log [2016-09-15 22:36:16 +0900] [65318] [INFO] Starting gunicorn 19.6.0 [2016-09-15 22:36:16 +0900] [65318] [INFO] Listening at: http://127.0.0.1:8000 (65318) [2016-09-15 22:36:16 +0900] [65318] [INFO] Using worker: sync [2016-09-15 22:36:16 +0900] [65332] [INFO] Booting worker with pid: 65332
ログレベル指定
gunicorn --log-level debug falcon_test:api
他も色々設定あるみたい。
後でヘルプで確認してみる
gunicorn -h