フリーランチ食べたい

No Free Lunch in ML and Life. Pythonや機械学習のことを書きます。

(古典)統計学と機械学習の翻訳テーブル

(古典)統計学機械学習では使う名称が全然違う

土日は医学系研究室で客員研究員として粛々と研究しているのですが、医学系の研究というのはまだまだ古典統計学が主流です。古典統計学を扱う時の問題は色々あるのですが、その中でも大きいのは機械学習と同じ概念なのに名称が違うことです。 これはけっこう大変で、自分は普段「機械学習の用語」で考えているので、「(古典)統計学の用語」で考えている教授や学生さんと話すときに脳をフル回転させて同時翻訳する必要があります。もはやバイリンガルみたいな気持ちです。

まぁ大変なだけだったら良くないけど良いのですが、ときどき認識の齟齬が発生したりして、それは実質的な問題なので、とりあえず今後間違いを減らせるように「翻訳テーブル」を作ってみました。

モデルに対する翻訳テーブル

(古典)統計学 機械学習 備考
重回帰分析 一般線形回帰モデル 一般化線形回帰モデルを(古典)統計学でなんと呼ぶのだろうか
従属変数(dependent variable) 目的変数(response variable) 数式ではY
独立変数(independence variable) 説明変数(explanatory variable) 数式ではX
要因, 質的変数 離散の説明変数 (古典)統計学では名義尺度、順序尺度などさらに分かれている
共変量, 量的変数 連続の説明変数
偏回帰係数, 回帰係数 パラメータ、係数
尤度関数 目的関数, 損失関数(符号は逆)

適宜更新していきたい

とりあえず今思いついたものを書き出してみただけなのですが、普段から言語の壁を感じまくっているので気付いたら書き足していきたいと思ってます。「これもあるよ!」という方がいたら教えてください。

リモートワークの戦略とメリデメを整理する+弊社のリモートワーク事例の紹介

「リモートワークどうですか?」に対する回答を考える

今、自分が働いている会社はリモートワークを推進していて、自分自身も週3~4でリモートワークをしています。そういう状況なので、最近よく「リモートワークってどうですか?上手くいきますか?」と聞かれることが多いです。自分に関して言えば、リモートワークは「上手くいっていて最高!」なのですが、世の中では「リモートワークの失敗例」というものも表面化していて、一概に「リモートワークはイイ!」「リモートワークはワルイ!」で語ることに限界を感じていました。

ちょうど良い案件があった

そんなことを考えているところに、リモートワーク導入を考えている会社の友人から質問リストをもらったので、それに回答しながらリモートワークにおける戦略とメリットデメリットを整理してみました。 基本的にここに書いたことは自分の経験を元に仮説として考えたものでたたき台のイメージです。これを元にリモートワーク導入について誰かと議論できたらいいなと思っています。また、結果的に弊社のリモートワーク事例の紹介にもなりました。

質問リスト

それでは、下記の質問に答えていきたいと思います。

①リモートワークと会社出勤、両方選べるならどっち選ぶ?
②その理由はなんで?
③リモートワークで起きるいいこと
④リモートワークで起きる悪いこと
⑤生産性あがった?
⑥会社として生産性管理やモチベーション管理はどうしてる?
⑦MTGはどうしてる?
⑧今後リモートワークができる会社に有能な人は集まると思う?

①リモートワークと会社出勤、両方選べるならどっち選ぶ?②その理由はなんで?

タスクによって向き不向きがあると感じているので、ときと場合によって使い分けています。

分類してみる

具体的には下の図のように分類できるのではないかと、ふわふわ考えています。

まずタスクの分類です。色々な分け方があるかと思いますが、今回はタスクの難易度意思決定の頻度で見てみました。

f:id:mergyi:20180804020931p:plain

自分の場合は

  • A(タスク難, 連絡 少): 基本的にリモートワーク
  • B(タスク易, 連絡 少): どちらでも良い(都合の良い方)
  • C(タスク易, 連絡 多): どちらでも良い(都合の良い方)
  • D(タスク難, 連絡 多): 基本的に出社

するようにしています。こう見てみると、タスクが簡単であれば、リモートでも出社してもそんなに生産性に差がなく、タスクが難しく複雑なときは生産性に大きく影響するのではという仮説を立てることができます。リモートワークの生産性に関して語るのであれば、タスクを分類して生産性が下がりそうなタスクに対してどう対応していくかが大事だと思います。

割合は?

人によってバラバラだと思いますが、自分はざっくりと下のような感じです。 f:id:mergyi:20180806120909p:plain

A(タスク難, 連絡 少)の割合が多く、(Aに集中させてもらえてるのは貴重なことだと思うので感謝してます)リモートワークで生産性がかなり上がった、と感じています。

③リモートワークで起きる良いこと

「リモートワークできる」ということは単純に人生というRPGの自由度が上がるということなので良いことはたくさんあります。

仕事に集中できる

オフィスで働いているときはいろんなインターラプトがありました。 誰かに質問されたり、近くで気になる会話をしていて耳をそばだててしまったり。 これは良い刺激だし、楽しいのですが、やはりフロー状態に入る回数は少なかったと思います。 今はインターラプトは宅急便くらいしかないし、集中できる時間帯(自分は深夜が一番捗ります)にまとめて作業できるので捗ります。フロー状態に入る回数はかなり多くなったと思います。

土日が「真の休日」になる

これはリモートワークしていないと意外とわからないかも、と思いました。 以前も土日は休みだったんですが、平日にできない家事や荷物受け取り、市役所・病院に行く用事などをするのに毎週半日は使ってたと思います。今はこれらの作業は全て仕事をこなしながら平日に行ってます。なので土日は完全に自分の時間として使えます。

家族との時間が取れるようになる

僕は独り身なので実感は薄いのですが、チームのメンバーを見ていると「子どもの送り迎え」や「ご家族の看病」など家庭へのコミット度がハンパないなと感じます。お子さんを膝に載せながら働いているメンバーを見ると微笑ましすぎてとても幸せな気持ちになってしまいます。普通に「自分の父親もこういう働き方していたら母親はありがたかったろうな〜」と思うことが多いです。

健康になる

これは人による、と思いますが、自分は転職前は食事は基本的に外食、運動は時間が取れず出来てないという、まさに現代人、な状態だったのですが、今は、食事は自炊が8割、毎日2回ジョギング、週に3回トレーニングしている状態なので、激変したと思います。食事も野菜の量に気を使ったりできるようになりました。「それってリモートワーク関係なくない?」と思われるかもしれませんが、実際リモートワークして変わったのです。多分、時間と精神的な余裕のおかげかなと思ってます。

※福利厚生と書いてありますが、会社の福利厚生ではないです。笑

遊びの自由度が広がる

遊びたいときに遊び、働きたいときに働くスタイルになりました。 ふつうの平日の昼間に外で流しそうめんをするなんてリモートワークしなければ考えられなかったです。

④リモートワークで起きる悪いこと

上述させてもらった内容になりますが、「リモートワークできる」ということは単純に(自分も他のメンバーも)人生というRPGの自由度が上がる、ということなのでリモートワークすると絶対に起きる「悪いこと」というのは存在しないと思います。ただ、RPGと同じ(?)で自由度が上がれば難易度も上がります。では「何ができなかったら、どんな悪いことが起きるのか」を考えてみました。 f:id:mergyi:20180804033150p:plain

上記のように「組織としてカバーすべきこと」「個人がカバーすべきこと」のどちらかが達成されなかった時に悪影響が発生すると考えています。この図自体はリモートワーク関係ないのですが、リモートワークは非リモートワークに比べて「組織に求められるもの」も「個人に求められるもの」もレベルがかなりあがるイメージがあります。

⑤生産性あがった?

①に書いたAのタスクに関しては非常に生産性が上がったと感じてます。 入社して3ヶ月で月間MVP、上半期MVPもらえたのはこの生産性向上がなかったら(リモートでなかったら)絶対できなかったと思ってます。(MVPはちょっと自慢。笑)

ikedaosushi on Twitter: "全社MVPをもらって喜ぶ28歳。入社して3ヶ月、大変な事もあったけど、頑張ってきた事を評価してもらえて本当に嬉しい🙌🙌🙌… "

⑥会社として生産性管理やモチベーション管理はどうしてる?

OKRを使って目標管理を行っており、全社、部門、部署、PJとドリルダウンしていく仕組みになっています。 モチベーション管理というかわからないですが、働きやすい環境をつくる工夫はたくさんされていて、その一部はBlogでも紹介されています。

⑦MTはどうしてる?

Zoomを使って行ってます。通信状態が悪くてもかなり繋がりやすいし、画面シェア機能の細かい設定ができるので便利に使ってます。 また、リモートワークだから得られた面白い利点みたいなものがあったので書いておきます。

オフィスにいてもリモートMT

今の会社に来て面白いなと思ったのは、MTに出席者が2人以上オフィスにいても参加者の何人かがリモートだとZoomでリモートMTするということです。最初はえ?と思ったのですがやってみるとパラダイムシフトが起こりました。どんな状況でもZoomを使う(使える)、ということはMTする相手がどこにいるか、や、MTの場所を一切考えなくていいんです。 今はMTを開催するまで/されるまで、の精神的障壁がかなり低く「MTの内容に集中できている」と感じます。’

どんなMTにでも参加できる

会議室ごとにZoomのURLが設定されているので、会議室で行われるような「経営会議」などには自由に参加して話している内容を聞くことができます。オンボーディングの一貫で自分が参加しない部としての方向を決定するMTにZoomで参加して部としての現状を把握するのは、その後の仕事にとても役立ちました。

⑧今後リモートワークができる会社に有能な人は集まると思う?

これは一般論半分という感じですが、下の図のように「A(リモートしたい人の集合)」「B(リモートしてもしなくても良い人の集合)」を書いた時にそれぞれに一定の割合で「優秀な人」がいるはずなので「リモートOKな会社」の方が当然、優秀な人を雇うチャンスは大きいと思います。 f:id:mergyi:20180804030348p:plain

今後、という話だと図にも書いたとおり、時代に合った働き方をしたい、みんな考えていると思うのでA(リモートしたい人の集合)が増えてくると思います。 そうなると「リモートOKな会社」の方が優秀な人を雇うチャンスはどんどん大きくなってくるのではないでしょうか。

さいごに

以上で質問への回答は以上です。今更ですが、自分はリモートワークをしているし、リモートワークが好きなので完全にポジショントークです。また、本当はもっと細かく詰めたいところばかりなのですが、体力が尽きたのでまた誰かと議論してまとまってきたら追記していきたいと思ってます!

Linuxでadduserに-gecosを指定したら何ができるか。なぜ gecosという名前なのか。

あるソフトウェアのセットアップで adduser -gecos を設定するExampleがあって、何をしているか理解していなかったので調べてみました。

TLDR

  • -gecos optiongecos field を設定するときに使うもの
  • なぜ gecos というかは歴史的経緯があった
  • システムとしてのみ使う場合に便利
続きを読む

pipが v10->v18になってビビってメーリングリスト見たみたらリリースサイクルも変わってた

TLDR

急にv18が来たので(QVK)

pipが急にv18になってビビった。 https://github.com/pypa/pip/releases/tag/18.0

$ pip install -U pip
Collecting pip
  Downloading https://files.pythonhosted.org/packages/5f/25/e52d3f31441505a5f3af41213346e5b6c221c9e086a166f3703d2ddaf940/pip-18.0-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 4.8MB/s
Installing collected packages: pip
  Found existing installation: pip 10.0.1
    Uninstalling pip-10.0.1:
      Successfully uninstalled pip-10.0.1
Successfully installed pip-18.0

「アップデートね、おけおけ…...18!!?」みたいな感じになった。

CalVer

Twitterを眺めてみると「calver」というワードがチラホラ出ていて、これはCalendar Versioningのことらしい。 calver.org

つまり pip v18.0 の18は2018の18だったということ。 ubuntu18.04 のようにMinor Versionは月になっているが pipは 18.0 のようになっているので 18.0~3 のようになるのかな。

リリースサイクルも変わってた

詳細な情報を確認するためにメーリングリストを見たらちゃんとCalVerになることが書いてあった

Google グループ

This is the first pip release since adopting 3 month release cadence and 
a Calendar based versioning scheme (also known as CalVer). In simpler 
words, there will be a new pip release every 3 months unless there are 
no changes since the previous release. More details such as release 
months can be found in pip's development documentation. 

それとは別にリリースサイクルも変わっていることにも気付いた。今後はCommitが1つでもあれば3ヶ月おきにリリースしていくとのこと。 今までは結構リリースにムラがあったので(Releases · pypa/pip · GitHub) 安定した開発を続けていこうという意思なのかな。 (Releases見て気付いたけど、2017は全くリリースがなかったのにビックリ)

他にもちょいちょい変更あった

Google グループ 上記のメーリスより

- Python 3.3 is no longer supported - if you need pip on Python 3.3, 
  you should stay on pip 10, which is the last version to support Python 
  3.3. 
- Complete PEP 518 support - includes support for installation of build 
  dependencies from source and Unicode support on Python 2 and Windows 
- New --prefer-binary flag, to prefer older wheels over newer sdists 
- Many bug fixes and minor improvements 

大きなものだと↓がありそう。

  • Python3.3のサポート終了
  • PEP518(https://www.python.org/dev/peps/pep-0518/)のサポート完了
    • なんのPEPかと思ったらpackageをbuildするformatの仕様だったよう
    • もしかしてこれでinstallできなくなるpackageがあるのかも?

まとめ

  • 能動的にメーリングリストを見ることは少ないけど、受動的に情報を受け取っているだけでは知れないことがたくさんあるので、できるだけチェックした方がよい。
  • Software全体としてCalVerに移行していく流れがあるような気がする。

docker-compose run は portをmappingしない

dokcer-composeでちょっとハマったのでメモ

TLDR

  • 単純に docker-compose run service_name すると設定したportがmappingされない
  • docker-compose run --service-ports service_name すれば良い

詳細

↓のようなdocker-compose.ymlがあったときに

version: '3.5'
services:
    a:
        image: hoge
        ports:
            1234:1234

service_aだけ実行したかったので、 $ docker-compose run a /bin/bash とaだけrunした。

プロセスをチェックしてみると、portsをmapping されていない。

$ docker-compose ps 
          Name                         Command               State            Ports
--------------------------------------------------------------------------------------------
reponame_a_1     /bin/bash    Up

この問題に関してはGithubで質問されていたりして、詰まっている人は多いようだ。 Docker-compose run command doesnt map ports · Issue #1259 · docker/compose · GitHub

原因と解決策は、公式ドキュメントにしっかり書かれている。 run — Docker-docs-ja 17.06.Beta ドキュメント

使い方: run [オプション] [-e キー=バリュー...] サービス [コマンド] [引数...]

オプション:
-d                    デタッチド・モード: コンテナをバックグラウンドで実行し、新しいコンテナ名を表示
--name NAME           コンテナに名前を割り当て
--entrypoint CMD      イメージのエントリーポイントを上書き
-e KEY=VAL            環境変数を指定 (複数回指定できる)
-u, --user=""         実行時のユーザ名または uid を指定
--no-deps             リンクしたサービスを起動しない
--rm                  コンテナ実行後に削除。デタッチド・モードの場合は無視
-p, --publish=[]      コンテナのポートをホスト側に公開
--service-ports       サービス用のポートを有効化し、ホスト側に割り当て可能にする
-T                    疑似ターミナル (pseudo-tty) 割り当てを無効化。デフォルトの `docker-compose run` は TTY を割り当て
-w, --workdir=""      コンテナ内のワーキング・ディレクトリを指定

のうち、↓を使えばよい。

--service-ports       サービス用のポートを有効化し、ホスト側に割り当て可能にする

なので結論としては、

$ docker-compose run --service-ports service_name

とすればよい。

$ docker-compose ps 
          Name                         Command               State            Ports
--------------------------------------------------------------------------------------------
reponame_a_1     /bin/bash    Up    0.0.0.0:1234->1234/tcp

正しくmappingされた🎉

「なんでそういう仕様なの?」という声も聞こえてきそうだが(Githubで「直したほうが良くね?」って言ってる人もいた)

理由もしっかり公式ドキュメントに書いてある。 run — Docker-docs-ja 17.06.Beta ドキュメント

2つめの違いとして、 docker-compose run コマンドはサービス設定ファイルで指定したポートを作成しません。これは、既に開いているポートとの衝突を避けるためです。

確かに?ただ docker-compose up を2回すると衝突しそうだよな。と思って試したら新しくコンテナは作成されなかった。 公式ドキュメントにはその辺り明言されていないようにも見えるが雰囲気から、そういう仕様ということはわかる。

up — Docker-docs-ja 17.06.Beta ドキュメント もしサービス用のコンテナが存在している場合、かつ、コンテナを作成後にサービスの設定やイメージを変更している場合は、 docker-compose up -d を実行すると、 設定を反映するためにコンテナを停止・再作成します(マウントしているボリュームは、そのまま保持します)。Compose が設定を反映させないようにするには、 --no-recreate フラグを使います。

まとめ

公式ドキュメントをしっかり読むと色々わかるからしっかり読もう

会社で上半期MVPもらいました!!

横浜で最高の夏を味わいながら全社イベしてきた。弊社最高 👏

さらに最高に嬉しいことに上半期の個人部門MVPをもらえました。

わーい。嬉しい。という報告でした。(笑)

PyCampのTAをしてきて、印象に残った質問のメモと、何かを教えるときの難易度と頻度の関係性について考えてみた

大学院生以来のTAを筑波大学でやってきた!

運営スタッフをやっているPyCon JP( https://pycon.jp/2018/ )がPythonを教えるBootCamp「PyCamp」を筑波大学で開催するということでTAとして参加してきた。

TAをやるのはM2夏以来なので、4年前ぶり…(時の流れが早すぎて涙が止まらない)

手前にちょっとだけ写ってる。船坂くんは大学のときにちょっとだけ関わりがあって、今回、感染に偶然に数年ぶりの再開を果たした。人生ってなんて面白い…!

教材はこちら→ Python Boot Camp(初心者向けPythonチュートリアル) — PyCon JP 。 無料でPythonの勉強ができるので勉強したい人は触ってみても良いかも。

印象に残った質問

何年かプログラミングをやっているとプログラマーとしてはあまりに当たり前になってしまって説明できない」ことが増えるのはあるあるだけど、それは思考が凝り固まってしまっているということだしエンジニア以外の人への説明力が落ちていることに他ならないと思うので、こういう場で予想していなかったような質問をされるのは思考が刺激されてとてもいい経験になった。せっかくなのでここにもメモしておく。

質問1. 「配列ってなんですか?for...in...で何が起こっているんですか?」

聞かれたコードは↓のようなものだった。

ret = []
for animal in animals:
    ret.appned(animal)

print(ret)
# => [cat, dog, ...]

一応チュートリアル内でも記載があって、講師の方も説明していたのだけど、その説明がたしか「配列は数字や文字列などの要素が集まったものです。forは要素ごとに処理を行うものです」というもので、それがあまりピンと来なかったよう。普段だったら自分も正直それ以上の説明は浮かばないのだけど、なんと幸運に先週fukabori.fmに出ていたkakakakakkuさんの話を聞いていたのでその通りに「レジに人が並んでます」「catさんから順番に処理していきます」(appendだったので)「今度は隣のレジに並んでもらいます」的な質問してくれたら理解してくれたよう。メタファー大事。kakakakakkuさん半端ないっす。

fukabori.fm

この回、超オススメです。

質問2. 「配列使うと何が便利なんですか?」

上の流れで聞かれた。ウワー本質的な質問だ、となって正直難しかったけど、Twitterを例に上げて『お腹空いた』とか『眠い』などのTweetが100個くらい配列に入っていて、それを一気にforとかで回して表示してるから、タイムラインで見れるんだよ、的な話をして一応わかってくれたみたいだった。これに関してはいい例があったら教えてください!

質問3. 「 res = requests.get(url) が何をやっているか全然わからないです。resには何が入っているんですか」

これはスクレイピングの課題で質問された。これは、質問されたあとに色々考えて、そういえば自分もエンジニア始めたばかりのころ、「URL」と「アクセスしたサイトの中身」の違いがピンと来なかったのを思い出してハッとした。最終的には↓のような図を書いてわかってくれた(気がする)。

f:id:mergyi:20180722003008p:plain

「なんでDNSだけフィーチャーしたの???」というツッコミはしないでください。。(笑) 色々しているというのを伝えたかったのです。

難易度と頻度の関係性について

人に教えるのは内容の選抜がとにかく難しい

ずっと講師の方の説明を聞いていて「これは発展的すぎるかも?」とか「これはそんなに使わないかも?」と思ったり、逆に途中から「生徒が中級者多め」という実感が湧いてきて、「これは簡単すぎるのかも?」とか勝手なことを思っていたのだが、最終的にこれ主観で「この内容は合ってない」とか議論してもなんの生産性もないやつだと気付き、習熟度に応じた優先度マップが必要なのでは?という結論に達した。

Pythonで教える内容の難易度と頻度の関係性

というわけでまとめてみた。教える内容としてこういう項目があるよね、というやつ。 網羅性は全然なくて、今日授業を聞いていて思いついたやつをメモっただけ。

f:id:mergyi:20180722003952p:plain

習熟度ごとの優先度マップ

そして初心者、中級者、上級者という対象者ごとの優先度マップ。

対象者: 初心者

f:id:mergyi:20180722004244p:plain もちろん難易度は低く、頻度が高いものが最優先。 次が悩みどころだけど、個人的には頻度が低いものより、頻度が高く、もうちょっと難しいものを優先した方が良いイメージ。

対象者: 中級者

f:id:mergyi:20180722004336p:plain 中級者は中くらいの難易度で頻度が高いものが最優先、その次が頻度が低い中くらいの難易度、低い難易度のもの。そろそろ頻度が低いものも抑えておこう的なイメージ。

対象者: 上級者

f:id:mergyi:20180722004358p:plain 上級者は高難易度で頻度が高いもの=>低いものの順でその後は、より頻度が低く、難易度が高いものをやっていけばいいと思う。

優先度マップについて

議論もしてないし、熟考もしてないので、最初のたたき台というくらいの温度感。 使い方としては、教えるコンテンツを考えるときに優先度が高いものを残し、低いものはできるだけバッサリ切っていくのがいいと思う。できるだけ頭に入れる内容は少ないほうがインプットしやすい気がするので。

まとめ

不特定の誰かに教えるというのもあまりない経験だったし、最近、自分が忘れていた発想にも気付かせてくれたし、参加してよかったと思った。 PyCampでの懇親会でも面白い話がたくさん聞けたし、貴重な繋がりもたくさんできた。また機会があればぜひ!参加したい。