「make_map.py」では,昨日の結果をもとに, 今日の予測値のしきい値を決定しています.
実は,モデルから出力される予測値は,0以上1以下の連続値です. そのため,「発生する」を示す「1」か,「発生しない」を示す「0」に振り分ける必要があります. その振り分ける基準が「しきい値」です.
直感的に,しきい値は0.5だと考えがちですが, 自分の研究では,予測精度が最大となるよう,しきい値を決定しています.
ここで,「予測精度」の話が出てきたので,追加で補足します. しきい値を決定すると,最終的に予測値は「0」か「1」になります. そのため予測精度は,単純に実測値と予測値がどちらとも合っている率 ...と考えがちですが(もちろんそれもひとつの指標で,「正答率」といいます), 自分の研究では,犯罪が発生していない例が極端に多いので, 発生が発生していない例がすべて予測できていなくても, 正答率が大きくなってしまいます.
そこで,このような不均衡なデータでも, より的確に測れる指標として「F1スコア」があり, 自分の研究でもそれを使っています.
時間があれば,下のページを読んでみてください. 第10回 機械学習の評価関数(二値分類用)の基礎を押さえよう:TensorFlow 2+Keras(tf.keras)入門 - @IT https://atmarkit.itmedia.co.jp/ait/articles/2010/27/news020.html
そのしきい値を,「hop.ipynb」で作成した検証用データを使って 決定するようにしました. 「step.ipynb」のいちばん最後に,その工程を追加していて, それを実行すると,しきい値が記録された「threshold.json」が追加されます.
また,プログラム全体を,より簡略化しました. ディレクトリの構成が変わっていますが, プログラムを動かす流れは変わっていません! …また,僕が実行したものがそのままになっているので, なにもしなくても予測マップが表示されます...
data/ :こまごまとしたデータを保存するディレクトリ modules/ :「pip install」ではインストールできないモジュールを入れておくディレクトリ
hop.ipynb :学習用データ,検証用データを作成するプログラム step.ipynb :モデルを作成するプログラム make_map.py :予測マップ,要因マップを作成するプログラム
get_crime_data.py :犯罪データを「犯罪発生マップ」から取得するプログラム(すでに取得しているため,使いません) make_mesh.py :メッシュのGeoJsonを作成するプログラム(すでに作成しているため,使いません)
crimes.csv :犯罪データ(get_crime_data.pyで作成される) data_by_mesh.csv :メッシュごとのデータ(hop.ipynbで作成される) data_by_day.csv:1日ごとのデータ train.csv:学習用データ(hop.ipynbで作成される) test.csv:検証用データ(hop.ipynbで作成される) model.pkl:犯罪発生予測モデル(step.ipynbで作成される) threshold.json:しきい値(step.ipynbで作成される) details.json:make_map.pyで予測した日(make_map.pyで作成される) today.json:予測日当日の予測結果(make_map.pyで作成される) yesterday.json:予測日前日の予測結果(make_map.pyで作成される) shap.json:SHAPの結果(make_map.pyで作成される)
map.html, map.js:予測マップ,要因マップを表示
ちなみに,これらのプログラムは,サーバ上に乗せて, 1日ごとに自動的に「make_map.py」を動かすことで 自動的に予測マップが更新されるようになっています.
富山県警の「犯罪発生マップ」から取得できる犯罪発生データは, 直近のものになるほど,データが少なくなっているため, 暫定的に4年前の今日を予測しています. いつを予測するかは,「make_map.py」の65行目で指定しています