「ベイズ統計「超」入門」を読んだ

どんな本?

200年以上前に発見されたベイズの定理を優しく解説
サブタイ通り,曖昧なデータから未来を予測する技術を実例を用いて解説してくれる

社内研修の統計講座という設定で話は進んでいく
統計インストラクターのお姉さんと社内研修を受ける社員2名の掛け合いがメイン
あと社員のお兄さんがアドバイスをくれる

どこがよかった?

実例がちょうどよかった
想像しやすく,ベイズの考えも理解出来た

学んだ技術や手法

ベイズ統計の概要
ベイズの定理
理由不十分の原則
ベイズ更新
ベイズ統計学
簡単なナイーブベイズ

どうやって進めたか

ひたすら読んだ

感想

学生時代に講義でならった「同時確率」や「条件付き確率」など確率の基本の復習になった.また,「事前確率」や「尤度」,「事後確率」を用いるベイズの定理への流れが単純明快で読みやすかった

確率分布や確率密度関数中心極限定理積分など
高校から学んできた数学的知識が線でつながるような感覚がした

次に読む本

手を動かして微分積分したくなってきたので大学数学的な参考書やりたい

VMインスタンスが立たない!

GCPマジわからん! こんにちは元無職です
今回はここ数日で頑張ったことを書きます

頑張ったこと

  1. GCEでVMインスタンス(GPU)を立てる
  2. ディープラーニング環境構築(Docker + PyTorch)

前編として、1の躓きについてメモ

VMインスタンスを立てたかっただけなのに

クラウドに環境構築したかったのでGCPを使ってVMインスタンスを立てる事にしました。

まず、GCPのナビゲーションメニューからCompute Engine を選択し、VMインスタンスを選択します。すると、VMインスタンス一覧が表示されます
f:id:sasassasadango:20200303125308p:plain インスタンスを作成ボタンを押下します。

インスタンス作成画面で設定した項目は以下です。

  • 名前
    • 適当に
  • リージョン
    • us-central1を選択しました
  • ゾーン
    • GPUリソースが使える場所を選択(GPUプラットフォーム欄が変化)
  • マシンの構成
    • マシンタイプをn1-standard-4 (4 vCPU, 15 GB メモリ) に変更
  • GPUプラットフォーム
    • 上で選択したリージョンとゾーンでは、NVIDIA Tesla T4 が使用できたのでこれを1枚選択
  • ブートディスク
    • OSはUbuntu、バージョンはUbuntu 18.04 LTS。標準永続ディスク100GBで設定
  • ファイアウォール
    • HTTP トラフィックを許可するにチェック

一番したの作成ボタンを押下するとインスタンスが作られます。書いていない項目はいじっていないです。また、リージョンとゾーンによって使用できるGPUの種類が異なるので注意してください。

ここで、GPUリソースを使用するので割り当ての確認をしておきましょう。
割り当てについてはGCPのナビゲーションメニューのIAMと管理から確認できます。 f:id:sasassasadango:20200303164604p:plain 指標と場所欄からインスタンス作成の際に選んだGPUなどのリソース割り当てを確認します。忘れてはいけないのは、指標でGPUs(all regions)を選択し場所でグローバルも確認することです。 アカウントに対してリソース割り当てがなされていないとインスタンスを立ち上げる際にエラーとなります。

Quota 'GPUS_ALL_REGIONS' exceeded. Limit: 0.0 globally.

これが何回も出て画面を叩き割りそうになったのは秘密です。

インスタンスが立ち上がったらSSH接続を確認してみましょう。
インスタンスを作成する際に、ファイアウォールの設定でHTTP トラフィックを許可するにチェックを付けました。GCPナビゲーションメニューのVPCネットワークファイアウォールルールから詳細を設定できます。
デフォルトではポート80空いてるし、IP全通しだからたぶんSSHできるでしょうということでこの辺は割愛。 SSH接続方法もたくさんあるしね。

後日談

インスタンス立ち上げっぱなしで課金されるので使用しない時は停止していたのですが、使用しようと思ってインスタンスを開始した際にエラーが出ました。

The zone 'projects/hogefuga/zones/us-central1-b' does not have enough resources available to fulfill the request. '(resource type:compute)'.

は?
リソース割り当ても確認してちゃんと使える状態だったしなんなんだと思って調べると、物理的リソースが余っていないとこんなエラーが出るらしい。待てばリソースは空くらしいが…。
待つのは嫌いなので、インスタンスのスナップショットをとってゾーンを変更して新しくインスタンスを立てました。 インスタンス立ち上げっぱなしならこんな事にはならないんだろうけどさ!
対処方法を探しています。

以上。ポチポチやるだけなのに躓くって…

Dockerについて学ぶ〜コンテナの操作〜

はじめに

sasassasadango.hatenablog.com

前回に引き続い,Dockerに入門しています
今回はコンテナの操作についての学習メモ

使用している教材は「Docker/Kubernetes 実践コンテナ開発入門

基本情報

Dockerコンテンは外から見ると仮想環境
ファイルシステムとアプリケーションが同梱された箱のようなもので,実行中・停止・破棄状態に分類される

実行中

docker container runで指定されたDockerイメージを基にコンテナが作成され,DockerfileのCMDやENTRYPOINTで定義されているアプリケーションが実行される

停止

実行中のコンテナはコンテナを停止するか,コンテナで実行されているアプリケーションが停止した場合に自動的に停止状態となる

破棄

停止したコンテナは明示的に破棄しない限りディスクに残り続ける
コンテナの実行・停止を繰り返すような環境ではディスクを専有して行くことになるので,不要なコンテナは破棄する必要がある

コンテナの作成と実行

docker container runはDockerイメージからコンテナを作成,実行するコマンド

$ docker container run [options] イメージ名 [:タグ] [コマンド] [コマンド引数]
$ docker container run [options] イメージID [コマンド] [コマンド引数]

docker container run時に引数を与えることでDockerfileで指定したCMDを上書きできる

docker container runでコンテナを実行する際,docker container lsで表示するNAMESには適当な名前が振られるが,--nameオプションを付与することでコンテナに任意の名前をつけることが出来る

$ docker container run --name [コンテナ名] [イメージ名]:[タグ]
コマンド実行時の頻出オプション

-i: docker起動時にコンテナ側に標準出力を繋いだままにする
-t: 疑似端末を有効にする(-iとセットで使用すし-itと省略可能)
--rm: コンテナ終了時にコンテナを破棄する
-v: ホストとコンテナ間でディレクトリ,ファイルを共有するときに使用する

コンテナ一覧
$ docker container ls [options]
コンテナ停止
$ docker container stop コンテナIDまたはコンテナ名
コンテナの再起動
$ docker container restart コンテナIDまたはコンテナ名

停止したコンテナは破棄しない限り,docker container restartコマンドで再実行できる

コンテナの破棄
$ docker container rm コンテナIDまたはコンテナ名

Dockerコンテナは停止してもディスク上に残り続ける
--rm オプションを付与することでコンテナ停止後に破棄することが出来る

標準出力の取得

docker container logsコマンドは実行している特定のDockerコンテナの標準出力を表示することが出来る

$ docker container logs [options] コンテナIDまたはコンテナ名
実行コンテナでのコマンド実行

docker container execコマンドでは実行しているDockerコンテナ内で任意のコマンドを実行可能

$ docker container exec [options] コンテナIDまたはコンテナ名 コンテナ内で実行するコマンド  
ファイルのコピー

docker container cpで,コンテナ間,コンテナ・ホスト間でファイルをコピー可能

$ docker container cp [options] コンテナIDまたはコンテナ名:コンテナ内のコピー元 ホストのコピー
$ docker container cp [options] ホストのコピー元 コンテナのIDまたはコンテナ名:コンテナ内のコピー元

運用管理コマンド

破棄

docker container pruneで実行していないコンテナを一括削除できる

$ docker container prune [options]

イメージも同様

$ docker image prune [options]

利用されていないDockerコンテナやイメージ,ボリューム,ネットワークといった全てのDockerリソースを一括で削除することも出来る

$ docker system prune
利用状況の取得
$ docker container stats [options] [表示するコンテナID]

所感

メモ書き程度にコマンド並べている程度ですが,教材である「Docker/Kubernetes 実践コンテナ開発入門」には想定する状況が記載されていてイメージしやすかったです
実務で使用するのが楽しみです

Dockerについて学ぶ〜イメージの操作〜

Dockerについて入門したいので,その学習メモ
使用している教材は「Docker/Kubernetes 実践コンテナ開発入門

今回はDockerイメージの操作について

基本情報

Dockerの操作はイメージに関する操作とコンテナに関する操作の2つに大別される

Dockerイメージ

DockerイメージはDockerコンテナを作成するためのテンプレート
OSとして構成されたファイルシステムや,コンテナ上で実行するアプリケーションや依存しているライブラリ・ツール,どのプロセスがコンテナ上で実行されるかと言った実行環境などの設定情報を含んでいる

Dockerコンテナ

Dockerイメージを基に作成される,ファイルシステムとアプリケーションが実行されているもの

Dockerfile

Docker独自のドメイン固有言語を使ってイメージの構成を定義し,FROMやRUNといった命令を記述
Dockerfile自身がDockerイメージになるわけではなく,テンプレートを構築することをDockerイメージをビルドすると言う

ポートフォワーディング

Dockerコンテナは仮想環境なので,外から1つの独立したマシンのように扱えるが,アプリケーションで設定した公開ポートはコンテナポートと呼ばれるコンテナ内に限定されたポートとなる
つまりHTTPリクエストを受けるアプリケーションの場合,コンテナの外から来たリクエストをコンテナ内で実行しているアプリケーションにまで到達させる必要がある

そこでポートフォワーディングdocker container runコマンドに-pオプションでポートを指定する
-pオプションは{ホスト側のポート}:{コンテナポート}の書式で記述

$ docker container run -d -p 9000:8080 hoge/huga:latest

ホスト側のポートは省略可能で,この場合はホスト側で空いているポートが自動的に割り当てられる

Dockerのイメージ操作

イメージのビルド
$ docker image build -t イメージ名[:タグ名] Dockerfile配置ディレクトリのパス
-fオプション

docker image buildコマンドはデフォルトでDockerfileを探す
そうでないDockefileを利用したい場合は-fオプションを利用

--pullオプション

docker image buildでイメージをビルドする際,DockerfileのFROMで指定されているイメージを一度レジストリからダウンロードし,それをベースイメージにして新たにイメージをビルドする
--pullオプションでtrueを指定すると,docker image build時にベースイメージを強制的に再取得させることが出来る
ローカルにベースイメージのキャッシュが存在している場合,Dockerは差分を活かしてビルドしようとする
docker image build時に確実に最新のベースイメージを取得してからイメージをビルドしたい場合は--pull=trueをつける

DockerHub

GitHubと同様にユーザーや組織がリポジトリを持つことでDockerイメージを管理している
docker searchコマンドでDockerHubのレジストリに登録されているリポジトリを検索できる

$ docker search [options] 検索ワード

--limitを指定することで表示件数を制限可能

イメージの取得

DockerレジストリからDockerイメージをダウンロードしてくるには,Docker image pullコマンドを利用する

$ docker image pull [options] レポジトリ名[:タグ名]

docker image pullでダウンロードしてきたイメージは,そのままDockerコンテナとして利用できる

イメージ一覧

docker image lsではコマンドの実行対象であるDockerホストに保持されているイメージの一覧を表示する
Dockerホストとは,Dockerデーモンを実行しているホスト環境

$ docker images ls [options] [リポジトリ [:タグ]]
イメージのタグ付け

docker image tagはDockerイメージのお特定のバージョンにタグ付けを行う
イメージIDはDockerイメージが変更・コピーされた際に変わる
Dockerで1つのタグに紐付けられるイメージは1つまでで,latestは最新のものにしか付けられない
Dockerイメージのタグはある特定のイメージIDを持つDockerイメージを識別しやすくするために利用されており,リリース番号を付けてイメージを管理しやすくするために使われる

イメージの公開

docker image push コマンドは保持しているDockerイメージをDockerHubレジストリに登録できる

$ docker image push [options] リポジトリ名 [:タグ]

DockerHubは自分が所有しているリポジトリにしかPush出来ないのでdocker image tagコマンドでイメージの名前空間を変更する

$ docker image tag example/echo:latest DockerHubのID/echo:latest

docker image pushでイメージを指定してDockerHubへPushする

docker image push DockerHubのID/echo:latest

公開するリポジトリにPushするイメージやDockerfileには,パスワードやAPIキーといった情報を含めないよう注意

所感

イメージとコンテナの関係,Dockerfileの役割を理解したところでDockerとはどんなものなのか分かった気がする
次はコンテナの操作についてやっていく

会社を辞めました

メリークリスマス!リア充爆発しろ!
こんにちは無職です
将来が不安で震えながらこの記事を書いています
この記事は彌冨研 Advent Calendar 2019 24日目の記事です

新卒入社した会社を辞めたので退職エントリを書きます

あんた誰?

彌冨研で人には言えない伝説を作った男
追い出されるように平成最後の年に卒業した者です
これからも宮○先生のC++連続履修回数記録を破るやつは現れないでしょう

なぜITエンジニアに?

まず伝説のじゃんけん大会に始まり…
長くなるので割愛すると彌冨研に入ったことがきっかけです
他の研究室だったらコード書きてぇなんて言っていなかったでしょう

そんなこんなでITエンジニアやりたいと思いました

どんな会社に入社した?

プロダクトを自社で開発運用しており、界隈では高いシェアの商材を有するWeb系ベンチャーに入社しました
雰囲気的にはガンガン成長というよりは比較的安定しているといった感じでした
入社した当初は変革の風が吹き荒れていましたが、辞める頃には落ち着きつつありました

エンジニア部隊は開発とアーキテクトが存在するといった規模感で、PHPとJSメインのLNMP環境でWebサービスを開発する会社でした

そもそも何でその会社?

面白そうな独自データがあることや新しい技術に明るそうだったこと、規模的に自分次第でどうとでもできそうだったという理由で決めました

当時は学業が楽しく就活に時間を取られるのが嫌だったことと、実際に働いてみなけりゃ何もわからんだろ的な考えがありました

働いてみて

変革の時期?であったため、 入社直前に色々とありましたが、無事にエンジニアとして働き始めることができました

マナー研修と骨折する程の厳しい修行が数日間、あとはOJT的な流れで実務へといった感じで俗に言う研修的なものはほぼ無かったです
とにかく手を動かすスタイルでイキっていたので気になりませんでしたが、エンジニアの教育に関しては放置プレイでした
また、既存製品の生みの親がすでに会社を去っていたり仕様書等のドキュメントがほとんどないという状態であったので、とにかく製品に触れて理解していくといった感じでした

組織の方針は、既存製品のスケールではなく新規プロダクトをスピード重視で開発していくというものでした
自身も入社2ヶ月程で新規プロダクト開発チームにアサインされたので、既存製品の二の舞いにならないようにしようという思いで開発していったという感じです

なぜ辞めるのか

チーム開発がしたかった
メンバーの個の能力は高かったと思いますが、完全分業縦割りでチーム開発の文化はありませんでした
全体を把握している人間が存在せず、テックリードとは名ばかり(何かあったら責任を取る役割?)
製品開発初期の段階において、将来のクライアントとの窓口である営業と開発の連携が必要な場面では特に辛かったです
口癖がしょうがないになりました

製品ビジョンが謎
小さな会社なのに上層部の考えていることが何もわからない
現場ではクライアントの言うことが絶対でその通りに作る下請けといった感じでした
とにかくカスタマイズありきで、クライアントが欲しいと言っているから作るみたいな
ボク傭兵ヤダ

成長とは
各々やることは最低限やっていたと思います
しかしエンジニア組織やチーム、製品の今後を考えると納得が行かない点がありました(どうしたいのか共有してほしかった)
売れなきゃ無駄、保守運用?とにかく動くものだろ!ということだったのでしょうか
開発とアーキがいるのにもったいない

やっぱり学んだことがやりたい
入社を決めた理由に面白そうなデータを持っている点がありました
しかしデータを使える状態にすることからはじめなくてはならなかった(データ活用基盤プロジェクトはあったがポシャった)
活用を想定せずに集積されたデータを弄くるなんてメインプロジェクトの片手間では無理でした
ある程度できる(金になる)ことを示しプロジェクト化できなかった

これから

上記の理由で辞める決断をしました
結局は実力不足じゃね?とか、組織を知るという意味では短すぎるし全然これから改善していけるのでは?とか考えましたが、今やりたいことを優先しました
長い年月をかけて形成されたものを、ぽっと出の新人が変えられるはずもなく
悠長に待っていることは自分には出来ませんでした

理由はネガティブでしたが、現場で開発者として働いたことで、自分がどうしたいのかが明確になったので良かったです

次は今より小さい会社
求められるレベルは高く明確
自分の活躍の場は自分で作るぞという気持ちでがんばります

おまけ

入社1社目の社員の皆さんは聞いていた通り、いい人たちでした
最後に色々な社員と話をして、今が最も挑戦できるときだと感じました
恋人も家族も家も車も金もない超身軽サイコー

LightGBMとOptunaを使って遊んだ(前編)

はじめに

LightGBMとOptunaで遊んだのでメモ

LightGBMとは

決定木に基づいた勾配ブースティングの機械学習フレームワーク
教師あり学習手法

決定木

決定木は条件に基づいて分岐を行う
これによりターゲットクラスを分類

アンサンブル学習

複数モデルを融合させて1つの学習モデルを生成する手法

「バギング」、「ブースティング」、「スタッキング」といった手法に大別

「バギング」によるアンサンブル学習をランダムフォレストと言う

「ブースティング」は前の弱学習器の結果を次の学習に反映させる

勾配ブースティング

「ブースティング」を用いたアンサンブル学習手法
LightGBMにおける決定木の扱いは「Leaf-Wise」であり、訓練時間が短い傾向にある
また、訓練データの特徴量を階級に分けてヒストグラム化することで、意図的に厳密な枝分かれを探さず、大規模なデータセットに対しても計算コストを抑えられる

以下、LightGBMを使ってた予測までの流れ

import lightgbm as lgb

# 適当なデータとそのラベルを用意し、訓練とテストに分割する  
# train:学習データ  
# target:ターゲットデータ  
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.1, random_state=0608)

# データセットの生成
lgb_train = lgb.Dataset(X_train, y_train)
lgb_valid = lgb.Dataset(X_test, y_test, reference=lgb_train)

# LightGBMのパラメータ指定
params = {
    'boosting': 'gbdt',
    'objective': 'gamma',
    'metric': 'fair',
    'num_leaves': 31,
    'learning_late': 0.01,
    'feature_fraction': 0.9,
    'bagging_fraction': 0.8,
    'bagging_freq': 5,
    'verbose': 0,
    'num_iterations': 20000,
    'early_stopping_rounds': 200,
    'seed': 42
}

# モデルの学習
model = lgb.train(params,
                  lgb_train,
                  valid_sets=lgb_valid,
                  categorical_feature=features_idx,
                  verbose_eval=200)

# テストデータで予測
predicts = np.expm1(model.predict(test))
パラメータについて

'boosting': boostingアルゴリズム(デフォルトはgbdt)
'objective': 目的変数
'metric': 評価指標
'num_leaves': 木の末端ノード数
'learning_late': 学習率
'feature_fraction': 使用する特徴量の割合
'bagging_fraction': 使用するオブジェクトの割合
'bagging_freq': バギングの間隔(0の場合はバギングなし)
'verbose': 学習経過の情報表示(-1で非表示)
'num_iterations': 木の数
'early_stopping_rounds': 性能が頭打ちになった時点で止める基準
'seed': シード値

目的変数について

回帰問題であれば正規分布を仮定したデフォルトのrmse
年収やある事象がおこる間隔など正規分布に当てはまらない様な分布に対してはgamma
一定期間内に起こるランダムな事象のカウントを予測する場合にはpoisson

過学習への対策

feature_fractionfeature_freqの値を下げる
bagging_fractionbaggin_freqを使用する これにより、学習の高速化も期待できる

lgb.trainの引数

上で説明したようなパラメータ
学習データ(categorical_featureで使用したいカラムを指定することができる)

学習したモデルで推論

model.predictにテストデータを渡してあげるだけ

参考サイト

Parameters — LightGBM 2.3.2 documentation
【アンサンブル学習】多様性が大事? バギング・ランダムフォレスト編 - Np-Urのデータ分析教室
勾配ブースティングで大事なパラメータの気持ち - nykergoto’s blog
scikit-learnとLightGBMの評価関数比較 - Qiita
LightGBM 徹底入門 – LightGBMの使い方や仕組み、XGBoostとの違いについて

次回、Optuna使ってみた

AWSのCloudFormerを使ってみた

はじめに

新たにサーバ立てて環境構築したくなった時に,イメージからインスタンスを起動してRoute53やらロードバランサーやらなどの設定するのは面倒くさい...

CloudFormationを試す

dev.classmethod.jp 既存の構成をテンプレートに落とし込める気がせず挫折
デザイナーを使えばドラッグ&ドロップで直感的に作成できそうだけど複雑な構成は面倒

Route53やロードバランサーの設定をいちいち設定したくないだけなのに...

CloudFormerを試す

docs.aws.amazon.com
これで既存のAWSリソースからCloudFormationのテンプレートが作れる

CloudFormerスタックの作成

上のリンクに書いてあるとおりに進める
1. AWS CloudFormationコンソールにログイン
2. スタックの作成を選択
3. サンプルテンプレートを使用を選択し,サンプルテンプレートの選択欄のプルダウンからCloudFormerを選択して次へ
4. スタック名パラメータ(Password, Username, VPCSelection)を入力し次へ
5. スタックオプションの設定と詳細オプションは特に何も設定することがなければ次へ
6. レビューページにて設定を確認し,一番下のThe following resource(s) require capabilities: [AWS::IAM::Role]にチェックをつけてスタックを作成

CloudFormerスタックのステータスがCREATE_COMPLETEになるまで数分待つ

作成したCloudFormerスタックの起動

  1. CloudFormationコンソールでCloudFormerスタックをクリックし、出力を選択
  2. URLをクリックして,CloudFormerを起動させる
  3. スタック作成時に設定したユーザー名とパスワードを入力し,CloudFormerにログイン

これでCloudFormerを使ってAWSリソースからテンプレートを作れるようになる

CloudFormerでAWSリソースからテンプレートを作成

バージョンは0.14(Beta)

  1. リージョンを選択し,CreateTemplateをクリック
  2. Introページ
    Resource Name Filterで必要に応じて,リソースの絞り込みや全選択が可能
  3. DNSページ
    Route53の設定
  4. VPCページ
    Amazon Virtual Private Cloudsの設定
  5. VPC Networkページ
    Subnets,
    InternetとCustomerとVPNのGateways,
    DHCP Options,
    VPNとPeeringのConnectionsの設定
  6. VPC Securityページ
    Network ACLs, Route Tablesの設定
  7. Networkページ
    Elastic Load Balancers, Elastic IP Adress, Network Interface, CloudFront Distributionsの設定
  8. Managed Servicesページ
    Auto Scaling Groups, Elastic Beanstalk Applications, OpsWorks Stacksの設定
  9. Managed Configページ
    Auto Scaling Launching Configurations,
    Elastic BeanstalkのApplication Versions, Environment, Configuration Templates, OpsWorksのApps, Layers, Elastic Load Balancer Attachementsの設定
  10. Computeページ
    EC2 Instances, OpsWorks Instancesの設定
  11. Storageページ
    Elastic Block Storage Volumes, RDS Database Instances, ElastiCache Cache Clusters, Redshift Cluster, DynamoDB Tables, S3 Buckets, SimpleDB Domainsの設定
  12. Storage Configページ
    RDS DB, ElastiCache, RedShift ClusterのSubnetとParameterのGroupsの設定
  13. App Servicesページ
    SQS Queues, SNS Topics, Kinesis Streams
  14. Securityページ
    EC2, RDS, ElasticCache, Redshift ClusterのSecurity GroupsとSQS Queue, SNS Topic, S3 BucketのPoliciesの設定
  15. Operationalページ
    Auto Scaling Policies, Auto Scaling Scheduled Actions, CloudWatch Alarms, CloudTrail Trails
  16. Summaryページ
    追加したリソースの確認
  17. Summaryの次に進み,Save Templateでテンプレートを指定したS3バケットに保存

あとはCloudFormationコンソールにて、S3に保存されたテンプレートを指定し、スタックを起動する

所感

jsonやらyamlで書かれたテンプレートに拒絶反応が出ていただけで、CloudFormerいじったり色々調べたりしているうちに分かってきた
一度、CloudFormerでテンプレート吐き出してみるのも良さそう

作成したテンプレートを実務に役立てていきたい