Tokyo Machine Learning Kitchen

Hello, I'm @lunardog. I work in Cookpad's Research and Development team as a machine learning researcher. I also host Tokyo Machine Learning Kitchen events. If you'd like to attend, you can sign up using meetup.com or connpass.

I first heard about Cookpad back in 2012 when I joined Tokyo Rails Meetup. At the time, Rails was immensely popular in the developer community and many coders, if not working with Rails in their day jobs, would learn Rails and build hobby projects in Rails after hours. I remember being quite impressed by the talks, especially the ones by Cookpad employees. I was amazed by Cookpad's hospitality and willingness to share the event space, the expertise of the staff and even contribute to open source projects. Cookpad was truly the cornerstone of the Rails community for Tokyo.

f:id:lunardog:20180625165758j:plain (A talk at the Tokyo ML event)

Fast forward to now. Machine Learning in general and Deep Learning in particular is the hot topic. I joined Cookpad's newly created Research and Development department as a Machine Learning researcher. Cookpad is, as it was those years ago, a dynamic, fast-paced company with a positive attitude to open source and sharing knowledge, be it recipes, open-source code or datasets for machine learning researchers. I have decided to make it my mission to contribute to the community of Deep Learning researchers in Tokyo by organizing Tokyo Machine Learning Kitchen events. Much like Tokyo Rails, the ML Kitchen events are a place where professionals and hobbyists can get together to share their interests, network and enjoy a good meal.

The focus of ML Kitchen events is networking between practitioners of Machine Learning. You can expect presentations on:

  • professional or personal ML-related projects
  • machine learning, deep learning, data science walkthroughs
  • paper reviews: own or found somewhere
  • reviews of machine learning frameworks and libraries
  • really interesting talks about math and statistics

To further facilitate networking, Cookpad provides snacks prepared in the kitchen where the event takes place. This is why it's called "ML Kitchen", by the way. It takes place in a kitchen.

Talks are in English, but it's not a problem to do a talk in Japanese, if the slideshow is in English. We usually have a keynote talk, followed by a snack break and a series of lightning talks. We end the evening with more networking, exchanging of business cards, eating and drinking.

f:id:lunardog:20180624183031j:plain

If you'd like to share something with the Machine Learning community in Tokyo, contact me through our group page or meetup or raise an issue in our github repository.

Hope to see you soon!

RubyKaigi 2018 ありがとうございました!

人事部の@mamiracle__ です。好きな Ruby のメソッドは Enumerable#entries です。みなさまからの entries をお待ちしています💖

さて、クックパッドは先日の RubyKaigi 2018 に Ruby Committers Sponsor と Network Sponsor としてスポンサーをいたしました。私たち人事メンバーも、ブースやドリンクアップを通じて、RubyKaigiを盛り上げることに貢献できたのではないかとおもっています。

会期中には、クックパッドに所属する桑原仁雄(@pocke)、Kirk Haines(@wyhaines)、 笹田耕一(@ko1)、遠藤侑介(@mame)がスピーカーとして登壇し、심 상용(@riseshia)がライトニングトークを行なっています。また、RubyKaigi運営では、オーガナイザーとして @nano041214@asonas@sorah が、スタッフとして @mozamimy が活躍してくれました。

イベント参加のご報告として、当社所属のメンバーの発表やブースの紹介をいたします!!!

発表

A parser based syntax highlighter

桑原仁雄(@pocke)からはパーサーベースのシンタックスハイライターであるIroに関して発表がありました。通常のシンタックスハイライターで利用されている正規表現では、複雑なプログラム表記でうまく機能しなくなってしまいがちですが、パーサーベースであればそういった問題が生じないそうです。また、gemとして提供されているので、Vimだけではなく色々なエディタでも活用できるとのことです。

また、RubyKaigi効果で意識が高まった本人からも力強い宣言がでておりますので、ぜひ今後にご期待ください!

It's Rubies All The Way Down

自身が2001年以来の Rubyist であると紹介した Kirk Haines(@wyhaines)からは、主に Web アプリケーションを動かすときのテクノロジスタックについて、それぞれの時代における Ruby で作られたソフトウェアの紹介や、概念実証(Proof of Concept)が示されたりしました!

特に Web アプリケーションにおいては Rack の登場がキーポイントになり、ミドルウェアとWeb サーバーの関係がそれ以前と比べてシンプルになったという説明は納得できました。また、10年以上前の Ruby では、ロガーやロードバランサーなどをやるには遅すぎると言われることがありましたが、近年の Ruby では十分なパフォーマンスが確保できることも示され、Ruby の進化がよくわかりました。

Guild Prototype

Ruby の新しい並行プログラミングモデルである Guild について、笹田耕一(@ko1)から発表がありました。冒頭では、シングルプロセスで合計40コアのCPUを使いきるデモがされていて、未来感ありましたね。

従来の並行プログラミングでは、データを共有するために競合状態をプログラマが頑張るか、データを共有しないという手法が主にとられてきました。Guild では、メンバーシップという概念を導入することで、容易にデータを共有しつつも、マルチコアを活用できるようにしています。Rubyで実用段階になるのが、今から楽しみです!

Type Profiler: An analysis to guess type signatures

遠藤侑介(@mame)の発表では、提案されている複数のRubyの型システムを概観したあと、Ruby 3に必要となってくる型データベースのために、型プロファイラーの導入が提案されました。型プロファイラーは、いくつかの手法で型を推測するための機構です。静的解析や動的解析をつかって、いい感じに型を推測できないかという試みです。それぞれの手法にメリットやデメリットがあって、まだまだ難しいところも多いようですが、 Ruby の改善が着実に進んでいる様子が伝わってきました。

また、ブースの質疑応答タイムでは、海外のファンからチョコレートのプレゼントをもらうなど、大人気ぶりを発揮していました!

ライトニングトーク

Find Out Potential Dead Codes from Diff

Cookpad のような長期でメンテナンスされているコードでは、どうしてもどこからも呼び出されないデッドコードが生まれてしまいます。심 상용(@riseshia)のライトニングトークでは、未使用コードの差分からデッドコードを検出する手法について発表がありました。クックパッドでも実際に使われて効果がある手法とのことです。

ブースやグッズ

クックパッドが海外展開している国を示した世界地図や、「Cookpad storeTV」、ユーザーボイスやミッションなどを詰め込んだオリジナルボードなどを展示しました。

f:id:cookpadtech:20180614152425j:plain
(地図にはクックパッドが展開している68カ国を⭐シールで示しました)

ノベルティには今年初めて作った「ロゴ入りお箸」や、仙台をイメージした「ずんだ餅どら焼き」を用意しました。どら焼きは、仙台の老舗和菓子屋さん「こだまのどら焼き」さんに相談をして作っていただきました。控えめな甘さのずんだ餡と、もちもちの食感が美味しくてあっという間に完売してしまいました!

【RubyKaigi 2018のスポンサーで仙台にきています♦️】 クックパッドは毎年、Rubyというプログラミング言語のカンファレンス #RubyKaigi に協賛しています🤗 2018年は5/31〜6/1まで #仙台 での開催なので、 #ずんだ餅どら焼き を作ってみました❤️ 仙台の老舗 #こだま さんのどら焼きです! クックパッドでは、ユーザーさんにより速く良い価値を届けるために、技術もすごく大事にしているんですよ! 今後はそういったこともご紹介できればと思います🎶 #クックパッド #テクノロジーカンパニー #どら焼き #ずんだ餅 #仙台名物 #こだま #cookpadorayaki #クックパッどら焼き #rubykaigi #rubykaigi2018 #cookpad #makeeverydaycookingfun #毎日の料理をたのしみにする #♦️ #💎 #🖥 #🥞 #🤗

クックパッドHRさん(@cookpad_hr)がシェアした投稿 -

その他ブースでは、クックパッドでRubyフルタイムコミッターとして活躍する遠藤侑介(@mame)と、仙台のずんだ豆にちなんで「mameさんの豆つかみ」も実施!CTOの成田一生(@mirakui)をはじめとして、まつもとゆきひろさん(@matz)さんやAaron Pattersonさん(@tenderlove)さんも参加してくださる盛況なイベントとなりました!

f:id:mamiracle:20180614153621j:plain
(今回の最速王はクックパッドHRメンバーで叩き出したタイムは0:06:92でした!)

Cookpad X RubyKaigi 2018: Day 2 Party

2日目の夜に開催したパーティには、90名近くのゲストが参加してくださいました!RubyKaigiの会期中にパーティを企画するのは、クックパッドにとってこれが初めてでドキドキしていましたが、多くの方にお楽しみいただけて本当に良い機会となりました!

【Asakusa.rb × Cookpad】Meetup after RubyKaigi 2018

RubyKaigi 2018終了後の翌火曜日には、Asakusa.rbとのコラボレーションイベントを開催しました!Railsコミッターであり、Rubyコミッターの松田明さん(@amatsuda)に司会を務めていただき、RubyKaigi 2018 の余韻を楽しみました。

この日は「Rubyコミッターによる RubyKaigi 2018の見どころ振り返り」「RubyKaigi 2018会期中に決まったRubyの次の方向性について」というふたつのテーマを設定。笹田耕一(@ko1)と遠藤侑介(@mame)を中心に、飲みながら食べながら語り合いながら、会場全体で楽しむことができました。

f:id:mamiracle:20180614153523j:plain
(クックパッドイベント恒例のキムラシェフの絶品ご飯)

おわりに:Rubyとクックパッドについて

クックパッドは、2008年にRuby on Rails へとリニューアルしてから、世界的にも大規模な通用事例として知られてきました。Ruby への貢献を現在も強化しており、二人のフルタイムコミッターを迎え入れクックパッドで次世代Ruby の開発に取り組んでいます。

また、技術をわたしたちが使うことはもとより、社外にも共有することで価値を生むようなソフトウェアやライブラリは、積極的にオープンソース化を行い公開しています。

今後もRuby を含む、さまざまなオープンソースソフトウェアの発展に貢献できるよう、クックパッド一同頑張りたいと思います!

次は8月30日から開催されるiOSDC Japan 2018に参加する予定です。みなさまにお会いできることを楽しみにしています😄

f:id:mamiracle:20180618181226j:plain (来年こそはRubyKaigiに参加した社員全員で集合写真撮るぞ!)

クックパッドでRubyを書きたいなと思ったら...
- バックエンドエンジニア(料理動画・広告配信)
- UXエンジニア
- バックエンドエンジニア(決済基盤)
- Webアプリケーションエンジニア
- セキュリティエンジニア
- ソフトウェアエンジニア (Site Reliability)

無理をしないコードレビュー

会員事業部の三吉です。 クックパッドでは、GitHub Enterprise の Pull Request を使ったコードレビューを広く実施しています。 この記事では、私がコードレビューすることに対する苦手意識をなくすために意識したことを紹介します。

クックパッドでは、テックリードや新卒、インターン、バイトといった肩書きに関係なく、誰もがレビュワー・レビュイーになります。 チームやプロダクトによって開発ルールは少しずつ異なりますが、私の所属する会員事業部では、PR を出したときに GHE やチャットで部内のエンジニアにメンションして、その時にレビューできる人がレビューするという形を取っています。

私は、昨年2017年に新卒入社したのですが、それまでは個人開発や研究用のコードしか書いたことがなく、短期インターンシップを除くチーム開発の経験がありませんでした。 配属当初からコードレビューすることは求められていのですが、はじめの数ヶ月間はレビューすることに対して苦手意識があり、なかなか積極的にレビューに参加することができませんでした。

コードレビューの難しさ

コードレビューに対する苦手意識は、自分のレビュー内容に自信が持てないことによるものでした。 コードレビューは、真剣に取り組もうとすると非常に難しい作業です。 以下、「見るべき項目の多さ」「文脈によるレビュー内容の変化」「開発速度とのトレードオフ」の3点からコードレビューの難しさを見ていきます。

見るべき項目の多さ

コードレビューでチェックするべき点は非常に多いです。 以下に、ざっくりとレビューの観点をカテゴライズしました(順序に深い意味はありません)。

  • 挙動(意図どおり動作するか)
  • バグ
  • セキュリティ
  • 可読性
  • テスト
  • パフォーマンス
  • ドキュメンテーション
  • 設計 *1
  • ……などなど

これらは、それだけで分厚い本が書けるようなカテゴリであり、それぞれについて一般的な原則や社内のルールがたくさんあります。 ちょっとした変更であればともかく、毎回のコードレビューでそれらを厳密に網羅することは不可能で、どこかで妥協する必要があります。

文脈によるレビュー内容の変化

では、どこで妥協するのかというと、それはレビュー対象のコードの文脈に依存します。

極端な例を挙げると、ユーザーテスト用のプロトタイプと、決済周りのデータ処理を行うジョブとでは、どのくらい細かくレビューするべきか変わってきます。 前者は、あくまでプロトタイプであって、テストするのに問題なければ最悪バグが含まれていても構いません。 それに対し、後者にバグが含まれていると、深刻なデータ不整合が起きたり、ユーザーに不利益が出たりすることになります。 後者をレビューするときには、テストの内容やエンバグの可能性の丁寧なチェックが必要です。

他にも、変更頻度の高い箇所であればメンテナビリティを考慮したり、検索などリクエストの多い部分であればパフォーマンスを意識したりと、コードの位置する文脈に依存して、重点を置くべき観点が変わってきます。

開発速度とのトレードオフ

レビュー時どこに重点を置くべきかは、文脈だけでなく、レビューに割ける時間によっても変わります。

コードレビューは思いのほかコストのかかる作業です。 レビューしているあいだレビュワーは他の作業をすることができず、また、レビュイーにも指摘箇所の修正だけでなく、レビューがつくたびに発生するコンテキストスイッチの負担があります。

しかし、コードレビューにはそのコストをかけるだけの価値があります。 私たちがコードを書く目的は、ユーザーに価値を届けることであり、コードレビューの目的も変わりません。 コードレビューは、届ける価値の品質を担保するために必要な作業です。

とはいえ、サービス開発においては、その価値をすばやく届けることも非常に重要です。 レビューに不必要なまでに時間をかけて、高速な開発サイクルを回せなくなっては本末転倒です。 品質と速度とのトレードオフから、レビューにどの程度コストをかけるべきか考える必要があります。

コードレビューをするときに意識していること

以上にみてきたように、コードレビューは、無数の項目について、コードが置かれた文脈から優先順位をつけ、開発速度と品質を最大化するような時間でチェックしていく、というとても困難な作業です。

……と、これが理想のコードレビューかもしれませんが、人間が意識的にできるものではありません。 重要なのは、そういった難しさがあることを知った上で、できる範囲でやる ことです。 とはいえ、コードレビューに慣れない頃は、できる範囲でやったレビューには多くのヌケモレがあるように思えて不安になったり、しっかりレビューしたときには時間をかけ過ぎではないかと不安になったりしていました。 ここからは、そうした不安や、それに起因する苦手意識をなくすために私が行っている工夫を紹介します。

レビューした範囲を明示する

自分のレビューが不十分に感じられたときは、何を見たか、あるいは、何を見られていないかを Review summary などに書くようにしています。

f:id:sankichi92:20180618184907p:plain

こうすることで、他のレビュワーに重点を置いて見てほしい場所を伝えています。 広く薄く見ただけであれば「ざっと見ました」というコメントでも構いません。

また、自信のないときは、素直に他のレビュワーに依頼します。

f:id:sankichi92:20180618184918p:plain

重要な定数などについて、仕様と照らし合わせて正しいことを指差し確認するのも、ヌケモレを防ぐのに大事です。

f:id:sankichi92:20180618184933p:plain

わからなかったら質問する

もちろん、他のレビュワーが現れることを期待できない場合は、ひとりで全範囲をレビューする必要があります。 そういう時に自信を持てない箇所、わからない箇所を見つけたら、わかった気になるまで読むのではなく、質問することが重要です。

次のように、質問に答えることで、実装者がミスや考慮漏れに気づくということも少なくありません。

f:id:sankichi92:20180618184946p:plain

コードから汲み取ったことを言語化して、その認識であっているか確認するだけでも効果があります。 込み入った内容であれば、実装者と一緒にペアレビューするという方法も有効です。 ペアレビューで理解した内容を PR にコメントするとなお良いです。

コードレビューには、問題点を見つけるだけではなく、そのコードの理解者を増やして属人性をなくす機能もあります。 GHE に残った質問のログが数年後に再び役立つということも珍しくありません。

nits や IMO, MUST といったラベルを利用する

先にも述べたように、サービス開発ではスピードも重要です。 本質的でない修正に時間をかけるよりも、先にリリースした方が良い場合もあります。

とはいえ、レビューしていると、どうしても細かいところが気になってしまうものです。 そうしたときは、[nits] や [IMO] といったラベルをレビューコメントの先頭につけて、修正の判断を実装者にゆだねます*2

f:id:sankichi92:20180618184957p:plain

逆に、どうしても修正してほしい場合は [MUST] ラベルをつけます。 すぐに修正できない問題であれば、その PR で修正するのではなく、Issue にして後日修正するのも有効です。

おわりに

以上が、私の意識している「無理をしないコードレビュー」です。 レビューすることに慣れて、日常化すれば特に意識する必要はなくなります。 しかし、1年前の私にとってそれはとても難しいことだったので、当時の私に伝えるつもりでコードレビューするときのコツを書いてみました。

コードレビューする機会が増えて感じるのは、レビュワー側も非常に勉強になるということです。 レビューする時の視点は、単にコードリーディングする時の視点とは違います。 エンバグはないか、テストは必要十分か、などなど普段以上に神経をとがらせて見ることになります。 そして、その視点はそのままコードを書く時にも活かすことができます。

また、今回はコードレビュー「する」ときの工夫に焦点を当てました*3が、「される」ときの工夫も重要です*4。 他にも、クックパッドでは、コードレビューのコストを下げるための自動化等の取り組みも行っています*5

コードレビューのスタイルは、組織や開発するプロダクトの性質によって変わってくるものだと思いますが、この記事が少しでも参考になれば幸いです。

*1:大きな変更であれば事前に設計レビューを行います。

*2:リポジトリにもよりますが、クックパッドでは実装者がマージを行うことが多いです。

*3:コードレビューすることに関する記事として、他にも たのしくなるコードレビュー があります。

*4:開発速度を上げるための Pull-Request のつくり方 など。

*5:Android開発のコードレビューbotを乗り換えた話 など。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/