ベイジアンネットで遅刻の原因推定
[やること]
ベイズの定理、条件付確率を使ったベイジアンネットで、遅刻の原因を推定します
[ベイジアンネットについて]
事象をノード、条件付確率をエッジにして、ネットワークを構築して、原因推定、意思決定モデルなどを行う手法です。
参考文献[1]がわかりやすいです。
[結果1]
条件付確率からベイジアンネットを構築しました
以下がそれぞれの事象の説明です
B:BeLate:遅刻する
O:OverSleep:寝坊する
Ti:Tired:昨日疲れてた
S:StayUpLate:昨日夜更かしした
Tw:TweetALot:昨日のツイート数が多い
[結果2]
遅刻した時に、昨日夜更かしした確率を計算します
P(S=1|B=1)です
P(S=1|B=1) = P(S=1,B=1)/P(B=1)です。
まず、分母P(B=1)から計算します
P(B=1) = P(B=1|Ov=1)P(Ov=1)+P(B=1|Ov=0)P(Ov=0)
P(B=1)の計算には、P(Ov=1)の値が必要です。
P(Ov=1)=P(Ov=1|Ti=[1,0],S=[1,0])P(Ti=[1,0])P(S=[1,0])
=0.8*0.5*0.4+0.5*0.4*0.5+0.6*0.6*0.5+0.4*0.6*0.5
=0.16+0.1+0.18+0.12
=0.56
分母P(B=1)が求まります。
P(B=1)=0.9*0.56+0.1*0.44=0.548
分子P(S=1,B=1)を計算します
P(S=1,B=1)
=P(S=1,B=1,Ti=[1,0],Ov=[1,0])
=P(B=1|Ov=[1,0])P(S=1,Ti=[1,0],Ov=[1,0])
=P(B=1|Ov=[1,0])P(Ov=[1,0]|Ti=[1,0],S=1)P(Ti=[1,0])P(S=1)
=0.9*0.8*0.4*0.5+0.8*0.6*0.6*0.5+0.4*0.2*0.4*0.5+0.4*0.4*0.6*0.5
=0.352
遅刻した時に、昨日夜更かしした確率が求まります。64%です。
P(S=1|B=1)=0.352/0.548=0.64
[結果3]
まず、寝坊した時に、夜更かしした確率を計算します。
その後、「昨日のツイート数が多い」という事象が加わった場合を計算します
P(S=1|O=1)、P(S=1|O=1,Tw=1)です
P(S=1|Ov=1)=P(S=1,Ov=1)/P(Ov=1)です。
分母P(Ov=1)は結果2で求まっています。
P(Ov=1)=0.56
分子P(S=1,Ov=1)を計算します
P(S=1,Ov=1)=P(Ov=1|S=1,Ti=[1,0])P(S=1)P(Ti=[1,0])
=0.8*0.5*0.4+0.6*0.5*0.6
=0.16+0.18
=0.34
寝坊した時に、夜更かしした確率が求まりました。61%です。
P(S=1|Ov=1)=0.34/0.56
=0.61
次に、「昨日のツイート数が多い」という事象が加わった場合を計算します
P(S=1|Tw=1,Ov=1)=P(S=1,Tw=1,Ov=1)/P(Tw=1,Ov=1)です。
分母P(Tw=1,Ov=1)を計算します
P(Tw=1,Ov=1)
=P(Tw=1,Ov=1,Ti=[1,0],S=[1,0])
=P(Ov=1|Ti=[1,0],S=[1,0])P(Tw=1,Ti=[1,0],S=[1,0])
=P(Ov=1|Ti=[1,0],S=[1,0])P(Ti=[1,0])P(Tw=1|S=[1,0])P(S=[1,0])
=0.8*0.4*0.7*0.5+0.5*0.4*0.5*0.5+0.6*0.6*0.7*0.5+0.4*0.6*0.5*0.5
=0.348
分子P(S=1,Tw=1,Ov=1)を計算します
P(S=1,Tw=1,Ov=1)
=P(S=1,Tw=1,Ov=1,Ti=[1,0])
=P(Ov=1|Ti=[1,0],S=1)P(Ti=[1,0])P(Tw=1|S=1)P(S=1)
=0.8*0.4*0.7*0.5+0.6*0.6*0.7*0.5
=0.238
「昨日のツイート数が多い」という事象が加わった場合の、寝坊した時に、夜更かしした確率が求まりました。68%です。少し確率が上がっています。直感と一致する結果です。
P(S=1|Tw=1,Ov=1)=0.238/0.348
=0.68
[今後の展望]
ベイジアンネットによる計算を自動化したいです
[参考文献]
[1]ベイジアンネットワーク
https://www.sist.ac.jp/~kanakubo/research/reasoning_kr/bayesiannetwork.html
最適なラーメンハシゴルート
[やること]
駅とラーメンのお店をネットワークで表現して、一番満足度の高いラーメンハシゴルートを計算します。
知識グラフを扱う練習が目的です。
[結果1]
青ノードが駅、赤ノードがラーメンのお店です。実際にあるお店です。
赤ノードの大きさが、ラーメンのお店の個人的なスコアです
エッジの数字はラーメンの値段、電車賃などを表します
[結果2]
以下のプログラムで、以下の設定で、スコアが一番高いルートを探索しました
設定:東京駅スタート、ラーメン2店舗ハシゴが上限
結果:['TOKYO', 'Rokurinsha', 'SHINJUKU', 'Konjiki']、1980円
[プログラム]
import networkx as nx import matplotlib.pyplot as plt import itertools class Noodle(): def __init__(self): #ネットワーク読み込み self.G = nx.read_edgelist('nodelist.txt', nodetype=str) nx.set_node_attributes(self.G, name='score', values=200) #スコア self.G.nodes["Rokurinsha"]["score"]=850 self.G.nodes["Konjiki"]["score"]=900 self.G.nodes["Ozeki"]["score"]=800 self.G.nodes["TOKYO"]["score"]=0 self.G.nodes["SHINJUKU"]["score"]=0 self.G.nodes["SHIBUYA"]["score"]=0 #コスト self.edge_labels={} self.edge_labels[("SHINJUKU","TOKYO")]=200 self.edge_labels[("TOKYO","SHINJUKU")]=200 self.edge_labels[("SHIBUYA","TOKYO")]=200 self.edge_labels[("TOKYO","SHIBUYA")]=200 self.edge_labels[("SHIBUYA","SHINJUKU")]=160 self.edge_labels[("SHINJUKU","SHIBUYA")]=160 self.edge_labels[("TOKYO","Rokurinsha")]=830 self.edge_labels[("TOKYO","Hyottoko")]=670 self.edge_labels[("TOKYO","Oboroduki")]=850 self.edge_labels[("TOKYO","Hachigo")]=850 self.edge_labels[("SHINJUKU","Gonokami")]=800 self.edge_labels[("SHINJUKU","Funji")]=700 self.edge_labels[("SHINJUKU","Konjiki")]=950 self.edge_labels[("SHINJUKU","Sho")]=700 self.edge_labels[("SHINJUKU","Hayashida")]=800 self.edge_labels[("SHIBUYA","Kiraku")]=700 self.edge_labels[("SHIBUYA","Hayashi")]=800 self.edge_labels[("SHIBUYA","Ozeki")]=830 #ネットワークをプロットする def plot(self): #色、サイズなど pos = nx.spring_layout(self.G, k=0.8) nx.draw_networkx_edges(self.G, pos, edge_color='y') c = ['blue' if n.isupper() else 'red' for n in self.G.nodes()] score_size = [1000 if n.isupper() else self.G.nodes[n]["score"] for n in self.G.nodes()] nx.draw_networkx_nodes(self.G, pos, node_color=c, alpha=0.5, node_size=score_size) nx.draw_networkx_edge_labels(self.G, pos, edge_labels=self.edge_labels, font_size=24) nx.draw_networkx_labels(self.G, pos, font_size=24) plt.figure(figsize=(10, 8)) plt.axis('off') plt.show() #ルートのコスト計算 def costscore_cal(self,route): score = 0 cost = 0 for a in range(len(route) - 1): if route[a] == route[a + 1]: continue else: if not (route[a].isupper()) and route[a + 1].isupper(): continue else: cost = cost + self.edge_labels[(route[a], route[a + 1])] score = score + self.G.nodes[route[a + 1]]["score"] return score, cost #店の一番近い駅 def store2station(self,storename): station = {'Rokurinsha': 'TOKYO', 'Hyottoko': 'TOKYO', 'Oboroduki': 'TOKYO', 'Hachigo': 'TOKYO', 'Gonokami': 'SHINJUKU', 'Funji': 'SHINJUKU', 'Konjiki': 'SHINJUKU', 'Sho': 'SHINJUKU', 'Hayashida': 'SHINJUKU', 'Kiraku': 'SHIBUYA', 'Hayashi': 'SHIBUYA', 'Ozeki': 'SHIBUYA'} return station[storename] #全ルート生成 def allroutes(self, noodle_count): noodle_shop = ('Rokurinsha', 'Hyottoko', 'Oboroduki', 'Hachigo', 'Gonokami', 'Funji', 'Konjiki', 'Sho', 'Hayashida', 'Kiraku', 'Hayashi', 'Ozeki') all_routes = () for a in range(noodle_count): all_routes = all_routes + tuple(itertools.permutations(noodle_shop, a + 1)) return all_routes #一番スコアが高いルート探索 def allroutes_costscore_cal(self,allroutes, start_station): result_route = [] for noodle_route in allroutes: list_kari = [] for a in noodle_route: list_kari.append(start_station) list_kari.append(self.store2station(a)) list_kari.append(a) list_kari.append(self.store2station(a)) result_route.append(list_kari) result_score = [] result_cost = [] for a in result_route: score, cost = self.costscore_cal(a) result_score.append(score) result_cost.append(cost) result_route=result_route[result_score.index(max(result_score))] result_cost=result_cost[result_score.index(max(result_score))] return list(dict.fromkeys(result_route)),result_cost if __name__=='__main__': n=Noodle() #2店舗はしごが限界 allroutes=n.allroutes(2) #東京駅スタート result_route,cost=n.allroutes_costscore_cal(allroutes,"TOKYO") #結果:['TOKYO', 'Rokurinsha', 'SHINJUKU', 'Konjiki'] print(result_route) #結果:1980円 print(str(cost)+"円") n.plot()
[参考文献]
[1]Pythonでネットワークを分析・可視化しよう!必要手順まとめ
https://www.sejuku.net/blog/91371
[2]【Python】NetworkX 2.0の基礎的な使い方まとめ
https://qiita.com/kzm4269/items/081ff2fdb8a6b0a6112f
カオスの軌跡のプロット
[やること]
微分方程式で表現されるカオスをPythonで解いて、軌跡をプロットします。
[カオスについて]
カオスは式で明確に定義されているのに、初期値の選び方で将来の状態が予測できない現象のことです。
参考文献[1][2]がわかりやすいです
[結果1]
ローレンツ方程式
p,r,b=10,28,8/3
初期値 x,y,z=1,1,1
初期値 x,y,z=1.0001,1,1
初期値 x,y,z=1.001,1,1
初期値 x,y,z=1.01,1,1
横軸に時間、縦軸にxを取ったプロットです。
初期値が少し変わるだけで軌跡が大きく変わることがわかります。
[結果2]
レスラー方程式
a,b,c=0.2,1.0,5.7
初期値 x,y,z=1.0,0.0,0.0
初期値 x,y,z=8.01,0.0,0.0
初期値 x,y,z=8.02,0.0,0.0
[プログラム]
微分方程式を解くライブラリodeintについては、参考文献[3]がわかりやすいです
import numpy as np from scipy.integrate import odeint import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D #レスラー方程式 def rossler(var,t,a,b,c): x_next=-var[1]-var[2] y_next=var[0]+a*var[1] z_next=b*var[0]-(c-var[0])*var[2] return np.array([x_next,y_next,z_next]) #ローレンツ方程式 def lorentz(var,t,p,r,b): x_next=-p*var[0]+p*var[1] y_next=-var[0]*var[2]+r*var[0]-var[1] z_next=var[0]*var[1]-b*var[2] return np.array([x_next,y_next,z_next]) if __name__ == "__main__": #レスラー方程式のパラメータと初期値 #abc=(0.2,1.0,5.7) #xyz_first=[1.0,0.0,0.0] #ローレンツ方程式のパラメータと初期値 prb=(10,28,8/3) xyz_first=[1.01,1,1] #ステップ数 t=np.linspace(0,1000,100000) #微分方程式を解く #var=odeint(chaos,xyz_first,t,args=abc) var=odeint(lorentz,xyz_first,t,args=prb) #グラフの枠を作っていく fig = plt.figure() ax = Axes3D(fig) #軸にラベルを付ける ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") #プロットして表示 ax.plot(var[:, 0], var[:, 1], var[:, 2], marker="o", linestyle='None') plt.show()
[参考文献]
[1]カオスアトラクタとは
http://www.gifu-nct.ac.jp/elec/deguchi/sotsuron/hisaki/node9.html#eqresura
[2]カオス
http://www.aoni.waseda.jp/yuuka/Sim/Chaos.html
[3]Pythonで運動方程式を解く(odeint)
https://qiita.com/binaryneutronstar/items/ad5efa27fd626826846f
自己組織化マップで色マップ画像作成
[やること]
自己組織化マップ(Self-Organizing Maps)で、RGBで表現された色データを、教師なし学習して、色マップを作成します。
[自己組織化マップの説明]
教師なし学習の手法です。
入力データに関して、近いデータを近くに配置するマップを作成します。
参考資料[1]がわかりやすいです
[結果1]
黒、緑、黄、赤、紫、白、水、青の8色を学習させた結果です。
青と水、赤と紫、など、近い色が近くに配置されています。
[結果2]
以下の12色相環の12色を学習させた結果です。
12色相環を再現できています。
[プログラムについて]
参考資料[2]をかなり参考にしました
[参考資料]
[1]自己組織化特徴マップ(SOM)
http://www.sist.ac.jp/~kanakubo/research/neuro/selforganizingmap.html
[2]MNISTの自己組織化マップ(SOM)を作った[Python]-もりとーにのブログ
山手線を徒歩で一周した
山手線を徒歩で一周しました。
新宿がスタート、ゴールで外回りで歩きました。
約40キロ、8時間21分かかりました。
1. 新宿駅:スタート
大きな駅。なんでもある。雑多。
2. 新大久保駅
韓国料理のお店がたくさんある。
新大久保ー高田馬場:きれいなマンション。落ち着いた感じ。
3. 高田馬場駅
豚カツ。全体的に低めの建物。とん太。
高田馬場ー目白:住宅街。
4. 目白駅
駅前オシャレ。住宅街。住みやすそう。落ち着いた感じ。ケーキ。
5. 池袋駅
大きな駅。雑多。なんでもある。飲み屋街。SEIBUビル。
池袋ー大塚:キレイめ。タワマンがあった。
6. 大塚駅
路面電車。落ち着いた感じ。緑多め。カッチャルバッチャル。
7. 巣鴨駅
地味な感じ。
8. 駒込駅
地味な感じ。
9. 田端駅
地味な感じ。
10. 西日暮里駅
神田っぽい。栄えている。
11. 日暮里駅
駅前がオシャレ。タワマンがある。
12. 鶯谷駅
駅前にラブホたくさんある。鶯谷苑。
13. 上野駅
14. 御徒町駅
神田っぽい。
15. 秋葉原駅
大きい駅。オタク。なんでもある。
16. 神田駅
線路下に店色々。飲み屋色々。低めの建物多い。
17. 東京駅
大きな駅。駅前かっこいい。なんでもある。皇居。
中間地点。ちょっと休憩した。
18. 有楽町駅
東京駅の続き見たいな感じ。
19. 新橋駅
大きな駅。なんでもある感じ。
この辺りで、脚を痛めた。ラスト10kmくらい、かなりしんどかった。
20. 浜松町駅
品川っぽい。
21. 田町駅
品川っぽい。大きな駅。
22. 品川駅
大きな駅。なんでもある。結構きれい。
23. 大崎駅
オシャレ。新しい。キレイ。
24. 五反田駅
雑多な感じ。品川っぽい。
25. 目黒駅
色々ある感じ。ちょっとオシャレ。
26. 恵比寿駅
オシャレ。色々ある。蕃 YORONIKU。
27. 渋谷駅
大きな駅。なんでもある。若い。人多い。
28. 原宿駅
竹下通り。若い。人多い。
29. 代々木駅
新宿駅の続きっぽい。
30. 新宿駅:ゴール
白のトイプードルの画像を集める:物体検出+クラス分類
やること
画像を入力すると、白のトイプードル(latte)の部分を切り出して保存するプログラムを作る。latteは家で飼っている白のトイプードルの名前です。
以下のようなことがやりたいです。
- 様々な画像がフォルダに含まれている
↓
↓
- 白のトイプードル(latte)の部分だけ切り出して、保存する
ルール
物体検出の学習はNG クラス分類の学習はOK 理由:物体検出+クラス分類の併用をやってみたかったため
実装の説明
学習データ収集 Kerasの物体検出モデル、YOLOv3、学習済みモデル(ImageNet)を使って、犬を切り出して、学習用の犬の画像を集める
学習 切り出した犬の画像で、Kerasのクラス分類モデル、VGG16をFine-Tuningする。クラスはdogとlatte。
推論 Kerasの物体検出モデル、YOLOv3、学習済みモデル(ImageNet)を使って、犬を切り出す 切り出した犬の画像を、KerasのFine-Tuningした、クラス分類モデル、VGG16で、クラス分類する クラス分類して、latteと分類された画像だけ、保存する
プログラム
作成したプログラムは全てgithubに上げてあります。 github.com
1.学習データ収集
Kerasの物体検出モデル、YOLOv3、学習済みモデル(ImageNet)を使って、犬を切り出して、学習用の犬の画像を集める
収集した犬が写っている画像をディレクトリyoloinputに入れる
yolo.py実行
- 切り出された犬の画像がディレクトリyolooutputに保存される
- 347枚の犬画像を収集,164:latte,183:dog
作成したプログラムはyolo.pyです。
2.学習
切り出した犬の画像で、Kerasのクラス分類モデル、VGG16をFine-Tuningする。クラスはdogとlatte。
ディレクトリ構成
keras-yolo3/train/dog:151枚、keras-yolo3/train/latte:150枚 keras-yolo3/validation/dog:22枚、keras-yolo3/validation/latte:9枚
keras-yolo3/classification_dog_train.py
説明
学習データをそれぞれ、上記のようにディレクトリに入れる。上記のようにそれぞれディレクトリ作って画像入れておけば、ImageDataGeneratorが読み込んで、水増ししてくれる
classification_dog_train.py実行
50epochで収束した。精度は95%くらい。
重み、モデル情報保存。
学習した重み:vgg16_dog_fine.h5。
モデル情報:vgg16_dog_fine.json
作成したプログラムはclassification_dog_train.pyです。
3.推論
手順
収集した犬が写っている画像をディレクトリyoloinputに入れる
yolo.py実行
- 切り出された犬の画像がディレクトリyolooutputに保存される
- classification_dog_predict.py実行
切り出された犬の画像をyolooutputから読み込んで、クラス分類実行する。
白のトイプードル(latte)画像はディレクトリlatteに保存される
結果
作成したプログラムはclassification_dog_predict.pyです。
参考文献
サブサンプションアーキテクチャによる知的な振る舞いの創発
以下の記事の一環として行いました。
1.はじめに
- AGI実現が最終目標
キーワード
→サブサンプションアーキテクチャに注目する
方法、実験、考察、結論の順で説明する
サブサンプションアーキテクチャの説明
以下の画像がわかりやすい
従来の知能ロボットの処理系は、モジュールが縦に並んでいる。センサからの情報をモジュールが1つずつ順に処理して、最後、アクチュエータにつながる。
サブサンプションアーキテクチャは、モジュールが横に並んでいる。複数のモジュールが、同時に、独立に、非同期に、動いている感じ。
2. 方法
- サブサンプションアーキテクチャを試せるシミュレーションソフト、SB-MASEを利用する
- 知的な振る舞いをするエージェントを作る
- つまり、賢そう、複雑そう、考えてそう的な動きをするやつを作る
SB-MASEの説明
2枚目の画像がシミュレーション世界です。赤いやつがエージェントです。
1枚目の画像は、このエージェントの中身です。サブサンプションアーキテクチャでエージェントの動きを構築できます。
3. 実験
- サブサンプションアーキテクチャを1層ずつ重ねていく
- 最終的に5層にして、
「獲物がいないなら待機、直進を繰り返す。いるなら追いかける。見失っても数秒その方向に進む。エージェント」
を作る
1層
- WALK:ひたすら直進する
→ひたすら直進する
2層
- WALK:ひたすら直進する
- AVOID:障害物があったら避ける
→障害物を避けながら、ひたすら直進する
3層
- WALK:ひたすら直進する
- AVOID:障害物があったら避ける
- PROWL:獲物がいないなら待機。いるなら直進
- STEER:獲物の方向に向き変更
→獲物がいないなら待機。いるなら追いかける
4層
- WALK:ひたすら直進する
- AVOID:障害物があったら避ける
- PROWL:獲物がいないなら待機。いるなら直進
- STEER:獲物の方向に向き変更
- PROWLKEEP:見失っても、直進を数秒続ける
→獲物がいないなら待機。いるなら追いかける。見失っても数秒その方向に進む。
5層
- WALK:ひたすら直進する
- AVOID:障害物があったら避ける
- PROWL:獲物がいないなら待機。いるなら直進
- STEER:獲物の方向に向き変更
- PROWLKEEP:見失っても、直進を数秒続ける
- EXPLORE:直進、待機を繰り返す
→獲物がいないなら待機、直進を繰り返す。いるなら追いかける。見失っても数秒その方向に進む。
以下のリンクで、5層サブサンプションアーキテクチャのエージェントの動きが確認できます。緑のやつです。
4. 考察と結論
- 賢そうな動きをするエージェントを作ることができた
→サブサンプションアーキテクチャで知的な振る舞いが創発できた!
- 構造はかなりシンプル
- サブサンプションアーキテクチャすごい!
- 推論、記憶などは実現できるのか?
- ハードウェアレベルで実装したい
- 身体性と絡めたい