コネヒト開発者ブログ

コネヒト開発者ブログ

Amazon ECSで2019年に導入した新機能

こんにちは。インフラエンジニアの永井(shnagai)です。

re:invent真っ最中で、EKS for Fargateが発表されたりFargate Spotが発表されたり今年も激熱ですね!!

今回は、日々アップデートされているECSの新機能の中から今年導入したものと今後導入を検討していきたいと思っているものについて書こうと思います。

内容はざっくりと下記3項目です。

  • パラメータストアに保管した値の環境変数への注入方法変更
  • Container Insightsを使ったタスクの監視
  • 今後導入していきたいこと
    • Savings PlansでのFargateのコスト削減
    • FireLensを使って脱CWLの柔軟なログルーティング

この記事はコネヒト Advent Calendar 2019 4日目の記事です。

続きを読む

コードレビューで心がけている3つのこと【PHPカンファレンス協賛記念ブログ!】

f:id:fortkle:20191129174026p:plain

こんにちは!エンジニアの @fortkle です。

あの伝説のゲーム「メダロット」のスマホゲームのリリース日がついに 2020年1月23日と発表がありました!*1 いまからワクワクしてきましたね!リリースしたらぜひロボトルしましょう!

さて、今回の記事は「コードレビュー」についてです。コネヒトに入社してから早4年、数百のPRをレビューしてきてだんだんと自分の中でコードレビューに対する接し方が定まってきました。今日は私がコードレビューで心がけていることについてご紹介できればと思います。

レビュワーとして

① "既存コード" の 歴史的経緯を素早く紐解く

コードレビューは様々な目的で行われますが、「欠陥・バグを検出すること」「コードの改善」に期待をしていることが多いかと思います。

これらの目的を達成するためには、既存・変更後のコードの実装意図や背景を理解することがとても重要になります。特に長年運用されているプロジェクトでは、前者の「なぜ今の、既存のコードがこのような実装になっているのか」という歴史的経緯を理解することは、不具合を出さずに安全に開発を行っていくためのスキルの1つです。

弊社コネヒトでは、GitHubのPRを使った開発スタイルを採用しているのでコードの意図や背景を理解するには純粋なコードリーディングと同じぐらい、過去のPRを見るのが効果的なケースがあります。

ここでは、過去のPRを素早く簡単に探し出すために、実際に私が使っているtipsを2つご紹介します。

方法1. PhpStormのAnnotate + Find Pull Request Plugins

  1. PhpStormでAnnnotateを表示
  2. 確認したい行を右クリックし、 Annotate Previous Revision で追加・編集されたコミットまで歴史を遡る
  3. Find Pull Request Plugin でそのコミットが追加されたPRを開く

という手順で簡単にPRを探し出すことができます。

PhpStormやGoLandなどJetBrains製品のエディタにはAnnotateというgit blameと同等の機能があります。行番号を右クリックすることで表示されるようになります。

f:id:fortkle:20191129123840p:plain
Annotate機能

また、Annotate部分を右クリックすると、さらに選択行のコミットの操作ができるようになります。 Annotate RevisionAnnotate Previous Revision を駆使すると、コードスタイルの変更などで追いづらくなってしまったコードも簡単に歴史を遡って探すことができます。

f:id:fortkle:20191129124314p:plain
選択された行をコミット単位で遡れる

最後に、この Find Pull Request というプラグインを利用すると、右クリックしてメニューを選ぶだけで、選択行が追加されたPRを開くことができるようになります。

plugins.jetbrains.com

https://raw.githubusercontent.com/shiraji/find-pull-request/master/website/images/screenshot.gif
https://plugins.jetbrains.com/plugin/8262-find-pull-request から引用

この方法はこちらのブログで紹介されており、大変参考になりました! tenkoma.hatenablog.com

方法2. tig blame + open-pull-request

次に tig と open-pull-request を使う方法です。

  1. tig blame {filename} で確認したい行があるファイルを開く
  2. , < と打つと選択行の履歴を遡れるので追加・編集されたコミットを探す
  3. P と打って open-pull-requestをtig上から実行し、PRを開く

という手順で簡単にPRを探し出すことができます。

方法1のやり方を知る前はこの方法でPRを探していました。 特別なエディタが不要でどんなプロジェクトにも対応できるので今でもたまに利用しています。

f:id:fortkle:20191129143258g:plain
tig blame + open-pull-request でPRを探すイメージ

この方法も設定方法などがこちらのブログで紹介されており、大変参考になりました! blog.mknkisk.com

② PR上でのコメントで工夫する

PRのコメントでもいくつか工夫することを心がけています。

ラベルを使う

PRにコメントを残すとき、私は以下のようなラベルを使うことが多いです。

ラベル 意味
[MUST] 必ず直してほしいとき
[IMO] 自分ならこう書くかな?どう?という緩やかな指摘のとき(In My Opnion)
[nits] 再レビュー不要な細かな指摘(typoやスタイル等)のとき
[質問] 分からないとき、確認したいとき

f:id:fortkle:20191129145823p:plain
ラベル付きのコメント

必要に応じてコメントの先頭にこれらのラベルをつけることで、例えば [MUST] は必ず修正してほしい、 [IMO] で指摘された点は一度考えてもらって採用するかしないか決めてほしい、などレビュイー自身に最終的な変更の意思決定をしてもらえるように考えて使っています。

良い点もコメントする

以前は問題がある点や確認したい点のコメントしか残していなかったのですが、最近は勉強になったときや感謝の気持ちを込めて良いと思った箇所にノイズにならない程度にコメントを残すようにしています。

コードレビューという場を、リスクや課題を見つけ出すことだけでなく、自身の学びや自信につながるポジティブな場として活用するために意味はあるかなと思っています。

f:id:fortkle:20191129144805p:plain
感謝のコメント!

③ とにかく動かしてみる

基本的にPRをレビューするときはどんなに些細な変更でもアプリケーションコードにdiffが入ったら実際にローカル環境で動かすようにしています。

変更内容にロジックが含まれるのであれば、レビュイーが様々なパターンを考慮に入れて実装できているか、抜け漏れがないか、を境界値やEmptyなstateを使って動かして確認します。 このとき単体テストがあれば簡単にチェックができるので、テストの有り難みを感じられますね!

レビュイーとして

続いてレビュイーとして心がけていることを紹介します。

... といいましたがです!

レビュイーとして心がけていることは、今週末の2019年12月1日(日)に開催されるPHPカンファレンス東京 2019でLTとして発表します!

高野福晃(@fortkle) 17:20〜 Track 1 (1F 大展示ホール) Lightning Talks
登壇タイトル:「余裕を生み出すコードレビュー」

当日ご参加される方はぜひ発表を聞いていただければ幸いです!

また、今年もシルバースポンサーとして協賛いたします。 ブースも出しますのでそちらにもぜひお立ち寄りください!

phpcon.php.gr.jp

”Twemoji" by Twitter, Inc and other contributors is licensed under CC-BY 4.0

PR

こんなハートフルなレビューのコネヒトでは一緒に働いてくれるエンジニア募集中です!興味があればこちらもみてください!

www.wantedly.com

【実装メモ】Gatsbyを使ってよかった・注意すべき点まとめ

f:id:dachi023:20191118114807p:plain

こんにちは、エンジニアの@dachi_023です。最近、MacBook Proの調子が悪いのですが修理に行くのが面倒で行っていません。放置し続けていたら直ったりしないかな・・・。

今回の記事はGatsbyで100ページ超えの静的サイトを構築したときの学びについてです。Gatsbyって実際どうなん?って思っている方に読んでもらえたら幸いです。

つくったもの

ママリユーザーが本当に使ってよかったと思う商品・サービスの口コミを元に、自分と家族に合うものを探すことができる「ママリ口コミ大賞」の2019年 秋版のサイトをGatsbyで実装しました。妊娠中の方、育児中の方におすすめしたいサイトです。私も実際つかってみて、「これ、子どもが産まれた時にあったらもっと便利だったな〜!」って毎回思っています。

award.mamari.jp

これまでの技術選定

ママリ口コミ大賞は今回で3回目なのですが、毎回使用する技術が変わっています。その時のリソース事情や要件などに合わせていた結果そうなったわけですが、ママリ口コミ大賞を3回とも実装してみた感想は「リソース足りなくても出来るところまででいいから最初からちゃんとやればよかったな」です。考えが甘かった。

  • 第1回:ejs + webpack
  • 第2回:自作のジェネレーター + pug + Spreadsheet (DB) + webpack
  • 第3回:Gatsby + MySQL

といった歴史があり、自作ジェネレーターの実装やSpreadsheetをDBとして運用するのがめちゃくちゃしんどかった辛さから今回はGatsbyでつくり直し + 商品や口コミのデータをちゃんとRDBに格納、GraphQL経由でデータを取得できるようになりました。開発がとても快適になったのと、RDBの偉大さを再認識することができました。ただ、Gatsbyは使った方が良いケース、悪いケースがはっきりしているのでその辺のPros/Consを書けたら、と思っています。

ちなみに: 第2回をつくったときの登壇資料

良かったところ

開発環境

静的ページしかない時なんかはwebpackをはじめとしたビルドできる環境をつくってもあんまり恩恵なかったりするんですが、自分で構築しなくてもサクッとReactが使えてビルドもやってくれる環境があるよっていうのは体験として良かったです。create-react-appという手もありますが、ejectした後の整理が大変すぎるので仕事では使っていません。

GraphQL

GraphQLを使うとなるとGraphQLサーバ立てて、そのサーバーにリクエストを投げて、だと思ってるんですがGatsbyの場合は内部でやってくれるのでqueryを書けばいいだけです。まあ静的サイトつくるのにGraphQLサーバ立てなきゃいけないってなってたら中々使わないですよね・・・。

f:id:dachi023:20191028153127p:plain www.gatsbyjs.org より引用

プラグイン

Gatsbyにはプラグインの機構があります。公式ページのプラグイン一覧からつなぎこみたいデータソース用のプラグインを探したりするのですが、今回繋ぎこみたかったデータソースに関するプラグインは全部ありました。この辺の開発は結構盛んなのかな?と思いました。

接続情報を設定するだけでGraphQL経由でデータを取得することができるようになりました、とても便利です。あとはgatsby-plugin-typescriptを入れてTypeScriptで書けるようにしたりなどでプラグインを導入しました。

デプロイ

$ gatsby build して成果物をS3の静的ウェブサイトホスティング用のバケットなどのストレージサービスに置けばデプロイ完了です。AWSならCodeBuildを使えば自動化も簡単です。

buildspec.ymlの例

version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 10
  pre_build:
    commands:
      - npm install
  build:
    commands:
      - npm run build
      - aws s3 sync ./public s3://{YOUR_BUCKET_NAME} --delete --acl "public-read"

パフォーマンス

静的サイトなのでバックエンドのパフォーマンスチューニングは基本不要です(とはいえ重いQuery書くとビルドは遅くなるのである程度は気をつけていますが)。Reactの実装だけ気をつけていればそうそう遅くはならないと思います。

注意すべきところ

使いどころは限られる

データ更新が頻繁に行われる、リアルタイムにデータを取得したい、などの要件がある場合は使わないほうがいいです。その条件でReact + SSRを実現したいならNext.jsかなーと。Gatsbyの場合、データ更新=再デプロイ(再ビルド)になります。ReactDOM.hydrate() してクライアント側で動的にごにょごにょするとかも出来ますが、もうそれGatsby使わなくてよくない?感がすごいので・・・。データの更新が頻繁でないコーポレートサイトやブログなどとの相性はいいと思います。

Gatsbyのお作法

Gatsby Node API(ビルド時に動作するスクリプト)を理解するために結構時間をかけました。動的なページの生成、GraphQLスキーマ周りのカスタマイズなど、中身が盛りだくさんかつGatsby独自の仕組みも結構あるので、調べて→動かして→実行結果を確認して、を繰り返しました。慣れれば楽ですが慣れるまでが大変なヤツです。今回は複数のデータソースから取得したデータのマージやページ生成を行うための事前データの取得など、色んなロジックが絡んだためその分複雑になってしまったかな、という印象でした。コンテンツがシンプルなページをつくるのであればそもそも深くまで知らずともサクッと構築できると思います。

www.gatsbyjs.org

規模が大きくなるとまあまあ遅い

ビルド時間の大半がGraphQLスキーマの構築とページの生成で持っていかれるのですが、外部データを取得したりページ数が増えてきたりして、現状は2分くらいかかっています。JSのビルドにしては遅いよね〜ってくらいなのでデプロイ全体で見ればまあそんなに遅い訳ではないかも?とは思いますが、長い目で見るといくらビルド処理全任せしているとはいえ、コード書く側もちゃんと気を遣わないとね〜といった感じでした。

その他やったこと

imgixの導入

S3 + CloudFrontの構成に加えてimgixという画像配信に特化したCDNを利用しています。WebPへの自動変換や画像のリサイズなどをQuery Stringで指定できるので、画像周りのパフォーマンス改善が簡単にできました。imgixに関しては@shnagaiさんの下記の記事が参考になると思います。

tech.connehito.com

おまけ

Gatsbyの仕様を噛み砕いたり、実装する際に詰まった部分など残したりするために使っていたメモをScrapboxで公開していますので読んでみてください。本記事の社内レビューで「おまけの方が技術的には本編感ある」と言われたので多分こっちのほうがより具体的だと思います。

scrapbox.io

PR

コネヒトではエンジニアを募集しています!家族向けサービスをつくりたいエンジニアの皆さん、お待ちしています。 www.wantedly.com

データ分析コンペで役に立つ特徴量管理方法と学習・推論パイプライン【コネヒトマルシェLT書き起こし】

こんにちは!MLエンジニアの野澤(@takapy0210)です!

気づけば2019年の営業日も残り20日強ですね。年始に立てた個人的な目標が1/5しか達成できていないことに先日気付いたので、残りの期間で1つくらいは達成できると良いですね、という他人行儀な振る舞いをしたくなっている今日この頃です。

さて今回は、11月5日に開催した(コネヒトマルシェ)でLTした内容の全文書き起こしです。参考資料とあわせてご紹介できればと思います。
全文書き起こしは初の試みなので「ふ〜ん。なるほど〜」ぐらいのお気持ちで見ていただければと思います。

発表資料はこちらです。


f:id:connehito:20191113190809p:plain:w500
f:id:connehito:20191113190823p:plain:w500
f:id:connehito:20191113190902p:plain:w500

Kaggleとは

Kaggleと書いて「カグル」と読みます。日本でも最近は定着してきましたが、Kaggleに参加している方を「カグラー(Kaggler)」とも呼びます。 「The Home of Data Science & Machine Learning」(データサイエンスと機械学習の家)と題されている通り、世界中の機械学習・データサイエンスに携わっている約40万人の方が集まるコミュニティです。最大の目玉とも言えるのは「Competetion(コンペ)」です。
https://www.kaggle.com/

SIGNATEとは

日本版Kaggleというのが一番わかりやすく、特徴としては、開催されるコンペティションのデータは日本の企業から提供されています。コンペティションで高順位をとると、後日表彰式および報告会という形で呼ばれることがあり、入賞すると、賞金が出ます。
https://signate.jp/

f:id:connehito:20191113191145p:plain:w500

(会場の9割強の人が挙手)

参加したことある方に聞いてみたいのですが、特徴量の管理ってどうされてますか?

f:id:connehito:20191113191208p:plain:w500

最初に、僕の実体験を添えてありがちなパターンを2つほどご紹介できればと思います。

例えば、[A, B, C, D]という特徴量があった時に、これらから[E, F, G, H, ...]という形で特徴量エンジニアリングする、というシチュエーションはよくあると思います。

f:id:connehito:20191114102914p:plain:w500

で、一通り特徴量を生成し終えた後に、実験したい特徴量を指定して学習データを作り、学習させます。

f:id:connehito:20191114102942p:plain:w500

一通り学習を終えたところで、ふとこんな事を思うタイミングがありました。

f:id:connehito:20191114103004p:plain:w500

どのような計算で生成した特徴量か探してみると、これが結構大変だったりします。

f:id:connehito:20191114103051p:plain:w500

特徴量生成場所が見つかっても、他の特徴量から段階的に生成されていたりする場合、この根源を探すのも大変です。(もちろん、特徴量の名前を一目で分かることにしておくことは前提としてとても大切だと思います。)

f:id:connehito:20191114103117p:plain:w500

続いて、2つ目のパターンをご紹介します。

f:id:connehito:20191114103206p:plain:w500

これは結構ありがちだと思います(笑)

f:id:connehito:20191114103231p:plain:w500

で、意気揚々とDuplicateしてnotebookの中身を見てみるとこんな感じになっているんですね。

f:id:connehito:20191114103247p:plain:w500

。。。

f:id:connehito:20191114103342p:plain:w500

お気付きの方もいると思うのですが、特徴量生成処理など、同じ計算を再度行う必要がでてきます。これは本当に無駄だと思っていて、どうにかしないとな〜と思っていました。

f:id:connehito:20191114103717p:plain:w500

また、Duplicateを繰り返していくと、気づいたらnotebookファイルだらけになっていた、なんてこともあるかと思います。

f:id:connehito:20191114103811p:plain:w500

最初は「めっちゃ良いモデルが作れた!」と歓喜していましたが、煩雑なnotebook、特徴量管理により、コンペのモチベーションも低下してしまう、なんてことにもなりかねません。

f:id:connehito:20191114104304p:plain:w500

今回は、上記で述べたような実体験から感じていた課題感を、玄人の事例を参考に少しづつ解消できてきたので、みなさんにも少しおすそ分けできたらと思っています。
題して
「データ分析コンペにおいて特徴量管理に疲弊している全人類に伝えたい想い〜学習・推論パイプラインを添えて〜」
という壮大なタイトル(笑)でお話できればと思っています。

f:id:connehito:20191114104414p:plain:w500

こちらがアジェンダです。

f:id:connehito:20191114104442p:plain:w500

いろいろ書いていますが、「玄人の知恵をお借りして、特徴量管理と学習・推論パイプライン構築に取り組んだ結果、めっちゃよかったよ」という話をします。 あくまで主観になりますので、「こんな方法で取り組んだらよかった!」などありましたら是非教えてください。

f:id:connehito:20191114104459p:plain:w500

まずは簡単に自己紹介させてください。

野澤哲照と言いまして、コネヒト株式会社で機械学習エンジニアとして働いています。
会社などでは「たかぱい」と呼ばれています。
Kaggleしたり、野球したり、ラーメン食べたりするのが好きです。

f:id:connehito:20191114104712p:plain:w500

次に特徴量管理方法についてお話します。

これから発表する特徴量管理については、下記記事を参考にさせていただきました。
参考記事:Kaggleで使えるFeather形式を利用した特徴量管理法 - 天色グラフィティ

f:id:connehito:20191114104737p:plain:w500

まずは「特徴量を列ごとに管理する」「メモファイルを作成する」という部分のイメージを共有できればと思います。

f:id:connehito:20191114104811p:plain:w500

「特徴量を列ごとに管理する」とは、下記のように1つの特徴量をtrainデータ, testデータそれぞれ1ファイルずつで管理することをイメージしてください。

f:id:connehito:20191114104922p:plain:w500

「メモファイルを作成する」とは、上記の特徴量を生成する際に自動的に「この特徴量はこうやって生成したもの」というメモファイルを生成することです。

f:id:connehito:20191114105030p:plain:w500

これだけ見ると結構大変そうに感じる方もいると思いますが、1つのスクリプトファイルを実行するだけで実現できます。

f:id:connehito:20191114105053p:plain:w500
f:id:connehito:20191114105112p:plain:w500

以下で具体的な方法についてお伝えできればと思います。

例えばhoge.pyという特徴量生成用のスクリプトを下記のように用意しておきます。
これを実行すると、「各特徴量」と「特徴量メモファイル」が生成されます。

f:id:connehito:20191114105222p:plain:w500
f:id:connehito:20191114105242p:plain:w500
f:id:connehito:20191114105300p:plain:w500

特徴量のメモファイルを作成する箇所に関しては、難しいことをやっている訳ではなく、生成した特徴量の記述がファイルになければ追記していく、ということをやっています。

f:id:connehito:20191114105505p:plain:w500

この特徴量メモはCSV形式で保存しておくとGithubから参照しやすかったりします。
ExcelやNumbersといったアプリケーションからでも綺麗に見えるので、今回はCSVファイルを採用しました。

f:id:connehito:20191114105555p:plain:w500

新しい特徴量を生成したい場合は、hoge.pyにその特徴量生成処理を新しく記述します。

f:id:connehito:20191114105642p:plain:w500

hoge.pyを実行すると新しい特徴量が生成されますが、この時すでに生成されている特徴量の計算はskipしてくれるので、余計な計算時間がかかることはありません。(もちろん、再計算することも可能です)

f:id:connehito:20191114111404p:plain:w500

特徴量をdataframeに読み込む場合は、読み込みたい特徴量名のリストを生成しておき、下記のように記述すれば指定した特徴量データのみを読み込むことが可能です。

f:id:connehito:20191114111439p:plain:w500

この特徴量管理方法を使って何が嬉しかったかと言うと

f:id:connehito:20191114111510p:plain:w500

特徴量管理をすることで下記のようなメリットを享受することができ、「時間的なコスト」を大幅に削減できたのが個人的にはとても嬉しかったです。
データ分析コンペでは特徴量生成だけではなく、学習、推論にも一定の時間がかかります。
そのような中で、特徴量を管理することで余計な計算時間が減るだけでなく、学習→推論のPDCAも回しやすくなったと感じています。

f:id:connehito:20191114111536p:plain:w500

次に、学習・推論パイプラインについてお伝えします。

こちらに関しては、昨今話題の下記書籍を参考にさせていただきました。
参考文献:Kaggleで勝つデータ分析の技術:書籍案内|技術評論社

f:id:connehito:20191114111610p:plain:w500

書籍で紹介されているパイプラインを土台に、下記run_nameをprefixとすることで、一貫性のあるファイルやモデル管理を、意識しなくてもできるように工夫しました。

f:id:connehito:20191114111758p:plain:w500
f:id:connehito:20191114111824p:plain:w500

生成されるファイルは下記のようなものになります。モデルや推論結果のファイルは皆さんの想像通りのものなので、それ以外のファイルについて少しご紹介します。

f:id:connehito:20191114112028p:plain:w500

features.txtは今回の学習に使用した特徴量が記載されたファイルです。

f:id:connehito:20191114112059p:plain:w500

また、param.txtは今回の学習に使用したハイパーパラメータが記載されたファイルです。

f:id:connehito:20191114112125p:plain:w500

shap.pngはshapで計算された可視化イメージを保存したものです。これを元に次の学習の勘所を見つけていきます。

f:id:connehito:20191114112306p:plain:w500

logファイルについては、処理過程を保存したもの(general.log)と、モデルのスコアだけを保存したもの(result.log)の2種類あります。

f:id:connehito:20191114112346p:plain:w500

この学習・推論パイプラインを構築して何が嬉しかったかというと

f:id:connehito:20191114112410p:plain:w500

「この特徴量」と「このパラメータ」を使って学習させたモデルに関して、「各タスクに要した時間」と「各foldと最終的なスコア」を意識しなくても管理できるようになったことです。
これにより、モデルの再現性はもちろん、どの特徴量を使うとスコアが上がった or 下がったということも自然と管理できるようになります。
また、shapの計算結果などを出力しておくことで、次の学習時の勘所も掴むことができます。

f:id:connehito:20191114112431p:plain:w500

最後にまとめです。

特徴量管理とパイプラインを構築することで、様々な「いいぞ!」を感じることができました。一定のイニシャルコストはかかりますが、一度構築してしまえば流用できるので、興味のある方は試してみてください!

f:id:connehito:20191114112521p:plain:w500

また、「他にこんな良い方法もあるよ!」といった知見・意見あれば、是非教えていただけると嬉しいです!

ご清聴ありがとうございました!

f:id:connehito:20191114112552p:plain:w500

発表資料全体をご覧になりたい方はこちらをご覧ください。

以上、当日の書き起こしでした。

今後、コネヒトのMLチームとしては推薦システムに取り組んでいく予定です。
取り組みから得た知見など、積極的に発信していきたいと思っていますので、楽しみにしていてください!


よろしければ、今までのキャリア、コネヒトでの業務などをまとめておりますのでこちらもご覧いただけたら嬉しいです。 www.wantedly.com

CakePHPの国際カンファレンス「CakeFest 2019」に協賛&参加しました!(資料まとめ)

こんにちは!サーバーサイドエンジニアの @fortkleです!
今回は、先週末に開催されたCakePHPの国際カンファレンスである「CakeFest 2019」に参加してきたのでレポートしたいと思います。

CakeFest 2019

CakeFestはPHPのフレームワークであるCakePHPの国際イベントで、セミナー2日、カンファレンス2日の計4日間に渡って開催されるイベントです。 開催地は事前に投票によって決められており、今回は初めての日本開催となりました。 私は後半のカンファレンスから参加しました。

cakefest.org

会の雰囲気

f:id:fortkle:20191110162031j:plain
後半2日間のカンファレンス会場はSmartNewsさんのオフィス

公式発表はないのであくまで推測になりますが、全体でいうと100名弱ほど、そのうち半分ほどが海外からの参加者という風に非常に国際色豊かなイベントでした。
このような形式のカンファレンスに参加したのは初めてだったのですが、堅苦しい感じとは真逆でアットホームな雰囲気の温かいカンファレンスでした。

f:id:fortkle:20191109172102j:plainf:id:fortkle:20191109171934j:plain
会場で提供されたドーナツと海外を感じるバナナの箱置き!

今回、微力ながら協賛もさせていただきました。
コネヒトのプロダクトはCakePHPに支えられているものばかりなので、少しでもCakePHPコミュニティの発展を支援できたのであれば幸いです!

当日のセッション

カンファレンス1日目の夜に行われたLTを除くセッションについて、すでに公開されている資料をまとめてみたので参考にしてみてください! ※ 敬称略

特に、José RodríguezさんによるCakePHPのまだあまり知られて機能の発表金澤さんによる滑らかなCakePHP3への移行についての発表などは知らないことも多くまさに"知見"という印象だったのでまた見返したいと思います。もちろん、弊社CTOの伊藤によるCakePHPではじめるOSSの発表もぜひご覧ください!(宣伝)

f:id:fortkle:20191110163556j:plain
弊社CTO伊藤も発表しました(タイトル: Let's start your first OSS with CakePHP )

Day1

※ 一部の資料はCakePHPのSlackチャンネルでのみ共有されていたため当該Slackチャンネルの投稿のリンクを記載します。*1

タイトル/スピーカー 資料公開先
A safer and more helpful CakePHP in 4.0 / Mark Story https://www.slideshare.net/markstory/safer-more-helpful-cakephp
The CakePHP features I wish you were using more / José Rodríguez https://cakesf.slack.com/archives/C172CS4TE/p1573272016104200
Consider a smooth upgrade to CakePHP 3 / Yuki Kanazawa https://speakerdeck.com/ykanazawa/consider-a-smooth-upgrade-to-cakephp-3
12 Factor CakePHP Applications - The Remix / Jose Gonzalez https://speakerdeck.com/josegonzalez/12-factor-php-applications-the-remix-1
Test-driven development to avoid painful of test code / KAZUKI HIGASHIGUCHI https://speakerdeck.com/hgsgtk/test-driven-development-to-avoid-test-painful
CakePHP & Spatial Big Data - Visualising Spatial Data & Metrics over 70 Billion+ rows / Daniel Voyce https://speakerdeck.com/voycey/cakephp-and-spatial-big-data-visualizing-70-billion-rows-of-data
Working with Database Replication / Tadahisa MOTOOKA https://speakerdeck.com/motooka/working-with-database-replications-in-cakephp

Day2

タイトル/スピーカー 資料公開先
Beyond unit testing: How to make your applications more reliable / José Rodríguez https://cakesf.slack.com/archives/C172CS4TE/p1573354079126300
GraphQL, CakePHP & JWT: A Fast & Secure Redemption from REST Hell / Prosper Otemuyiwa 諸事情により発表なし
Baking with Vue.js / David Yell https://docs.google.com/presentation/d/1bgilFVNRtvhp9KyCLVWMMKtlS-Q39rx07AXCOpf67G4/edit#slide=id.p
CakePHP with Habitat - Build once, deploy everywhere / Graham Weldon 諸事情により発表なし
Building interactivity with websockets / Wim Godden https://www.slideshare.net/wimg/building-interactivity-with-websockets-191944043
Life after CakePHP / Andrej Griniuk https://docs.google.com/presentation/d/1Hlrs_T-rZ_7LNy6iQh-S_Ff8Ca6O8HlThYfjg6D8GO4/edit
Let's start your first OSS with CakePHP / Sho Ito https://speakerdeck.com/itosho525/lets-start-your-first-oss-with-cakephp

最後に

今回のCakeFestは、Github上でしかやりとりをしたことがなかったCakePHPのコアコミッターの皆さんと直接コミュニケーションが取れたことがとても貴重な機会でした。
運営の皆様、会場提供してくださったDMM.com様・スマートニュース様、そして当日参加された皆様、本当にありがとうございました。そして、お疲れ様でした!

*1:CakePHPのSlackチャンネルは誰でも自由に入れますし、日本語話者向けのチャンネル#japaneseもあります! 参加方法はこちら https://twitter.com/fortkle/status/1193390451883040768

Connehito Marché vol.6 〜機械学習・データ分析市〜 を開催しました!

f:id:taxa_program:20191108125429p:plain

こんにちは。MLエンジニアの野澤(@takapy0210)です!

11月に入っていよいよ寒くなってきましたね。
寒いといえば、毎朝洗濯物を干すのが辛くなる季節でもあります。
このような季節も影響し、我が家ではドラム式洗濯機のデプロイが検討されています。もしオススメのドラム式洗濯機があれば教えてください!!

さて今回は、先日無事に開催することができました、「Connehito Marché vol.6 〜機械学習・データ分析市〜」の様子や、LTの内容などを簡単にご紹介できればと 思います!
(嬉しいことにLT枠もオーディエンス枠も満席となり、大盛況で終えることができました!)

connehito.connpass.com

今回のテーマ

今回は第6回目ということで「機械学習・データ分析」をテーマとして開催しました。

抽象的なテーマだったため、LT内容含めてどのような方々が参加してくださるのか、非常に楽しみでした!

ちなみにコネヒトマルシェでは毎回テーマを変えており、過去には下記のようなテーマで開催しています。

今回は、下記3つのお願いお伝えした上で、スタートさせていただきました!

f:id:taxa_program:20191108130206p:plain

LT内容

データ分析コンペにおいて特徴量管理に疲弊している全人類に伝えたい想い

by @takapy0210

概要

  • データ分析コンペをnotebookだけで挑むといろんなツラミがある
  • 特徴量管理とパイプライン組むとちょっと良くなった
    (初っ端から時間オーバーしてすみませんでした。。。)

SageMakerで構築する価格推定システム

by @0xb5951さん

www.slideshare.net

概要

  • 機械学習でなんかやってみてよと言われてやった
  • 依頼がいくらで成約するかを推定
  • SageMakerを用いて手早く実装した
  • 今日リリース予定だったが、リリースできず

社内での円滑なデータ分析のために

by @yu__ya4さん

概要

  • データ分析業務のポジティブな社内政治のお話
  • 直接関係のないPJなどにも顔をだしたり、ランチに行ったりコミュニケーション取るのがめっちゃ大事(何やってるかわからない人にならないためにも)
  • 結果として社内外でのプレゼンスが向上しいろんなことが円滑に進んだ

初めて機械学習PJをやってみて得た知見

by @yaginuuunさん

概要

  • 自社サービスにレコメンドエンジンを入れた
  • 簡単でも良いので、まずは結果を見える形にする
  • Kaggleは役に立つ

SIGNATEの練習問題コンペで 57位までスコアを上げた話

by @shnagaiさん

概要

  • 機械学習勉強しはじめて初めて自分でモデルを作った
  • あとで分析結果などを見返したい時のために、メモを取るのが大切
  • ドメイン知識をフル活用して、スコアを向上させた(57位/1748)

BigQueryいいよね!って話をしようと思ったらBigQueryより早いAzure Synapseが出た

by @YASU11552288さん

概要

  • BigQuery良いよね、という話をしようと思っていたら、75倍速いAzure Synapseが出たので、急遽内容を変更
  • Azure Synapseはインスタンス単位の課金でインデックスのチューニングが必要
  • 導入を考えるとすこし運用コストが高そう

日本語学習済みモデルについて

by @TwYamatさん

docs.google.com

概要

  • 今はBERT が微笑む時代
  • 学習済み言語モデルのGood / Badポイント
  • 日本語学習済みモデルを使用すれば、様々なNLPタスクに取り組める一方で、日本語の学習済みモデルが少ないので、適応するには制限がありそう

Meta Kaggleを覗いてみた

by @IshizakiYukoさん

概要

  • Kaggleって本当に流行っているか、Meta Kaggleを覗いて調べてみた
  • 新規ユーザーは右肩上がりの一方、コンペにSubmitしているユーザーで分析してみると、鈍化している
  • 最近は画像コンペが増えている
  • kaggleの沼にはまろう

NGBoost論文読んでみた

by @ml_taroさん

概要

  • kagglerにも人気かつ、つよつよAndrewNg先生が共著者だったので、読んでみた
  • NGBoostは出力の不確実性を確率値として出力する
  • 自然勾配(勾配が大きく変化する場所は慎重に&勾配があまり変化しない場所は大胆に)を用いることで、最適化を効率的にしている

NLP Beginner BERTを試す

by @ktr_wtbさん

概要

  • BERTでkaggleの過去コンペを解いてみた
  • BERTなら特になにもしなくてもそこそこ良いスコアが出るかと思いきや、そんなことはなかった
  • Fine Tuningのやり方を工夫することが大事

SQLベースのMLパイプライン

by @hatuninaさん

概要

  • データセットの作成と特徴量エンジニアリングをSQLで
  • SQLをベースにすることで、使い回しやすい、共有しやすいなどのメリットがある
  • 一方で、DBが混んでいるとデータ作成がボトルネックになりがち

競艇の順位予想をしてみた

by @wakame1367さん

docs.google.com

概要

  • 競艇のデータセットは公開されているが、表データっぽいtxtデータで、データクレンジングに8割の労力を割いた
  • LightGBMでランク学習させた
  • ドメイン知識が少なく、特徴量エンジニアリングがあまりできなかった。
  • 実際に予測してみたところ、勝率は。。。

懇親会

今回はお寿司とお酒を手に乾杯しました。

参加者の方々で質問しあったり、LTの感想を伝えたりしていて、終始楽しそうな雰囲気で幕を閉じることができました!
個人的には、Twitter上で知っている人と顔を合わせてお話できたのがとても嬉しかったです!

f:id:taxa_program:20191108115122j:plainf:id:taxa_program:20191108114935p:plain

最後に

というわけで、当日の様子をお届けしました!

拙い司会・進行でしたが、最後までお付き合い頂きありがとうございました!
私自身もとても楽しく参加させていただきました!

次回開催時期・テーマなどはまだ決まっておりませんが、今回のマルシェの振り返りを社内で実施したときに「今回盛況だったから、次回も機械学習でいこうよ!(いこう)」という話がチラっとあがっていたので、もしかしたらもしかするかもしれません(笑)

参加していただいた皆さま、ありがとうございました!
また次回のマルシェでお会いできたら嬉しいです!

iOSでWebThread関連のクラッシュが急増した件

こんにちは!エンジニアの柳村です。

9月末頃からママリのiOSアプリでWebThread関連のクラッシュが増加し、ときどき爆増するといった事が起こりました。

f:id:yanamura:20191025172637p:plain

クラッシュレポートを調べてみると以下の3つクラッシュが多数発生していました。

Crashed: WebThread
0  JavaScriptCore                 0x1a583e14c WTFCrashWithInfo(int, char const*, char const*, int) + 20
1  JavaScriptCore                 0x1a5d21b3c JSC::Interpreter::prepareForRepeatCall(JSC::FunctionExecutable*, JSC::ExecState*, JSC::ProtoCallFrame*, JSC::JSFunction*, int, JSC::JSScope*, JSC::ArgList const&) + 742
2  JavaScriptCore                 0x1a5f808c0 JSC::boundFunctionConstruct(JSC::ExecState*) + 588
Crashed: WebThread
0  JavaScriptCore                 0x19407aad4 <redacted> + 20
1  JavaScriptCore                 0x1948013dc <redacted> + 746
2  JavaScriptCore                 0x194a80b50 <redacted> + 608
Crashed: WebThread
0  libGPUSupportMercury.dylib     0x1d8145fe4 gpus_ReturnNotPermittedKillClient
1  AGXGLDriver                    0x1dc7f2ed8 (シンボルが不足しています)
2  libGPUSupportMercury.dylib     0x1d8146fac gpusSubmitDataBuffers
3  AGXGLDriver                    0x1dc7f4404 (シンボルが不足しています)
4  IOAccelerator                  0x1be209884 IOAccelContextFinishResourceSysMem + 64

見ての通り、どれもなるほどわからんというエラーですね・・・

しかも、アプリやiOSのアップデートとは関係なく急増するという不思議な状況でした。

原因の分析

ママリのiOSアプリではいくつかWebViewを使っている箇所があり、どこのWebViewが原因かをまず洗い出す必要がありました。

ママリのiOSアプリではFirebase Crashlyticsを利用しており、Firebase Crashlyticsだとクラッシュレポートとログが一緒に見れるのでどの画面でクラッシュしたか判断するのに役に立ちました。

調べた結果は起動直後にクラッシュしているユーザーがいたのでトップページのどこかであるということに絞れました。

しかし、トップページにWebViewは使った心当たりはなかったので、XcodeのDebug View Hierarchy を使ってどこでWebViewが使われているか調査しました。

その結果Google Mobile AdsのDFPBannerView内でUIWebViewが使われていることがわかりました。

f:id:yanamura:20191025175922p:plain

対策

まずはSDKが古かったので最新(7.50.0)にしてみましたが効果はありませんでした。。

そこでGoogle Mobile Adsのフォーラムを見たところUIWebViewをWKWebViewに変えることができるとの情報が得られたのでやってみました。

以下のようにinfo.plistにgad_preferred_webview というKeyとwkwebview というValueを設定するとWKWebViewに変えることができました。

<key>gad_preferred_webview</key>
<string>wkwebview</string>

これをリリースしたところ、多数発生していたクラッシュがWKWebViewにしたバージョンでは発生しなくなりました!

まとめ

急にWebThread関連のエラーが増えて、Google Mobile Adsを使っている場合はinfo.plistを変更してWKWebViewに変えるとよいです。

UIWebViewはiOS13ではdeprecatedになっていますし、iOS13でUIWebViewでwindow.confirm を使うと挙動がおかしかったりするということも弊社で確認しているので、UIWebViewは捨て去ったほうがよいかと思います。