Pay money To my Life

Spend time for myself, and you... "Knowledge was the only way to remember that your past is true"

TensorFlow Liteについて語る会に参加しました

はじめに

 TensorFlow Liteは、デバイス上での推論を可能にする、オープンソースディープラーニングフレームワークである。 思いっきり学習させると、モデルは当然大きくなる。そう言った学習させたモデルをエンドデバイススマホやIoTデバイス)に実装するとなると、そのままではきついことがあり、その問題を解決するためのフレームワーク

www.tensorflow.org

 そんなTFLiteについて、気楽に語り合おうという会が企画されたため、参加してみた。そんな備忘録。clusterを初めて使用したので、そこもまた新鮮でした。

tfug-kansai.connpass.com

TensorFlow Liteについて語る会・発表

発表者は2名。@cocodripsさんと、@natsutanさん。

twitter.com

twitter.com

スマホでDeepLearning実践入門(@cocodrips)

  • v1, v2で全く挙動が違うので注意(みんなどんどん使って情報をネット上に増やしたい)
  • Weightの量子化、WeightとActivationの量子化、の2種類の最適化オプションがある
  • 後者はデータセットを最適化する必要あり、今回は前者に関するお話
  • weightをint8に量子化すると、float32からは推論速度は2~3倍になる
  • 物体検出で63MB、画像のクラス分類モデルで20MB(90class)、5classで8.5MBになる
  • 類似画像検索では、特徴量抽出機をfloat32->float16にすると問題なく使えるけど、int8では全くだめだった
  • SavedModelからはconvertできない(稀、ネットで拾ってくるようなモデルは無理)、Lite用に加工してやる必要あり
  • TFLiteはサイズを可変にすることができない、、、
  • python APIはオプションが少ない(shapeの-1を自動で変換してくれない、固定になっていないと使えない)、v2はクソなのでv1を使った方便利
  • tflite_convertではSavedModelもKerasも変換可能、細かいことを設定できる
  • けど、チュートリアル以外のモデルはv2ではconvertできなかったため基本的にv1を使用している(体験談)
  • tocoはもうすでに公式では推奨されていないけれど、一番オプションも多く使いやすい(cocoさんもこれ推奨、使い方等は過去のブログ参照)
  • NETRON(ネットロン)がめっちゃ便利、グラフ構造やレイヤーが簡単に把握できる(TensorFlowBoardを使用する必要がない、ダブルクリックで詳細が確認可能)
  • これを入れるとTF使っているなら、幸せになれること間違いなし f:id:K_PTL:20200508192436p:plain
  • TF Liteが使えるモバイル用のフレームワークはいくつかある
  • MLKitが一番有名かな?(AndroidiOS両方に対応)
  • firebaseにモデルを上げておいて、後からDLするっていうスタンスも3行くらいで書けちゃう
  • Core ML (iOS)は、最初から入っているためframework分のアプリ容量膨張を防げる
  • Mediapipe(AndroidiOS両方に対応)、ストリーミングで推論可能、資料が少なく勉強するのが大変、、??
  • iOSはobject-cでframework対応していないため、独自にframework作成する必要あり、、今後に期待、、、
  • リアルタイムでエリアディテクションできちゃう f:id:K_PTL:20200508193352p:plain
  • v1, v2で全く挙動が違うので注意(みんなどんどん使って情報をネット上に増やしたい)

TFLiteのグラフ構造について(@natsutan)

  • NetronでTFLiteのグラフをみましょう。
  • TFLiteはChainerと同じ計算グラフ、、??
  • 基本的なNNでは計算の向きは変わらない(推論のForwarding、学習のBackprop.)
  • 分岐があるときに、BackProp.時にオペレータの前に変数を「勾配を足し合わせる」というノードとして機能させるため、動的にグラフを変化させたい時など非常に便利
  • tfliteは推論特化だけど、エッジ側で再学習するケースが最近で始めているのでBackProp.も使うことになるかもしれない

終わりに

 ちょうど今、機械学習を使用することになるかどうかはわからないが、エンドデバイスでセンサデータを取り扱う研究に取り組んでいるため、将来使うことになる(今の研究でなくても、いつかは必ず使うだろう)。趣味程度にでも、独学で進めていきたいなぁ。。まだコミュニティもTensorFlow本体に比べれば小さめなので気楽に楽しめそう。



昨夜、あいみょんのインスタライブがありましたね。ほんわかしました。
しかも昨日はまんげつだったんす。す。
ってことで、今回はこちらの曲を聞いてお別れです。

(せーのっ)

\\\ 満月の夜なら ///

DockerでUbuntu上にPython環境を作った備忘録

※こちらは2020.04.29時点での記事です。Githubのレポジトリなど、最新のものでは修正されている可能性があります。確認の上ご利用ください。

更新情報

優秀参考記事 ←Dockerfileの中身に非常に参考にしました

そもそも何がやりたかった?

Githubからcloneしてきたファイルを実行するための、それ専用のPython環境を作成したかった。さらに、その環境はWindows OSでもなくMac OSでもない、Ubuntu上に作成したかったのです。
今回対象としているのは、コチラのやつ。
以前論文内容を日本語に訳して記事にした、Feynmanの物理学に関するAI。

k-ptl.hatenablog.com

執筆時点(2020年4月29日 日本時間12時頃)で、cloneするとフォルダ構成は以下のとおり(この時点での最終commitは2020年4月26日)。なお、cloneは作成した/git-repos/ディレクトリ上に行う。

/git-repos
    |- /AI-Feynman
        |- Code
        |   |- ai_feynman_terminal_example.py
        |   |- ...
        |
        |- example_data
        |   |- example1.txt
        |   |- ...
        |
        |- LICENSE
        |- README.md
        |- requirements.txt

履歴なぐりメモ

作成から実行まで、やったことを全部メモに残す。 なかなかうまくいかなかったけれど、どうにか成功したので、、

githubのrepositoryのclone

~/git-repos% git clone https://github.com/SJ001/AI-Feynman.git
Cloning into 'AI-Feynman'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 193 (delta 6), reused 0 (delta 0), pack-reused 174
Receiving objects: 100% (193/193), 31.23 MiB | 1.96 MiB/s, done.
Resolving deltas: 100% (87/87), done.

cloneした後、requirements.txtを一部書き換える。

python >= 3.6
torch >= 1.4.0
matplotlib
sympy = 1.4
pandas
scipy
sortedcontainers

torch >= 1.4.0
matplotlib
sympy == 1.4
pandas
scipy
sortedcontainers

んで、カレントディレクトリをcloneしてきたディレクトリ内部に移動する。

~/git-repos% cd AI-Feynman

Dockerfile作成・編集

Dockerfileを/git-repos/AI-Feynmanに作成し、VSCodeで編集する。
terminal上でcodeと入力しVSCodeを開く設定はここを参考に、ドゾ

~/git-repos/AI-Feynman% touch Dockerfile
~/git-repos/AI-Feynman% code Dockerfile

Dockerfileの中には、以下のように書き込む。

FROM ubuntu:18.04
RUN apt-get -y update \
    && apt-get -y upgrade \
    && apt-get install -y locales curl python3-distutils \
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install -U pip \
    && mkdir /code \
    && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8
WORKDIR /code
ADD requirements.txt /code
RUN pip install -r requirements.txt    # requirements.txtからパッケージのインストール

この時点でのディレクトリ構成は、以下の通り。

/git-repos
    |- /AI-Feynman
        |- Code
        |   |- ai_feynman_terminal_example.py
        |   |- ...
        |
        |- example_data
        |   |- example1.txt
        |   |- ...
        |
        |- LICENSE
        |- README.md
        |- requirements.txt
        |- Dockerfile

Dockerfileのビルド

下記コマンドでビルドする。

~/git-repos/AI-Feynman% docker build -t ai-feynman .                  

すると、以下のようにドバドバッと出力が返ってくる。ここでは、

  • Ubuntu image fileのダウンロード
  • requirements.txtに記載されている各種ライブラリのpip install

が実行されている。

Show
\
Sending build context to Docker daemon  95.66MB  
Step 1/6 : FROM ubuntu:18.04  
18.04: Pulling from library/ubuntu  
23884877105a: Pull complete   
bc38caa0f5b9: Pull complete   
2910811b6c42: Pull complete   
36505266dcc6: Pull complete  
Digest: sha256:3235326357dfb65f1781dbc4df3b834546d8bf914e82cce58e6e6b676e23ce8f  
Status: Downloaded newer image for ubuntu:18.04  
 ---> c3c304cb4f22  
Step 2/6 : RUN apt-get -y update     && apt-get -y upgrade     && apt-get install -y locales curl python3-distutils     && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py     && python3 get-pip.py     && pip install -U pip     && mkdir /code     && rm -rf /var/lib/apt/lists/*     && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8  
 ---> Running in 82f23f173081  
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]  
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]  
Get:3 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [8213 B]  
Get:4 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [839 kB]  
Get:5 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]  
Get:6 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]  
Get:7 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [11.3 MB]  
Get:8 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [894 kB]  
Get:9 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [46.8 kB]  
Get:10 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB]  
Get:11 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [186 kB]  
Get:12 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB]  
Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1376 kB]  
Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [62.7 kB]  
Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [12.9 kB]  
Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [1200 kB]  
Get:17 http://archive.ubuntu.com/ubuntu bionic-backports/main amd64 Packages [8286 B]  
Get:18 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [7671 B]  
Fetched 17.8 MB in 19s (943 kB/s)  
Reading package lists...  
Reading package lists...  
Building dependency tree...  
Reading state information...  
Calculating upgrade...  
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.  
Reading package lists...  
Building dependency tree...  
Reading state information...  
The following additional packages will be installed:  
  ca-certificates file krb5-locales libasn1-8-heimdal libcurl4 libexpat1  
  libgssapi-krb5-2 libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal  
  libheimntlm0-heimdal libhx509-5-heimdal libk5crypto3 libkeyutils1  
  libkrb5-26-heimdal libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common  
  libmagic-mgc libmagic1 libmpdec2 libnghttp2-14 libpsl5 libpython3-stdlib  
  libpython3.6-minimal libpython3.6-stdlib libreadline7 libroken18-heimdal  
  librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libsqlite3-0  
  libssl1.1 libwind0-heimdal mime-support openssl publicsuffix python3  
  python3-lib2to3 python3-minimal python3.6 python3.6-minimal readline-common  
  xz-utils  
Suggested packages:  
  krb5-doc krb5-user libsasl2-modules-gssapi-mit  
  | libsasl2-modules-gssapi-heimdal libsasl2-modules-ldap libsasl2-modules-otp  
  libsasl2-modules-sql python3-doc python3-tk python3-venv python3.6-venv  
  python3.6-doc binutils binfmt-support readline-doc  
The following NEW packages will be installed:  
  ca-certificates curl file krb5-locales libasn1-8-heimdal libcurl4 libexpat1  
  libgssapi-krb5-2 libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal  
  libheimntlm0-heimdal libhx509-5-heimdal libk5crypto3 libkeyutils1  
  libkrb5-26-heimdal libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common  
  libmagic-mgc libmagic1 libmpdec2 libnghttp2-14 libpsl5 libpython3-stdlib  
  libpython3.6-minimal libpython3.6-stdlib libreadline7 libroken18-heimdal  
  librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libsqlite3-0  
  libssl1.1 libwind0-heimdal locales mime-support openssl publicsuffix python3  
  python3-distutils python3-lib2to3 python3-minimal python3.6  
  python3.6-minimal readline-common xz-utils  
0 upgraded, 49 newly installed, 0 to remove and 0 not upgraded.  
Need to get 13.5 MB of archives.  
After this operation, 61.2 MB of additional disk space will be used.  
Get:1 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libssl1.1 amd64 1.1.1-1ubuntu2.1~18.04.5 [1300 kB]  
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3.6-minimal amd64 3.6.9-1~18.04ubuntu1 [533 kB]  
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libexpat1 amd64 2.2.5-3ubuntu0.2 [80.5 kB]  
Get:4 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3.6-minimal amd64 3.6.9-1~18.04ubuntu1 [1609 kB]  
Get:5 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-minimal amd64 3.6.7-1~18.04 [23.7 kB]  
Get:6 http://archive.ubuntu.com/ubuntu bionic/main amd64 mime-support all 3.60ubuntu1 [30.1 kB]  
Get:7 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpdec2 amd64 2.4.2-1ubuntu1 [84.1 kB]  
Get:8 http://archive.ubuntu.com/ubuntu bionic/main amd64 readline-common all 7.0-3 [52.9 kB]  
Get:9 http://archive.ubuntu.com/ubuntu bionic/main amd64 libreadline7 amd64 7.0-3 [124 kB]  
Get:10 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsqlite3-0 amd64 3.22.0-1ubuntu0.3 [498 kB]  
Get:11 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3.6-stdlib amd64 3.6.9-1~18.04ubuntu1 [1710 kB]  
Get:12 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3.6 amd64 3.6.9-1~18.04ubuntu1 [203 kB]  
Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3-stdlib amd64 3.6.7-1~18.04 [7240 B]  
Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3 amd64 3.6.7-1~18.04 [47.2 kB]  
Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 openssl amd64 1.1.1-1ubuntu2.1~18.04.5 [613 kB]  
Get:16 http://archive.ubuntu.com/ubuntu bionic/main amd64 ca-certificates all 20180409 [151 kB]  
Get:17 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libmagic-mgc amd64 1:5.32-2ubuntu0.3 [184 kB]  
Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libmagic1 amd64 1:5.32-2ubuntu0.3 [68.7 kB]  
Get:19 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 file amd64 1:5.32-2ubuntu0.3 [22.1 kB]  
Get:20 http://archive.ubuntu.com/ubuntu bionic/main amd64 locales all 2.27-3ubuntu1 [3612 kB]  
Get:21 http://archive.ubuntu.com/ubuntu bionic/main amd64 xz-utils amd64 5.2.2-1.3 [83.8 kB]  
Get:22 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 krb5-locales all 1.16-2ubuntu0.1 [13.5 kB]  
Get:23 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libkrb5support0 amd64 1.16-2ubuntu0.1 [30.9 kB]  
Get:24 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libk5crypto3 amd64 1.16-2ubuntu0.1 [85.6 kB]  
Get:25 http://archive.ubuntu.com/ubuntu bionic/main amd64 libkeyutils1 amd64 1.5.9-9.2ubuntu2 [8720 B]  
Get:26 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libkrb5-3 amd64 1.16-2ubuntu0.1 [279 kB]  
Get:27 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libgssapi-krb5-2 amd64 1.16-2ubuntu0.1 [122 kB]  
Get:28 http://archive.ubuntu.com/ubuntu bionic/main amd64 libpsl5 amd64 0.19.1-5build1 [41.8 kB]  
Get:29 http://archive.ubuntu.com/ubuntu bionic/main amd64 publicsuffix all 20180223.1310-1 [97.6 kB]  
Get:30 http://archive.ubuntu.com/ubuntu bionic/main amd64 libroken18-heimdal amd64 7.5.0+dfsg-1 [41.3 kB]  
Get:31 http://archive.ubuntu.com/ubuntu bionic/main amd64 libasn1-8-heimdal amd64 7.5.0+dfsg-1 [175 kB]  
Get:32 http://archive.ubuntu.com/ubuntu bionic/main amd64 libheimbase1-heimdal amd64 7.5.0+dfsg-1 [29.3 kB]  
Get:33 http://archive.ubuntu.com/ubuntu bionic/main amd64 libhcrypto4-heimdal amd64 7.5.0+dfsg-1 [85.9 kB]  
Get:34 http://archive.ubuntu.com/ubuntu bionic/main amd64 libwind0-heimdal amd64 7.5.0+dfsg-1 [47.8 kB]  
Get:35 http://archive.ubuntu.com/ubuntu bionic/main amd64 libhx509-5-heimdal amd64 7.5.0+dfsg-1 [107 kB]  
Get:36 http://archive.ubuntu.com/ubuntu bionic/main amd64 libkrb5-26-heimdal amd64 7.5.0+dfsg-1 [206 kB]  
Get:37 http://archive.ubuntu.com/ubuntu bionic/main amd64 libheimntlm0-heimdal amd64 7.5.0+dfsg-1 [14.8 kB]  
Get:38 http://archive.ubuntu.com/ubuntu bionic/main amd64 libgssapi3-heimdal amd64 7.5.0+dfsg-1 [96.5 kB]  
Get:39 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsasl2-modules-db amd64 2.1.27~101-g0780600+dfsg-3ubuntu2.1 [14.8 kB]  
Get:40 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsasl2-2 amd64 2.1.27~101-g0780600+dfsg-3ubuntu2.1 [49.2 kB]  
Get:41 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libldap-common all 2.4.45+dfsg-1ubuntu1.4 [16.9 kB]  
Get:42 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libldap-2.4-2 amd64 2.4.45+dfsg-1ubuntu1.4 [155 kB]  
Get:43 http://archive.ubuntu.com/ubuntu bionic/main amd64 libnghttp2-14 amd64 1.30.0-1ubuntu1 [77.8 kB]  
Get:44 http://archive.ubuntu.com/ubuntu bionic/main amd64 librtmp1 amd64 2.4+20151223.gitfa8646d.1-1 [54.2 kB]  
Get:45 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libcurl4 amd64 7.58.0-2ubuntu3.8 [214 kB]  
Get:46 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 curl amd64 7.58.0-2ubuntu3.8 [159 kB]  
Get:47 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsasl2-modules amd64 2.1.27~101-g0780600+dfsg-3ubuntu2.1 [48.8 kB]  
Get:48 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-lib2to3 all 3.6.9-1~18.04 [77.4 kB]  
Get:49 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-distutils all 3.6.9-1~18.04 [144 kB]  
debconf: delaying package configuration, since apt-utils is not installed  
Fetched 13.5 MB in 10s (1348 kB/s)  
Selecting previously unselected package libssl1.1:amd64.  
(Reading database ... 4046 files and directories currently installed.)  
Preparing to unpack .../libssl1.1_1.1.1-1ubuntu2.1~18.04.5_amd64.deb ...  
Unpacking libssl1.1:amd64 (1.1.1-1ubuntu2.1~18.04.5) ...  
Selecting previously unselected package libpython3.6-minimal:amd64.  
Preparing to unpack .../libpython3.6-minimal_3.6.9-1~18.04ubuntu1_amd64.deb ...  
Unpacking libpython3.6-minimal:amd64 (3.6.9-1~18.04ubuntu1) ...  
Selecting previously unselected package libexpat1:amd64.  
Preparing to unpack .../libexpat1_2.2.5-3ubuntu0.2_amd64.deb ...  
Unpacking libexpat1:amd64 (2.2.5-3ubuntu0.2) ...  
Selecting previously unselected package python3.6-minimal.  
Preparing to unpack .../python3.6-minimal_3.6.9-1~18.04ubuntu1_amd64.deb ...  
Unpacking python3.6-minimal (3.6.9-1~18.04ubuntu1) ...  
Setting up libssl1.1:amd64 (1.1.1-1ubuntu2.1~18.04.5) ...  
debconf: unable to initialize frontend: Dialog  
debconf: (TERM is not set, so the dialog frontend is not usable.)  
debconf: falling back to frontend: Readline  
debconf: unable to initialize frontend: Readline  
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)  
debconf: falling back to frontend: Teletype  
Setting up libpython3.6-minimal:amd64 (3.6.9-1~18.04ubuntu1) ...  
Setting up libexpat1:amd64 (2.2.5-3ubuntu0.2) ...  
Setting up python3.6-minimal (3.6.9-1~18.04ubuntu1) ...  
Selecting previously unselected package python3-minimal.  
(Reading database ... 4303 files and directories currently installed.)  
Preparing to unpack .../0-python3-minimal_3.6.7-1~18.04_amd64.deb ...  
Unpacking python3-minimal (3.6.7-1~18.04) ...  
Selecting previously unselected package mime-support.  
Preparing to unpack .../1-mime-support_3.60ubuntu1_all.deb ...  
Unpacking mime-support (3.60ubuntu1) ...  
Selecting previously unselected package libmpdec2:amd64.  
Preparing to unpack .../2-libmpdec2_2.4.2-1ubuntu1_amd64.deb ...  
Unpacking libmpdec2:amd64 (2.4.2-1ubuntu1) ...  
Selecting previously unselected package readline-common.  
Preparing to unpack .../3-readline-common_7.0-3_all.deb ...  
Unpacking readline-common (7.0-3) ...  
Selecting previously unselected package libreadline7:amd64.  
Preparing to unpack .../4-libreadline7_7.0-3_amd64.deb ...  
Unpacking libreadline7:amd64 (7.0-3) ...  
Selecting previously unselected package libsqlite3-0:amd64.  
Preparing to unpack .../5-libsqlite3-0_3.22.0-1ubuntu0.3_amd64.deb ...  
Unpacking libsqlite3-0:amd64 (3.22.0-1ubuntu0.3) ...  
Selecting previously unselected package libpython3.6-stdlib:amd64.  
Preparing to unpack .../6-libpython3.6-stdlib_3.6.9-1~18.04ubuntu1_amd64.deb ...  
Unpacking libpython3.6-stdlib:amd64 (3.6.9-1~18.04ubuntu1) ...  
Selecting previously unselected package python3.6.  
Preparing to unpack .../7-python3.6_3.6.9-1~18.04ubuntu1_amd64.deb ...  
Unpacking python3.6 (3.6.9-1~18.04ubuntu1) ...  
Selecting previously unselected package libpython3-stdlib:amd64.  
Preparing to unpack .../8-libpython3-stdlib_3.6.7-1~18.04_amd64.deb ...  
Unpacking libpython3-stdlib:amd64 (3.6.7-1~18.04) ...  
Setting up python3-minimal (3.6.7-1~18.04) ...  
Selecting previously unselected package python3.  
(Reading database ... 4761 files and directories currently installed.)  
Preparing to unpack .../00-python3_3.6.7-1~18.04_amd64.deb ...  
Unpacking python3 (3.6.7-1~18.04) ...  
Selecting previously unselected package openssl.  
Preparing to unpack .../01-openssl_1.1.1-1ubuntu2.1~18.04.5_amd64.deb ...  
Unpacking openssl (1.1.1-1ubuntu2.1~18.04.5) ...  
Selecting previously unselected package ca-certificates.  
Preparing to unpack .../02-ca-certificates_20180409_all.deb ...  
Unpacking ca-certificates (20180409) ...  
Selecting previously unselected package libmagic-mgc.  
Preparing to unpack .../03-libmagic-mgc_1%3a5.32-2ubuntu0.3_amd64.deb ...  
Unpacking libmagic-mgc (1:5.32-2ubuntu0.3) ...  
Selecting previously unselected package libmagic1:amd64.  
Preparing to unpack .../04-libmagic1_1%3a5.32-2ubuntu0.3_amd64.deb ...  
Unpacking libmagic1:amd64 (1:5.32-2ubuntu0.3) ...  
Selecting previously unselected package file.  
Preparing to unpack .../05-file_1%3a5.32-2ubuntu0.3_amd64.deb ...  
Unpacking file (1:5.32-2ubuntu0.3) ...  
Selecting previously unselected package locales.  
Preparing to unpack .../06-locales_2.27-3ubuntu1_all.deb ...  
Unpacking locales (2.27-3ubuntu1) ...  
Selecting previously unselected package xz-utils.  
Preparing to unpack .../07-xz-utils_5.2.2-1.3_amd64.deb ...  
Unpacking xz-utils (5.2.2-1.3) ...  
Selecting previously unselected package krb5-locales.  
Preparing to unpack .../08-krb5-locales_1.16-2ubuntu0.1_all.deb ...
Unpacking krb5-locales (1.16-2ubuntu0.1) ...
Selecting previously unselected package libkrb5support0:amd64.
Preparing to unpack .../09-libkrb5support0_1.16-2ubuntu0.1_amd64.deb ...
Unpacking libkrb5support0:amd64 (1.16-2ubuntu0.1) ...
Selecting previously unselected package libk5crypto3:amd64.
Preparing to unpack .../10-libk5crypto3_1.16-2ubuntu0.1_amd64.deb ...
Unpacking libk5crypto3:amd64 (1.16-2ubuntu0.1) ...
Selecting previously unselected package libkeyutils1:amd64.
Preparing to unpack .../11-libkeyutils1_1.5.9-9.2ubuntu2_amd64.deb ...
Unpacking libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...
Selecting previously unselected package libkrb5-3:amd64.
Preparing to unpack .../12-libkrb5-3_1.16-2ubuntu0.1_amd64.deb ...
Unpacking libkrb5-3:amd64 (1.16-2ubuntu0.1) ...
Selecting previously unselected package libgssapi-krb5-2:amd64.
Preparing to unpack .../13-libgssapi-krb5-2_1.16-2ubuntu0.1_amd64.deb ...
Unpacking libgssapi-krb5-2:amd64 (1.16-2ubuntu0.1) ...
Selecting previously unselected package libpsl5:amd64.
Preparing to unpack .../14-libpsl5_0.19.1-5build1_amd64.deb ...
Unpacking libpsl5:amd64 (0.19.1-5build1) ...
Selecting previously unselected package publicsuffix.
Preparing to unpack .../15-publicsuffix_20180223.1310-1_all.deb ...
Unpacking publicsuffix (20180223.1310-1) ...
Selecting previously unselected package libroken18-heimdal:amd64.
Preparing to unpack .../16-libroken18-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libroken18-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libasn1-8-heimdal:amd64.
Preparing to unpack .../17-libasn1-8-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libasn1-8-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libheimbase1-heimdal:amd64.
Preparing to unpack .../18-libheimbase1-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libheimbase1-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libhcrypto4-heimdal:amd64.
Preparing to unpack .../19-libhcrypto4-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libhcrypto4-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libwind0-heimdal:amd64.
Preparing to unpack .../20-libwind0-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libwind0-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libhx509-5-heimdal:amd64.
Preparing to unpack .../21-libhx509-5-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libhx509-5-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libkrb5-26-heimdal:amd64.
Preparing to unpack .../22-libkrb5-26-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libkrb5-26-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libheimntlm0-heimdal:amd64.
Preparing to unpack .../23-libheimntlm0-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libheimntlm0-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libgssapi3-heimdal:amd64.
Preparing to unpack .../24-libgssapi3-heimdal_7.5.0+dfsg-1_amd64.deb ...
Unpacking libgssapi3-heimdal:amd64 (7.5.0+dfsg-1) ...
Selecting previously unselected package libsasl2-modules-db:amd64.
Preparing to unpack .../25-libsasl2-modules-db_2.1.27~101-g0780600+dfsg-3ubuntu2.1_amd64.deb ...
Unpacking libsasl2-modules-db:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Selecting previously unselected package libsasl2-2:amd64.
Preparing to unpack .../26-libsasl2-2_2.1.27~101-g0780600+dfsg-3ubuntu2.1_amd64.deb ...
Unpacking libsasl2-2:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Selecting previously unselected package libldap-common.
Preparing to unpack .../27-libldap-common_2.4.45+dfsg-1ubuntu1.4_all.deb ...
Unpacking libldap-common (2.4.45+dfsg-1ubuntu1.4) ...
Selecting previously unselected package libldap-2.4-2:amd64.
Preparing to unpack .../28-libldap-2.4-2_2.4.45+dfsg-1ubuntu1.4_amd64.deb ...
Unpacking libldap-2.4-2:amd64 (2.4.45+dfsg-1ubuntu1.4) ...
Selecting previously unselected package libnghttp2-14:amd64.
Preparing to unpack .../29-libnghttp2-14_1.30.0-1ubuntu1_amd64.deb ...
Unpacking libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...
Selecting previously unselected package librtmp1:amd64.
Preparing to unpack .../30-librtmp1_2.4+20151223.gitfa8646d.1-1_amd64.deb ...
Unpacking librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...
Selecting previously unselected package libcurl4:amd64.
Preparing to unpack .../31-libcurl4_7.58.0-2ubuntu3.8_amd64.deb ...
Unpacking libcurl4:amd64 (7.58.0-2ubuntu3.8) ...
Selecting previously unselected package curl.
Preparing to unpack .../32-curl_7.58.0-2ubuntu3.8_amd64.deb ...
Unpacking curl (7.58.0-2ubuntu3.8) ...
Selecting previously unselected package libsasl2-modules:amd64.
Preparing to unpack .../33-libsasl2-modules_2.1.27~101-g0780600+dfsg-3ubuntu2.1_amd64.deb ...
Unpacking libsasl2-modules:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Selecting previously unselected package python3-lib2to3.
Preparing to unpack .../34-python3-lib2to3_3.6.9-1~18.04_all.deb ...
Unpacking python3-lib2to3 (3.6.9-1~18.04) ...
Selecting previously unselected package python3-distutils.
Preparing to unpack .../35-python3-distutils_3.6.9-1~18.04_all.deb ...
Unpacking python3-distutils (3.6.9-1~18.04) ...
Setting up readline-common (7.0-3) ...
Setting up libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...
Setting up mime-support (3.60ubuntu1) ...
Setting up libldap-common (2.4.45+dfsg-1ubuntu1.4) ...
Setting up libreadline7:amd64 (7.0-3) ...
Setting up libpsl5:amd64 (0.19.1-5build1) ...
Setting up libsasl2-modules-db:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Setting up libsasl2-2:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Setting up libroken18-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...
Setting up libkrb5support0:amd64 (1.16-2ubuntu0.1) ...
Setting up libmagic-mgc (1:5.32-2ubuntu0.3) ...
Setting up libmagic1:amd64 (1:5.32-2ubuntu0.3) ...
Setting up krb5-locales (1.16-2ubuntu0.1) ...
Setting up publicsuffix (20180223.1310-1) ...
Setting up xz-utils (5.2.2-1.3) ...
update-alternatives: using /usr/bin/xz to provide /usr/bin/lzma (lzma) in auto mode
update-alternatives: warning: skip creation of /usr/share/man/man1/lzma.1.gz because associated file /usr/share/man/man1/xz.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/unlzma.1.gz because associated file /usr/share/man/man1/unxz.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzcat.1.gz because associated file /usr/share/man/man1/xzcat.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzmore.1.gz because associated file /usr/share/man/man1/xzmore.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzless.1.gz because associated file /usr/share/man/man1/xzless.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzdiff.1.gz because associated file /usr/share/man/man1/xzdiff.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzcmp.1.gz because associated file /usr/share/man/man1/xzcmp.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzgrep.1.gz because associated file /usr/share/man/man1/xzgrep.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzegrep.1.gz because associated file /usr/share/man/man1/xzegrep.1.gz (of link group lzma) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/lzfgrep.1.gz because associated file /usr/share/man/man1/xzfgrep.1.gz (of link group lzma) doesn't exist
Setting up libheimbase1-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up openssl (1.1.1-1ubuntu2.1~18.04.5) ...
Setting up libsqlite3-0:amd64 (3.22.0-1ubuntu0.3) ...
Setting up libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...
Setting up libsasl2-modules:amd64 (2.1.27~101-g0780600+dfsg-3ubuntu2.1) ...
Setting up ca-certificates (20180409) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype
Updating certificates in /etc/ssl/certs...
133 added, 0 removed; done.
Setting up locales (2.27-3ubuntu1) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype
Generating locales (this might take a while)...
Generation complete.
Setting up libmpdec2:amd64 (2.4.2-1ubuntu1) ...
Setting up libpython3.6-stdlib:amd64 (3.6.9-1~18.04ubuntu1) ...
Setting up libk5crypto3:amd64 (1.16-2ubuntu0.1) ...
Setting up python3.6 (3.6.9-1~18.04ubuntu1) ...
Setting up libwind0-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up libasn1-8-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up libhcrypto4-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up file (1:5.32-2ubuntu0.3) ...
Setting up libhx509-5-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up libkrb5-3:amd64 (1.16-2ubuntu0.1) ...
Setting up libkrb5-26-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up libheimntlm0-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up libpython3-stdlib:amd64 (3.6.7-1~18.04) ...
Setting up python3 (3.6.7-1~18.04) ...
running python rtupdate hooks for python3.6...
running python post-rtupdate hooks for python3.6...
Setting up libgssapi-krb5-2:amd64 (1.16-2ubuntu0.1) ...
Setting up libgssapi3-heimdal:amd64 (7.5.0+dfsg-1) ...
Setting up python3-lib2to3 (3.6.9-1~18.04) ...
Setting up python3-distutils (3.6.9-1~18.04) ...
Setting up libldap-2.4-2:amd64 (2.4.45+dfsg-1ubuntu1.4) ...
Setting up libcurl4:amd64 (7.58.0-2ubuntu3.8) ...
Setting up curl (7.58.0-2ubuntu3.8) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Processing triggers for ca-certificates (20180409) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1824k  100 1824k    0     0   914k      0  0:00:01  0:00:01 --:--:--  914k
Collecting pip
  Downloading pip-20.1-py2.py3-none-any.whl (1.5 MB)
Collecting setuptools
  Downloading setuptools-46.1.3-py3-none-any.whl (582 kB)
Collecting wheel
  Downloading wheel-0.34.2-py2.py3-none-any.whl (26 kB)
Installing collected packages: pip, setuptools, wheel
Successfully installed pip-20.1 setuptools-46.1.3 wheel-0.34.2
Requirement already up-to-date: pip in /usr/local/lib/python3.6/dist-packages (20.1)
Removing intermediate container 82f23f173081
 ---> e282835b1748
Step 3/6 : ENV LANG en_US.utf8
 ---> Running in aca68ea617c0
Removing intermediate container aca68ea617c0
 ---> 5312955af5cf
Step 4/6 : WORKDIR /code
 ---> Running in 85cb0e9e06ca
Removing intermediate container 85cb0e9e06ca
 ---> be234371a5f9
Step 5/6 : ADD requirements.txt /code
 ---> 948c5c74175b
Step 6/6 : RUN pip install -r requirements.txt    # requirements.txtからパッケージのインストール
 ---> Running in ee2120e31bb6
Collecting torch>=1.4.0
  Downloading torch-1.5.0-cp36-cp36m-manylinux1_x86_64.whl (752.0 MB)
Collecting matplotlib
  Downloading matplotlib-3.2.1-cp36-cp36m-manylinux1_x86_64.whl (12.4 MB)
Collecting sympy==1.4
  Downloading sympy-1.4-py2.py3-none-any.whl (5.3 MB)
Collecting pandas
  Downloading pandas-1.0.3-cp36-cp36m-manylinux1_x86_64.whl (10.0 MB)
Collecting scipy
  Downloading scipy-1.4.1-cp36-cp36m-manylinux1_x86_64.whl (26.1 MB)
Collecting sortedcontainers
  Downloading sortedcontainers-2.1.0-py2.py3-none-any.whl (28 kB)
Collecting numpy
  Downloading numpy-1.18.3-cp36-cp36m-manylinux1_x86_64.whl (20.2 MB)
Collecting future
  Downloading future-0.18.2.tar.gz (829 kB)
Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1
  Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Collecting cycler>=0.10
  Downloading cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)
Collecting kiwisolver>=1.0.1
  Downloading kiwisolver-1.2.0-cp36-cp36m-manylinux1_x86_64.whl (88 kB)
Collecting python-dateutil>=2.1
  Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting mpmath>=0.19
  Downloading mpmath-1.1.0.tar.gz (512 kB)
Collecting pytz>=2017.2
  Downloading pytz-2020.1-py2.py3-none-any.whl (510 kB)
Collecting six
  Downloading six-1.14.0-py2.py3-none-any.whl (10 kB)
Building wheels for collected packages: future, mpmath
  Building wheel for future (setup.py): started
  Building wheel for future (setup.py): finished with status 'done'
  Created wheel for future: filename=future-0.18.2-py3-none-any.whl size=491058 sha256=6aae3371cbd21ca84a0729b747cd0ae6c815bac5b81ed8a19685177e9c8aeb72
  Stored in directory: /root/.cache/pip/wheels/6e/9c/ed/4499c9865ac1002697793e0ae05ba6be33553d098f3347fb94
  Building wheel for mpmath (setup.py): started
  Building wheel for mpmath (setup.py): finished with status 'done'
  Created wheel for mpmath: filename=mpmath-1.1.0-py3-none-any.whl size=532239 sha256=bffa3787e5ec47483396a0b915b7b8a1e01cd56fec79b02fdd38bba572697669
  Stored in directory: /root/.cache/pip/wheels/e8/38/69/aa17553ad31f09ff5fa44c8a1a6c5b47e7c9261e9c7c16b9fb
Successfully built future mpmath
Installing collected packages: numpy, future, torch, pyparsing, six, cycler, kiwisolver, python-dateutil, matplotlib, mpmath, sympy, pytz, pandas, scipy, sortedcontainers
Successfully installed cycler-0.10.0 future-0.18.2 kiwisolver-1.2.0 matplotlib-3.2.1 mpmath-1.1.0 numpy-1.18.3 pandas-1.0.3 pyparsing-2.4.7 python-dateutil-2.8.1 pytz-2020.1 scipy-1.4.1 six-1.14.0 sortedcontainers-2.1.0 sympy-1.4 torch-1.5.0
Removing intermediate container ee2120e31bb6
 ---> 83a20b651a69
Successfully built 83a20b651a69
Successfully tagged ai-feynman:latest

imageの確認

さて、これでビルドが完了した。作成されたイメージを見てみよう。

~/git-repos/AI-Feynman% docker images    (git)-[master]
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ai-feynman          latest              83a20b651a69        38 minutes ago      2.68GB
ubuntu              18.04               c3c304cb4f22        5 days ago          64.2MB
python              3.6                 b63ef4ef530f        5 days ago          914MB

うむ、くるしゅうない。
もしnoneになっていたりしたら、Dockerファイルを見直しましょう(Dockerファイルの記述方法に関しては、他の記事に譲ります)。

containerの作成

imageファイルが無事作成できていることを確認したら、それを使用してcontainerを作成する。

~/git-repos/AI-Feynman% docker run -it -v /~full path to/git-repos/AI-Feynman:/code --name test ai-feynman:latest /bin/bash

ここで、もしも

docker: Error response from daemon: Mounts denied: 
The path /git-repos/AI-Feynman
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

といったエラーが出力された場合、dockerのファイルシェアリングに関して設定をする必要がある。その設定方法は、こちらを参考にされたい。

 上のターミナルでのコマンドについて、Dockerfile内でWORKDIRに設定した/codeと、PC上の操作したいディレクト/ ~full path to~ /git-repos/AI-Feynmanを繋ぐために、-vで設定している。また、--name test ai-feynmanでは、ai-feynmanというimageを使用してtestというcontainerを作成しており、最後の/bin/bashではcontainer作成後、そのままbashシェルを起動した状態にする(コンテナから出ない、コンテナ内で作業ができる状態)。

コンテナに入った状態で、ls -aと打つとコンテナ内(WORKDIRに設定した/code内)の全ファイル一覧を取得できる。さらに、python3.6.9が入っていることも確認できた。

root@244227505b95:/code# ls -a
.   ..   Code   Dockerfile   example_data   .git   LICENSE   README.md   requirements.txt
root@244227505b95:/code# python3 --version
Python 3.6.9

コンテナの扱い(出入り)について

コンテナは、docker ps -aとコマンドを入力することでその状態を確認することができる。

~/git-repos/AI-Feynman
% docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
2948d035556b        ai-feynman:latest   "/bin/bash"         22 seconds ago      Exited (127) 5 seconds ago                       test1
244227505b95        ai-feynman:latest   "/bin/bash"         10 minutes ago      Up 10 minutes                                    test

ここに見られるように、STATUSという項目があり、

  • STATUS = Up ... コンテナ起動中
  • STATUS = Exited ... コンテナ停止中

である。これらの操作に関して、メモがてら残す。

containerを作成したいとき

先ほどと同様に

docker run -it -v ~~:~~ --name xxxx IMAGE [command]

と入力すると、IMAGEを元にしたxxxxという名前のコンテナを作成し、そのコンテナに入った状態(ログイン状態)になる。さらに、[command]を入力することで、そのまま何かしらの処理を実行することができる。

コンテナから一時的に出たい時(コンテナは止めない;STATUS=Up)

コンテナを起動させた状態で、ログイン状態を抜けるには、特別コマンドを使用しない。

[control] + P -> [control] + Q

で抜けることができる。この時、STATUS=Upのままである。
なお、この動作を「デタッチ dettach」という。

STATUS=Upのコンテナに入る

STATUS=Upを維持した状態でログイン状態から抜けることをdettachと呼んだが、ここではその逆;attachする。以下のコマンド。

docker attach <CONTAINER ID or NAME>

ログイン状態で、コンテナを停止させて抜ける;STATUS=Exit

以下のコマンド。ログイン状態が解除されるだけでなく、コンテナが停止するため、処理も停止することに注意。

exit

ログアウト状態で、コンテナを起動させる;STATUS=Exited->Up

docker start <CONTAINER ID or NAME>

ログアウト状態で、コンテナを停止させる;STATUS=Up->Exited

docker stop <CONTAINER ID or NAME>

起動しているコンテナにログインする

予め、startでコンテナを起動しておくか、dettachすることで起動した状態であることが条件。以下のコマンド。

docker exec -it <CONTAINER ID or NAME> /bin/bash

サンプルプログラムの実行

README.md内で、GitHubからcloneしたこのレポジトリを使用するためには以下のコマンドをターミナル上で入力することで可能であるとのこと。

python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt

scikit learnがない

やってみたところ、errorが。

root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
Traceback (most recent call last):
  File "ai_feynman_terminal_example.py", line 2, in <module>
    from S_run_aifeynman import run_aifeynman
  File "/code/Code/S_run_aifeynman.py", line 6, in <module>
    from RPN_to_pytorch import RPN_to_pytorch
  File "/code/Code/RPN_to_pytorch.py", line 12, in <module>
    from sklearn.metrics import roc_curve, auc
ModuleNotFoundError: No module named 'sklearn'

、、、、requirementsに書いてなかったやんけコンテナ内で、scikit learnをインストールする。

root@244227505b95:/code/Code# pip install sklearn
Collecting sklearn
  Downloading sklearn-0.0.tar.gz (1.1 kB)
Collecting scikit-learn
  Downloading scikit_learn-0.22.2.post1-cp36-cp36m-manylinux1_x86_64.whl (7.1 MB)
     |████████████████████████████████| 7.1 MB 2.0 MB/s 
Requirement already satisfied: scipy>=0.17.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn->sklearn) (1.4.1)
Collecting joblib>=0.11
  Downloading joblib-0.14.1-py2.py3-none-any.whl (294 kB)
     |████████████████████████████████| 294 kB 1.6 MB/s 
Requirement already satisfied: numpy>=1.11.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn->sklearn) (1.18.3)
Building wheels for collected packages: sklearn
  Building wheel for sklearn (setup.py) ... done
  Created wheel for sklearn: filename=sklearn-0.0-py2.py3-none-any.whl size=1315 sha256=0626703174a4bb8db6dca7865c9c86f20ff744c1c0fa3c42076ebf653d82959a
  Stored in directory: /root/.cache/pip/wheels/23/9d/42/5ec745cbbb17517000a53cecc49d6a865450d1f5cb16dc8a9c
Successfully built sklearn
Installing collected packages: joblib, scikit-learn, sklearn
Successfully installed joblib-0.14.1 scikit-learn-0.22.2.post1 sklearn-0.0

seabornがない

さて、気を取り直して。

root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
Traceback (most recent call last):
  File "ai_feynman_terminal_example.py", line 2, in <module>
    from S_run_aifeynman import run_aifeynman
  File "/code/Code/S_run_aifeynman.py", line 6, in <module>
    from RPN_to_pytorch import RPN_to_pytorch
  File "/code/Code/RPN_to_pytorch.py", line 15, in <module>
    import seaborn as sns
ModuleNotFoundError: No module named 'seaborn'

、、、、、、、、、、、、、(複雑な感情)seabornをインストールするよ。

root@244227505b95:/code/Code# pip install seaborn
Collecting seaborn
  Downloading seaborn-0.10.1-py3-none-any.whl (215 kB)
     |████████████████████████████████| 215 kB 487 kB/s 
Requirement already satisfied: pandas>=0.22.0 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.0.3)
Requirement already satisfied: numpy>=1.13.3 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.18.3)
Requirement already satisfied: scipy>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.4.1)
Requirement already satisfied: matplotlib>=2.1.2 in /usr/local/lib/python3.6/dist-packages (from seaborn) (3.2.1)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->seaborn) (2020.1)
Requirement already satisfied: python-dateutil>=2.6.1 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->seaborn) (2.8.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (1.2.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (2.4.7)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (0.10.0)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.6/dist-packages (from python-dateutil>=2.6.1->pandas>=0.22.0->seaborn) (1.14.0)
Installing collected packages: seaborn
Successfully installed seaborn-0.10.1

torch visionがない

さて。めげない。

root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
Traceback (most recent call last):
  File "ai_feynman_terminal_example.py", line 2, in <module>
    from S_run_aifeynman import run_aifeynman
  File "/code/Code/S_run_aifeynman.py", line 8, in <module>
    from S_NN_train import NN_train
  File "/code/Code/S_NN_train.py", line 6, in <module>
    from torchvision import datasets, transforms
ModuleNotFoundError: No module named 'torchvision'

、、、、めげぬ。

root@244227505b95:/code/Code# pip install torchvision
Collecting torchvision
  Downloading torchvision-0.6.0-cp36-cp36m-manylinux1_x86_64.whl (6.6 MB)
     |████████████████████████████████| 6.6 MB 1.3 MB/s 
Requirement already satisfied: torch==1.5.0 in /usr/local/lib/python3.6/dist-packages (from torchvision) (1.5.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from torchvision) (1.18.3)
Collecting pillow>=4.1.1
  Downloading Pillow-7.1.2-cp36-cp36m-manylinux1_x86_64.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 1.2 MB/s 
Requirement already satisfied: future in /usr/local/lib/python3.6/dist-packages (from torch==1.5.0->torchvision) (0.18.2)
Installing collected packages: pillow, torchvision
Successfully installed pillow-7.1.2 torchvision-0.6.0

最終的に

※2020年4月29日日本時間12時頃の情報です。現在とは動作が異なることがあるでしょう。本稿はDocker環境構築がメインディッシュであるため、ここを最新版に反映させてはおりませんのでご容赦ください。

root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
Checking for brute force + 

Traceback (most recent call last):
  File "ai_feynman_terminal_example.py", line 18, in <module>
    NN_epochs=opts.NN_epochs, vars_name=opts.vars_name, test_percentage=opts.test_percentage)
  File "/code/Code/S_run_aifeynman.py", line 164, in run_aifeynman
    PA = run_AI_all(pathdir,filename+"_train",BF_try_time,BF_ops_file_type, polyfit_deg, NN_epochs)
  File "/code/Code/S_run_aifeynman.py", line 39, in run_AI_all
    PA = run_bf_polyfit(pathdir,pathdir,filename,BF_try_time,BF_ops_file_type, PA, polyfit_deg)
  File "/code/Code/S_run_bf_polyfit.py", line 27, in run_bf_polyfit
    brute_force(pathdir_transformed,filename,BF_try_time,BF_ops_file_type,"+")
  File "/code/Code/S_brute_force.py", line 27, in brute_force
    subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename])
  File "/usr/lib/python3.6/subprocess.py", line 287, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
PermissionError: [Errno 13] Permission denied: './brute_force_oneFile_v3.scr'

はい、これはもうプログラム上の問題でございます。
ちなみに、このエラーはS_brute_force.pyに以下のように追記することで回避可能なエラーであることを知っていますボクは。自分で見つけたの、エライ(ちゃんとGithubでも報告します)

def brute_force(pathdir,filename,BF_try_time,BF_ops_file_type,sep_type="*"):
    try_time = BF_try_time
    try_time_prefactor = BF_try_time
    file_type = BF_ops_file_type
    try:
        os.remove("results.dat")
    except:
        pass
    if sep_type=="*":
-        subprocess.call(["./brute_force_oneFile_v2.scr", file_type, "%s" %try_time, pathdir+filename])
+        subprocess.call(["./brute_force_oneFile_v2.scr", file_type, "%s" %try_time, pathdir+filename], shell=True)
    if sep_type=="+":
-        subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename])
+        subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename], shell=True)

    return 1

でも、まだdenyされる。前のversionではこれで突破できたのだけれど、、他の部分もコード変わっているのかな、、

root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
Checking for brute force + 

14ops.txt: 1: 14ops.txt: ./brute_force_oneFile_v3.scr: Permission denied
Checking for brute force * 

14ops.txt: 1: 14ops.txt: ./brute_force_oneFile_v2.scr: Permission denied
Checking polyfit 

(2020.04.30追記)requirements.txtの出力

 massoさん(Twitter: @masso)から、container内で新たにライブラリを追加したのち、その一覧をrequirements.txtとして出力する方法をご教授いただいたのでそれをメモ。

pip freezeで、インストールされているライブラリの一覧を取得することができる。

root@244227505b95:/code# pip freeze
cycler==0.10.0
future==0.18.2
joblib==0.14.1
kiwisolver==1.2.0
matplotlib==3.2.1
mpmath==1.1.0
numpy==1.18.3
pandas==1.0.3
Pillow==7.1.2
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
scikit-learn==0.22.2.post1
scipy==1.4.1
seaborn==0.10.1
six==1.14.0
sklearn==0.0
sortedcontainers==2.1.0
sympy==1.4
torch==1.5.0
torchvision==0.6.0

そして、これをrequirements.txtとして出力するためには以下のコードを走らせるだけで良い。

root@244227505b95:/code# pip freeze > requirements.txt

実際に出力されたrequirements.txtがこちらである。

cycler==0.10.0
future==0.18.2
joblib==0.14.1
kiwisolver==1.2.0
matplotlib==3.2.1
mpmath==1.1.0
numpy==1.18.3
pandas==1.0.3
Pillow==7.1.2
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
scikit-learn==0.22.2.post1
scipy==1.4.1
seaborn==0.10.1
six==1.14.0
sklearn==0.0
sortedcontainers==2.1.0
sympy==1.4
torch==1.5.0
torchvision==0.6.0

これで、今回作成したcontainerの環境を再現することが可能となる。

その他のよく使うdockerコマンド

imageファイルを削除したい

docker rmi <IMAGE ID or NAME>

containerを削除したい

docker rm <CONTAINER ID or NAME>

使用していないimage/containerを一括削除したい

docker system prune -a

未使用のものは全部消える。個別にしたいときは、

docker container prune -f
docker volume prune -f
docker network prune -f
docker image prune -f

終わりに

Dockerを使用したいときに、ボクの思っている使い方(やり方)を説明してくれているブログや記事がなかったため、ずっとうまく構築できていなかった。ようやく実行できる環境を構築できてハッピーなので、備忘録にした。
OSの問題だと思っていたけれど、WindowsでもMacでもUbuntuでもできないならやっぱりコードの問題。issue報告しつつ、AI-Feynmanが使える日が来ることを祈ろう。



昨夜はYouTubeで[Alexandros]のVipParty2018が放送された。
[C]の頃から好きだった、久しぶりに聞いたので余韻がすごい。

ってことで、今回はこちらの曲を。

(せーのっ)

\\\ 言 え ///

AI-Feynman: A physics-inspired method for symbolic regression(日本語訳)

はじめに

 本記事は、2020年4月15日にScienceAdvancesより出版された、MITのSilviu-Marian UdrescuとMax Tegmarkによる論文"AI Feynman: A physics-inspired method for symbolic regression"の日本語訳である。この論文は、インターネット上で公開されているうえに、pythonで記述されたプログラムがGithub上で公開されている。なお、この論文は2019年にも出版されているが、内容に大差はないため、本記事では2020年のものを対象にする。
 このGithubで公開されているサンプルプログラムを実行しようとしたところ、うまく動作しなかった。そこで、備忘録がてらに元論文を翻訳することにした。AI-Feynmanの使用感も、うまく使えた時に記事化する予定。

本文翻訳に際して

 まず、本論文を翻訳するに際して、事前にお断りさせていただきたいこととして、この分野の論文に触れる機会が滅多にないため、単語を適切に翻訳できていない可能性がある、ということ。よって、一部単語について、以下のルールで翻訳する。

  • mystery ... mystery equationなど、イマイチどの日本語がピッタリハマるのかが不明だったため、mystery方程式、などといったようにそのままmysteryを使用します(探索対象となる方程式やデータセットに対して使用されているため、ベールに包まれているもの、これから正体が明らかになるもの、といったような意味合いでのmysteryという単語の採用かと推測しますが、、真実は如何に、、)
  • symbolic regression ... 直訳すると記号回帰、ここでは関数同定(問題)という訳を採用

Abstruct

 物理学と人工知能(AI)の核心的な課題は、未知の関数からデータと一致する記号式を見つけるという関数同定問題である。この問題は、原理的にはNP困難であると思われるが、実用的に関心のある関数は、しばしば対称性、分離可能性、構成性、および他の単純化された特性を示す。この精神に基づき、我々はニューラルネットワークのフィッティングと物理学からヒントを得た一連の技術を組み合わせた再帰的な多次元関数同定アルゴリズムを開発した。我々はそれをファインマン物理学講義からの100の方程式に適用したところ、以前に公開されていたソフトウェアが71しか解けなかったのに対し、すべての方程式を発見することができた。

Introduction

 1601年、ヨハネス・ケプラーは惑星軌道に関する世界最高のデータ表を手に入れ、火星のデータを様々な楕円形に適合させようと4年と約40回の試みに失敗した後、火星の軌道が楕円であることを発見して科学革命を起こした ^{[1]}。これは、与えられたデータセットと正確に一致する記号的な仮定を発見する、という関数同定問題 (symbolic regression; 記号回帰とも呼ばれる) の例である。より具体的には、我々には \{x_1, ...., x_n, y \} という形式の数字の表が与えられ、その行は \{x_1, ...., x_n, y \}という形式であり、我々の課題は、任意の複雑なノイズを含有する、未知のmystery関数 fの正しい記号式を発見することである。
 データセットの増加に伴い、このような回帰タスクを自動化しようとする試みが活発化し、顕著な成功を収めている。未知の関数 f\{x_1, ...., x_n \}の既知の関数の線形結合であるという特殊なケースでは、記号回帰は単に一次方程式の系を解くだけで済む。線形回帰( fが単にアフィン関数である場合)は、金融から心理学まで、科学文献(論文)のどこにでもある(ユビキタスである)。 f \{x_1, ...., x_n \}の単項式の線形結合である場合は、相互作用項を持つ線形回帰や、より一般的な多項式フィットに対応する。フーリエ展開からウェーブレット変換まで、既知の関数の線形結合である一般的な回帰関数の例は、他にも数え切れないほどある。このような特殊なケースでの成功にもかかわらず、一般的な関数同定問題は未解決のままであるが、その理由は簡単に理解できる。関数を記号の文字列として符号化すると、そのような文字列の数は文字列の長さに応じて指数関数的に増加するためである。

 指数関数的に大きな探索空間の組合せ問題は、コードブレーキングやルービックキューブから、進化的に最も適合する遺伝子コードを見つける自然淘汰問題に至るまで、多くの有名な問題を特徴づけている。このことが、指数関数的に大きな空間での標的検索のための遺伝的アルゴリズム ^{[2,3]}の動機付けとなっている。このアルゴリズムは、上述のブルートフォース検索を突然変異、選択、継承、組換え(ざっくり言うと、遺伝子の役割は、求められている式やプログラムの一部を形成しているかもしれない有用な記号文字列によって決まっている)などの生物学にインスパイアされた戦略に置き換える。このようなアルゴリズムは、アンテナ ^{[4,5]}や車両 ^{[6]}の設計から、ワイヤレスルーティング ^{[7]}、車両ルーティング ^{[8]}、ロボットナビゲーション ^{[9]}、コードブレーキング ^{[10]}偏微分方程式の発見 ^{[11]}、投資戦略 ^{[12]}マーケティング ^{[13]}、分類 ^{[14]}ルービックキューブ ^{[15]}、プログラム合成 ^{[16]}代謝ネットワーク ^{[17]}に至るまで、様々な分野に応用されてきた。

 数学関数の関数同定問題(この論文の焦点)は、スパース回帰 ^{[21-24]}遺伝的アルゴリズム ^{[25,26]}など、さまざまな手法 ^{[18-20]}で取り組まれてきた。これらの中で最も成功しているのは、結果で見るように、 ^{[27]}で概説した遺伝的アルゴリズムであり、商用のEureqaソフトウェア ^{[26]}に実装されている。
 この論文の目的は、ニューラルネットワークによって可能になった物理学にインスパイアされた戦略を使用して、この技術の状態をさらに向上させることである。我々の最も重要な貢献は、ニューラルネットワークを使用して、mysteryデータの対称性や分離可能性などの隠れた単純さをカバーすることであり、これにより、より困難な問題をより少ない変数でより単純な問題に再帰的に分解することができる。
 本論文の残りの部分は以下のように構成されている。

  • Results : 最先端のEureqaアルゴリズムよりも大幅な改善が見られた、6つの戦略を再帰的に組み合わせた我々のアルゴリズムを適用した結果を紹介する
  • Discussion : 結論をまとめ、さらなる進展の機会について議論する

Results

本節では、我々の結果と、それを得るためのアルゴリズムを紹介する。

overall algorithms

 汎用関数 y=f(x_1, ..., x_n) は非常に複雑で、関数同定問題(記号回帰)では発見が不可能に近い。しかし、物理学や他の多くの科学的応用に登場する関数は、発見を容易にする次のような単純化された特性を持っていることが多い。

  1. 単位 Units:  fとそれに依存する変数は既知の物理的単位を持っている
  2. 低次多項式 Low-order polynomial :  f(またはその一部)は低次の多項式である
  3. 構成性 Compositionality :  fは,それぞれが通常2つ以下の引数を取る小さな素関数の集合の構成である
  4. 平滑性 Smoothness :  fは連続的であり, おそらくその領域では分析的でさえある
  5. 対称性 Symmetry :  fは,その変数のいくつかに関して並進,回転,またはスケーリングの対称性を示す
  6. 分離可能性(因数分解) Separability :  fは、共通の変数を持たない2つの部分の和または積として書くことができる

 なぜこれらの特性が共通するのかという疑問は、まだ論争の余地があり、完全には理解されていない ^{[28,29]}。しかしこれらの疑問は、後述するように、記号回帰を容易にするためにこれらの特性を発見・利用することを妨げるものではない。
 特性(1)は,次元分析を可能にし,それはしばしば問題をより少ない独立変数でより単純なものに変換する.
 特性(2)は多項式フィットを可能にし、これは多項式係数を決定するために線形方程式のシステムを解くことによって問題を素早く解決する。
 特性(3)は、 fを少数のノードタイプを持つ構文木として表現することを可能にし、時にはブルートフォース検索によって fや部分式を見つけることを可能にします。
 特性(4)は、滑らかな活性化関数を持つフィードフォワードニューラルネットワークを用いて fを近似することができる。
 特性(5)は、前記ニューラルネットワークを用いて確認することができ、問題を独立変数が1つ少ない( n > 2回転対称の場合はさらに少ない)より単純なものに変換することができる。
 特性(6)は、前述のニューラルネットワークを用いて確認することができ、独立変数を2つの不連続な集合に分割し、問題を2つのより単純な集合に変換することができる(それぞれがこれらの集合の1つからの変数を含む)。
 図1に全体的なアルゴリズムの模式図を示す。これは、上述の特性をそれぞれ利用しようとする一連のモジュールで構成されている。人間の科学者のように、多くの異なる戦略(モジュール)を順番に試し、それが一度に完全な問題を解決できない場合は、それを変換しようとし、それを別々に取り組むことができるより単純な部分に分割し、再帰的に各部分上の完全なアルゴリズムを再起動する。図2は、あるmysteryデータセット(9つの変数を持つニュートンの重力の法則)がどのようにして解かれるかの例を示している。以下、これらのアルゴリズムモジュールを順番に説明する。

f:id:K_PTL:20200422113452j:plain
図1. AI-Feynman アルゴリズム:反復的な4つのステップで新しいデータセットが生成され、アルゴリズムの新しいインスタンスに送られる。

f:id:K_PTL:20200422113459j:plain
図2. AI-Feynman アルゴリズムがmystery方程式を発見する方法(例:万有引力の法則...Dimensional analysisで万有引力 fの次元を持つ部分と無次元部分に分離、Translational symmetryで問題を簡単にする(変数の置換)、Separabilityで簡単な問題に分離する、こうして得られた式に対して次元解析や多項式フィッティング、組み合わせ総当たりで解🙂を求める)

Dimension analysis; 次元解析

 我々の次元解析モジュールは、『物理学の多くの問題は、方程式の両辺の単位を一致させることで単純化できる』というよく知られた事実を利用している。これにより、多くの場合、問題は無次元変数かつその個数がより少ない、より単純なものに変換される。最良のシナリオでは、変換された問題は、変数を含まない関数、すなわち定数を解くことを含む。次元解析を以下のように自動化する。
 表3は,100の謎に登場するすべての変数の物理的な単位を示しており,基本単位(メートル,秒,キログラム,ケルビン,ボルト)とさまざまな整数倍の積として表現されている.したがって、各変数の単位は、表のように5つの整数からなるベクトルuで表されます。 y=f(x_1, ..., x_n) というmystery formに対して、 i番目の変数 \textbf{x}_{i}に対応するカラムのベクトル \textbf{u}と、その中でも yに対応する \textbf{u}をベクトル \textbf{b}として定義した行列 \textbf{M}を定義する。ここで、ベクトル \textbf{p}を方程式 \textbf{Mp} = \textbf{b}の解とし、マトリックス \textbf{U}のカラムが零空間の基底を形成するので、 \textbf{MU}=0となる。さらに、以下の定義のもとで新たなmystery  y' = f'(x'_1, x'_2, ... , x'_n)を定義する。

 \displaystyle
x'_{i} \equiv \prod_{i=j}^{n} x_{j}^{U_{ij}} \ , \ 
y'      \equiv \frac{y}{y_{*}} \ , \
y_{*} \equiv \prod_{I=1}^{n} x_{i}^{p_{I}} \
\tag{1}

 新しい変数 x'_i y'_iは無次元であり、そしてそれらの個数 n'は零空間の次元数に一致する。 n' > 0である時、零空間の基底を自由に選択することができ、さらに任意のベクトル \textbf{a}に対して、ベクトル \textbf{p} \textbf{p}=\textbf{Ua}に置換することができる。これを利用して、例えば既存の変数にできる限り依存しない新たな変数を作成するように、 \textbf{p} \textbf{U}の可能な限り多くの要素を0に等しく設定する。この選択は、一般的に無次元変数の累乗が整数となり、累乗が分数や無理数である場合に比べて、最終的な式を見つけるのが非常に簡単になるので有用である。

Polynominal fit; 多項式フィッティング

 物理や他の科学では、多くの関数は低次多項式である。例えば、運動エネルギ K = \frac{m}{2} \bigl( {v_x}^2 + {v_y}^2 + {v_z}^2 \bigr ) のように関数そのものであったり、万有引力 F = \frac{Gm_1m_2 }{ {(x_1 - x_2)}^2 + {(y_1 - y_2)}^2 + {(z_1 - z_2)}^2 } のように分母等関数の一部分に含んでいたりする。そのため、低次の多項式で謎が解けるかどうかをテストするモジュールを導入する。我々の方法は、線形方程式の系を解く標準的な方法を用いて、最適な多項式の係数を見つける。これは、次数 0, 1,..., d_{\rm{max}} = 4多項式にmysteryデータを適合させようとした時に、最適な多項式が「二乗平均平方根(root mean square; rms)の適合誤差 ≤  \rm{\boldsymbol{\epsilon}}_{\rm{p}}」を与える場合にそのフィッティングが適切であるとするものである(このしきい値の設定については後述)。

Brute force; 組み合わせ総当たり

 組み合わせ総当たり関数同定モデル(Brute-force symbolic regression model)は、あるクラス内で可能なすべての記号式を複雑な順に試行し,最大適合誤差がしきい値 \rm{\boldsymbol{\epsilon}}_{\rm{p}}以下になったとき、または最大ランタイム t_{\rm{max}}を超えたときに終了する。このモジュールだけでも原理的にはすべてのmisteriesを解くことができるが、多くの場合、実際には宇宙の年齢よりも長い時間がかかります(非現実的)。したがって、我々の組み合わせ総当たり法は一般的には、後述するモジュールによってmysteryが変換されたり、より単純な断片に分解されたりした後に、最も有用である。
 試す式を記号の文字列として表現し、最初に長さ1のすべての文字列を試し、次に長さ2のすべての文字列を試すなどして、構文的に正しい文字列だけを生成して時間を節約/短縮する。使用されている記号は、独立変数と表1に記載されている変数のサブセットで、それぞれが定数または関数を表している。ポーランド記法逆ポーランド記法を用いて文字列の長さを最小限に抑えているため、括弧は不要である。 例えば、

  • 関数  x + y → 文字列 "xy+"
  • 数値 -2/3 → 文字列 "0<<1>>/"
  • 相対論的運動量  \frac{mv}{1 - \sqrt{\frac{v^2}{c^2}} } → 文字列 "mv*1vv*cc*/-R/"

f:id:K_PTL:20200422151929p:plain

 表1を見てみると、多くの記号が冗長であることがわかる(例えば、"1"="0>"、 "x~"="0x-")。また、 \pi = 2 \arcsin{1}であることから、もし \piを表現する"P"をdropしたとしても、 \piが含まれているmysteriesは"P"="1N1>"で表現し解くことが出来るとはいえ、ただ時間がかかるだけ(ナンセンス)である。
  s個のシンボル(アルファベット)を使った長さ n s^nの文字列があるため、シンボルの数が多すぎ( sを増やす)たり、シンボルの数が少なすぎ(必要な nを増やしたり、解を不可能にしたりする)たりと、かなりのコストがかかることがある。妥協案として、組み合わせBrute forceモジュールでは、表1のキャプションで説明されているように、3つの異なるシンボルサブセットを使用して謎を解こうとしている。多くの方程式やその一部が乗算定数や加算定数を持っているという事実を利用するために、Brute force法には、そのような定数を自動で数学的に解く2つのバリエーションがある。
 overfitting問題は連続的なパラメータ空間を探索するときに最もよく知られているが、シンボル文字列の離散空間を探索するときにも同じ現象が発生する。これを緩和するために,提案 ^{[30]}に従って,式(2)に示す合計記述長さ;  DLが最小となるrmsのフィッティング誤差 \rm{\boldsymbol{\epsilon}} \lt \rm{\boldsymbol{\epsilon}}_{\rm{b}}を持つ関数をwinning functionと定義する。


DL \equiv \log_{2} N + \
\lambda \log_{2} \
\bigl[  \
\rm{max}( 1, \frac{ \rm{\boldsymbol{\epsilon}} }{ \rm{\boldsymbol{\epsilon}}_{\rm{d}} } )  \
\bigr] \
  \tag{2}  \

ここで、 \rm{\boldsymbol{\epsilon}}_{\rm{d}} =10^{-15} であり、 Nは、試したすべての文字列のリスト上の文字列のランクである。この2つの項は,ハイパーパラメータ \lambdaをデータ点数 N_dと等しく設定した場合、それぞれシンボル文字列を格納するのに必要なビット数と予測誤差におおよそ対応している。以下の実験では、より単純な式を優先するために \lambda = N_d^{1/2}を使用する。mysteryがニューラルネットワーク(後述)を用いて生成されている場合、精度閾値 \rm{\boldsymbol{\epsilon}}_{\rm{b}}を検証誤差の10倍に設定し、そうでない場合は 10^{-5}に設定する。

Neural network-based tests and transformations;

to be continued.....

Neural network training; NNでの学習

Translational symmetry and generalizations; 並進対称性と一般化

Separability; 因数分解

Setting variable equal; 変数を等価にする

Extra transformations

Tha Feynman Symbolic Regression Database

Algorithm comparison

Dependence on data size

Dependence on noise level

Bonus mysteries

Discussion

Key findings

Opportunities for further work

Materials and methods

Reference and Note

  1.  A. Koyré, The Astronomical Revolution: Copernicus-Kepler-Borelli (Routledge, 2013).
  2.  N. M. Amil, N. Bredeche, C. Gagné, S. Gelly, M. Schoenauer, O.Teytaud, European Conference on Genetic Programming (Springer, 2009), pp. 327–338.
  3.  S. K. Pal, P. P. Wang, Genetic algorithms for pattern recognition (CRC press, 2017).
  4.  J. D. Lohn, W. F. Kraus, D. S. Linden, IEEE Antenna & Propagation Society Mtg. 3, 814 (2002).
  5.  D. S. Linden, Proceedings 2002 NASA/DoD Conference on Evolvable Hardware (IEEE, 2002), pp. 147–151.
  6.  H. Yu, N. Yu, The Pennsylvania State University, (University Park, 2003) pp. 1–9.
  7.  S. Panthong, S. Jantarang, CCECE 2003-Canadian Conference on Electrical and Computer Engineering. Toward a Caring and Humane Technology (Cat. No. 03CH37436) (IEEE, 2003), vol. 3, pp. 1597–1600.
  8.  B. Oh, Y. Na, J. Yang, S. Park, J. Nang, J. Kim, Genetic algorithm-based dynamic vehicle route search using car-to-car communication. Adv. Electr. Comput. En. 10, 81–86 (2010).
  9.  A. Ram, R. Arkin, G. Boone, M. Pearce, Using genetic algorithms to learn reactive control parameters for autonomous robotic navigation. Adapt. Behav. 2, 277–305 (1994).
  10.  B. Delman, Genetic algorithms in cryptography. Rochester Institute of Technology (2004). 11. S. Kim, P. Lu, S. Mukherjee, M. Gilbert, L. Jing, V. Ceperic, M. Soljacic, arXiv preprint arXiv:1912.04825 (2019).
  11.  R. J. Bauer, Genetic algorithms and investment strategies, (John Wiley & Sons, ed. 1, 1994), vol. 19, p. 320.
  12.  R. Venkatesan, V. Kumar, A genetic algorithms approach to forecasting of wireless subscribers. Int. J. Forecast. 18, 625–646 (2002).
  13.  W. L. Cava, T. R. Singh, J. Taggart, S. Suri, J. Moore, International Conference on Learning Representations (2019), https://openreview.net/forum?id=Hke-JhA9Y7.
  14.  S. McAleer, F. Agostinelli, A. Shmakov, P. Baldi, International Conference on Learning Representations (2019); https://openreview.net/forum?id=Hyfn2jCcKm.
  15.  J. R. Koza, J. R. Koza, Genetic Programming: On the Programming of Computers by Means of Natural Selection (MIT Press, 1992), vol. 1.
  16.  M. D. Schmidt, R. R. Vallabhajosyula, J. W. Jenkins, J. E. Hood, A. S. Soni, J. P. Wikswo, H. Lipson, Automated refinement and inference of analytical models for metabolic networks. Phys. Biol. 8, 055011 (2011).
  17.  R. K. McRee, Proceedings of the 12th Annual Conference Companion on Genetic and Evolutionary Computation (ACM, New York, NY, USA, 2010), GECCO ‘10, pp. 1983–1990; http://doi.acm.org/10.1145/1830761.1830841.
  18.  S. Stijven, W. Minnebo, K. Vladislavleva, Proceedings of the 13th Annual Conference Companion on Genetic and Evolutionary Computation (ACM, New York, NY, USA, 2011), GECCO ‘11, pp. 623–630; http://doi.acm.org/10.1145/2001858.2002059.
  19.  W. Kong, C. Liaw, A. Mehta, D. Sivakumar, International Conference on Learning Representations (2019); https://openreview.net/forum?id=rkluJ2R9KQ.
  20.  T. McConaghy, Genetic Programming Theory and Practice IX (Springer, 2011), pp. 235–260.
  21.  I. Arnaldo, U.-M. O’Reilly, K. Veeramachaneni, Proceedings of the 2015 Annual Conference on Genetic and Evolutionary Computation (ACM, 2015), pp. 983–990.
  22.  S. L. Brunton, J. L. Proctor, J. N. Kutz, Discovering governing equations from data by sparse identification of nonlinear dynamical systems. Proc. Natl. Acad. Sci. U.S.A. 113, 3932–3937 (2016).
  23.  M. Quade, M. Abel, J. Nathanutz, S. L. Brunton, Sparse identification of nonlinear dynamics for rapid model recovery. Chaos 28, 063116 (2018).
  24.  D. P. Searson, D. E. Leahy, M. J. Willis, Proceedings of the International multiconference of engineers and computer scientists (Citeseer, 2010), vol. 1, pp. 77–80.
  25.  R. Praksova, Eureqa: Software review. Genet. Program. Evol. M. 12, 173–178 (2011).
  26.  M. Schmidt, H. Lipson, Distilling free-form natural laws from experimental data. Science 324, 81–85 (2009).
  27.  H. Mhaskar, Q. Liao, T. Poggio, Technical report, Center for Brains, Minds and Machines (CBMM), arXiv (2016).
  28.  H. W. Lin, M. Tegmark, D. Rolnick, Why does deep and cheap learning work so well? J. Stat. Phys. 168, 1223–1247 (2017).
  29.  T. Wu, M. Tegmark, Toward an artificial intelligence physicist for unsupervised learning. Phys. Rev. E. 100, 033311 (2019).
  30.  L. N. Smith, N. Topin, Super-convergence: Very fast training of residual networks using large learning rates (2018); https://openreview.net/forum?id=H1A5ztj3b.
  31.  L. N. Smith, A disciplined approach to neural network hyper-parameters: Part 1 – learning rate, batch size, momentum, and weight decay. arXiv:1803.09820 (2018).
  32.  J. Howard et al., Fastai, https://github.com/fastai/fastai (2018).
  33.  R. Feynman, R. Leighton, M. Sands, The Feynman Lectures on Physics: The New Millennium Edition: Mainly Mechanics, Radiation, and Heat, vol. 1 (Basic Books, 1963); https://books.google.com/books?id=d76DBQAAQBAJ.
    35.  R. Feynman, R. Leighton, M. Sands, The Feynman Lectures on Physics, vol. 2 in The Feynman Lectures on Physics (Pearson/Addison-Wesley, 1963b); https://books.google.com/books?id=AbruAAAAMAAJ.
  34.  R. Feynman, R. Leighton, M. Sands, The Feynman Lectures on Physics, vol. 3 in The Feynman Lectures on Physics (Pearson/Addison-Wesley, 1963); https://books.google.com/books?id=_6XvAAAAMAAJ.
  35.  H. Goldstein, C. Poole, J. Safko, Classical Mechanics (Addison Wesley, 2002); https://books.google.com/books?id=tJCuQgAACAAJ.
  36.  J. D. Jackson, Classical electrodynamics (Wiley, New York, NY, ed. 3, 1999); http://cdsweb.cern.ch/record/490457.
  37.  S. Weinberg, Gravitation and Cosmology: Principles and Applications of the General Theory of Relativity (New York: Wiley, 1972).
  38.  M. Schwartz, Quantum Field Theory and the Standard Model, Quantum Field Theory and the Standard Model (Cambridge Univ. Press, 2014); https://books.google.com/books?id=HbdEAgAAQBAJ.
  39.  J. McDermott, D. R. White, S. Luke, L. Manzoni, M. Castelli, L. Vanneschi, W. Jaskowski, K. Krawiec, R. Harper, K. De Jong, Proceedings of the 14th Annual Conference on Genetic and Evolutionary Computation (ACM, 2012), pp. 791–798.

Sports Analyst Meetup #7に参加しました

Sport Analyst Meetupって?

 Sport Analyst Meetupは、「現役スポーツアナリストとスポーツ分析に興味のある方々で情報共有をする」ことを掲げたMeetupである。Meetupの目的は、リンク先から抜粋すると、

  • スポーツアナリストおよびスポーツデータ分析に興味のある方に向けたイベントです。
  • 本イベントはスポーツのジャンルを問わずスポーツアナリスト(を目指す人)にとって有益な情報共有の場になることを目的としています。

である。発表者は、本職のアナリストでもいいし、アカデミアでもいいし、趣味の一環でスクレイピングして分析したらこういった知見が得られましたよーって人もおk。いろいろなスポーツに関する知見を共有できればいいなっていう意向らしいので、みなさま是非是非。
 そして、今回参加するのは第7回のSport Analyst Meetup #7である。発表を聞きながらダダダダッとこの記事を執筆しているので、間違えているところがあったら教えてください。。。

参加の目的

 Kaggleでアメリカンフットボールの獲得Yard距離を予測するコンペ(NFL Big Data Bowl)に去年参加した。コンペを通じて、スポーツアナリストの凄さを思い知るとともに、それがとてもとても楽しいことを知った。あくまでアメフト におけるデータアナリシスの極一部に過ぎないが、それでも、この世界をもっと知ってみたいと思った。
 このMeetup自体は、はんぺんさんのテニスの姿勢確認する機械学習モデルを通じて知っていた。以下のスライド。Sports Analyst Meetup #6での発表資料です。過去には、誰のフォームに近いかを推定したり、フォアハンドかバックハンドかを判定したりするモデルも作成していた。このフォア/バック判定のスライドを見て、Sports Analyst Meetupの存在を知ったくらいだもの。すごいよね、こういうことを私もやってみたい。

 そして今回、偶然(開催日前日に)このMeetupの開催を知ることができた。ので、Sport Analystとはどんななのか、機械学習統計学がどのようにスポーツと絡んでいくのかを知り、知見を深めていこう。  なお、後日動画はYoutTubeにUpされるらしい。Upを確認次第、ここにリンクを貼る。

Sports Analyst Meetup 07

※バレーボールについての発表予定だったいとまきさんは欠席のため、全4公演。
参考:スポーツアナリティクス Advent Calendar 2019

Meetupの目的

司会: u++、tsuyupon


[Sports Analyst Meetup #7] オープニング #spoana

 参加者の使用言語はPythonがぶっちぎりで多いが、ExcelがRと同じくらいいる。これは、スポーツのデータ分析ならではの現象だろう。データ分析界隈では絶滅危惧種だと思っていたので、珍しい。。。。 f:id:K_PTL:20200416194015p:plain

フェンシング@千葉洋平

  • 日本フェンシング協会
  • 大学時代は学生トレーナー(サッカー)、国のプロジェクトで協議に注力して協議を強くしよう、と配属された先がフェンシングだった(データアナリストとして赴いたわけではない)
  • 局面・課題・・動作
  • 誰が、いつ、どこで、何をしたのか、どうなったのか、の最低5つをタグづけする
  • データのビジュアライズには最注力している
  • 素材を作る作業;タグづけが最も時間のかかるし、分析をしたいけど何よりもここが大事
  • タグづけは、やりたいところ全てをやろうとしたらキリがなく、絞り込んだ上で仕事の半分くらいを占めている
  • AI等でタグづけを自動化できないか、というのは皆考えるが、フェンシングの国際ルールの理解や技の判定など、理解の深いプロの目が必要となるためタグづけという作業から逃れる術がない
  • 一番のKPIは得点率

バスケ @keisuke_fj

  • アカデミアの方
  • 位置データから攻撃・守備戦術の自動分類
  • 現場では見てわかるデータしか信用されていない(動画ベース、フェンシングと一緒やね)
  • スクリーンプレーのように、複数人が同時に絡む戦術があるため自動分類が難しい
  • 特徴を作成して機械学習なしで分類
    スクリーンに対するディフェンスの動きを決定木で分類していく
  • 特徴を作成して機械学習SVM)で自動分類
    境界を決定する
  • 特徴を機械学習で抽出して分類
    空間モード・時間モードから特徴を抽出し、その特徴のベクトルを解釈する(ロジスティック回帰;解釈性のため)
    f:id:K_PTL:20200416201132p:plain

  • マーカーをつける場合には、実際の激しいプレーを測定することは大変

  • プレイヤーの身長等を解析に使用していない、そこらの情報が必要となる分析もあるけど(スイッチプレーなど)

野球@nowism_sports

  • どうしてバントは減らないのか?
  • 送りバントをすると得点確率は減少する、非効率的である
  • 0.103よりも打率が低い選手にとっては有益
  • だけどバントは減っていない
  • 人間の心理的側面;最悪のシナリオを回避したい、が強く作用している(併殺回避);損失回避の考え方
  • 一打で得点が入る、というメリットに関して時間割引という概念を使用して解説
  • 明日1万確実にもらえる vs. 1年後に1.5万確実にもらえる、どっちらいい??(Aが圧倒的に多い)
  • 心理学的には、将来的な報酬を割り引いて評価する傾向がある(時間割引は双曲的)
  • 無死一塁と一死二塁とでは、将来性(時間軸長さ)が異なるので報酬を低く見積もっている可能性?
  • 確かにバントをして送ったほうが、特典までに要する打席数は少なくなるが、得点期待値は小さくなる
  • 時間割引と期待得点の掛け合わせで監督は評価している、期待得点が高くなると信じて、、、
  • 期待得点としては、バントをすると大損だが、得点までの時間が短くなる、これが強く作用していると考えられる
  • バント前のシチュエーションが過小評価されている
  • 送りバントは統計的に、損であることが分かっていても、そのバイアスを心理的に逃れることが困難なのである
  • 私も元野球プレイヤーなので聴いてて楽しかった
  • パイロットスタディとして今回はこのケース比較を行った、同じケースでの比較を実施したり(質問内容:「今回のご報告は、異なる局面(無死一塁と一死二塁)の比較でしたが、傾向スコアなどを使って、同じ局面(無死一塁)の得点までの所要打席数を比較することはご検討されましたでしょうか。送りバントを処置と考えて、処置群と統制群で得点までの打席数を比較すると、「送りバントによって短縮される、得点までの所要打席数」を純粋に取り出せるかなあ、などと思ったのですがどうなのでしょうか。」)、チーム単位で比較することは今後実施していく
  • 一点を争う試合なのかどうか、とかも面白い結果が得られそう

サッカーとか@Fanalyst

  • 現役のサッカーアナリスト(9年目、元指導者14年間)
  • アナリストはどのように進化していくのか?
  • アナリスト進化の要件;DORAEMON
  • 1: Domain
  • 専門分野に対する深い知識・肌感覚
  • 2: Origin
  • 限界だと感じた時に思い出す、支えとなるもの
  • 3: Relationship
  • 異人で相談できる人がたくさんいる
  • 安宅和人「データドリブン社会の双発と戦略」も言っている(公開されている)
  • 4: Analysis
  • 分析は手段(映像編集も手段)
  • 勉強と実践あるのみ
  • 現象を説明することに加えて、要因を特定すること、曖昧性(偶然性)を偶然である、と言い切れることが大切
  • 5: English
  • 語学力、最新情報を入手していくためには英語ができないとわからない、日本語だけでは手に入らない情報が多すぎる
  • 海外進出も視野に
  • 6: Monetize
  • やりがいを搾取しない、1円でもいいからもらう、もらうことで責任が生まれる
  • リソースには限界があることを忘れずに
  • 7: Output
  • 発信側と受信側が繋がり、適正な評価と健全な競争がある場
  • リテラシーが問題になっているように思われる。。。
  • 基本的に動画等は勝手に使ってはいけない、いい分析・発信をするならその許可を然るべきところにとったりすること。ダメであることを知っている、ということが大切。
  • 8: Newcomer
  • アナリスト職の多様化
  • 色々な角度からの参画、一部だけでもいいから手伝ってほしい、などでもおk f:id:K_PTL:20200416205718p:plain

終わりに

 私自身、小学3年からサッカー、野球、バレーボールと大学までずっとスポーツに関わってきた。10年間野球はやってきたし、バントの話を聞いた時にはこれまで気にも留めてなかった(当たり前になっていた)。この当たり前を、データを持って打ち崩していく、これはほんとに感激ものだし、思い通りに体が動かなくなってきた26歳の今だからこそ、こういった形で是非ともスポーツに関わって行ってみたいと心の底から思う。それこそ、カバディの戦術とかでもいいよね。誰もやったことないでしょうまだ?
 新たな目標になった、このSports Analyst Meetupにていつか、自分の趣味で進めた分析を発表してみたいものだ。そのために勉強がんばらなきゃだし、まずはみんなでコロナを乗り切ろう。。。



最後にこの曲を聞いてお別れです。

コロナに負けずに頑張っていくたいですね。。

今こそ、自分のために生きることが誰かのために生きること
誰だってヒーローになれちゃうチャンスなんだから。

(せーのっ)

\\\ SUPER HERO //

VS Code Meetup #4 Extensionを使う編2 に参加しました

VS Code Meetupとは

今回参加したのはこちらのVS Code Meetup #4でございます。VSCoeは言わずもしれた、Microsoft無料で提供している超強力なコードエディターですね。こちらからダウンロードできます。

過去のVS Code Meetup

 今回のは#4です、ということは過去に#3まで存在しているということですよ。ちなみにこちらのMeetup、全てYouTubeでオンライン参加できるようになっているだけでなく、過去のMeetupの動画も残っている優れたMeetupです。以下に、過去のVS Code Meetupのリンクを貼っておきます。#4は#3の続編ですね。

記念すべき初回;VS Code Meetup #1 - 初回基礎編

VS Code Meetup #2 - Live Share編

VS Code Meetup #3 - Extensionを使う編

そして今回の#4です。 https://www.youtube.com/watch?v=KH3kj9QqsTA

 そしてなんでこれに参加しようと思ったかって、基本的にコードを書くときにVSCodeを使用させてもらっているのだけれども、Docker使用したときのコンテナの取り扱いを知りたくて、、、、コンテナ初心者なので、、、そこに、Codewindというコンテナに関する発表があるとのことで参加することに。ついでなので、全部見てみるし、ここにメモしながらきいていく。詳細は後からYouTube見ればいいので。。。

15分押しでスタート。
 今日、緊急事態宣言が発令されましたね、コロナの影響が大きいですがフルオンラインで開催されます。

VS Code Meetup #4 Extensionを使う編2

Meetupについて by Nori Suzuki (@szkn27)

  • 今回が4回目(2019年12月から)、今日でメンバーが1500人突破した(オメー)
  • 10分LT、5分LTの計8セッション

10min Visual Studio Code February 2020アップデート (@setoazusa)

  • GWのあいみょんのライブが延期になったという悲しいお知らせ
  • スライドが表示されずに進まないというもっと悲しい状態
  • 最初からというTake 2実施
  • だがしかしまだ顔とスライドが被ってる
  • Take 3....とはならずに、顔移動で続行www
  • YouTubeでの叫びに運営が気づき
  • Feb. 2020 ver.1.43の見どころについて
  • 検索に関してアップデートきた
  • フルサイズ検索エディターで検索でシンタックスハイライトと行番号の表示ができるように
  • 烈選択モードの切り替え(9系モードとも呼ばれる)が可能に
  • editer.definitionLinkOpenInPeek -> Trueで同一画面内で定義箇所を見れるように
  • editer.rulersで複数のルーラーを表示できるように
  • 選択部分での空白文字の表示は地味に嬉しいのでは
  • macOS, Windowホストに対してsshでの接続サポートが可能に

10min LT1: Codewindで簡単!コンテナ開発環境構築 (榎本 陽祐 (@motumotuo))

  • 今回のMeetupのボクの大本命
  • Codewind初めて聞いた
  • これですねん
  • ベンチャーJoolenのエンジニア(千葉県松戸市
  • 2020年のIBM Championをもらっている(スゲー)
  • 今回のCodewindもIBM
  • PHPerってペチパーって発音するんか
  • Codewind=スラウドネイティブな開発を加速するextension
  • 通常のextensionと同じようにインストールできる
  • 多様な言語に対応(例としてNode.js)
  • 勝手に雛形ファイルを作成してくれる
  • Application~に表示されると、ビルドまで完了されている状態であり、そこをクリックすると作成されたウェブサイトに飛ぶことができる
  • コードを変更すると、すぐに反映されるためデバッグにも便利
  • テスト機能も実装されている
  • dockerとかクラウドライクなやつを使用してみたければ最初の取っ掛かりにいいかも

10min LT2: VSCode拡張機能で始めるAzure Cosmos DB (まっぴぃ (@mappie_kochi))

* 青いRの中の人 * Azure Cosmos DBの拡張機能の話 * 2020.03.06(米国時間)~ 400 RU/s (request unit), ~5 GB/月で無料枠がある * 環境構築に関してはQiita参照 * Gremlinいいな、グラフ可視化 * これを使用するとvscodeをコーディングのHubにすることができる * JSONファイルを作成しておけば一括でimportできる反面、コア(SQLVSCode上)でクエリが打てない * databaseが1000からしかできない、無償枠を超えてくる、、、、みんなGitHubで喚いてる

10min LT3: 開発チーム管理で役立ったVSCode拡張機能 (鈴木 正樹(@makky12))

  • Setting Sync:複数端末に環境コピーするやつ(環境複製そのものはいずれ標準機能になる)
  • 環境のずれによるエラー回避(OSが違う場合については未検証(マッキーさんはWindowsだった))
  • ESLint/Prettier:Javascriptの静的検証ツール/コード整形ツール、これらは併用可能
  • チーム内でルールづけができる他、初心者に対してもリーダブルコーディングの大切さを知ってもらうことができる
  • Live Share:複数人で同時にコードの変更ができる
  • VS Code Meetup #2内で戸倉彩さん(IBM)と井上章さん(Microsoft)のセッション動画があるので参考になるよう
  • Git Lens/Git Graph:Git管理下のファイルの変更者やコミットメントを表示、ファイルの差分比較も可能(殿堂入りレベル)/リポジトリの変更履歴をツリーで表示してくれる
  • 良いプロダクトは良いエンゲージメントから

5min LT1: No, aws console! Yes, aws cdk!~vscodeだけでAWS開発をしよう~ (yuta_matsunaga)

  • スポーツIoLTL主催者
  • AWSのインフラ構築にコンソールを使用すると大変、cdk使えば解決できちゃう
  • AWS Toolkit for Visual Studio Codeを使用
  • CDKを使用するとVSCodeだけでAWSが使用できる(AWSのコンソールを使用する必要がない、極力使用したくないものだもの、、)

5min LT2: AnsibleでVSCode拡張を管理しちゃおう! (answer_d)

  • ansibleっていうツーうが好き
  • 一般枠だと思って応募したらしい。笑
  • 昨日、発表枠ということに気付いて急遽資料作成、参加した方。すげぇな
  • サーバの設定管理をコードでやりましょうっていうのがansible
  • setting syncが使えないアナタに!
  • VSCode以外の環境設定にもできる
  • Macの設定構築にも使えちゃう(これすごいじゃん、いつPCが死んでもすぐにバックアップできる安心感)

5min LT3: Remote Development(ssh)小技集 (@setoazusa)

  • 踏み台経由のリモート接続
  • VSCodeとサーバーの間に一つ挟む
  • proxyCommandを使用して踏み台用のサーバーを経由させられる
  • windowsの場合には、空白を含まないフルパスである必要があるためMac, Linuxと同じようにはできない(アップデートで対応予定)
  • AWS Session Maneger経由でのリモート接続
  • インターネットに対してSSHポートを開く必要なく、Session Managerを使用して接続できる
  • これもsshのconfigにProxyCommandを設定するだけ
  • これもWindowsの場合にはちと変更する必要あり
  • リモート接続とLiveShareの併用
  • Remote developmentとLive Shareは併用可能なのです、セッションできます
  • ラズパイの場合にはリモートはできるけどLiveshareはできない
  • Remote Developmentって使ったことないし意識したことない概念だなぁ、hmm、ちょっと調べてみる、??

5min LT4: Twilio Serveless VSCode Extension 使ってみた (池原大然 (@neri78))

  • Twilioとは;電話の受発信をプログラミング可能(アプリはサーバーやクラウドに置くことができる)
  • 基本的にスライド内の動画とかみたほうがいいねこれは(スライドじゃないね、実演している動画だからyoutubeみたほうがいいやつだ)
  • これは面白い機能だ
  • コーディングからデプロイまですごくスムーズ

終わりに

 コロナウィルスの影響で製造業ですがリモートワーク、正直できることは限られています、、、なので極力勉強に当てる時間を大き確保したいなと考えているのです、プログラミングに関連する内容もいくつか入ってくるし、都合よく手元に会社用のPCがあるし。VS Codeをもっと使いこなせるように環境構築を進めてみるのも、お気に入りのextensionを探すのもありかなと思えました。時間があるうちに、色々とトライしてみたいですね。



最後にこの曲を聞いてお別れです。

コロナに負けずに頑張っていくたいですね。。

最後まで力の限り叫んで、叫んで、僕らは生きましょう、

(せーのっ)

\\\ sweetest vengeance //

正規分布の変数変換とその期待値・分散・密度関数

本記事について

(誤植が多いにも関わらず)世代を超えて愛用されている名著"統計学入門"。
一通り本書での勉強(独学)を終え、復習がてらに章末の練習問題を解いていると自分の理解がいかに浅いかを度々感じさせられます。

統計学入門 (基礎統計学Ⅰ)

統計学入門 (基礎統計学Ⅰ)

  • 発売日: 1991/07/09
  • メディア: 単行本

そんな練習問題の中から、単純なことなのに小一時間ハマってしまった問題を解説付きで紹介しようかと思います。わかっている人にとっては

「え?これのどこでハマるの?」

となること間違いありません。世の中にはこんなバカもいるんだよと知ってくれれば。ベローチェのカフェラテを枯らした問題を解いていきます。ちなみに、勉強するカフェはベローチェタリーズコーヒーです。片や安い、片や若者が多い。どちらも捨てがたいですね。環境はダイジです。

ハマった問題

第5章『確率変数』練習問題5.7より

確率変数 Xが、正規分布 \mathscr{N}(0,1)に従うとき、
 {X}^{2}の累積確率分布、密度関数、期待値、分散を求めよ

です。まず最初に、ハマってしまった解答例を。。。その後に、無事に解けた解法を示します。

悪い解き方

 まず初めに、「悪い」とは書きますが、人によっては問題ないのかも。少なくともボクは、この解き方で完全に手が詰まってしまいました。沼の入り口です。

 まず問題から、 X \sim \mathscr{N}(0,1)より、 X確率密度関数 f(x)

 \displaystyle
f(x) = {\frac{1}{\sqrt{2\pi}} e^{ -\frac{x^{2}}{2} } }

であることが分かります。
 求めたいのは X^{2}に関する確率密度関数なので、

 Y = X^{2} \sim g(y)

と置きます。ここで、 g(y)は確率変数 Y確率密度関数であり、本問において求める答えの一つです。ここから、 X Y変数変換します。
変数変換の公式の導出はしませんが、これは

 \displaystyle
g(y) = f(h^{-1}(y)) |(h^{-1})'(y)|

で求められます。ここで、 h(x) = yは、確率変数 Xを確率変数 Yへ変換する数学的な関数であり、 h^{-1}(y)はその逆関数です。
 今回の問題では、 h(x) = x^{2}であるので、 h^{-1}(y) = y^{\frac{1}{2}}と求まります。これを変数変換の公式に代入すると、

 \displaystyle
\begin{eqnarray}
 g(y) &=& f(h^{-1}(y)) |(h^{-1})'(y)|   \\
&=& f(y^{\frac{1}{2}}) | \frac{ y^{ -\frac{1}{2} } }{2} | \\
&=& \frac{1}{\sqrt{2\pi}} e^{ -\frac{ {(y^{ 1/2 })}^{2} }{2} } \frac{1}{2\sqrt{y}} 
\end{eqnarray}

ってな感じに求まります。これが Y=X^{2}確率密度関数です。
 そこから、累積確率分布を算出するために、 g(y)積分 (0 \leq  \alpha)すると、

 \displaystyle
\begin{eqnarray}
 G(y) &=& \int^{\alpha}_{-\infty} \frac{1}{\sqrt{2\pi}} e^{ -\frac{ {(y^{ 1/2 })}^{2} }{2} } \frac{1}{2\sqrt{y}} dy 
\end{eqnarray}

....少なくともボクは、これの積分が解けずに詰みました(いつの日かひょんなことから解けちゃいそうな気もするけど、、、わからない、、、ぴえん)。

 つまりですね、この悪い解法って何が悪いかって、『圧倒的に計算が大変だしこれ以上計算できなくなってしまう』ことなんですね。問題文からしても、先に累積確率分布を算出して、その後に密度関数を算出して、それを使って期待値・分散を算出して、っていう流れが基本なんだと思うんです。きっと。 練習問題前最後のページが変数変換だったのでまんまと引っ張られましたコンチクショウ。
 ただ、勘違いして欲しくないのは、この解き方でも、数学的には間違えていないはずなんです。ただ単に、数学力が足りていないだけです。次に紹介するのは、もっと簡単な解き方です。

解ける解き方(著者の意図)

では、次に実際に解けた解法を紹介します。筆者の考えを汲み取り、累積確率分布から順番に求めていきます(散々センター試験対策で筆者の意図は汲んできた)。
 先ほどと同様に、 X \sim \mathscr{N}(0,1)より、 X確率密度関数 f(x)

 \displaystyle
f(x) = {\frac{1}{\sqrt{2\pi}} e^{ -\frac{x^{2}}{2} } }

であり、

 Y = X^{2} \sim g(y)

とします。すると、 Yの累積確率分布 G(y)

 \displaystyle
\begin{eqnarray}
G(y) &=& P\left(X^{2} \leq y\right) \\
&=& P\left(-\sqrt{y} \leq X \leq \sqrt{y}\right) \\
&=& 2P\left(0 \leq X \leq \sqrt{y}\right) \left(\because X \sim \mathscr{N}(0, 1) \right) \\
&=& 2\Bigl\{  \Phi\left(\sqrt{y}\right) - \Phi\left(0\right) \Bigr\}
 \left(\therefore \Phi(x=a) = \int^{a}_{-\infty}{ \frac{1}{\sqrt{2\pi}} e^{-\frac{x^{2}}{2}} dx} 
\right) \\
&=& 2 \Bigl\{  \Phi\left(\sqrt{y}\right) - \frac{1}{2}  \Bigr\}
\end{eqnarray}

と表されます。 Y確率密度関数 g(y)は、これを微分して、

 \displaystyle
\begin{eqnarray}
g(y) = \Bigl\{G(y)\Bigr\}'  &=& \biggl\{  2 \left(  \Phi\left(\sqrt{y}\right) - \frac{1}{2}  \right)  \biggr\}' \\
&=& 2 \Bigl\{  \Phi \left(\sqrt{y}\right)\Bigr\}'  \cdot  \left(\sqrt{y} \right)'  \\
&=& 2 \frac{1}{\sqrt{2\pi} } e^{ -\frac{\sqrt{y}^{2}}{2} }  \left| \frac{1}{2\sqrt{y}} \right|   \\
&=& \frac{1}{\sqrt{2\pi y} } e^{ -\frac{y}{2} }
\end{eqnarray}

となります。簡単な計算だけで累積確率分布 G(y)確率密度関数 g(y)が得られます。さすがですね、これが筆者の意図ですね。

ここから、 X^{2} = Yの期待値 E[Y]、分散 V[Y]は

 \displaystyle
\begin{eqnarray}

E[Y] = E\bigl[X^{2}\bigr] 
&=& \int^{\infty}_{-\infty}{
                                        x^{2} \frac{1}{\sqrt{2\pi}}  e^{ -\frac{x^{2}}{2} } dx } \\
&=& \frac{1}{\sqrt{2\pi}} \int^{\infty}_{-\infty}{
                                        x^{2}  e^{ -\frac{x^{2}}{2} } dx } \\
&=& \frac{1}{\sqrt{2\pi}} \int^{\infty}_{-\infty}{
                                        x \cdot xe^{ -\frac{x^{2}}{2} } dx } \\
&=& \frac{1}{\sqrt{2\pi}} \biggl\{
                                        \biggl[  x  \cdot  \cfrac{ e^{ -\frac{x^{2}}{2} } }{ -2 \cdot \frac{1}{2} } \biggr]^{\infty}_{-\infty}    -  \int^{\infty}_{-\infty}{ - e^{ -\frac{x^{2}}{2} } dx }
                                        \biggr\} \\
&=& \frac{1}{\sqrt{2\pi}} \biggl\{
                                        0 + \int^{\infty}_{-\infty}{ e^{ -\frac{x^{2}}{2} } dx }
                                        \biggr\} \\
&=& \frac{1}{\sqrt{2\pi}} \sqrt{ \cfrac{\pi}{\frac{1}{2}} }  (\because ガウス積分  )   \\
&=& 1

\end{eqnarray}
 \displaystyle
\begin{eqnarray}

V[Y] = V\bigl[X^{2}\bigr] &=& E\bigl[X^{4}\bigr]  -  \biggl\{E\bigl[X^{2}\bigr]\biggr\}^{2} \\
&=& \int^{\infty}_{-\infty}{
                                        x^{4} \frac{1}{\sqrt{2\pi}}  e^{ -\frac{x^{2}}{2} } dx }   -1 \\
&=& \frac{1}{\sqrt{2\pi}} \int^{\infty}_{-\infty}{
                                        x^{4}  e^{ -\frac{x^{2}}{2} } dx }   -1 \\
&=& \frac{1}{\sqrt{2\pi}} \int^{\infty}_{-\infty}{
                                        x^{3} \cdot xe^{ -\frac{x^{2}}{2} } dx }  -1 \\
&=& 3 \cdot E\bigl[X^{2}\bigr]  -1\\
&=& 3-1 \\
&=& 2

\end{eqnarray}

よって、最終的な答えとしては、

 X \sim \mathscr{N}(0,1)である {X}^{2}において、

累積確率分布  F(x^{2}) = 2 \Bigl\{  \Phi\left(\sqrt{y}\right) - \frac{1}{2}  \Bigr\}、 密度関数  f(x^{2}) = \frac{1}{\sqrt{2\pi y} } e^{ -\frac{y}{2} }
期待値  E\bigl[X^{2}\bigr] = 1、 分散  V\bigl[X^{2}\bigr] = 2

終わりに

 悪い解き方についても、標準正規分布の累積確率分布の形に直せるよ〜と気づければ良かったのですが、あの状態からだと変形して導くは難しかったです。とは言っても、今回の問題にそぐわなかったのと、基本的に数学としては間違えていないはずです。単純に計算力不足。
 ルベーグ積分を勉強している今日この頃なのですが、先が不安になります。ある程度勉強して、微分積分の勘が戻ってきたなら、再度あの積分を解いてしまいましょう。

ルベーグ積分入門―使うための理論と演習

ルベーグ積分入門―使うための理論と演習

ここまで読んでいただき、ありがとうございました。

最後にこの曲を聞いてお別れです。

今年ついに日本中に知られる時なのではないでしょうか。
親心さながら、少し寂しくもありますが。。

(せーのっ)

\\\ かくれんぼ //

AliA「かくれんぼ」MV

効果検証入門 Day02 - t検定

はじめに

 こちらは、効果検証入門の備忘録Day02です。
 前回記事はこちらからどうぞ。
 また、使用している書籍は、こちらのものになります。巷では読んでいる人がどんどん増えてきていて、読まなきゃ読まなきゃと少し煽られる本ですね。

 正直、私は統計学を勉強し始めたばかりなので、知識が十分ではありません。なので、こちらの某有名な統計入門書を参考に学習を進めております。いつか統計学入門に関しても記事にできたらな。確率密度関数とか分布とか、検定とか、自分用にわかりやすくまとめたいです。

統計学入門 (基礎統計学Ⅰ)

統計学入門 (基礎統計学Ⅰ)

  • 発売日: 1991/07/09
  • メディア: 単行本

 効果検証入門ですが、前回まで読んでいたところまでは言葉による説明が中心だったため気にならなかったのですが、いざ数式が出てくる部分を読んでいると「この分散って何だ?」とか「この式ってどう出てきたの?」とかって感じることが多いんですね。
 統計の基礎が固まっている人ならわからなくても無視する何の苦労もないのだろうと思います、実務で使用する人ならこういうものだと呑み込んで仕舞えばいい、だがしかし勉強している身からするとどうだ。そこで理解が止まってしまう。
 なので、今回の記事では本書籍内でざっくりとしか描かれていない部分に関しても参考書「統計学入門(基礎統計学Ⅰ)」を読みながら丁寧に説明していけたらと思います。

本記事について

内容と対象者

 本記事は、セレクションバイアスの影響を有意差検定;t検定で判定することが目的です。しかし、t検定の部分で私が「ん?」と理解が止まってしまったので、この記事のメインはt検定とは何か?という部分になります。ついでに、似ている有意差検定である \chi^{2}検定についても触れていきます。効果検証入門の流れに沿って進めますが、著作権の都合上、基本的には「私の解釈」を述べていきます。
 t検定って何?実際どう使うの?という方にはこちらの記事はタメになると思います。

キーワード

  • 有意差検定 test of significant :: ある仮説に基づき、標本から推定した結果が統計学的に有意であるかどうかを知るための検定
  • t検定 t-test :: 母集団の母平均に関する検定
  •  \chi^{2}検定 Chi-squared test :: 母集団の母分散に関する検定
  • スチューデントのt統計量 Student's  t-statistics :: 標本分散を用いて表される、標本平均の標本分布を標準化した統計量
  • 標準誤差 standard error :: データから得られた推定量が、母集団における真の値とどれだけずれているかを表す値
  • 帰無仮説 null hypothesis :: 何もない、差異はない、などを意味する仮定(有意差検定はこれを棄却できるかどうか判定することが目的)
  • 対立仮説 alternative hypothesis :: 帰無仮説と反対の意味を持つ仮定(帰無仮説が棄却された時に採択される)
  • 有意水準 significance level :: どの程度をもって帰無仮説を棄却するかの基準となる値(通常5%、1%あたりが採用される)
  • t値 t-value :: t検定で使用される検定統計量
  • p値 p-value :: 帰無仮説の下で実際にデータから計算された統計量よりも極端な(仮説に反する)統計量が観測される確率

本記事で使用する記号・添字

  •  Y :: 被説明変数(本記事内では売上を表す)
  •  Y^{(0)} :: 介入が無かった場合の被説明変数
  •  Y^{(1)} :: 介入が有った場合の被説明変数
  •  Z :: 介入(本記事ではメール配信の有無;0 or 1を表す)
  •  N :: 標本のサンプル数
  •  E[Y] :: 期待値(母集団における Yの平均)
  •  E[Y|Z] :: 条件付き期待値(母集団における Y|Zの平均;ある変数 Zがある値をとるときの Yの期待値)
  •  \bar{Y} :: 平均(標本における平均)
  •  V :: 分散(標本における不偏分散
  •  \tau :: 母集団における介入による効果
  •  \hat{\tau} :: 標本における介入による効果
  •  H_{0} :: 帰無仮説
  •  H_{1} :: 対立仮説

 ややこしいですよね。「期待値」と称されるものは母集団に関するもの、「平均」と称されるものは母集団からサンプリングされた標本に関するもの、です。また、標本において算出される「分散」と称されるものも、不偏分散を表しています。このあたり、書籍内でも明記してホヂ、、、、、

前提

 本記事内では、上に示した記号を使用して「メール配信の有無による売上への影響(メールという介入に対する売上という効果)」について、t検定を用いて検証していきます。
 そこで、まずは話を進める上で前提となる定義付けをやっていきます。

想定しているシチュエーション

 これは前回記事に引き続きなのですが、舞台はメールマーケティングです。とあるECサイトが顧客に対して購買を促す、いわばクーポンのようなメールを配信します。そのメールが配信された顧客と、配信されなかった顧客との比較を行うことでこのクーポンメールの配信(介入)が売上にどれだけ影響するのか(効果)を知りたいわけです(ABテストなんて呼ばれたりしますね)。
 ただ、メールの配信は全顧客を対象にすることはできません。観測されるデータの裏には、潜在的に観測しうる全てのデータを含む母集団がいます。今回観測されたデータを用いて、この母集団における介入の効果・性質を推測することになります。このように、観測可能なデータから母集団の性質を推測することを推定と言います。本記事ではこの推定をやっていくのです。

効果が孕むセレクションバイアス

 介入の有無は、 Zで表されます。とあるサンプル iに対して、介入が行われた場合を1、行われなかった場合を0とします。

 {
\begin{eqnarray}
Z_{i} =\left\{ \begin{array}{ll}
 1 & (with \ treatment) \\
 0 & (without \ treatment)
 \end{array}\right.
\end{eqnarray}
}

 また、サンプル iの売上に関しては、介入の有無によって次のように書かれます。

 {
\begin{eqnarray}
Y_{i} =\left\{ \begin{array}{ll}
 {Y_{i}}^{(1)} & (Z_{i}=1) \\
 {Y_{i}}^{(0)} & (Z_{i}=0)
 \end{array}\right.
\end{eqnarray}
}


もしくは、

 {
Y_{i} = (1 -Z_{i}){Y_{i}}^{(0)} + Z_{i}{Y_{i}}^{(1)}
}

 このように、あるサンプル iに介入があった場合の { Y_{i} }^{(1)} と無かった場合の { Y_{i} }^{(0)} が存在し、その差が介入の効果であると考える枠組みをポテンシャルアウトカムフレームワーク (Potential Outcome Framework)といい、因果推論の根本問題により観測されない方をポテンシャルアウトカムといいます。
 この枠組み内において、介入の効果は

 {
\tau = {Y_{i}}^{(1)} - {Y_{i}}^{(0)}
}

で表される。しかし、この { Y_{i} }^{(1)}  { Y_{i} }^{(0)} は同一サンプルからは片方しか入手できません。そこで、介入を受けたサンプルとそうでないサンプルに分け、それぞれの期待値の差、すなわち

 {
\tau = E[{Y_{i}}^{(1)}] -E[{Y_{i}}^{(0)}]
}

が、介入の効果であると考えます。ここで、 E[{ Y_{i} }^{(1)} ]と E[{ Y_{i} }^{(0)} ]はそれぞれ、介入があった場合となかった場合の期待値(母集団における平均)です。このような、母集団における期待値の差分によって得られる平均的な効果は平均処置効果 (Average Treatment Effect; ATE)と呼ばれます。
 それに対し、今回観測可能なデータ(標本)から推測される介入の効果は、

 {
\displaystyle
\begin{equation}
\hat{\tau}_{naive} = \frac{
\sum_{i=1}^{N} Y_{i}Z_{i}
}{
\sum_{i=1}^{N} Z_{i}
} - \frac{
\sum_{i=1}^{N} Y_{i}(1-Z_{i})
}{
\sum_{i=1}^{N} (1-Z_{i})
}
\end{equation}
}

と表されます。これは、母集団に対する条件付き期待値の差である

 {
\displaystyle
\begin{equation}
\tau_{naive} = E[Y^{(1)}|Z=1] - E[Y^{(0)}|Z=0]
\end{equation}
}

を推定していることになります。データの平均の差は母集団の期待値の差そのものではなく、母集団の「ある条件を満たした」条件付き期待値の差だったんですね。データをそのまま解釈してもそのまま母集団の期待値の差を比較しているわけではないというわけです。
 この式を、 \tau = E[ {Y_{i}}^{(1)} ] - E[ {Y_{i}}^{(0)} ] であることを利用し変形していくと、

 {
\displaystyle
\begin{eqnarray}
\tau_{naive} &=& E[Y^{(1)}|Z=1] - E[Y^{(0)}|Z=0] \\
&=& E[Y^{(1)}|Z=1] - E[Y^{(0)}|Z=1] + E[Y^{(0)}|Z=1] - E[Y^{(0)}|Z=0] \ \ (\because - E[Y^{(0)}|Z=1] + E[Y^{(0)}|Z=1] = 0) \\
&=& E[Y^{(1)} - Y^{(0)}|Z=1] + E[Y^{(0)}|Z=1] - E[Y^{(0)}|Z=0] \\
&=& E[Y^{(1)} - Y^{(0)}] + E[Y^{(0)}|Z=1] - E[Y^{(0)}|Z=0] \ \ (\rm \because no\ relation\ between\ Z\ and\ effect)\\
&=& \tau + (\rm Selection\ bias)
\end{eqnarray}
}

となる。すなわち、母集団における条件付き期待値の差分は、本来観測したい介入に対する効果と、セレクションバイアスの和であることを意味しています。もしもセレクションバイアスが0なのであれば、条件付き期待値の差である \hat{\tau}_{naive} は本来の効果 \tauと等しくなるため、介入の効果を正しく推定できていることになるのです。

セレクションバイアスが E[Y^{(0)}|Z=1] - E[Y^{(1)}|Z=0]で表されるというこの式から、以下のことがわかります。

  • 介入 Zが介入がないときの目的変数(ここでは、潜在的な購買意欲) Y^{(0)}が高いサンプルに多く振られるとき、介入の効果 \tau過剰に評価される
  • 介入 Zが介入がないときの目的変数(ここでは、潜在的な購買意欲) Y^{(0)}が低いサンプルに多く振られるとき、介入の効果 \tau過小に評価される

 すなわち、セレクションバイアスが抱えている問題というのは、「データから得られる推定結果は、介入の本来の効果である E[Y^{(1)} - Y^{(0)}|Z=1 ]とセレクションバイアスである E[Y^{(0)}|Z=1] - E[Y^{(1)}|Z=0]を足し合わせた別の値である」ということなのです。推定している値がそもそも興味のある値ではない状況でデータのサンプルサイズを増やしたところで、この興味のない別の値を精度良く推定するだけなのです。

有意差検定

(本節は参考書「統計学入門(基礎統計学Ⅰ)」第12章を参考にしております。非常に良い、辞書のように簡単に使用できる参考書なのでぜひ一度手に取ってみてください。)

統計学入門 (基礎統計学Ⅰ)

統計学入門 (基礎統計学Ⅰ)

  • 発売日: 1991/07/09
  • メディア: 単行本

 「推定」の考え方は数学的にはごく単純なものであり、「仮説検定」もまた人間の論証感覚を定式化したものであり、ごく自然で理解しやすい。その目的は、「母集団について仮定された命題を、標本に基づいて、検証すること」である。重要なのは、得られた結果の理論比からのずれが誤差の範囲内か、それともそれ以上の何かの意味のあるものか、ということである。後者の場合、統計学では、その仮説(からのずれ)は有意 (significant)であるという。ここで立てられた仮説を統計的仮説 (statistical hypothesis)といい、この仮説検定こそが統計的仮説の有意性検定 (test of significance)である。
(効果検証入門中では有意差検定と表現されているが、統計学入門ではそれを有意性検定と称しているだけであり、本質としては一緒である*1

t検定を用いた有意差検定

さて、効果検証入門§1の最難関ポイント、t検定です。いよいよです。
「t検定?基本だろ今更何言ってんだよ」という方はもう十分です。お疲れ様でした。
「t検定って何だっけ。。聞いたことはあるけどなんだっけ。。」

はいそこのあなた!!きましたよー!!僕と一緒にこっそりt検定を勉強するチャンスですよ!!
ちゃっかりこっそり勉強して、明日から何食わぬ顔で「は?t検定も知らないのかよ使えねーな」とかましてやりましょう。ビッグになるのです!!

 さて。下らぬ前振りはここまでにしましょう。ここで、私かまず最初に抱いた疑問から順に解決していきましょう。

お勉強の時間

t検定?カイ二乗検定

 ここです。諸学者である私は、まずこれから使用するのがどっちなのか、結局t検定なのですが、どうしてt検定なのか、と勝手につまづきました。ここでは、これらの違いを簡単に述べるに留めることにします。
 すっごく簡単にいうと、正規母集団の母平均に対する検定をt検定母分散に対する検定を \chi^{2}検定というのです。今回は、介入の有無による母平均の差 \tauを知りたいわけですから、使用するのはもちろんt検定ですね。基本的に考え方は似ているので、いっそのことどちらも丁寧に説明してしまいましょうか。なお、このt検定と \chi^{2}検定の説明に際しては、記号は統計学入門で使用されているものに準じます。説明で使用するだけです。混同しないように注意されたいですね(ボクも注意して書きます)。

t検定とは

まず大前提として、以下の2つを満たす必要があります。

  • サンプル数が十分あること(30以上):標本平均に対する中心極限定理の適用(正規分布に近似)
  • 比較する集合の母分散が等しい

正規母集団 \mathcal N(\mu, \sigma^{2})の母平均 \muに関する検定である。
ここで、サンプル数 nの確率変数 X

 {
\displaystyle
\begin{equation}
X_{0}, X_{1}, X_{2}, ... , X_{n} \stackrel{i.i.d.}{\sim} \mathcal N(\mu, \sigma^{2})
\end{equation}
}

であるとする。ここで、 i.i.d.とは、independent and identically distributedの略称で、日本語では独立同一分布なんて言われたりする(つまり、確率変数が互いに独立で、かつ同じ確率分布を持つこと)。すなわち、これらの平均である標本平均 \bar{X} \bar{X} \sim \mathcal N(\mu, \frac{\sigma^{2}}{n})である。

検定統計量の決定

母分散 \sigma^{2}が既知であるとき

標本平均 \bar{X}の標本分布は、それを標準化した Zについて

 {
\displaystyle
\begin{equation}
Z = \frac{\bar{X} - \mu}{ {\sigma}/\sqrt{n} } \sim \mathcal N(0, 1)
\end{equation}
}

を満たす(ここで使用している Zは介入とは無関係です。表記を統計学入門に合わせてあります、ご容赦ください)。

母分散 \sigma^{2}が未知であるとき

母分散が既知である、という仮定はそもそも現実的ではないです(母平均を知りたいのに、それより先に母分散、母標準偏差と言った情報が手に入るか?という疑問。じゃあ説明するな)。そこで、母分散の代わりに標本分散 s^{2}を使用する。ここで、標本分散 s^{2}

 {
\displaystyle
\begin{equation}
s^{2} = \frac{ \sum_{i=1}^{n} X_{i} - \bar{X} }{ n-1 }
\end{equation}
}

のように求まる。これを母平均の代わりに用いることで、

 {
\displaystyle
\begin{equation}
t = \frac{\bar{X} - \mu}{ \sqrt{s^{2} / n} } 
\end{equation}
}

を定義する。これをスチューデントのt統計量 (Student's t-statistic)という*2。この確率分布は、標準正規分布  \mathcal N(0, 1)に従わない。これを変形すると、

 {
\displaystyle
\begin{eqnarray}
t &=& \frac{\bar{X} - \mu}{ \sqrt{ {s^{2} / n } } } \times \frac{1}{ \sqrt{\frac{ \sigma^{2} }{ \sigma^{2}} }} \\
&=& \frac{ \frac{\bar{X} - \mu}{ \sqrt{ \sigma^{2} / n } } }{ \sqrt{s^{2} / \sigma^{2}} } \\
&=& \frac{ \frac{\bar{X} - \mu}{ \sqrt{ \sigma^{2} / n } } }{ \sqrt{ \frac{   \frac{ (n-1) s^{2} }{ \sigma^{2} } }{ n-1 } } } 
\sim \frac{ \mathcal N(0, 1) }{ \chi^{2}(n-1) }
\end{eqnarray}
}

を得る。つまり、分子は標準正規分布 \mathcal N(0, 1)に、分母は自由度 n-1 \chi^{2}分布 \chi^{2}(n-1)に従うことを意味する。さらに、正規分布の確率密度の計算から、 \bar{X} s^{2}は互いに独立であるので、 \mathcal N(0, 1) \chi^{2}(n-1)の組み合わせから、tの密度関数が決定される。正規標本論では、これはt分布と呼ばれており、自由度 kのt分布 t(k)は次のように定義される。

 {
\displaystyle
\begin{equation}
t = \frac{Z}{ \sqrt{Y / k} } \sim t(k) = \frac{ \Gamma{ ({\frac{k+1}{2}}) }} { \sqrt{ k\pi } \Gamma{ (\frac{k}{2}) } } {(1 + \frac{{t^2}}{k})}^{ -\frac{k+1}{2} }
\end{equation}
}

f:id:K_PTL:20200301031459p:plain

ここで、 Z \sim \mathcal N(0,1) Y \sim \chi^{2}(k)であり、 Z Yは独立である。これによると、前述の

 {
\displaystyle
\begin{equation}
t = \frac{\bar{X} - \mu}{ \sqrt{s^{2} / n} } 
\end{equation}
}

で定義されたt統計量は、自由度 n-1のt分布 t(n-1)に従い、この分母である \bar{X}標準偏差 \sqrt{s^{2} / n}は、標本平均 \bar{X}標準誤差 (standard error)と呼ばれている。

両側検定の場合

検定の有意水準 \alphaとする。
帰無仮説、対立仮説は

 {
\displaystyle
\begin{equation}
H_{0} : \mu = \mu_{0} , ~~~~~ H_{1} : \mu \neq \mu_{0}
\end{equation}
}

で与えられる。

 \sigma^{2}が既知であるとき
前述の通り、検定検定量 Z

 {
\displaystyle
\begin{equation}
Z = \frac{\bar{X} - \mu}{ {\sigma}/\sqrt{n} }
\end{equation}
}

で与えられる。帰無仮説 H_{0}が正しい場合、  \mu = \mu_{0}において Z \sim \mathcal N(0, 1)である。また、標準正規分布は原点に対して対称であるため、標準正規分布表から得られるパーセント点*3 Z_{\alpha/2}と比較して、

 \sigma^{2}が未知であるとき
前述の通り、検定統計量はスチューデントのt統計量

 {
\displaystyle
\begin{equation}
t = \frac{\bar{X} - \mu}{ \sqrt{s^{2} / n} } 
\end{equation}
}

を使用する。帰無仮説 H_{0}が正しい場合、  \mu = \mu_{0}の時には t \sim t(n-1)であるので、t分布表から得られるパーセント点*4 t_{\alpha/2}(n-1)と比較して、

片側検定の場合

検定の有意水準 \alphaとする。
帰無仮説、対立仮説は

 {
\displaystyle
\begin{equation}
H_{0} : \mu = \mu_{0} , ~~~~~ H_{1} : \mu > \mu_{0}
\end{equation}
}

で与えられる(右片側対立仮説を考える)。

 \sigma^{2}が既知であるとき
両側検定の時と同様に検定統計量 Zを計算し、

 \sigma^{2}が未知であるとき
両側検定の時と同様にt統計量 tを計算し、

カイ二乗検定とは

正規母集団 \mathcal N(\mu, \sigma^{2})の母分散 \sigma^{2}に関する検定である。
ここで、サンプル数 nの確率変数 X

 {
\displaystyle
\begin{equation}
X_{0}, X_{1}, X_{2}, ... , X_{n} \stackrel{i.i.d.}{\sim} \mathcal N(\mu, \sigma^{2})
\end{equation}
}

であるとする。これらの分散である標本分散 s^{2}

 {
\displaystyle
\begin{equation}
s^{2} = \frac{ \sum_{i=1}^{n} X_{i} - \bar{X} }{ n-1 }
\end{equation}
}

である。

検定統計量の決定

 {
\displaystyle
\begin{equation}
\chi^{2} = \frac{ (n-1)s^{2} }{ \sigma^{2} } \sim \chi^{2}(k)|_{k=n-1} = \frac{1}{ 2^{ \frac{k}{2} } \Gamma{ (\frac{k}{2}) } } x^{ \frac{k}{2}-1 } e^{ -\frac{x}{2} }
\end{equation}
}

である。この \chi^{2}を検定統計量とする。

f:id:K_PTL:20200301033217p:plain

検定方法

検定の有意水準 \alphaとする。
帰無仮説 H_{0}

 {
\displaystyle
\begin{equation}
H_{0} : \sigma^{2}  = {\sigma_{0}}^{2}
\end{equation}
}

とする。t検定の時とは異なり、対立仮説によって検定範囲、棄却域が変化する。帰無仮説 H_{0}が正しい場合、  \sigma^{2}  = {\sigma_{0}}^{2}の時には \chi^{2} \sim \chi^{2}(n-1)であるので、 \chi^{2}分布表から得られるパーセント点*5 {\chi_{1-\alpha/2}}^{2}(n-1) {\chi_{\alpha/2}}^{2}(n-1)などを求めておく。

パターン1

対立仮説 H_{1} : \sigma^{2}  \neq {\sigma_{0}}^{2}の時、両側検定を実施する。

パターン2

対立仮説 H_{1} : \sigma^{2}  > {\sigma_{0}}^{2}の時、右片側検定を実施する。

パターン3

対立仮説 H_{1} : \sigma^{2}  \lt {\sigma_{0}}^{2}の時、左片側検定を実施する。

実際に行うt検定のプロセス

ここから、再び話を効果検定入門に戻します(使用する記号も元に戻します)。クーポンメールという介入の効果を検証するためにt検定を実施するのですが、それは次の手順で実施していきます。

  1. 標準誤差の算出
  2. 効果の推定値と標準誤差を使ってt値を算出
  3. t値を使用してp値を算出
  4. p値を有意水準と比較する

 これらのプロセスを一つ一つ見ていきます。なお、今回は母集団の分布が事前にわかっており、その分布の形状を特定するために必要なパラメータを推定する作業を行います。この母集団に帰属するパラメータの真の値を母数といい、母数を推定することをパラメトリック推定なんて呼んだりします。
 なお、今回の検定における帰無仮説は、「介入の有無に依らずそれぞれの期待値は等しい」です。検定を用いて、この帰無仮説を棄却する、すなわち2つの母集団間の期待値は等しくなく、介入には一定の効果があることを示すか、棄却せずに期待値が等しいという可能性を残すか、を判定します。ここで大事なのは、検定では、帰無仮説を棄却する、つまり否定することはできても肯定することはできません。ただ、そうなる可能性があるということを示すのみです。よって、本来知りたいこととは逆のことを帰無仮説に設定し、その可能性を否定することで本当に欲しい情報を手に入れる、という手法が取られることが一般的です。

標準誤差の算出

標準誤差 SEは、t検定について説明した際に述べた通り、一標本問題に対しては標本平均 \bar{Y}を用いて

 {
\displaystyle
\begin{equation}
SE = \sqrt{\frac{V}{n}} = \sqrt{ \frac{ \frac{ \sum_{i=1}^{n} (Y_{i} - \bar{Y})^{2} }{ n-1 } }{n} }
\end{equation}
}

で与えられる ( s^{2} \rightarrow Vで表記)。ここで、n-1は自由度であり、一標本に対して分散を計算するごとに1つ自由度が失われます( Y_{1}, ... , Y_{n}まで考えた時、 Y_{n-1}まで決定されると、自動的に \bar{Y}を基に Y_{n}が決定されます。このように、最後の1つに対しては自由に決定できない、つまり自由度を1つ失うことになるのです)。
 しかし、今行おうとしているt検定は、介入がなかった標本介入があった標本の2つの標本に対して実施するものです。これは二標本問題と呼ばれ、この場合の標本分散 Vは、次式で表されます。

 {
\displaystyle
\begin{equation}
V =  \frac{ \sum_{i=1}^{n}{ ({Y_{i}}^{(0)} - \bar{Y}^{(0)}) }^{2} +  \sum_{i=1}^{m}{ ({Y_{i}}^{(1)} - \bar{Y}^{(1)}) }^{2}  }{ m+n-2 }
\end{equation}
}

わかりますでしょうか。標本が2つ使用されているため、自由度は合計2つ失っています。この標本分散を用いて、標準誤差は

 {
\displaystyle
\begin{equation}
SE = \sqrt{ \frac{V}{n} + \frac{V}{m} } 
\end{equation}
}

と求まります。

効果の推定値と標準誤差を使ってt値を算出

スチューデントのt統計量は、前述した通り

 {
\displaystyle
\begin{equation}
t = \frac{\bar{Y} - \mu}{ \sqrt{ {V / n } } } \sim t(n-1)
\end{equation}
}

で表される ( s^{2} \rightarrow Vで表記)。これは、「グループ間(異なる標本間)の平均の差が標準誤差の何倍あるか」を示しており、今回は

 {
\displaystyle
\begin{equation}
t = \frac{\bar{Y}^{(1)} - \bar{Y}^{(0)}}{ SE } \ \ ( \because \mu^{(1)}=\mu^{(0)} )
\end{equation}
}

で表されるt値を検定統計量とする。

t値を使用してp値を算出

 p値は、得られた推定結果が、本当の効果が0であるにも関わらず得られてしまう確率のことです。これまでのお勉強セクションでは、有意水準 \alphaに対応して求められる積分値(確率密度函数の面積、すなわち確率そのもの)を使用し、帰無仮説を棄却するかどうかというお話をしておりました。
 p値の算出については、手作業であればt分布表を用いて計算するのだけれど、昨今は自動で計算してくれるプログラムも充実しているため、ここでは特記しません。解く方程式は、注釈にリンクで示してあります。積分計算、つまり面積の算出です。p値がどういうものであるのかについてのみわかっていれば十分です。

p値を有意水準と比較する

 最後に、得られたp値(確率密度関数のある範囲における面積)と有意水準と呼ばれる値を比較します。有意水準は、推定を行う人が勝手に決めていいものですが、慣習的に5%と設定されることが多いです(ただ、10%のものも見たことがあるので一概には言えません。ケースバイケースです)。
 比較した結果、p値が有意水準よりも小さい場合、帰無仮説は棄却されます。逆にp値が有意水準よりも大きい場合には、帰無仮説を否定することはできません。

※p値の代わりに、信頼区間を利用した意思決定が行われる場合もあります。信頼区間は標準誤差から算出され、「95%の信頼区間」という時には「推定値±1.96×標準誤差」を指します。この95%信頼区間内に0を含んでいる場合には、95%信頼区間はp値が5%よりも高い状態(有意水準を5%とした時、有意水準よりもp値が高い確率)と同じ意味を持つことになります。

Pythonによるt検定

 効果検定入門は、Rで書かれていますが、昨今の世の中ではPythonが爆発的に普及していること、Rと同じことができることから、ここではt検定をPythonで実装し、クーポンメールという介入には実際に効果があるのか、セレクションバイアスはt検定にどのような影響を与えるのかについて見ていきたいと思います。
 ここで使用するデータセットは、「MineThatData E-Mail Analytics And Data Mining Challenge dataset」を使用します。このデータセットは、ECサイトのユーザに対してRCTを適用したメールマーケティングを行ったものです。
 なお、ここで使用しているPythonのコードは、GitHubに上げています。この記事は、Python講座を行いたいわけではないので、本記事に記載するコードは最小限とします。ご了承ください。

データセットの概要

変数名 説明
recency 最後の購入からの経過月数
history_segment 昨年の購入額の階層
history 昨年の購入額
mens 昨年に男物の商品を購入しているタグ
womens 昨年に女物の商品を購入しているタグ
zipcode zipcodeをもとに地区を分類したもの
newbie 過去12ヶ月以内に新しくユーザになったか?
channel 昨年においてどのチャネルから購入したか?
segment どのメールが配信されたか?
visit メールが配信されてから2週以内にサイトへ来訪したか?
conversion メールが配信されてから2週以内に購入したか?
spend 購入した際の購入額

 Pythonでデータセットを読み込みました。データはこんな感じになっています。一番左の列はindexを表しているので、特別意味はありません。

f:id:K_PTL:20200227235408p:plain

f:id:K_PTL:20200227235820p:plain

データは全部で64,000件あります。MineThatData E-Mail Analytics And Data Mining Challenge datasetによると、男女のメール配信された人と、メール配信されていない人が1/3ずつの割合で存在しているようですが、、

f:id:K_PTL:20200228000538p:plain

確かに、ほぼ1/3ずつデータが入っているようです。

(バイアスなし)男性向けメール配信 vs. メール配信なし

 さて、本と同様に分析を進めていきます。まず、こちらから「男性向けのメールが配信されたサンプル」と「メールが配信されなかったサンプル」のみを抽出します。そしてそれらに対して、メール配信の有無によってconversion(購入の有無)とspend(購入額)がどのように異なるのか、その平均を比較します。

f:id:K_PTL:20200228002719p:plain

 男性向けメールが配信されたサンプルは、conversion発生率が平均1.25%、購入額が1.42(単位不明)であったのに対し、メールが配信されなかったサンプルはconversion発生率が平均0.57%、購入額が0.65と大きく離れました。この分析結果は、「メール配信という介入が売上増加という効果がある」ことを示唆しています。

 ではここで、実際に有意差検定、ここでは平均値を比較しているため、t検定をやってみましょう。

f:id:K_PTL:20200228003019p:plain

 t統計量、p値がそれぞれ5.3、1.16E-07であるという結果が得られました。今、帰無仮説は「メールという介入の有無に依らず期待値は等しい」ということでした。今回、有意水準を5%としており、得られたp値は有意水準を下回ります。よって、帰無仮説は棄却され、この介入の有無による売上の差、すなわち介入の効果は統計的に有意であるということが示されました。今、有意差検定に使用したデータはRCTによるものであるため、セレクションバイアスの問題もないと考えられます。
 では、セレクションバイアスがある場合の有意差検定はどのようになるのでしょうか?

(バイアスあり)男性向けメール配信 vs. メール配信なし

 バイアスのかかったデータセットを作成します。先ほどまで使用していた、女性向けメールが配信されたサンプルを除外したデータセットに対して、さらにサンプリングを、しかも恣意的にバイアスをかけた状態で実施します。
 メールが配信されていないサンプルに対してのバイアスの条件は、

  • history > 300 ... 昨年の購入金額が300未満
  • recency < 6 ... 最後の購入してから6ヶ月以内
  • channel = "Multichannel" ... 昨年に複数のチャネルから商品を購入している

のいずれかを満たしている場合であり、それに該当するサンプルのうちランダムに半分削除します。これによって、メールが配信されていないサンプルは、購買意欲が平均的に下がるほうへバイアスがかかりました。  逆に、男性向けメールが配信されたサンプルに対しては、上の3つの条件のいずれにも該当しないサンプルのうちランダムに半分を削除します。これによって、男性向けメールが配信されたサンプルは、購買意欲が平均的に上がるほうへバイアスがかかりました
 先ほどと同じように、バイアスのかかったデータセットに対して、メール配信の有無によってconversion(購入の有無)とspend(購入額)がどのように異なるのか、その平均を比較します。

f:id:K_PTL:20200228005512p:plain

 バイアスがかかっていないデータセットでは、男性向けメールが配信されたサンプルは(conversion, spend)=(1.25%, 1.42)、メールが配信されなかったサンプルは(conversion, spend)=(0.57%, 0.65)でした。バイアスがかかることで、男性向けメールが配信されたサンプルは(conversion, spend)=(1.36%, 1.54)とどちらも増加し、メールが配信されなかったサンプルは(conversion, spend)=(0.45%, 0.56)とどちらも減少しました。意図した通りのセレクションバイアスが発生しています。
 このバイアスがかかったデータセットに対して有意差検定;t検定を実施するとどうなるでしょうか。

f:id:K_PTL:20200228010603p:plain

t統計量、p値がそれぞれ5.59、2.21E-08であるという結果が得られました。このセレクションバイアスが発生しているデータセットでも、p値は有意水準5%未満であり、帰無仮説を棄却、すなわち介入による効果が統計的に有意なものであることを示せてしまいました。先程の、バイアスがかかっていないデータセットに対するt統計量、p値がそれぞれ5.3、1.16E-07であったことから、セレクションバイアスが発生することで介入の有無による平均的な差は広がり、不確実性はより低くなったということです。
 今回の有意差検定の手法は何一つ変更していません。しかし、明らかにセレクションバイアスが発生しているにも関わらず、逆に統計的により有意であることが示されてしまいました。このことから、統計的に有意な差があればどんな結果も正しい効果が推定できていると考えることはできないということがわかります。

ビジネスにおける因果推論の必要性

  • RCTによってランダムにアクションを選択することは、分析する上で非常に都合の良い状況を作り出す一方で、ビジネスを実施する側にとっては大きなコストとなってしまうことが多々ある
  • 分析者が事象の理解、特にセレクションバイアスの理解から分析を設計する必要がある
  • 分析者が認知していないセレクションバイアスの影響を取り除くことはできない

非常に興味深いことが記載されていました。ざっくりとまとめると、次のことです。
 ある施策を始める時に、バイアスのある評価を行い、その評価結果をもとに施策の改善を考えたとしましょう。すると、次に設計・実行される施策もまたバイアスを孕んでおり、それを評価することでさらにバイアスを生み出していく、という負のスパイラルに陥ってしまうことが、ビジネスにおいては最も警戒すべき状況です。この状況下では、次のような問題が生じます。

  • 本当にKPIが改善されているかわからないものにコストを支払い続ける
  • 蓄積される知見の多くがセレクションバイアスの作り方になってしまう

...どうでしょう。面白くないですか?真実を知りたいのに、真実を知るために一派データを集めて分析したのに、コストもいっぱいかけたのに、それはより正確な嘘に近づいていっている、というのです。怖い。怖いですね。これこそ、第一章で最も大切なことなのではないかと思います。

おわりに

 いかがだったでしょうか?t検定について知りたくてこのブログに辿り着いた方もいるかもしれません。でも、本当に正しく効果を検証できていますか?
 「効果検証入門」は、まだ全部読み終わったわけではないですが、非常に勉強になります。何より、この恐ろしい悪夢から醒める術を教えてくれるのですから。対魔的な、ホーリー感があります。詳しく知りたくなった方は、ぜひ一度目を通してみるといいと思います。面白いですよ。

 また、最初にも述べましたが、t検定についてわからない、正規分布もt分布もベータ分布もよくわからない、という人は一度、統計学入門のような広く統計学の基礎についてまとめられている本に目を通してみるといいと思います。インターネット上からは拾えない情報がいっぱい詰まっていますよ。

統計学入門 (基礎統計学Ⅰ)

統計学入門 (基礎統計学Ⅰ)

  • 発売日: 1991/07/09
  • メディア: 単行本





正直今回、こんなに書く予定なかった、、、すごく疲れた、、、疲れた、、、
疲れた分、皆さんの理解の助けになったら嬉しいです、、、


最後にこの曲を聞いてお別れです。

このブログのタイトル名の由来である、大好きなラウドバンドです。

(せーのっ)

\\\ Another day comes //

Pay money To my Pain【Another day comes】

*1:もし違っていたら教えてください

*2:「スチューデント」は、これを定義したゴゼット (William Gosset)の仮名に由来する

*3: Q(\alpha)=1-\Phi(\alpha)=\int_{\alpha}^{\infty}{\phi(u)du} Qについて解くことで求まる

*4: t_{\alpha}(\nu): \int_{t_{\alpha}}^{\infty}{ \frac{1}{ \sqrt{\nu}B(\frac{1}{2}, \frac{1}{2})(1 + \frac{t^{2}}{\nu}) }dt = \alpha } t_{\alpha}について解くことで求まる

*5: {\chi_{\alpha}}^{2}(\nu): \int_{{\chi_{\alpha}}^{2}}^{\infty}{ \frac{1}{ \Gamma(\frac{\nu}{2})} {( \frac{\chi^{2}}{2} )}^{\frac{\nu}{2}-1} e^{-\frac{\chi^{2}}{2}} }d\chi^{2} = \alpha  {\chi_{\alpha}}^{2}について解くことで求まる