Goalist Developers Blog

Does your neural net need more data?

Hi! This is Chinnapa, from Goalist. Today I decided to write an English post, because we clearly have fewer of those than we need :).

When improving a neural net (or any machine learning algorithm) one question that inevitably comes up, is

Will the algorithm do better if I give it more data?

The thing is, very often gathering more data involves time, effort, and money. So it's probably a good idea to think carefully about it first. Accurately diagnosing whether you need more data, and what kind of data you should go about collecting, can save a lot of headache.

Under-fitted models

One thing to consider is whether your algorithm is under-fitting your data. Under-fitting is when the algorithm is :
- (a) not doing as well as you'd like (low accuracy or low f-score)
- (b) It is performing badly on both the training set, as well as the validation set, and the gap between these scores is relatively small.

In this case, gathering more of the same data is unlikely to improve your results significantly, if at all. However, increasing the input features may help. So, for example, if you're trying to predict the height of a person based on their age - you may want to collect other data for the data labels - such as weight. As opposed to getting more data of age -> height.

If, however, your data does already allow for a reasonable prediction, then the problem probably resides in the model, and not in the quantity of data. You can test this by considering if a human (equipped with the expertise) would be able to make predictions based on your input data.

For example, if your model is attempting to label a picture, and you have an under-fitting issue, increasing the size of the picture (more input features) is unlikely to help. The model should be able to label the picture with the data it already has. As discussed above, increasing the number of pictures is also unlikely to improve an underfitting issue, and your efforts would likely be best spend in trying different neural network models (more filters in a conv net, more layers etc.)

Over-fitted models

The opposite case is when your model is over-fitting your data. Overfitting is when your model does well on your training set, but does significantly worse on the validation set.

Here too, before deciding to gather more data, it would be wise to perform an error analysis first. Actually looking at each mistake that a model makes can help significantly. There may be some type of skew or bias in your training set Maybe you didn't shuffle the training and validation data? Maybe there are certain noise / signals that your model is picking up that are non-representative or don't make sense?

https://github.com/marcotcr/lime

Is one tool you can use to help you analyze why your model is making the decisions it is.

You also have two amazing tools that can emulate the effects of gathering more data:

Regularization

Regularization is a method that increases the loss of your model based on factors that are not related to accuracy. One example is using regularization to cause the magnitude of the weight matrices to contribute to loss. It prevents your model from trying to account for the peculiarities of anomalies that may (do) exist in your data.

Essentially it stops this:

f:id:c-pattamada:20180308115959p:plain

Dropout

Dropout layers are a simple an extremely effective tool that randomly ignore features in a layer of the neural net (during training only). This results in the model being unable to fixate on single features, and force it to use all possible information in the data to make predictions. Note that you'll have to increase the number of epochs the model trains for when you use dropout.

Here's what a simple net might look like in python/keras using the above features.

input_features = Input(shape=(num_features,))
processing = Dense(1024, activation='relu', kernel_regularizer=l2(0.01))(input_features)
processing = Dropout(0.5)(processing)
processing = Dense(1024, activation='relu', kernel_regularizer=l2(0.01))(processing)
processing = Dropout(0.5)(processing)
output = Dense(category_count, activation='softmax')(processing)
model = Model(inputs=input_features, outputs=output)

The kernal_regularizer parameter takes a regularization function that works to keep the weights on the layer from getting too large. l2() is one of the default regularizers that comes with keras, and it's parameter, 0.01 is the lambda multiplier (increasing it will increase regularization). Dropout(0.5) is a dropout layer that has a 50% chance of ignoring a specific feature. Dropout layers are only used during training, so they won't change hamper your model in production.

In summary

When evaluating your model and deciding how best to improve it, diagnosing what problem you're trying to solve under-fitting or over-fitting is the first step. This will guide you on whether you need to gather more of the same type of data, new features, whether data isn't relevant to your problem at all.

Next, in the case of over-fitting, experiment with regularization and dropout.

Finally, once you are convinced that your model is actually overfitting, and neither regularization or dropout has improved it sufficiently, then it is worth setting down the arduous road of gathering more data.

Best of luck!

デザインスプリント ~ DAY3 ~

こんちは。渡部です。
ついにデザインスプリント最終日、DAY3です。
今回はユーザーテストとスプリント3日間のまとめです。
 
振り返りはDAY1DAY2をご覧ください。

developers.goalist.co.jp

developers.goalist.co.jp

f:id:watabe1028:20180302170604j:plain

目次

 

インタビュー内容を確認

まずは最初に戻り、HRogチャートの中長期目標を確認します。

f:id:watabe1028:20180302145749j:plain

その後にペルソナシナリオの確認です。

f:id:watabe1028:20180302145959j:plain

認識を全メンバーで合わせたらいよいよユーザーテストです。

 
 

ユーザーテスト準備

初日と同様にユーザーテストを行います。
テストは別室で緊張しないように配慮します。

 

ユーザーテストの重要ポイント1~ テスト前~

「あなたを試しているのではなく、サービスを試している」
「何か上手くいかないところがあっても、あなたのせいではない」
「作ったのは私じゃないから」
 
と伝え、ネガティヴな感想も言いやすくしておきます。
ユーザーは目の前の人に気を使ったり
上手く操作できない自分を責めたりしてしまいます。
そういった不安をまず解消してあげます。

 

ユーザーテストの重要ポイント2 ~ テスト中、後 ~

5W1Hで聞く
Yes / No などの選択肢の質問はしない
なぜ?を聞く
誘導尋問しない
 
このようにユーザーに発言を促し
なるべく返答してもらうのではなく話してもらうようにします。

次にテスト環境です。
テスト用のPCと表情をとるPCで
操作と表情を同時に確認します。

f:id:watabe1028:20180302152327j:plain

隣では会話をしたり、操作を簡単にファシリテートしたりするインタビュアーがいます。
 

ユーザーテストの重要ポイント3 ~ インタビュアーの心がけ ~

いつも笑顔でフレンドリーに
世間話などのトークからさりげなくインタビューに入る
シナリオのみを伝え、細かいアクションは説明しない
 
これはやってみて思ったのですが
雑談しながら操作してもらった方が表情にも出るし
ネガティヴな要素も気軽に発言してくれている気がします。

今回はゴーリスト随一フレンドリーで愛されキャラを
インタビュアーにし、テストしていきます。
f:id:watabe1028:20180302170353p:plain
 
 

ユーザーテスト

別室では全メンバーがユーザーの動向を見守ります。
今回はappear.inで繋いでいます。

f:id:watabe1028:20180302164206p:plain
f:id:watabe1028:20180302164249p:plain

見守っているメンバーは
ユーザーがテストしてる際に気づいたことを
ポストイットに書いていきます。
今回もポジティブならP、ネガティブならNをつけて
壁、ホワイトボードに貼っていきます。
シナリオ毎に気づいた点と、UIについて気づいた点などを
まとめながら進めます。
 
シナリオ毎
f:id:watabe1028:20180302154727j:plain

UIについて
f:id:watabe1028:20180302154845j:plain

そんなこんなで社内外合わせて5人のユーザーにテストをしてもらいました。

 
 

テスト結果取りまとめ

テストが終わったらまたシールを使って投票します。
この指摘良いね!と思ったらどんどん貼っていきます。

f:id:watabe1028:20180302154926j:plain
 

その後、今回のペルソナ、シナリオ、テストからの気づきをもとに
このプロトタイプ はどうだったかの意見を出し合いました。

f:id:watabe1028:20180302164324p:plain

また、この後にユーザーテストの観察結果記入表に
思いのまま書いていきます。

最後にスプリントの個人の気づきを全メンバーに共有して
DAY3は終了です。

 
 

まとめ

これで1回のデザインスプリントが完了です。
ここからもう一度スプリントを回すのか、
ピボットするのか、もう辞めるのか、色々検討します。
 
今回のスプリントでは HRogチャートのフローから始めましたが、
1つのフローやUI、各文言など、ちょっとした改善にも持ってこいです。
 
HRogチャート、お客さんからの要望もたくさん頂いているので
今回の改善案は採用されるかわかりませんが、
是非アップデートの機能候補に加えて欲しいですね。
 
これからデザインスプリントはゴーリストの問題解決のツールとして
標準化していきます。
 
デザインスプリントやってみたい、どんな感じでやるか話を聞いてみたいという方は
こちらからお問い合わせください。

 
 

最後に

みんなでパシャり
みなさん、お疲れ様でした。
f:id:watabe1028:20180302122645j:plain
 

いやー疲れた。

デザインスプリント ~ DAY2 ~

こんちは。渡部です。
今回はデザインスプリントDAY2についてです。
DAY2はプロトタイプとユーザーインタビューの項目作成がメインになります。

DAY1はこちら

developers.goalist.co.jp

f:id:watabe1028:20180228094142p:plain

目次

 
 

プロトタイプって必要?

プロダクトの開発に携わったことがない人は
プロトタイプの必要性がイマイチわからないと思います。
「なんで紙芝居なんて作る必要あるの?」的な。
 
逆にアジャイル開発経験者はプロトタイプがあるとすごく安心します。
それはなぜか?
 
まず一番は手戻りが発生しにくいからです。
設計書からの画面作成では細かい動きや挙動が曖昧です。
するとクライアントから「思ってたんと違う!」となり
再度設計なり開発なりをしないといけません。
こういった流れの繰り返しを個人的に「報われない努力」と考えています。
 
たとえ手戻ったとしてもプロトタイプと本番とでは修正コストが違いすぎます。
 
ゆえに個人的には必ずプロトタイプを作って
クライアントやユーザーの意思からずれていないかを確認する
プロセスが大事だと思っています。
 
つまりプロトタイプは必要です!

 
ただ本来のプロトタイプ の狙いは
プロダクトの世界観、ビジュアル、ストーリーをより詳細に伝えることだと思います。
 
 
f:id:watabe1028:20180223204555p:plain

とはいえ、デザインスプリントは時間が限られてるため
作り込みはできません。
ゆえに「それっぽく見せる」に特化していきます。

 
 
今回は画面をSketchで作り
挙動をInVisionで繋げていきます。

www.sketchapp.com
www.invisionapp.com

 
 

役割分担

また、DAY2ではこのような役割分担があります。

 Maker     画面デザインを作成する人 (2人以上)
 Sticher     プロトタイプを組む人 (1人)
 Writer     よりリアルな言い回しができる人 (1人)
 Interviewer   完成したプロトタイプを用いてインタビューする人 (1人)
 Test scenario  ユーザーテストのためのシナリオを作成する人 (2人)
 
何度も言いますが、デザインスプリントは時間の勝負でもあります。
得意な役割を担い、チームで協力しないと半端なモノができてしまいます。
良いプロダクトを作るために集まったのに、それでは勿体なさすぎます。

 
DAY1のストーリーボードを再確認し、
デザイナーの担当を割り振ります。
あとは手を動かして作ることに集中します。

 
 

ユーザーインタビュー作成

プロトタイプの方針が決まったら
ユーザーインタビューを作成します。
 
まずペルソナを決め、シナリオを作ります。
ここでは常にユーザーと向き合い直接声を聞いている
セールスの意見がとても参考になります。
 
セールスのメンバーを中心にペルソナ、シナリオを作って行きます。

f:id:watabe1028:20180223204509j:plain

 
常にユーザーと向き合ってきたセールスの議論が熱くなります。。。

f:id:watabe1028:20180223210236j:plain
 
より明確に、具体的にしていくと情報量がとんでもないことになります。
ただ字が汚いだけじゃありません。

f:id:watabe1028:20180223210948j:plain
 
ここから限られた時間でディスカッションを重ね、5つのシナリオに絞り込みました。

f:id:watabe1028:20180223211018j:plain
 
ペルソナもイラスト付きだとイメージしやすいですね。
(もうCTOの絵は出て来ませんw)

f:id:watabe1028:20180223211044j:plain

 
 

プロトタイプ 作成

ここからプロトタイプを作成していきます。
ゴーリストのデザイナー3人が分担して作業します。

画面を割り振り各々のSketchで作業します。

f:id:watabe1028:20180301195417p:plain
こんな感じ。。。  
 
 
Sketchで画面を作ったらInVisionに上げます。
余談ですがInVisionに上げる際に「チン!」と音がします。
 
上がってきた画面をInVisionでつなぎこみをします。
ここはデザイナーじゃなくても作業できるのでやってみます。

f:id:watabe1028:20180301195950p:plain

ここでちょっとしたtipsを紹介(ただの備忘録)。
InVisionでヘッダーの固定をします。

まず画面下のタブメニューから「BUILD MODE」にします。

f:id:watabe1028:20180301201956p:plain

 
 
「BUILD MODE」にすると、画面上部に「FIXED HEADER」が現れるので チェックマークを入れます。
f:id:watabe1028:20180301203001p:plain
 
 
f:id:watabe1028:20180301203021p:plain
 
 
 
チェックマークを入れると、ヘッダーを固定したい位置に設定できるようになります。 f:id:watabe1028:20180301202040p:plain

 
 
これを画面のヘッダー部分に合わせて、「BUILD MODE」を終了させるともう固定されてます。
f:id:watabe1028:20180301202101p:plain
 
 
わかるかな。。。
f:id:watabe1028:20180301202121p:plain

これ簡単で良いですね。

画面数や操作数でプロトタイプの工数がめっちゃ変わるので
InVisionで色々やれると助かりますね。
こんな感じでプロトタイプを作っていきます。
 
 

DAY2 まとめ

インタビューのシナリオ作成ではセールスを中心に盛り上がり、
プロトタイプ作成ではデザイナーが八面六臂の活躍で
デザインツールが使えないエンジニアは無力感を感じるかもしれません。
(実際に感じてました。。。)
 
Sketchが扱えないのでInVisionの手伝いをするが
InVisionもさほど使えない。。。
 
でも本番画面と近づけさせるためには
画面上の文言や表示させるテキストなどが必要です。
 
これらの準備をしたり
自分にできる作業を見つけてやる、という当たり前のことを
意識するきっかけにもなりました。
 
新鮮な気持ちにもなるし、身近な気づきもあるし
デザインスプリントは良い勉強になります。

 
 

おまけ

ゴーリストでは、今回デザインスプリントで使っているスペースで
勉強会などをたまーに開催しています。
会場などをお探しの方は是非お声かけください!
(20人くらいはいけます!)
f:id:watabe1028:20180301204143j:plain

 
 
また、一緒に働く仲間も募集しています!

recruit.goalist.co.jp

IaC by Terraform ~DAY1: Preparation~

どうも,新卒エンジニアのナカノです.

今回はTerraformに関する記事です.

Terraformに関する第一回の記事はintroductiveな内容でした.

今回からは細かい部分に立ち入り,いくつかのパートに分けてお話しようと思います.

Day1の内容は,Terraformの実行環境の構築に関してです.

目 次
  • Installation   
    • For Windows
      • 1. Download a specific version of Terraform packages
      • 2. Extract the downloaded Terraform package
    • For Mac
      • 1. Install tfenv using Homebrew
      • 2. Install Terraform using tfenv
  • 最後に

Installation

For Windows

Windowsでのインストールだと,割と地道な感じになります.以下,その手順です.

  

1. Download a specific version of Terraform packages

最新のバージョンを使いたいならば,以下のページからパッケージをダウンロードしましょう. www.terraform.io

或いは,ある特定のバージョンをダウンロードしたいならば,下記の手順に沿ってダウンロードを行ってください:

  1. 上記URLの先のdownload older versions of Terraformという項目をクリックする.
  2. ダウンロードしたいバージョンの項目を選ぶ.
  3. 使用しているPCのOSを確認し,対応するパッケージを選んでダウンロードする.

  

2. Extract the downloaded Terraform package

ダウンロードしたものを適当な場所で解凍し,その後にterraformをパスの通った場所に配置すればよいです.

以下は,その作業方法の例です.

$ mv terraform_0.x.x_windows_amd64.zip path/to/src
$ cd path/to/src
$ unzip terraform_0.x.x_windows_amd64.zip
$ mv terraform path/to/bin

ここまでの作業が出来たならば,ホームディレクトリに移動してTerraoformのコマンドが実行できるかどうかを試してみましょう.

$ cd ~
$ terraform -version

バージョンが表示されれば,実行環境の構築は完了です.  

  

For Mac

Macの場合は,Homebrewを使ってインストールすることが出来ます.例えば,次の様にです:

$ brew install terraform 0.x.x

ただ,tfenvというTerraformのバージョン管理のツールがあるため,Macユーザーはtfenvを使ってTerraformをインストールしてみましょう.

  

1. Install tfenv using Homebrew

$ brew install tfenv

  

2. Install Terraform using tfenv

インストールの際に,Terraformのバージョンを指定する必要があります.

以下,バージョンの指定方法によるTerraformのインストールコマンドです:

1. A specific version
$ tfenv install 0.x.x
2. The latest version
$ tfenv install latest
3. The latest version matching regex
$ tfenv install latest:^0.x.x

なお,ここではtfenvについて詳細には立ち入りません.

詳しく知りたい方がいらっしゃいましたら,下記の参考ページを読んで頂けるとよいかもしれません. qiita.com github.com

最後に

実行環境の構築に関する話は以上となります.

Macユーザーの方には,是非ともtfenvを利用されることを推奨致します.

異なるバージョンをインストールする際には非常に便利ですので.

Day2以降では,Terraformの使い方Tipsなどをご紹介していこうと思います.

では,今回はここまでと致します.

デザインスプリント ~ DAY1 ~

こんちは。渡部です。
今回は社内外で行なっているデザインスプリントについて紹介します。
いつもの記事よりちゃんと書いたので長くなります〜

f:id:watabe1028:20180222160553j:plain

目次

 
 

デザインスプリントとは

米Google Venturesがスタートアップ支援の為に用いているプログラムで、
新規のアイデアをプロトタイプとして具体化し、
ユーザーテストを通じてアイデアの妥当性や効果の検証を行うもの
です。
(間違った認識だったらご指摘ください)

詳しくはこちら

 
今回は時間がないのでDAY5を3日間で行うプログラムを選択しました。
そしてスプリントの対象は弊社サービスの「HRogチャート」です。
改善点が多い、伸びしろしかねぇ!サービスです。
 
 

きっかけ

きっかけは個人的にデザインスプリントに参加できる勉強会などを探していたところ
ワークショップを開催している会社さんがあったので
速攻で問い合わせを投げました。
 
興味あった人がちらほらいたので
そのメンバーでやれれば良いかな、と思っていたら
社員の半分近くが参加することになってましたw

 
そして今回はその会社さんにファシリテーターをして頂いてのスプリントです。
株式会社ISAOのお二人にファシリテートして頂きます。

www.isao.co.jp

性格の良い会社」に選ばれている企業で、
海外でもデザインスプリントに参画している腕利きの方々です。
今回はなんと14人も参加だったので2チームに分けて同時にスプリントを回します。
(本当は5人くらいがベストです)

 

STEP1 Discover 発見

ここでのゴールは
f:id:watabe1028:20180222162224p:plain
です。

 
次にHRogチャートの中長期ゴールを書き出し
このスプリントのゴールも設定します。
またHRogチャートの歴史をCTOから話してもらいました。 f:id:watabe1028:20180222163210j:plain
 
HRogチャートの前バージョンの開発者でありゴーリストCTOに
開発の背景や苦労話をしてもらいます。
ゴーリスト内でも業務上、HRogチャートに触れずにいるメンバーもいます。
この話を聞くことによって
今まで関わってなかったメンバーも自分ごととして意識できるようになります。多分。
 
次にユースケース作成です。
ここから2チームに分かれ、それぞれ進めていきます。
 
こちらのチームはこんな感じ。

f:id:watabe1028:20180222163422j:plain

こちらはこんな感じ

f:id:watabe1028:20180222163441j:plain
視点がそれぞれのチームで違い、
”1つの課題”が別物になりそうです。
 
 
次にユーザーテストを行います。
既存のサービスを操作してもらい
ユーザーの操作、表示を観察します。
 
今回は社内のHRogチャートを操作したことがない社員に操作してもらいました。
このテストは別室で行いユーザーに緊張を与えないように注意します。
 
ディスプレイからユーザーの動向を観察し
それぞれの気づきをポストイットに書き込んでいきます。
 
ポジティブな気づきは右上に「P」を
ネガティヴには「N」をつけて書いていきます。
ここはポストイットの色で分けるのもありです。
(実はポストイットを1色しか用意してなかったとは今更言えない)

f:id:watabe1028:20180222163729j:plain
Nがいっぱいw

 
次にHow might me メソッドを用い
複数の角度から解決の方向性をあげます。
 
「私たちはどうしたらxxxな体験を良い体験にできるだろうか?」
f:id:watabe1028:20180222164424p:plain 
 
HRogチャートで言うとこういった角度があります。
f:id:watabe1028:20180222164518p:plain 
それをマップに当てはめていきます。
 
それをみんなでそれぞれ評価します。
いいね、と共感できる問題にシールを貼っていきます。
これが大事!となる問題には大きいシールを貼ります。
 
これが終わるとヒートマップができます。  
 
 

STEP2 Realization 見える化

ここから個人の作業になります。
テキストメモ、マインドマップ、ラフスケッチなど
自由に検討し
UIスケッチとしてアウトプットします。
f:id:watabe1028:20180222165449j:plain  

 
3枚ほどのストーリーUIを書き出し、
キャッチーなタイトルをつけます
その周りには補足コメントなどをつけ
何を意図しているか伝わるようにします。
f:id:watabe1028:20180222165551j:plain

 
 

STEP3 Decision 決定

全員のアイデアを壁に貼り
ポストイットと同様にシールをつけて投票していきます。
投票の際は相談はやめましょう。
他の人の意見に惑わされず
自分の良いと思ったアイデアにどんどん投票します。
 
またポストイットもそうですが
誰がどのアイデアを出したかを
なるべくわからないようにしましょう。
権限や個人的に付き合いのある人を
無意識に高評価してしまうことがあります。
 
ここで最も良い!と思ったアイデアには
大きいシールを貼ります。
大きいシールは1人2つだけです。
f:id:watabe1028:20180222172130j:plain
f:id:watabe1028:20180222172152j:plain
 
最後にDecider(決定者)が1つのアイデアを決めます。

ここでの注意点は
シールの多いアイデアを選ぶ必要はありません
シールが一つもないアイデアでも
Deciderがこれだ!と思ったアイデアを選びます。
 
Deciderが一つアイデアを選んだら
このアイデアを考えた人に説明をしてもらいます。
ここでチーム全体でアイデアを共有します。
 
 
ここからまたチーム作業です。
選んだアイデアからストーリーボードを作成して
どのようなプロトタイプを作るか決めていきます
ここがあやふやだとプロトタイプを作成をするデザイナーがキレます。
f:id:watabe1028:20180222172327j:plain
 
今回は2チームあるのでお互いのストーリーボードを見せ合い
どちらのアイデアでプロトタイプを作るかを決めます。
今回はこちらのチームのプロトタイプを作成することに決まりました。
f:id:watabe1028:20180222172255j:plain

 

DAY1 まとめ

デザインスプリント、結構疲れます
普段使わないような頭の使い方、
立ったり座ったり、話したり作業したりを
時間を設定して、シビアにアウトプットを出して行くので
なかなかあっという間です。
 
デザインスプリントの良いところは
プロダクトを良い方向に持っていくだけではなく、
普段あまりコミュニケーションを取らないメンバーも
遠慮なくディスカッションが出来るところにある
と思います。
 
DAY2はプロトタイプ作成とインタビュー作成です。
プロトタイプはデザイナーの腕の見せ所です。
インタビューは普段お客様と接しているセールスチームの意見が貴重になります。
それぞれの強みを活かしあって、プロダクトを良くしていく。。。
これ、めっちゃ楽しいです!

 
 

おまけ

やっぱりデザイナーのイラストなどがあると捗るね、と話していたところ
俺もあれくらい書けるよ!と言ったCTOの絵です。
狂気を感じます。。。
f:id:watabe1028:20180222173603j:plain

Selenium WebDriverでスクリーンショットを撮る

こんにちは ゴーリスト開発のモリツグです

Selenium WebDriverで画像キャプチャが必要になった時、Firefoxだとスクロールで見えない部分まで撮影できるのに、Chromeだと見えている部分しか撮影してくれません。
この問題を解決してくれる便利なライブラリaShotのご紹介です。
言語はJavaです。

aShotの使い方

まずは以下のReadMeを参考にpom.xmlをかいたり、直接jarを落としてきたり好きな方法でaShotを使えるようにします。

github.com

Mavenリポジトリのリンクはこちらです

以下のような感じで撮影してファイルに書き出せばよいと思います。

private void captureImage(WebDriver driver, String filePath, float quality) throws IOException {
    JPEGImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(quality);
        
    // 150はミリ秒でスクロールを待つ時間、短すぎるとダメな模様
    ShootingStrategy ss = ShootingStrategies.viewportPasting(150); 
    // スクロールせずにそのまま撮影したい場合は以下
    // ShootingStrategy ss = ShootingStrategies.simple();

    Screenshot screenshot = new AShot().shootingStrategy(ss).takeScreenshot(driver);

    ImageWriter writer = null;
    try {
        writer = ImageIO.getImageWritersByFormatName("jpg").next();
        writer.setOutput(ImageIO.createImageOutputStream(new File(filePath)));
        writer.write(null, new IIOImage(screenshot.getImage(), null, null), param);
    } finally {
        if (writer != null) {
            writer.dispose();
        }
    }
}

複数の画像を連結したい!

aShotとは直接関係はありませんが、複数の画像を1枚につなげて保存したいという要望があると思います。
画像サイズは同じであるとして、以下のような感じでできます。(厳密には横のサイズが1枚目と同じ前提)

private void createAllImage(WebDriver driver, String filePath) throws IOException {
    ShootingStrategy ss = ShootingStrategies.viewportPasting(150); 
    
    driver.navigate().to("https://www.google.co.jp/");
    BufferedImage image1 = new AShot().shootingStrategy(ss).takeScreenshot(driver).getImage();
    
    driver.navigate().to("https://goalist.co.jp/");
    BufferedImage image2 = new AShot().shootingStrategy(ss).takeScreenshot(driver).getImage();
    
    JPEGImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(1.0f);
    
    List<BufferedImage> captureList = new ArrayList<BufferedImage>();
    captureList.add(image1);
    captureList.add(image2);

    int entireHeight = 0;
    for (BufferedImage imageBuf : captureList) {
        entireHeight += imageBuf.getHeight();
    }
    BufferedImage entireImage
        = new BufferedImage(captureList.get(0).getWidth(), entireHeight, captureList.get(0).getType());

    ImageWriter writer = null;
    Graphics entireGraphic = null;
    try {
        entireGraphic = entireImage.getGraphics();
        int tempHeight = 0;
        for (BufferedImage imageBuf : captureList) {
            entireGraphic.drawImage(imageBuf, 0, tempHeight, null);
            tempHeight += imageBuf.getHeight();
        }
        writer = ImageIO.getImageWritersByFormatName("jpg").next();
        writer.setOutput(ImageIO.createImageOutputStream(new File(filePath)));
        writer.write(null, new IIOImage(entireImage, null, null), param);
    } finally {
        if (writer != null) {
            writer.dispose();
        }
        if (entireGraphic != null) {
            entireGraphic.dispose();
        }
    }
}

まとめ

ブラウザに関係なくお手軽にスクリーンショットが取れるaShotが本当に便利でした。
スクロールバーは出ているけれど、このパターンの時はスクロールしなくていいなぁみたいな時にShootingStrategyでスクロールさせない方法が指定できるのも使いやすかったです。

【知ってるようで知らない】AWS EC2インスタンスのしくみ

こんにちは、ゴーリスト開発の飯尾です

最近AWSからこんなお知らせが来てなんじゃいと思いましたが
どうやらとあるインスタンスがもうすぐ死んでしまうらしい

f:id:y-iio:20180213162724p:plain

このあたり見るにつけ

docs.aws.amazon.com

qiita.com

ルートデバイスタイプがEBSなので、いったんインスタンス停止して開始したらOK〜

はい

よく考えたらルートデバイスタイプって何?なんで再起動したらOKなの?

EC2インスタンス日々使っているくせに
どういう仕組みで動いてるのかはぜんぜん知らなかったので調べてみました

そもそもEC2ってなんだ

EC2ってなんだ
仮想のサーバーをゾンアマさんから借りれるしくみだよ

インスタンスってなんだ
借りた仮想のマシンだよ
ホストコンピュータの一部分を一つのマシンとして扱うよ
ここではホストコンピュータ君の一部に肉体の型と魂を与えて一つのマシンとみなすよ

f:id:y-iio:20180213163049j:plain:w300

リージョンってなんだ・アベイラビリティゾーンってなんだ
ホストコンピュータが物理的に置いてある国・地域の分別のことだよ

f:id:y-iio:20180213163109j:plain

AMIってなんだ
インスタンスを作るためのテンプレートだよ
アマゾンマシンイメージの略だよ
マシンの肉体の型だよ

f:id:y-iio:20180213163135j:plain

EBSってなんだ
マシンのデータ置き場のひとつと思っておこう
ここではデータ=魂ということにするよ

f:id:y-iio:20180213163202j:plain:w300

肉体の型と魂さえあればどのホストコンピュータ上にも同じマシンを作れるよ

ルートデバイスタイプってなんだ

インスタンスはテンプレートを使って起動されるよ

昔はテンプレート置き場がS3にあって、インスタンス起動のたびに
それぞれのホストコンピュータのインスタンスストアにそれをコピってきて使っていたよ
データボリュームはその都度ホストコンピュータ上に作られているから
インスタンスを停止したらデータは失われるよ
「ルートデバイスタイプがインスタンスストア」っていうのはこういうことを言うよ

f:id:y-iio:20180213163241j:plain

今ではEBSというしくみがあって、
EBSベースに作られたテンプレートを使って、EBSに置いてある魂を紐づけて使ったりするよ
インスタンスを停止してもデータはEBS上に残るよ
「ルートデバイスタイプがEBS」っていうのはこういうことを言うよ

f:id:y-iio:20180213163305j:plain

docs.aws.amazon.com

なんで再起動したらOKだったんだ

ゾンアマさんからきた死亡宣告は、
「今動いてるインスタンスのホストコンピュータが調子悪いぜ!」
と言う意味だったよ

f:id:y-iio:20180213163422j:plain:w300

なのでいったん停止してまた起動し直すことで
別のホストコンピュータ上でインスタンスが起動したからOKになったよ

f:id:y-iio:20180213163357j:plain:w300

はい