TIL blog

Data Mining(Machine Learning) Engineer 3年目 技術ネタ, その他学んだことのアウトプット用

zplug -> zplugin に乗り換えた話 (+ exit code のbug調査)

TL;DR;

  • plugin managerを zplugから zplugin に乗り換えた. 結果, 起動時間は1/2 ~ 1/3 程度になった.
  • zpluginの簡単な紹介
  • setopt print_exit_valuezshの設定ファイルから外さないとバグる

※ドキュメントはまだそこまできちんと読んでないので, 記述に間違いがあるかも

はじめに

少し前にzshの起動が遅いのが気になってプロファイル取ったら plugin のloadで時間くってることが判明したため, plugin managerを zplugから zplugin に乗り換えた.

zpluginとは?

Zdharma Initiative のプロジェクトの一つで zplug などと同様のplugin manager

github.com

特徴として, 透過的かつ自動的に pluginをコンパイルしてくれる + 遅延読み込みの記述が容易 なため, zsh の起動が他plugin と比べて著しく速い.

意外とまだzsh のplugin managerの中ではマイナー な模様. google のsearch trendだとこんな感じだった.

  • world-wide

  • Japan

Qiitaだとzpluginの記事は7件ほど https://qiita.com/search?q=zplugin

どれだけ早くなったか

論より証拠で time benchmarkの結果を示す, およそ起動は 1/2 ~1/3 になった印象.

zplug

~
❯ for i in {1..10}; do time ( zsh -i -c exit ); done
( zsh -i -c exit; )  0.36s user 0.44s system 52% cpu 1.530 total
( zsh -i -c exit; )  0.39s user 0.44s system 65% cpu 1.258 total
( zsh -i -c exit; )  0.37s user 0.41s system 65% cpu 1.197 total
( zsh -i -c exit; )  0.36s user 0.40s system 65% cpu 1.170 total
( zsh -i -c exit; )  0.37s user 0.42s system 66% cpu 1.197 total
( zsh -i -c exit; )  0.38s user 0.41s system 65% cpu 1.198 total
( zsh -i -c exit; )  0.36s user 0.39s system 65% cpu 1.142 total
( zsh -i -c exit; )  0.37s user 0.40s system 64% cpu 1.194 total
( zsh -i -c exit; )  0.35s user 0.39s system 63% cpu 1.163 total
( zsh -i -c exit; )  0.31s user 0.33s system 64% cpu 0.992 total

zplugin

~
❯ for i in {1..10}; do time ( zsh -i -c exit ); done
( zsh -i -c exit; )  0.17s user 0.19s system 69% cpu 0.513 total
( zsh -i -c exit; )  0.18s user 0.20s system 72% cpu 0.527 total
( zsh -i -c exit; )  0.17s user 0.18s system 73% cpu 0.464 total
( zsh -i -c exit; )  0.17s user 0.19s system 72% cpu 0.489 total
( zsh -i -c exit; )  0.17s user 0.18s system 72% cpu 0.468 total
( zsh -i -c exit; )  0.17s user 0.19s system 71% cpu 0.509 total
( zsh -i -c exit; )  0.17s user 0.19s system 71% cpu 0.506 total
( zsh -i -c exit; )  0.17s user 0.18s system 73% cpu 0.477 total
( zsh -i -c exit; )  0.16s user 0.18s system 74% cpu 0.460 total
( zsh -i -c exit; )  0.17s user 0.18s system 74% cpu 0.469 total

zplg だとmodule 毎に読み込み時間を出せる, autopairは機能の割に読み込みが遅い気もする.

❯ zplg times
Plugin loading times:
0.043 sec - sindresorhus/pure
0.007 sec - sorin-ionescu/prezto
0.020 sec - zsh-users/zsh-history-substring-search
0.002 sec - junegunn/fzf-bin (command)
0.050 sec - zsh-users/zsh-autosuggestions
0.003 sec - zsh-users/zsh-completions
0.035 sec - zdharma/fast-syntax-highlighting
0.017 sec - b4b4r07/enhancd
0.003 sec - desyncr/auto-ls
0.042 sec - hlissner/zsh-autopair
0.009 sec - zdharma/zui
0.003 sec - zdharma/zplugin-crasis
0.003 sec - zdharma/history-search-multi-word
0.002 sec - zdharma/zsh-diff-so-fancy (command)
Total: 0.239 sec

踏んだbug

zplugin を入れた直後 exit code が0以外だと繰り返しexit code が表示されるbug が発生した.

以下は ctrl+c でsigint を送信した場合

Screen Recording 2019-05-11 at 11.16 AM.gif

debug でやったこと

  • zplugin を含む最小の構成でzshrc を記述 -> bug発生
  • singal 周りの記述を確認, 本家zshからコードを移植していたようなので, 本家とのdiffを確認
  • zshrcの他の設定に問題ないか binary chopでsearch
    • setopt print_exit_value が原因だった ため設定を削除
  • 結論コレと同様だった https://github.com/zdharma/zplugin/issues/45

TODO memo

Redash meetup #5 参加レポート

TL;DR;

4/23 にRetty で行われた Redash Meetup にお邪魔してきたので, 参加レポートもどきの手元のメモ公開させていただきます。。

イベントURL

redash-meetup.connpass.com

Twitter ハッシュタグはこちら

twitter.com

Redashとは

Redash とは Python製の の OSS/SaaS のBIツール (Tableau, Looker などの仲間) いろいろなデータソース(BQ, Athena, MySQL, SpreadSheet)に対して, ユーザライクなinterfaceを提供して可視化などを行うツールです。

自分も普段の業務で仮説検証のための集計やABテストのための集計などで日頃からお世話になっています。

以下, 登壇内容についてです。

OP talk

参加者へのアナウンスで拍手のお願いがあったのが斬新でした 笑 良さそうなので主催側の勉強会でも取り入れたいです。

改めて振り返る Redashの使いどころ (ユニトーン 有田)

  • 有田さんはOSS版のRedash のメンテナの一人
  • 会場内でver7.0 使っている人3割くらい
  • バージョンアップの歴史, 国内で話題になったイベントの歴史などの振り返り

Redash の良さの振り返り

  • OSSかつwebベース
    • ユーザーフレンドリ
    • クエリをURLで共有できる
  • 様々なデータベースの集計クエリが集約される
    • クエリが集約されるので, 秘伝のクエリが生まれにくい
  • hackable
    • python data source利用, クエリランナー拡張でSQLだけではないデータ処理が可能
    • OSSだから自分たちで手を入れられる
    • Query をVCS管理するより, APIで撮ってきた加工のプロセスをVCS管理するほうが楽 <- わかる

クエリランナー については存在を全然知らなかったです。

登壇者の有田さんがブログを書いているようなので, あとで読ませていただこうと思います。

ariarijp.hatenablog.com

Retty における Redash の活用事例 (Retty 田中 さん)

www.slideshare.net

Retty さんの取り組みに関する過去の技術ブログ記事はこちら

engineer.retty.me

  • データ量が増加, ステークホルダの増加, 意思決定難易度の上昇から, 瞬時に多様な観点からの分析が必要なフェーズになってきた
  • Redash, DataPotal, SpreadSheet などを組み合わせて分析を行っている, それぞれの用途は以下の通り

Data Potal

  • DataPotal ではチャネル遷移の分析の可視化
  • dailyで更新させているので, ad-hoc にクエリ打たなくても気になった時に結果を見に行ける

Spread Sheet

  • 細かな数値間の確認

Redash

  • 変化を瞬時に察知するのに利用(= ログからサービスの健康診断)

時系列情報の可視化は実感としてもRedashの方がやりやすいなと思います

Redash 利用の課題感

  • 数値を見る習慣をどうやって作る?
  • ツールの使い分け
  • Scheduled Query の増加に伴う実行コスト増加(Retty だとBQ利用のため辛かったよう)
    • こちらtweetしたところリプでスキャン件数事前に見れると教えていただけました :pray:

[MEMO] A/Bテストの効果測定はスプレッドシートなどで行っている, SpreadSheet, DataPotal で済むならそちらを使ったほうが効率的
[MEMO] 現状Rettyでは意思決定でのデータ活用がメインなので今後はデータを利用した機能の開発をやっていきたいそう

Redash で何を見るのか?(エブリー 島田 さん)

普段は DWH アーキテクト としてお仕事されているそう。

インフラ構成

  • インフラ構成とクエリ数紹介など
  • Spark で以下のようにETL
    • DataRake S3-> DWH TD ->DataMart Redash

上記のDataRake, DWH, Data Mart の概念の話は yuzutas0さんの記事がとてもわかりやすかったです。

yuzutas0.hatenablog.com

  • ユーザはPO, アナリスト, 機械学習エンジニア, マーケターなど

何を見るのか

実際に見ているKPI紹介
DAU, 継続率(cohort chart) からKPI treeの各構成要素の見方の紹介
例えば継続率は以下のように分解される

  • 継続率
    • 認知
    • プレファレンス
    • 配荷率

課題感

  • データガバナンス
  • SQLクエリの管理と権限設定
    • 管理という観点から言えば特にBQ使うのであれば, エンジニア的にはレビューしたい <- わかる
    • 協力会社へのデータ提供が難しい (Looker使ってみたが...)

LT1 チームの BI や可視化強化に Redash はどうかと雑談した時の話 (はてな koudenpa さん)

www.slideshare.net

BQをRedash に持ってくるのではなくて, BQの方にサービスログをembulkで持っていくのを検討中らしい。
Embulk 辛そうな話が DPCT で伺った話だと多かったが未経験なので感覚がわからないです。。。

LT2 Ruby エンジニア選ぶ Redash の好きなところ Top10 (フリーランス samemuraさん)

特に共感したのはこの辺り

  • 逆にGUI凝っていないからSQL書いて可視化までが早い
  • 他のクエリの結果を使って負荷の軽減と再利用ができる, クエリの結果がキャッシュできる
  • 管理画面が不要になる, 簡単な分析依頼ならRedash 内で完結する

感想

ユーザ側とデータエンジニア側の方両方いらっしゃったみたいでいろいろなお話が伺えて楽しかったです。 欲を言えばもう少し深い話が聞きたかったので, 懇親会があると嬉しかったかもです 笑

Redash のメジャーバージョンに追いつくまでは開催していただける ということなので, 次回も楽しみにしています!

クエリ管理の話 とか オンプレ非DockerのRedashのバージョン上げる話 とか機会あればLTなどで話したいなと思いました。

新卒(ML)エンジニアにオススメの書籍・Web サイト等

 新卒だった頃の自分に薦めたい本の一覧とそれらに対してのコメントを書いていきます。 自分が新卒だったのは2年前なので最近だともっと良い本があるかもしれません。
 まとめていった結果MLに限らず一般的な新卒webエンジニアに薦めたい本になりました。

 ちなみに 自分がここ数年で読んだ本一覧はこちらにまとめています。https://booklog.jp/users/schumi543

想定読者

自分と同様, 大学の研究で簡単な数値計算機械学習のコードは書いたことがあるが, 大きめのソフトウェアを書いたことがない新卒MLエンジニア。

ソフトウェア基礎

Linux, shell

 IDE (Matlab, Rstudio, Pycharm)) などに慣れていてまともに Linux触ったことなかったので最初厳しかった気がします。 以下の2冊は自分で実際にCやgo で低レイヤのAPI触りながら仕組みが理解できるのでオススメです。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

 スクリプトを書くのはad-hocになりがちですが, 別のコマンド, APIを知っていると より効率的に書ける ということは割とよくあります(shell以外も)。 一度リファレンスをざっと通読しておくとよいかなと思います。

git

 学生の時はバージョン管理システムをまともに使ってなかったので, 慣れるのに苦労しました。。。 概念に慣れるまでが一番厳しかったのですがとっつきやすかったのは以下の本でした。 マンガだと逆に抵抗感ある方もいるかも知れませんが, 内容と説明両方の面から今見ても十分オススメできる本です

わかばちゃんと学ぶ Git使い方入門

わかばちゃんと学ぶ Git使い方入門

正規表現

 コードやログを読むときに普通に検索するより正規表現の知識があると効率がとても良くなります。

正規表現辞典 改訂新版 (DESKTOP REFERENCE)

正規表現辞典 改訂新版 (DESKTOP REFERENCE)

データ構造とアルゴリズム

 情報系あるいはそれに近い分野が専門だった場合, 大学で理屈は学んでいるかと思いますが, 実際にコードに落とすには慣れが必要なので オンラインジャッジ系の競技プログラミングの問題を解いてみるのはオススメです。
 今だと AtCoderがとっつきやすくて良いかなと思います。

以下の入門記事から初めてステップアップしていくのが良さそうです。

qiita.com

集団開発の基礎

 テスト, コードの書き方, 開発手法というトピックで何冊か選びました。
 個人的にはここが会社で開発するうえで一番知識のギャップがあったなと感じます。 実際に仕事やってレビューしてもらう過程で知識は身についていくかと思いますが, 並行してこの辺りの書籍で勉強しておくとよさそうです。

テスト

テスト駆動開発

テスト駆動開発

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

コードの書き方

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

開発手法

 見積もりとコミュニケーションのための本です。
 手を動かす側の職だったとしても, プロジェクト or プロダクトマネージャがどう考えているか知ることは有用だと思います。

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

設計

 小規模なコードだといきなり書き始めてもなんとかなりますが, ある程度以上のコードは設計せずに書き出すと論理の不整合などで厳しくなってきます。 運良く完成できたとしても, 保守性が厳しいコードになりがちなので設計は少し勉強しておいたほうが良いでしょう。
 設計の経験がない場合 コード書き始める前に設計や方針を先輩方にレビューしてもらうと良いと思います。

UMLモデリングの本質 第2版

UMLモデリングの本質 第2版

 また、オブジェクト指向のSOLID原則の解説について学ぶには, 最近技術書典で出されていた以下の本がオススメです。 (自分が今まで見た中で一番わかり易いと感じました)

booth.pm

web開発基礎

 開発するソフトの全体像掴むためにもwebの基礎技術については勉強しておいたほうが良いかと思います。

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

ドメイン知識

 自分の場合はアドテクなので以下をオススメします。web業界は特に変遷激しいので各々の会社の先輩に聞くのが良いかと思います。

アドテクノロジーの教科書 デジタルマーケティング実践指南

アドテクノロジーの教科書 デジタルマーケティング実践指南

 上記はどちらかと言うとビジネス職の人向けの話が多いので, 個人的にはこちらのほうがわかりやすかったです。 booth.pm

SQL

 データベースの利用者としてみるか, 設計者としてみるかでオススメの本変わってきますが, 利用者の場合以下2冊がおすすめです。

ビッグデータ分析・活用のためのSQLレシピ

ビッグデータ分析・活用のためのSQLレシピ

エンジニアとしての心構え的なもの

 エンジニアの哲学, 仕事の作法や向き合い方, キャリアなどの話題に触れているもので今も度々読み返している書籍たちです。

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

ベタープログラマ ―優れたプログラマになるための38の考え方とテクニック

ベタープログラマ ―優れたプログラマになるための38の考え方とテクニック

xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com

git のエイリアス紹介

TL;DR;

世の中のエンジニアのalias設定 - Qiita の記事がqiitaでバズっていたので自分の gitの エイリアス設定を整理, 見直しがてら公開してみようと思った。
項目ごとに簡単なコメントもつけているので, 参考になるものがあったらどうぞ使ってください。

参考元

この辺りを参考にして人のdotfilesとかを見て適宜付け足していった気がする。

一覧

gist.github.com

alias一覧

最近は使わなくなったが alias設定した当初は, これを使ってちょこちょこエイリアスを確認していた。

  # aliasの一覧を表示
  alias = !git config --get-regexp '^alias\\.' | sed 's/alias\\.\\([^ ]*\\) \\(.*\\)/\\1\\\t => \\2/' | sort

省略形

# abbr
  # interactive にadd
    a = add -p
  # 作業中のものを 全部addして status確認
    aa = !git add -A && git s
    b = branch
  # 最新のcommit とcommit hashをあわせて表示
    bb = branch -vv
    c = checkout
    cam = commit --amend
    cm = commit -m
    cp = cherry-pick
    s  = status --short --branch
    ss = status
    sh = show

diff系

# diff
    d  = diff
    d1 = diff HEAD~
  # staging(addした) diffを確認
    dc = diff --cached
  # 単語単位でdiffを確認
    df = diff --word-diff

log系

  #log
    l = log
  # merge履歴などをグラフィカルに表示
    lt = log --graph -n 20 --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(green)- %an, %cr%Creset'
  # git log + commit ごとの diff --stat
    ll = log --stat --abbrev-commit
  # 直近のcommit 確認用 
    lo = log --oneline -n 20
  # head commit log
    ls = log --stat --abbrev-commit -n 1
  # head commit log + diff --stat
    lss = show HEAD

tig を使うほどでもない時に使う

github.com

wip系

たしか自作。割り込みのタスクが入ったときなどに現在の作業状況をwipでcommitするのに使う。

# wip
    wip = !git add -A && git commit -m 'wip'
    unwip = reset --soft HEAD~

stash系

# stash
    st = stash
    sp = stash pop

fix系

# fix
    amend = commit --amend -C HEAD
    unstage = reset -q HEAD --
    # 編集中のfileを HEADと同じ状態に戻す
    discard = checkout --
    uncommit = reset --mixed head~

hub系

hub はgithubcli連携するためのtool https://github.com/github/hub

## hub alias
  # github でリポジトリを開く
    open = !hub browse
  # 自分が作ったPRを開く
    byme = !hub browse -- pulls/$(git config user.username)
  # 自分にassignされたPRを開く
    tome = !hub browse -- pulls/assigned/$(git config user.username)
  # 現在いるブランチのPull Requestを確認する
    see  = !hub browse -- pull/$(git symbolic-ref --short HEAD)
  # 指定したcommitを追加した PRを開く
    openpr = "!f() { hub browse -- `git log --merges --oneline --reverse --ancestry-path $1...master | grep 'Merge pull request #' | head -n 1 | cut -f5 -d' ' | sed -e 's%#%pull/%'`; }; f"

Atcoder Beginers Contest 123 の解法ふりかえり

最近 アルゴリズムとデータ構造 の重要性を業務で意識させられることがあって, ちょこちょこ Atcoder Beginners Contestの過去問を解いている。
生のコンテストも出たいなと思いつつ時間がなかなか合わなかったのだが, 今回はタイミングあったので出場した。

atcoder.jp

結果

利用言語は Python3
A, B, C は解けた, Dはゴリ押し解法でサンプル一個目だけ通せたが時間制限に間に合わず。。。 以下, それぞれの問題について振り返ったあと, 全体の感想述べていく。

問題振り返り

A

考えたこと

  • 入力の時点で sort されているので, 最大の差分は 先頭の要素と末尾の要素の差分
  • 直接回答書き始めたら for の後の : 書きそこねてて RE くらった. 最低限の local debug はしましょう...
  • 最近 Python 以外書くことが多かったから, 3項演算子 の書き方忘れててググった, ドキュメントの該当箇所は以下

  • 最初は 配列初期化 + append で入力作っていたが, 内包表記 で書ける

解説での学び

  • Aは想定通りだったので, 特になかった

AC 回答

  • before
a = []

for i in range(5):
    a.append(int(input()))

f = a[-1] - a[0] <= int(input())

print("Yay!" if f else ":(")
  • after
a = [int(input()) for i in range(5)]
d = a[-1] - a[0] <= int(input())
print("Yay!" if d else ":(")

B

考えたこと

  • Bは 全探索 で間に合うパターンが多いのは過去問見てて思ってたいので最初考えたが, 下一桁が0以外のもので最小のものを探せば良いことに気づいた。
  • 下一桁が0以外のもので最小のものを探す 関数を map, filter 使って作ったが, テストケースで最後のものだけ RE
  • RE の原因気づくのに時間がかかったが, すべての入力の下一桁が 0のとき min([]) するような関数を作っていたからだった。
  • python の map or filterで 無名関数 使いたいとき lambda の文字列タイプするのはやや面倒
RE回答
a = []

for i in range(5):
    a.append(int(input()))


def ceil10(n):
    if n % 10 == 0:
        return n
    else:
        return ((n // 10) + 1) * 10


def min_1(a):
    a2 = list(filter(lambda a: a > 0, (map(lambda e: e % 10, a))))

    return min(a2)


ans = sum(map(ceil10, a)) - 10 + min_1(a)
print(ans)

解説での学び

  • 切り上げの実装は, 下一桁が0 のケースで場合分けする方法もあるが, 9を足して ((n + 9) // 10) * 10 のようにする方法もある。
  • わざわざmap, filter使わなくても, loopで書けるしその方が読みやすい(解説がC++だからというのはあるかもしれない)

AC 回答

  • before
a = []

for i in range(5):
    a.append(int(input()))


def ceil10(n):
    if n % 10 == 0:
        return n
    else:
        return ((n // 10) + 1) * 10


def min_1(a):
    a2 = list(filter(lambda a: a > 0, list(map(lambda e: e % 10, a))))

    if len(a2) == 0:
        return 10

    return min(a2)


ans = sum(map(ceil10, a)) - 10 + min_1(a)
print(ans)
  • after
a = [int(input()) for i in range(5)]

def ceil10(n):
    return ((n + 9) // 10) * 10

ans = 999 # > 123 * 5

for i in range(5):
    t = 0

    for j in range(5):
        if j == i:
            t += a[j]
        else:
            t += ceil10(a[j])
    ans = min(ans, t)

print(ans)

C

考えたこと

解説での学び

AC 回答

n = int(input())
a = [int(input()) for i in range(5)]

ans = n // min(a) + 4 + (1 if n % min(a) != 0 else 0)
print(ans)

D

考えたこと

  • 愚直な 全探索(10 ** 10) ** 3 なので間に合わない
  • 出力が大きい順なので, 入力は sort desc しておいたほうが効率が良い.
    • 10 ** 10 の sort の O(NlogN) はセーフ
  • 出力はuniqueなので, 今まで計算した値は cache しておきたい
  • 和を考えるため, 各配列の最大の要素を比較して, 最大のものから取り出して行けば大きい順に出力が構成される
  • それぞれの値は A なら Y * Z 回使われる, B,Cについても循環的に考えて同様, 利用回数も cache

=== この辺りでコンテスト終了

解説での学び

  • 回答を見て, 出力の制限 (K<3000) にも着目するべきだった点に気づいた.
  • 回答には4種類の解法があったが, まだ解法1しか見ていないので後ほど それぞれ 確認, 実装する予定

AC回答

解法#1 O(k2 log k) 制限2000ms に対して max 1945ms かかっていたのでギリギリ

from itertools import product

x, y, z, k = list(map(int, input().split()))
a = sorted(list(map(int, input().split())), reverse=True)
b = sorted(list(map(int, input().split())), reverse=True)
c = sorted(list(map(int, input().split())), reverse=True)

ab = [ai + bi for (ai, bi) in product(a[:k], b[:k])]
ab.sort(reverse=True)
abc = [abi + ci for (abi, ci) in product(ab[: min(k, x * y * z)], c[:k])]
abc.sort(reverse=True)

for abci in abc[: min(k, x * y * z)]:
    print(abci)

他の人の回答を見て

  • コード長が短いコード を見て, パット見でに気になったものは以下

  • c_r_5 さんの回答 より

a,*_,e,k=eval('int(input()),'*6);print(':('*(e-a>k)or'Yay!')
  • eval で 文字列として 'int(input())' と 書ける
  • if-else ではなくて or で表現できる

終了後の雑多な感想

  • 参加者 が過去最大規模(約4000人!) だったらしく, コンテスト開始直後アクセスちょっと重かった
  • 最近資格試験など受けたりもしていないので, 時間制約付きで問題を解く機会がなかなかなかったので楽しかった
  • 入力だけでなく, 出力の制約 にも着目して解法考えるの大事
  • Python が比較的慣れているから, 書きやすいが map, filter辺り使い始めると method chaining ないのが辛い。この辺り書きやすい言語は模索してみる。 script 言語で時間問題なさそうなら Rubyとかかな? Dで時間, メモリ的にだめなら Julia, Kotlin あたりが候補

  • 以下のpodcast で聞いてデバッガちゃんと使おうという気持ちになったので, pdb をちゃんと使ってみた。今まで IDE debuggerに慣れてたけどこれは便利。 anchor.fm

  • GCJ は出そびれたのでまた来年...

  • データ構造については, Open Data Structure の邦訳がありがたいことに無料公開されているので, そちらで勉強中
    • 一人でやるとダレそうなので, お互い進捗報告しあうやつやりたい

sites.google.com

書籍レビュー 経営システム 28巻2号「ビジネスでインパクトが出せるデータサイエンティストになるには」

@pseudo_finite さんより, 経営システム 28巻2号をいただいたので, @pseudo_finite さんの解説記事 「ビジネスでインパクトが出せるデータサイエンティストになるには」の感想などを書いていきます。
(1/24 には届いていたのに引っ越しなど諸々忙しくて感想を書くのが遅くなりました :pray:)

本記事では, まず自分の立ち位置を示した上で記事の各章について本文の主張に関連して感想や実務を通して身につけた自分の考え方を述べていこうかと思います。
書いてから記事を読み直すと, 本文が学術誌ということでこの記事の書き方もやや硬めの書き方になってしまいました。

解説記事の章立ては以下のとおりです

1. はじめに
2. データサイエンティストが力を発揮する場
3. 課題設定
4. 解決方法の設計
5. 検証
6. 育成
7. まとめ

このフォーマットはu++ さんのものを大幅に参考にさせていただきました :bow:

【書籍メモ】「ビジネスでインパクトが出せるデータサイエンティストになるためには」 - u++の備忘録

また一旦勢いで書いたのでこの記事はdraft に近いです。参考になるリンクなど随時追記していきたいと思います。

自分の立ち位置

アドテク会社のData Mining (Machine Learning) Engineer 新卒2年目(もうすぐ3年目)です。
肩書はEngineer とはいえ, 会社の特性上, ログ, KPIの分析, 文献調査, offline検証, 設計, 開発, online検証, 運用 など割と全部やるため, フェーズによってはいわゆるデータサイエンティストっぽい業務もあります。

1. はじめに

いわゆる序論で導入と記事の構成の説明を行っています。
導入の中で 近年データサイエンス自体に注目が集まっているのはもちろんだが, 本来的にビジネスの場で必要とされているのは広義のサイエンティストである という要旨の記述があり, とても同意しました。
データサイエンス(以下DS)やMachine Learning(以下ML)は, いわゆるエンジニアリングとは違って結果が確率的なものであるため, 方法論ありきのやり方は失敗しやすいなと最近いろいろな方の話を伺って感じているところです。

2. データサイエンティストが力を発揮する場

企業という場に絞って, 表題通りの内容について解説しています。
本文中で大事なのは主に以下2点だと述べられています。

  1. データサイエンスによってスケールさせられるビジネスドメインである
  2. 十分な量と質のデータを保有している

1 について, DS, MLは0->1や1->10というよりは 100000 を10000 * 1.01 にするような役割を果たすことが多いため, 解説記事中にあるようにニッチな産業あるいは十分なデータがない新規事業だとビジネスインパクトを出すのは難しいと思っています.
ただ例外はあると思っていて, DS, MLの知識自体を売るモデル(教育, コンサル) や既存事業のデータを活用した新規事業の場合はこの限りでないかなと思います。

2 について, 量については割と当たり前なので質の部分に触れていきます。
本文中ではデータの質に関して, 匿名データより実名データ, 閲覧データより購買データの方がユーザの性質をよく表しているため質の高いデータであるという旨が書かれています。

自分の業務(アドテク)周りだと, アドフラウドなどで不正なclick除外したり, conversion はユーザによって定義が違うので気をつける必要があります。実務のML Engineer の業務は前処理がほとんどと言われるのもこの辺りの所以なのかなと思います。
またデータをどう活用するかという観点からテーブル定義やロギングの設計を行うのもとても大事なことです。

3. 課題設定

適切な課題設定が大事だと言う話でそもそも解くべき問題か?を考えるのが重要だと述べられています。

伝え聞く話では Japanese Traditional Big company などでは, "Deep Learningでいい感じにしてくれ" というようなオーダーがお偉方から降ってくるらしいですが, そのような方にこそ本章を読んでいただくのが良いのではないでしょうか。
ただ翻ってみると自分も方法論ありきで課題を設定してしまう(この言語, フレームワーク,ライブラリ, アルゴリズム が使いたい)ということはあるなと思ったので気をつけようと思いました。

4. 解決方法の設計

前半部では, 手法の検討において, ML, 数理計画, 確率モデリングなどを解決手法として公平に考える必要がある旨が述べられています。

こちらの主張もほぼ同意で, 自分の意見を加えるとプロジェクトの期限やリソースに寄ってはルールベースのロジックで設計するのも検討する必要があるなと考えています。
いずれにせよ前章でも触れたように方法論で解決方法を決めるとロクなことにならないは確かです。
若干後付けですが, 自分も解法をMLで縛りたくないため MLエンジニアではなく Data Mining Engineer の肩書を名乗っています (弊社では肩書は個人で決めてOKだった)

後半部ではML, 数理モデリングにおいて重要なことがおおまかに以下のように述べられています。

  • 実装可能性(いわゆる feasibility)
    • 不可能な場合は問題の方の性質を変更する
  • 実装容易性, 保守, 運用の容易性
  • 近似の精度

それぞれについて, 自分の考えを述べます。

実装可能性

これはちょうど最近あまり考えず雑にタスクを進めてしまったせいで, アプリケーションエンジニア, インフラエンジニアとのコミュニケーションコストが増大して余計に開発期間を要したということあったので耳が痛い話でした。
新規にロジックを実装する場合は アプリケーションエンジニア, インフラエンジニアには事前に確認とっておきましょう。。。

実現容易性, 保守, 運用の容易性

本文中にも述べられていますが, 実務だとモデリングの手直しが必要なことはままあります。
実際に経験したのは オンライン検証の結果モデルに問題があることが判明した, 本番運用において入力データが想定しない形で変更された などです。 本来はモデリングの際に考慮できていればよいのですが, 完璧な考慮は無理です。
したがって改修が容易なコードで実装しておくのが良いため, 設計, リファクタリング周りの勉強はDS, ML Engineer でもしておくと良いと思います。
学習コストとのバランス考えたときの個人的なオススメ本は以下あたりです。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

UMLモデリングの本質 第2版

UMLモデリングの本質 第2版

近似の精度

実務において何がしかの近似は必ず必要になってくるので, その影響を考えるのは大事です。
時に近似が思わぬ挙動をすることがあるので, モデルの予測精度まで時系列で監視できるような基盤があるのが望ましいかなと思います。またDS, ML周りで物理の強い人が多いのはこの辺りが強いなのかなと思います。

5. 検証

本章で重要だと述べられているのは主に以下2点です。

  • スピード重視で検証をおろそかにするのはNG
  • 施策の「良さ」の評価

スピード重視で検証をおろそかにするのはNG

これはもちろんで要件定義の段階で検証でモニタリングするKPIはビジネスの意思決定者と握っておくのが望ましいでしょう。
ただし, 対象KPIは検証を行う過程である程度柔軟に変更,追加できるようにしておくほうが良いです。
モニタリングについては改善すべきKPIはもちろん非機能要件の精度, データの量, 質などについても行っておくのが望ましいです。 
また, ないとは思いますがMLのフリーランス, SIでPoCまともにやらないところは避けたほうが良いです(社会性フィルタ)

どの程度の確信度で検証を行いたいか。

DS, ML では特に 施策の良さの評価が難しい. 常にmore better の施策が存在することが多いうえにそれを確かめるすべがないという旨が書かれていました。

本文ではよりよい施策の探索法として以下二点が挙げられていました。

  1. 仮説を元に網羅的に施策を走らせる
  2. 複数のDSに施策を競わせる

これは業務上では前者は時間や後者は人的リソースの制約で厳しいパターンが多く, (DS, ML Enginner にとって)十分な検証ができないまま開発が進んでしまうのが多いのかなと感じています。
この辺り解決するいい感じのOSS, SaaSが生まれてくれればよいのですが...

6. 育成

サイエンスの能力実務遂行能力 の二点を育てるのが大事だと書いてあります。

実務遂行能力 については,いろいろな人にレビューをしてもらうように著者は心がけていると記述があり, この点についてはとても同意できました。 実務においてまず身につけないといけないのはドメイン知識でありその部分はレビューの中で質問するのが身につくのが早いと考えています。

あとちょうど昨日こんなツイートが流れてきて, そうだなーと思いました。

新人でDS職の人でも最低限のproduction deploy くらいは経験積んでおいたほうが良いかと思います。

サイエンスの能力 については正直アカデミアでないと満足な教育が難しいため各自大学時代に勉強するのが一番大事だと思います。 企業の中では社内での書籍, 論文の紹介仕合いや有識者による勉強会などがあると良いのかなと思いました。

全体を通しての感想

ML, DSは新しい分野であるが故に企業で成果を出すためのノウハウは形式知化してないことが多く, その点で本解説記事はとてもよくまとまっていて良いと思いました。
自分もスキル的にまだまだ未熟ですがスキルを成長させるのはもちろん, 実務で得た知識も積極的に世の中に還元して DS, MLに関わるひとがハッピーになるように貢献できればと思います。

久々に長めの文章を書いて疲れた

よく使うツールまとめ - 個人wiki, タスク管理編

ちょいちょい聞かれるのでまとめてみる。 結構いろいろ試したが, 最近は

個人wiki -> Inkdrop タスク管理 -> ClickUp

で落ち着いた感がある。 簡単に今まで試したものと今使っているものの使い方についてまとめていく。 今まで使った事あるやつの個別の使用感は直接聞いてください。

個人wiki

https://inkdrop.app/ が個人的には今の所ベスト, 有料サービスで 4.99$/mo
今回の記事もdraftは inkdrop で書いている。

今まで試したもの

この辺

自分が使う上で欲しかった機能

使い方

とりあえずなんでもメモを放り込む感じ, 全文検索があるのでタグ付けとかは気が向いたときにする。 昔はslackやissue投稿の下書きもやっていたが, そちらは最近 editaro を使っている

タスク管理

https://clickup.com/ こちらは個人利用は基本無料。無料でも十分だが, ヘビーユーザ向けの機能が50$/year ほどで使える.

今まで試したもの

自分が使う上で欲しかった機能

  • クロスプラットフォーム対応
  • kanban形式でのタスク管理
  • 他サービスとのAPI連携
  • time tracking
  • pomodoro
  • サブタスク作成
  • タスクの繰り返し機能

使い方

  • タスクの階層構造
    • workspace
    • 仕事
    • 個人プロジェクト
    • プライベートのタスク
    • list
      • 仕事, 個人プロジェクト
        • 通常業務(ここでGTD)
        • 後で調べることリスト
        • 掛け持ちしているプロジェクトごとのissueためとく場所
      • プライベートのタスク
        • これも大きいタスクごとにプロジェクトを切っている
        • プロジェクト化するまでもないやつは any.do を使っている. 昔から使っていてUXがかなり好み
  • 少なくとも朝10分, 晩10分タスク整理と振り返りの時間をとる
  • [MEMO] メインの仕事がredmine 使っているのでいい感じにチケット流せるやつを作成中