全国規模の感染シミュレーションと結果の可視化をしてみる

先日、都道府県間通勤・通学を考慮した感染症流行のシミュレーションを行った。 この時は関東のみのシミュレーションだったが、今回は全国規模の感染シミュレーションを実施してみる。 なお、この記事ではモデルに関する説明は特に記載しないため、モデルの詳細は以下過去の記事を参照していただきたい。 感染症数理モデルについて触りの部分だけ学ぶ | kouya17.com 都道府県間通勤・通学を考慮したパンデミックシミュレーションもどき | kouya17.com ※本シミュレーションや上記リンク先のシミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 利用するデータ シミュレーションを全国規模に拡張するには各都道府県の人口のデータと、各都道府県間の通勤・通学者人数のデータが必要になる。 これらのデータは総務省統計局「平成27年国勢調査結果」1を利用した。 パラメータ、初期状態について SEIRモデルに置ける各パラメータは今回以下のように設定する。 基本再生産数 \(R_0\) : 2.0 平均潜伏期間 \(l\) : 5日 平均発症期間 \(i\) : 14日 初期状態はAM0時に、東京都に1人の感染者がいる状態とする。 今回は都道府県間通勤・通学について 通勤・通学者なし 通勤・通学者あり、通勤・通学者数は特に加工しない 通勤・通学者あり、通勤・通学者数は元データの20%にする 通勤・通学者あり、通勤・通学者数は元データの0.01%にする の4パターン、計算を実施して、通勤・通学者数が与える影響を調べてみる。 また、前回のシミュレーションでは休日の概念を設けていなかった。 働きっぱなしは可哀想なので、土日は休みにし、通勤・通学はしないものとする。 ただし、祝日や土日以外の長期休暇は考慮しない。 結果及び可視化 今回はデータが少し多くなってくるので、可視化の方法も工夫する必要がある。 japanmapという、日本地図を都道府県別に色分けできるライブラリがあるようなので、これを利用させていただく。 発症者比率の可視化 各都道府県について、人口に占める発症者の比率(\(\frac{I}{S+E+I+R}\))を可視化する。 発症者の比率を赤色の濃淡で表したアニメーションを以下に示す。 通勤・通学者なしの場合 都道府県の人の移動が発生しないため、東京でしか流行しない。 通勤・通学者ありの場合 日本全国に感染が広がる。 ただし、感染のピークは東京から遠い都道府県ほど遅くなる。 通勤・通学者あり、ただし人数20%の場合 人数を絞る前の結果とほぼ変わらないように見える。 通勤・通学者あり、ただし人数0.01%の場合 人数を思いっきり絞ってみると、人数を絞る前と比べて感染が広がるスピードが遅いように見える。 1000日目時点での累計感染者数の可視化 それぞれの条件で1000日目時点での累計感染者数(\(E+I+R\))をグラフ化する。 横軸を各都道府県、縦軸を累計感染者数にした棒グラフを以下に示す。 通勤・通学における各条件の結果をそれぞれ色を変えて並べている。 累計感染者数に関しては、通勤・通学者数を絞っても変化はない。 ソースコード 今回使用したコードは以下に置いてある。 ただし、全然整理できていない…。 統計局ホームページ/平成27年国勢調査/調査の結果 ↩︎

May 20, 2020 · 1 min

LogisticRegression().fit()のConvergenceWarningを解消する

環境 Anacondaの環境情報 >conda info conda version : 4.8.2 conda-build version : 3.18.11 python version : 3.7.6.final.0 platform : win-64 現象 pythonでLogisticRegression.fit()を実行したところ、以下のワーニングが出た。 ConvergenceWarning: lbfgs failed to converge (status=1): STOP: TOTAL NO. of ITERATIONS REACHED LIMIT. 実行時のjupyter notebookは以下のような感じ。 一応正解率は出せているらしい。 解決策の1つ モデルが収束していないそうなので、max_iterを明示的に設定して、反復回数を増やす。 max_iterの初期値は100だが、上の例では1000に設定している。 今回はこれで警告が出なくなったので、よしとする。 参考 見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑posted with ヨメレバ秋庭 伸也/杉山 阿聖 翔泳社 2019年04月17日 楽天ブックスで購入楽天koboで購入Amazonで購入Kindleで購入

May 16, 2020 · 1 min

Vue.jsでローディング表示を実装する

ローディング表示モジュールの調査 vue.jsでローディング表示を行う場合、ローディング表示に関係するモジュールについて調査する。 出来れば、 実装が簡単 よく見かけるような見た目(独自性がない) メンテされている という条件にあてはまるものを採用したい。 調べた結果を以下の表にまとめた。 名前 種類 GitHub Star 最終更新(2020/05/06時点) 備考 vue-loading Vueコンポーネント 2018/12/22 紹介している記事が多い vue-spinner Vueコンポーネント 2017/10/07 Vue2.0をサポートしていない Single Element CSS Spinners css 2019/12/09 よく見かける見た目 vue-loading-overlay Vueコンポーネント 2020/04/18 全画面に表示するらしい vue-wait Vueコンポーネント 2019/10/08 だいぶ機能がリッチそう ajaxload.info gif - - よく見かける見た目 調べて出てきた候補は以上。...

May 6, 2020 · 1 min

都道府県間通勤・通学を考慮したパンデミックシミュレーションもどき

先日、SEIRモデルを用いた感染症流行のシミュレーションを行った。 このプログラムを少し拡張して、都道府県間通勤・通学を考慮したパンデミックシミュレーションもどきを行う。 ※本シミュレーションや上記リンク先のシミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 都道府県間通勤・通学をシミュレーションに組み込む 都道府県間通勤・通学の影響をシミュレーションに組み込むため、総務省統計局「平成27年国勢調査結果」1を参考にする。 今回は東京都・群馬県・栃木県・茨城県・埼玉県・千葉県・神奈川県間の自宅外就業者数及び通学者数データを扱う。 モデルへの組み込み方としては、移動用のグループを形成し、移動用のグループは移動先のデータと感染率を共有するという方法を採る。 なお、今回はシミュレーション内時刻が8:00の時に通勤・通学者が一斉に(移動時間0で)移動し、シミュレーション内時刻が17:00の時に通勤・通学者が一斉に(移動時間0で)帰宅すると仮定する。 東京都と千葉県間の人口移動を例にして説明する。 まず、初期状態として以下のような状態になっているとする。 値はすべて適当だが、東京都に10人感染者(\(I\))がいるとする。 この後、時間を進行させる。 シミュレーション内の時刻が8:00になった時、人口移動用のグループを分割する。 移動用グループの総人数は総務省統計局「平成27年国勢調査結果」1における自宅外就業者数及び通学者数に従う。 \(S:E:I:R\)比は移動元の都道府県データの比と等しくする。 ここで、移動用グループは移動先の都道府県のデータと、感染率\(\frac{R_0I}{iN}\)を共有する。 感染率を共有させた状態で、時間を進行させる。 なお、感染率を共有する関係で、非感染者から潜伏感染者への遷移に関する項については時間刻みに対して1次精度になってしまう。 シミュレーション内の時刻が17:00になった時、人口移動用のグループを移動元のデータに合流させる。 上の図中の値もすべて適当だが、以上のような形で、都道府県間の感染伝播をシミュレートする。 計算する 人口データについて 人口データは各自治体のページを参考に、以下の値を使う。 都道府県 人口[人] 備考 東京都 13951635 2020年1月1日時点推計2 茨城県 2866325 2020年1月1日時点推計3 栃木県 1942313 2019年10月1日時点推計4 群馬県 1938053 2019年10月1日時点推計5 埼玉県 7341794 2020年4月1日時点推計6 千葉県 6280344 2020年4月1日時点推計7 神奈川県 9204965 2020年4月1日時点推計8 各都道府県毎の通勤・通学による流入・流出人口は総務省統計局「平成27年国勢調査結果」1より、以下の値(単位は[人])を使う。縦が流出元で横が流出先。...

May 5, 2020 · 1 min

感染症数理モデルについて触りの部分だけ学ぶ

目的 特にしっかりした目的はない。 なんとなく数値シミュレーションについて学び直したくなったため、現在身近にある現象を題材にして学ぶ。 ネットの情報を参考に、適当にシミュレーションを走らせてみる。 ※本シミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 今回扱うシミュレーションモデル SEIRモデルを扱う。 SEIRモデルとは SEIRモデル(エスイーアイアールモデル)とは感染症流行の数理モデルである。 モデルは 感染症に対して免疫を持たない者(Susceptible) 感染症が潜伏期間中の者(Exposed) 発症者(Infectious) 感染症から回復し免疫を獲得した者(Recovered) から構成され、その頭文字をとってSEIRモデルと呼ばれる。 (Wikipediaより) モデル式は以下のような式で表される。 $$ \begin{aligned} \frac{dS}{dt} &= m(N - S) - bSI &(1) \cr \frac{dE}{dt} &= bSI - (m + a)E &(2) \cr \frac{dI}{dt} &= aE - (m + g)I &(3) \cr \frac{dR}{dt} &= gI - mR &(4) \end{aligned} $$ ここで\(t\)は時間、\(m\)は出生率及び死亡率、\(a\)は感染症の発生率、\(b\)は感染症への感染率、\(g\)は感染症からの回復率を表す。 また\(N\)は全人口を示し、 $$N \equiv S + E + I + R (5)$$...

May 2, 2020 · 2 min

Chart.jsで時刻データを扱う

Chart.js公式のドキュメントを参考にして、Chart.jsで時刻データを扱う場合の描画オプションについて確認する。 入力データ 入力データはx軸データをy軸データを各点それぞれ指定する。 今回はx軸データに時刻データを使う。 例としては、以下のように指定すればOK。 data: [{ x: '1995-12-17T00:00:00', y: 1 }, { x: '1995-12-18T00:00:00', y: 10 }, { x: '1995-12-21T00:00:00', y: 20 }, { x: '1995-12-25T12:00:00', y: 30 }, { x: '1996-01-01T00:00:00', y: 40 }] データフォーマット 時刻スケールのデータを使う場合、フォーマットはMoment.jsが扱えるフォーマットであればどういった形式でも良い。詳細はMoment.jsのドキュメント参照。 描画オプション 時刻目盛りを扱う場合、以下のオプションを設定できる。 adapters.date 外部の時刻ライブラリ(つまりMoment.js以外)を使うためのオプション。 distribution データのプロット方法。 指定できる値はlinearまたはseriesのいずれか。 初期値はlinear。 linearはデータ描画間隔が時間間隔に応じて変化する。 seriesはデータ描画間隔がすべて同じになる。 以下に同一データを用いてdistribution設定のみ変えた場合の描画例を示す。 linearを指定した場合 var ctx = document.getElementById('distribution_linear').getContext('2d'); var chart = new Chart(ctx, { // The type of chart we want to create type: 'line', // The data for our dataset data: { datasets: [{ label: 'linear', backgroundColor: 'rgb(255, 99, 132)', borderColor: 'rgb(255, 99, 132)', fill: false, data: [{ x: '1995-12-17T00:00:00', y: 1 }, { x: '1995-12-18T00:00:00', y: 10 }, { x: '1995-12-21T00:00:00', y: 20 }, { x: '1995-12-25T12:00:00', y: 30 }, { x: '1996-01-01T00:00:00', y: 40 }] }] }, // Configuration options go here options: { scales: { xAxes: [{ type: 'time', //!...

April 26, 2020 · 9 min

Vue.jsを使ったSPAにおいてTwitter等でのリンク表示がいい感じになるようにする

Vue.jsでSPAを構成した際、TwitterなどのOGPが上手く表示されなかったので、対処した。 SPAとは?→シングルページアプリケーション この記事で扱っているSPAとは、シングルページアプリケーションを指す。 SPAについては少し以下の記事で触れたが、詳細は他のサイトの方が詳しいと思う。 OGPとは?→Webページのリンクを表示する仕組み OGPとはOpen Graph Protocolの略で、TwitterとかFacebookとかでリンクがいい感じに表示されるアレに使われているプロトコルのこと。 ↓これ。 Chart.jsで横軸が日付のグラフを作成する https://t.co/evu4HqqQ4f @aoki_kouyaさんから — 青木晃也 (@aoki_kouya) April 4, 2020 webサイトをいちから作る際、OGP対応していないと、Twitterとかでリンクを貼り付けても画像や説明文は表示されない。 そこらへんはTwitter側でなんとかしてくれるわけではなく、サイト作成者側が適切にOGP設定を行う必要がある。 SPAの場合はOGP設定にひと工夫必要 OGPは、具体的にはHTMLにmetaタグを設定することで対応できる。 例えば、以下のようなmetaタグを<head>要素内に設定する。 上記は私が作成したサイトの実装例になるが、他のサイトを調べると、head要素にprefix属性を適切に設定する必要があるようだ。 私は設定していなかったが、とりあえずTwitterあたりでは問題なく動いているように見える。 まあ、正しい対応ではないと思う。 このOGP設定だが、SPAの場合はひと工夫必要になる。 理由は、OGPによってリンクを作成する際、JavaScriptが動かないケースがあるため。 OGPによってリンクを表示する際、クローラーと呼ばれるプログラムによって、リンク先のページをスキャンする。 スキャン結果に従ってリンクを表示するのだが、TwitterやFacebookのクローラーはJavaScriptを実行してくれないらしい。 よって、JavaScriptによってmetaタグを生成しても、リンクには反映されない。 SPAでOGP設定を適切に行う場合はここら辺の対処が必要。 今回は特定条件時のみ静的ページを返すように実装 今回の結論、解決策になる。 調べてみると、(Vue.jsを用いた)SPAでのOGP設定については色々対応策があった。 いくつか参考にさせていただいたページを挙げておく。 上記のページの方法はページ内にも書かれている通り、全てのページで同じ内容のOGPになってしまう。 今回はそれぞれのページで異なるOGPを設定したいため、同じ方法はとらなかった。 上記のページは詳しく書いてあり、参考になりそうだったが、Firebaseを使ってない、使ったことがないため今回は同じ方法をとれなかった。 最終的には以下のページの方法を真似させていただいた。 上のページの方法は、TwitterやFacebookなど特定のクローラーに対してのみOGP対応用のテンプレートを返すというものになっている。 アプローチとしては一番最初に挙げたページと同じだが、こちらはクローラー検出用にControllerを作成して、テンプレートの出し分けをしている。 比較的容易に実装でき、ページごとに異なるOGP設定ができそうだったため、こちらの方法を採用した。 この方法の課題としては、OGP対応用のテンプレートを返す相手をピンポイントで指定する必要があるため、明示的に指定したクローラー以外に対しては対応できない点がある。 また、OGP対応用のControllerを新規に作成する必要があり、Controllerが単純に1個増える。 なお、各サービスのクローラーの情報は以下のサイトを参考にさせていただいた。 雑記 Twitterでのリンク表示内容確認には以下の公式のサイトが便利。 これからはじめるVue.js実践入門 山田 祥寛 Amazon Kindle 楽天 楽天Kobo

April 25, 2020 · 1 min

Chart.jsで横軸が日付のグラフを作成する

webサイト上で横軸が日付情報のグラフを作りたかったのでChart.js周りで色々調べた。 横軸が単純な数値じゃない場合は面倒くさくなるかなと思っていたが、Chart.jsが非常に使いやすく、すんなりできた。 最終的に作ったもの 画像で貼ろうと思ったが、結構サイズが大きいのでリンクで貼り付けておく。 Chart.jsとは グラフ類を描画するためのJavaScriptライブラリ。 HTMLの<canvas>要素に2Dグラフィックを描画できる。 ライセンスはMIT。 Chat.jsのインストールと使い方 基本的な使い方を公式に従って確認してみる。 インストール 今回はとりあえず手軽そうなCDNを使う。 よってHTMLに以下のタグを追加する。 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script> なお、ここで Chart.bundle.min.js を選択したのは、今回日付データを扱うため。 Chart.min.js の方は日付データを扱うためのライブラリMoment.jsが含まれていない。 使い方 HTML側はグラフ描画用の<canvas>タグを作成する。 先ほどのCDNの参照及び今回作成するJavaScriptの読み込みを合わせて、HTML側のソースは以下のようになる。 index.html JavaScript側は公式のサンプルを参考にして以下のようにする。 main.js これら2つのファイルを適当なところに保存して、index.htmlをブラウザで開く。 以下のようなグラフがブラウザ上に表示される。 横軸が日付情報のデータをプロットする サンプルが動いたので、今回扱いたい、横軸が日付情報のデータをプロットする。 HTML側は特に変更せず、JavaScript側を以下のように変更する。 main.js 参考ページ main.jsを上記のように変更し、index.htmlをブラウザで開くと以下のようなグラフが描画される。 横軸が日付になっており、横軸の間隔もデータに合わせていい感じになっている。 まとめ Chart.jsを使って横軸が日付情報のデータをプロットできた。 色々と描画オプションがあるようなので、それぞれ変更させるとどのようにグラフが変化するか、また今度まとめたい。 確かな力が身につくJavaScript「超」入門 第2版 狩野 祐東 Amazon Kindle 楽天 楽天Kobo

April 5, 2020 · 1 min

Laravel+Vue.jsでSPA(シングルページアプリケーション)を作成した

今回作成したサイト 今回作成したサイトは以下のサイト。 ClubPage 私が所属している電子工作サークルのホームページを作った。 このブログからcssを流用しているので、見た目がだいぶ似ている。 構成 Laravel Vue.js バックエンドはLaravel、フロントエンドはVue.jsを使っている。 シングルページアプリケーションとは 今回はシングルページアプリケーション(SPA)という構成を採用した。 シングルページアプリケーションとは シングルページアプリケーション(英: single-page application、SPA)とは、単一のWebページのみから構成することで、デスクトップアプリケーションのようなユーザ体験を提供するWebアプリケーションまたはWebサイトである。必要なコード(HTML、JavaScript、CSS)は最初にまとめて読み込むか[1]、ユーザの操作などに応じて動的にサーバと通信し、必要なものだけ読み込みを行う。 Wikipediaより というものらしい。 これまでRuby on RailsやDjangoとかを使ってwebサイトを作ってみてきたが、どれも各ページ毎に、サーバ側でHTMLの生成を行うマルチページアプリケーションだった。 今回はLaravelでwebAPIを作成し、そのAPIから取得した情報を、Vue.jsを使ってブラウザ上に表示するような構成にした。 なぜSPAにしたのか 理由は1つで、今回参考にしたサイトがSPAを採用していたから。 今回参考にしたサイトは以下のサイト。 このサイトにあるチュートリアル、書かれている情報量がかなり多くて、これだけの情報をタダで得られるのが信じられない。 今回初めてLaravelとVue.jsを触ったが、このサイトのおかげで色々と基礎を学ぶことができた。 今回学んだこと、感じたこと インタフェース部とエンジン部の分離はやはり重要 今回の構成はAPI(Laravel)と表示部(Vue.js)を分離している。 たとえばhttps://home.lchika.club/api/tagsにアクセスすれば、Laravelの機能によって、タグの一覧をJSON形式で取得できる。 こういったAPIから取得した情報をVue.jsで処理して、ブラウザにレンダリングする。 このように分離することで、UIを変えたいときは、基本的にVue.jsの部分のみを修正するだけですむ。 Laravelの処理部は一切手を加える必要がない。 まあ、一般的なwebフレームワークを使っていれば、実装の分離は適切に行われているが、ある一部分のフレームワークをごっそり切り替えることはできない。 今回の構成では、例えばフロントエンドにReactを使いたければ、Laravel部分はそのままで、フロントエンド部分をごっそり切り替えられる(と思うけど、Laravel-mixとかの関係で難しいのかもしれない…)。 このように、インタフェースとエンジン部の分離で得られる効果はやはりでかいなと思った。 ローディング表示がないとwebサイトの質が落ちる これは個人的な印象かもしれないが、ローディング画面の表示はユーザにとって(ある程度)重要だなと思った。 現状ではローディング表示は実装していないため、読み込み直後は一部のコンテンツが表示されていないし、一部のコンテンツについては結構な時間表示されないことがある。 これはサイト利用者側からすると、違和感を覚える要因になり、満足度の低下につながると思った。 YouTubeとかもローディング中はコンテンツ表示部をグレーで表示したりしている。 最初はこれ意味あるのか?と思っていたが、今回自分でJavaScriptを多用したサイトを構築してみて、こういった対応も重要だなと思った。 WYSIWYGエディタの選定は毎回の課題 今回はブログのようなサイトを構築したので、フォームから記事を投稿できる必要があった。 さすがにHTML直打ちで入力はできないし、リッチテキストエディタを採用する必要があった。 毎回どのリッチテキストエディタを使うか苦労するが、今回も例に漏れず苦労した。 とりあえず今のところはCKEditorを使っている。 ただ、まだ課題があって、iframeの挿入が上手くいっていない。 いつも大体、リッチテキストエディタまわりは 画像の挿入 画像の整形 外部コンテンツの挿入 目次の作成 あたりで詰まっている。 今回はまだ目次の作成について考えていないので、目次が必要になった時に多分また詰まる。 SPAのパフォーマンス向上はバンドルサイズの削減こそ正義 今回作成したサイトのパフォーマンス向上については以下の記事に書いた。 最初特に何も考えずにサイトを作っていたら、パフォーマンスが崩壊した。 今もパフォーマンスが良いとは言えないが、バンドルサイズを削減することで、パフォーマンスが向上した。 こういったパフォーマンス向上のための施策は必要不可欠だなと感じた。 まとめ 今回はLaravelとVue.jsを使ってサイトを作った。...

March 15, 2020 · 1 min

Laravel+Vue.jsでLighthouseのスコアを0点から97点にした(バンドルサイズ削減)

Laravel+Vue.jsで作成していたwebサイトの応答速度が激遅だったので、対策を実施した。 環境 Laravel 6.14.0 Vue.js 2.6.11 対策前はページロードに20秒かかっていた 特に何も考えずにwebサイトを作っていたら、トップページのロードに20秒ほどかかっていた。 これではさすがにwebサイトとして成立しない。 Googleが提供しているwebページ分析ツールLighthouseを使ってパフォーマンスの測定を行ったところ、以下のような結果になった。 堂々の0点である。提示されている対応策の詳細を見ると、以下のように書かれていた。 どうやらバンドル後のapp.jsのサイズが約4MBと、超巨大になっているらしい。対応策としてapp.jsのサイズ削減を行った。 対策1:本番用ビルド設定を適用する バンドルサイズ 3.86MB(app.js) → 1.59MB(app.js) 解説 そもそもビルド設定が間違っていた…。ビルドコマンドとして npm run dev を実行していたが、これは開発用のビルドコマンドらしい。 本番用のビルドコマンド npm run prod を実行したところ、バンドルサイズは3.86MB→1.59MBと、約40%になった。 Lighthouseの結果 0点→10点に上昇した。 対策2:gzipで圧縮する バンドルサイズ 1.59MB(app.js) → 395KB(app.js.gz) 解説 以下のページを参考に、gzipでapp.jsを圧縮した。 そのままコピペで適用できた。 Lighthouseの結果 10点→63点に上昇した。 対策3:ページごとにJSファイルを分割する バンドルサイズ 395KB(app.js.gz) → 243KB(app.js.gz) 解説 以下のページを参考に、ページごとにJSファイルを分割した。 こちらも特に詰まることはなく、ほぼコピペで実装できた。 この対策を実装したことで、ビルド後のJSファイルが以下のように、分割されて生成されるようになった。 Lighthouseの結果 63点→87点に上昇した。 対策4:bootstrap-vueの選択的インポート バンドルサイズ 243KB(app.js.gz) → 129KB(app.js.gz) 解説 対策1~3で、あらかた大きなところは対策できたと思ったので、より細かいところを対応するため、webpack-bundle-analyzerを使ってバンドル結果の分析をした。 webpack-bundle-analyzerの出力結果は以下のようになった。 この結果から bootstrap-vue ckeditor lodash あたりのサイズが大きいらしいことが分かった。...

March 8, 2020 · 1 min