ユニファ開発者ブログ

ユニファ株式会社システム開発部メンバーによるブログです。

「価値の押しつけ」とならないように。

f:id:unifa_tech:20201010174141p:plain こんにちは、PdM(プロダクトマネージャー)の田嶋です。

プロダクト開発において、何を置いても大切なのは、顧客に「使われる」こと。そして、そのために顧客を「よく知る」ということ。
理想を求めるばかり、最近は基本を忘れかけていました。改めて思い出すためにもこのブログを書こうと思います。

これから新規事業に取り組まれる方にとっても、「使われる」を目指すペインの超入門編として参考にして頂ければ幸いです。
※特定の参考文献はなく、様々な知識の寄せ集めのため、別の理解があればぜひ教えてください。

【目次】

■1.顧客に使われなければ始まらない

大前提として、下図の「作れる」領域でしか事業化できず、★領域でしか事業は持続できません。 f:id:unifa_tech:20201010174223p:plain

では、「儲かる・作れる・使われる」のうち、第一に私たちが意識すべきは何でしょうか?
それは、顧客に「使われる」ことです。

時は遡ることX年、高度経済成長の最中では、作れば売れる時代もあったそうですが、供給過多の現代においては、顧客に「使われる」ことのハードルが上がっています。
この状況において、単に「作れる」モノを作っても、使われず無駄になる場合がほとんど。顧客に「使われる」確度の高いモノを、後から「作れる」か検討すれば良いでしょう。

※ここで指す「作れる」とは、技術的な可否だけを想像しがちですが、「既存リソースの強み,制約」と捉えておくと、後に"ビジネス上の要件"として働くため、事前に整理しておくと良いかもしれません。

また「儲かる」については、「作れる・使われる」を見込めない状況では値決めすらできないため、考えるのは最後です。マネタイズ方法は、これから私も勉強したいと思っているところです。

■2.課題解決型を狙う

顧客に「使われる」を目指すにおいて、新しい領域に事業展開するには大きく分けて2通りのビジネスがあります。
それは、「価値提案型」と「課題解決型」です。 f:id:unifa_tech:20201010174151p:plain

両者を比較した際、ビジネスとして成功しやすいのは「課題解決型」だと思っています。
その理由は、人間は悩みが切実なほど、お金を払ってでも解決したいと考えるからです。この "お金を払ってでも解決したい切実な痛み" を「ペイン」と呼び、ペインの解決を通じてお金を得ることがビジネスとなります。

一方で「価値提案型」の場合は、新しいビジョンや価値観によほど強い共感を得られない限り、浸透させることが難しい印象です。

まさに今私の取り組む "保育施設の先生向けプロダクト" においても、この方向性で悩んだ時期がありました。特に教育事業においては、こうあるべき!という理想が掲げられる一方、現場とはギャップがあることもしばしば。
保育書籍のインプットから始めた私にとって、インタビュー訪問を通じた現場の実態と、どのようにバランスを取るべきかに苦しみました。
しかし、顧客の共感を得られない価値提案型は、それこそ「価値の押しつけ」となりかねません。
仮に売りたいものが新しい価値だとしても、ビジネスとしては課題解決を謳う方が顧客に受け入れられやすい。認識を改め、現場の先生方のペインを探りました。

■3.課題の深いペインを狙う

さあ、解決すべきペインを見つけよう!と意気込む訳ですが、一概にペインと言っても、より「使われる」に足る "ペインの質" の見極めが重要です。

では、「課題の深いペイン(=お金を払ってでも解決したい、より切実な痛み)」とは、どんなものでしょうか? f:id:unifa_tech:20201010174402p:plain

それは、「既にコストを払って対策しており、それでも解消できない不満」です。コストとは、金銭だけでなく、時間的や労力的なものでも良いでしょう。痛みが強いほど解決したい想いとなり、対策(コスト)として現れているはず。このコストを大きく払っているほど、より課題の深いペインとも言えます。

そして、現状より低いコストで不満解消できる手段(=新サービス)を提供できれば、顧客はぜひ乗り換えたいと思うでしょう。

このペインを探るにあたり、注視すべきは顧客の行動です。
既にコストを払って対策を取っているか?行動の事実をきちんと確認します。一方で「課題だ」「困ってます」と口で言うだけの事象は、そもそも解決に懸ける想いが弱いため、もし新サービスを提供しても、「お金を払うくらいなら今のままで十分!」と、使われる可能性は低くなります。 f:id:unifa_tech:20201010174206p:plain

ただ、便利な世の中になったもので、私たちの日常生活は不便の少ないものになりつつあります。(未来の自分が見たらどう思うかな?笑)
"顕在的なペイン" は、既にサービス化されているか、訳ありで解決されていない場合かが殆どでしょう。そこで私たちは、"潜在なペイン" にも目を配らせます。普通という価値観は、環境に依存しやすく、傍から見ると異質なことも。顧客が当たり前と思って取り組むことは、意外と本人がコストと気付いていない場合も多くあります。だからこそ、私たちは顧客の行動を注視し、顧客を「よく知る」ことが大切です。

〜おわりに〜

これまで、
・事業における「使われる」ことの重要性
・「使われる」には課題解決型、課題の深いペインを狙うと良いこと
を説明しました。

引き続き、顧客に使われることを目指して、顧客と向き合っていきます。くれぐれも「価値の押しつけ」とならないように。

以上、ありがとうございました!

ーーーーーーーーーーーーーーーーーーーーーーーーーー
ユニファでは、新たな仲間を積極採用中です。
プロダクトマネージャーも大絶賛募集中!よろしくお願いします! herp.careers

強化学習で最強の打順を求める(前編)

こんにちは。機械学習やデータ分析に加えて最近インフラ周りにも入門して修行中の浅野です。新しいことにチャレンジするのは楽しいですね。新しいことといえば機械学習の中でも強化学習についてはなかなか手をつけられていなかったので、今回はその強化学習を使って何かを作ってみたいと思います。息子が野球をやっていることもあり、「シチュエーション別の打率データから最強の打順を求める」という課題設定にします。通常は解くべき課題に対して最適な解法を選択していくのが筋ですが、今は「理解を深めるために強化学習をオリジナルの課題に使ってみたい」というのがモチベーションなので、強化学習を使うのが適切か、そもそも解けるのか、といったところはあまり気にせず探索していきたいと思います。

長くなりそうなので次のように2回に分けてまとめていく予定です。

  • 前編:打率データの作成とシミュレーション環境の構築 ← いまココ
  • 後編:強化学習モデルの学習と評価

強化学習としての大まかな問題設定

強化学習では、ある環境においてエージェントが観測した状態をもとに行動を起こし、それによって得られる報酬の累積値を最大化するような行動指針を学習していきます。今回の課題では、9人の打者のシチュエーション(アウトカウントとランナーの有無)別の打率データがあるとき、ランダムな打順からスタートしてある二人の打順を入れ替えていき、得点力がなるべく大きくなるような打順を求める、という立て付けを考えています。強化学習の枠組みに照らし合わせると、打順が状態に対応し、打順の中で1組を入れ替えることが行動にあたります。報酬については、与えられた打順で各イニングの攻撃をシミュレートし、1試合(9イニング)で得られる総得点をもとに設計していくつもりです。まだこのモデル化が良いのかどうか定かではありませんが、この前編ではそれを検証する上で必要になってくる打率データの生成と得点シミュレーション部分の作成について書いていきます。後編ではそれをもとに実際に行動モデルを強化学習によって求めます。

打率データ

f:id:unifa_tech:20201005143500j:plain
高打率タイプの打者のランナー状況毎のアクション割合(ノーアウトの場合)

上図はある打者の状況別の打率を定義したものです。ランナーがいるほうが一般に打率が高くなりますが、この打者はランナー状況によってヒット(single), 2塁打(double)、3塁打(triple)、ホームラン(homerun)、犠打(sacrifice)、アウト(out)の割合は変化しない設定です。どんな状況においても35%の確率でシングルヒットを打ち、3%の確率で2塁打、3塁打とホームランは1%ずつです。犠打は行いません。1人の打者に対してこれをアウトカウントごとに定義します。それを9人分作成します。ノーアウトかワンアウトでランナーがいれば高確率で犠打を成功させる川相タイプ、満塁になると異常に打率があがる駒田タイプ、2塁打が多い立浪タイプなど、いろんなバリエーションの選手を用意します(例えが昭和ですね)。一般にツーアウトになると投手が有利なので打率を全般に下げたりするなどの調整も自由ですし、現実のデータを利用することも可能です。今回準備した9人のラインナップは下記のような感じです。

  1. リードオフマンタイプ:ランナーがいないときの出塁率が高い
  2. 川相タイプ:犠打の成功率が高い
  3. 高打率タイプ:どんな状況でも出塁率が高い
  4. 三冠王タイプ:長打も含めてとにかく打つ
  5. 駒田タイプ:満塁に強い
  6. 立浪タイプ:2塁打が多い
  7. ランスタイプ:打率が極端に低いがホームランだけは多い
  8. 守備の人: 全体的に打率が低い
  9. ジョーカータイプ:なぜかツーアウトになると打ちまくる

試合における得点数のシミュレーション

ある打順が与えられたとき、1回の先頭打者から1人ずつ上記で定めた打率データに基づいてアクションを選び、アクションに応じてアウトカウント/ランナー/得点をアップデートし、3アウトになったらイニングを終了させる。それを9イニング繰り返すことで、その打順で1試合でどれだけ得点することができたのか計算することができます。特に実装が難しい部分はありませんが、アクションに応じてランナーを進塁させたり得点を計算したりする部分は下記のようにビット演算にすることで多少すっきりと書けるので一応例を示しておきます。

def update(self, out, runner, action):
    if action == 'out':  # アウト
        out += 1
    elif action == 'sacrifice':  # 犠打:ランナーを1つ進塁(左シフト)してアウトカウントを1つ増やす
        runner = runner << 1
        out += 1            
    elif action == 'single':  # ヒット:ランナーを1つあるいは2つ進塁して1塁走者をおく(第0ビットをたてる)
        if random.random() > 0.5:
            runner = runner << 1
        else:
            runner = runner << 2
        runner = runner | 0b0001
    elif action == 'double':  # 2塁打: ランナーを2つあるいは3つ進塁して2塁走者をおく
        if random.random() > 0.5:
            runner = runner << 2
        else:
            runner = runner << 3                
        runner = runner | 0b0010
    elif action == 'tripple':  # 3塁打: ランナーを3つ進塁して3塁走者をおく
        runner = runner << 3
        runner = runner | 0b0100
    elif action == 'homerun':  # ホームラン: ランナーを4つ進塁し第3ビットをたてる
        runner = runner << 4
        runner = runner | 0b1000

    run, runner = self.get_score(runner)  # アクションの結果入った得点を計算
        
    return out, runner, run
    
def get_score(self, runner):
    run = bin(runner & 0b1111000).count('1')  # 第3ビット以上で1がたっているビット数が得点
    runner = runner & 0b111  # 第0−2ビットに残っているのがランナー
        
    return run, runner

得点力が高い打順の例

9人で組める打順は9!= 362,880通りです。かなり時間はかかりますが全てのケースで上記の得点シミュレーションを走らせることで、どんな打順が得点力が高いのかを知ることができます。各打順で100試合分のシミュレーションを行い平均得点数を調べてみた結果、私が直感でこんな順番がよいのではないかと思った打順での平均得点は3.05点でした。また、すべての組み合わせの中で最も平均得点が高かった打順では4.03点でした(最低は1.76点)。それぞれの打順を比べてみるとこんな感じです。

私の案 (3.05点) 最高の打順 (4.03点)
1 リードオフマン 高打率
2 川相 三冠王
3 高打率 ジョーカー
4 三冠王 駒田
5 駒田 川相
6 立浪 ランス
7 ランス 守備の人
8 守備の人 立浪
9 ジョーカー リードオフマン

平均だけでなく得点の分布も比較してみましょう。水色のヒストグラムが私が考えたオーダーの得点分布で、クリーム色が最高得点の打順の分布です(茶色は両者が重なっている部分)。これを見ると確かに5点以上得点する試合の数がかなり違いますね。

f:id:unifa_tech:20201005180456j:plain
2つの打順における得点の分布
最高得点の打順を見てみると、まず、2番に強打者を置くという最近のトレンドと合致していて面白いです。また、上位に打率が高めのバッターを集め、ランナーが溜まったときにまわりやすい4番に満塁に強い駒田を入れたり、川相/ランス/守備の人と打率が低めな選手を固めることで打線が分断されるのを防ぐなど、言われてみるとそうだよなと納得させられるオーダーになっており興味深いですね。

まとめ

打率データをもとにある打順での得点数を算出するシミュレーションが完成しました。対戦相手の能力や相性、ボールカウント、走力、代打、守備力など野球において考慮できていない要素がたくさんありますが、今回は野球の正確なシミュレーション環境を構築するのが目的ではないので気にしないでおきましょう。また、全探索の結果から得点力の高い打順の例を示しましたが、打者の特徴が少しでも変わるたびにこのような計算を行うことは現実的ではないため、後編では強化学習モデルによって得点力のある打順をより効率的に求める手法に挑戦していきます。

AWS Startup Architecture of the Year Japan 2020 で優勝しました!!

f:id:akanuma-hiroaki:20200923223808j:plain

皆様こんにちは、ユニファの赤沼です。

先日プレスリリースも出させていただきましたが、9/16 に行われた AWS Startup Architecture of the Year Japan 2020 Live Finale にて、ルクミー午睡チェックのアーキテクチャについてプレゼンさせていただき、ユニファが優勝することができました!これも日々社内でサービス提供のために取り組んでいる開発、ビジネス、コーポレートの全メンバーの努力が評価されたものですし、メンタリングいただいた AWS の松田さん、岡田さんのおかげですし、何より日々保育の現場で真摯に保育に取り組まれている保育者の方々のご尽力の成果でして、本当にありがたく思っています。

今回はどういったところが評価されて受賞に至ったのか、また、事前の準備や当日の様子などについてご紹介できればと思います。

AWS Startup Architecture of the Year とは

「AWS Startup Architecture of the Year」は2018年に日本で生まれ、今年から世界規模で展開されるスタートアップのためのコンペティションで、評価の対象はビジネスを成功に導く優れた「アーキテクチャー」です。そのアーキテクチャーがいかに AWS Well-Architected Frameworkの基準に適合しているか、ビジネスにインパクトを与えているかといった点が評価の対象となります。日本、米国、インド、欧州の各地域から、優れたアーキテクチャーでビジネスをけん引しているスタートアップが選出され、11月に開催予定の世界大会(オンライン)にて世界一を決定します。

Startup Architecture of the Year Japan 2n020

aws.amazon.com

評価されたポイント

さて、今回どういったところを評価いただいたかですが、受賞時に審査員の藤本さんからいただいたコメントから、派手さはないけれどやるべきことをしっかりやっているというところを評価いただいたと思っています。

ルクミー午睡チェックでは命に関わる業務の安心・安全をサポートするというプロダクトの性質上、 Well-Architected Framework の5つの柱の中でも、特に信頼性と運用上の優秀性が求められます。信頼性という点では、DynamoDB と SQS を使ってパフォーマンスを担保している点や、 Design for Failure を考慮した DLQ の仕組み、ネットワーク障害等が発生してもローカルのみで一定の業務が継続可能にしている点等で担保しています。また、運用上の優秀性といった点では、SORACOM Air Sim を用いたセルラー回線を使うことでの安定した接続や導入時の保育園側のハードルの低減といった点で考慮しています。

一つ一つは技術的に尖っているわけではないですが、サービスの特性を考えて求められる点を総合的にしっかりカバーし、そしてこれらが実際にプロダクトの導入実績と紐づいて、事業に貢献できているというところが評価いただけたものと思っています。

メンタリング

応募後に書類選考を通って Live Finale での登壇が決まった段階で、 AWS の松田さんと岡田さんにメンタリングいただき、5分間という短い時間でどういった点を伝えるのが良いかをアドバイスしていただきました。それをもとにプレゼン資料とシナリオを作成したのですが、5分間というのは思っていたよりもとても短く、その中で事業やアーキテクチャ、ビジネスへの貢献をしっかり説明するには、スライドで表示して理解してもらうことと喋って説明することを吟味して、不要なものをできる限り削る必要がありました。そして一旦作ったもので松田さんと岡田さんにレビューいただき、ダメ出しを経てなんとか5分間で伝えるべきことをまとめることができたと思います。松田さんと岡田さんには本当に感謝です。

当日の様子

当日のプレゼンの順番は社名の五十音順ということで、六社中一番最後だったのですが、ということは一番最後まで緊張してることになるので、正直他社のプレゼンをしっかり見てる余裕はありませんでした。見てると余計に緊張しちゃうので。。

またこれは完全に自社の事情なのですが、当日 Live Finale の直前に取締役会があり、どうしても外せなかったので、岡田さんに会議室を手配いただき、Amazon目黒オフィスの会議室からリモートで取締役会に参加させてもらいました。取締役会では自分のアジェンダもあり、 Live Finale のことを考えるとそわそわしながら参加していたのですが、なんとか無事に予定時間までに取締役会も終えることができました。岡田さんには私のわがままにご対応いただき、感謝です。

朝から吐きそうに緊張してましたが、プレゼン自体もなんとか5分間に収めることができ、審査員のCTOの方々からどんなマサカリが飛んでくるかとびびっていた質疑応答も乗り越えて、やっとほっとした感じでした。

世界大会

今のところ世界大会については、11月にオンラインで開催、という以外にはまだ何も聞いていないので、プレゼン英語なのかなー、というぐらいなのですが、審査員の藤本さんや松本さんからはしっかりプレッシャーかけられたので、日本代表としてはがんばらねばと思っています。プレゼン自体は英語でもなんとかなりそうな気がしますが、質疑応答が英語でできるのか。。英語力を鍛える必要がありますね。。

まとめ

事前の準備は色々と大変でしたが、受賞できたことは本当に嬉しく、SNS等でも多くの方からお祝いの言葉をいただきました。本当にありがとうございます。また、社内のメンバーとしても自信につながるところもあると思いますし、社外に向けてのアピールになる点も大きいのではないかと思います。私自身も改めてアーキテクチャを見直して Well-Architected Framework について考えるきっかけにもなりましたし、今後より良いプロダクトを提供できるようにチャレンジしていこうというモチベーションにもつながりました。

そしてインフラエンジニアをはじめ、このチャレンジに一緒に参加してくれる方を募集してますので、興味のある方はぜひご連絡ください。一緒に保育をハックしていきましょう!!

herp.careers

Jamstackで動的サイトを作ってみる

こんにちは、サーバーサイドエンジニアの柿本です。

みなさんは Jamstack をご存知ですか??!!

先日知人が Jamstack について熱く語ってくれまして、私は「ナニソレオイシイノ?」と思って聞いていたのですが、彼があまりに熱く語るので「サゾカシオイシイニチガイナイ!」ということでいろいろ調べてみました。

「 SPA と SSR のいいとこ取り」や「動的サイトと静的サイトのいいとこ取り」といった魅力的な言葉が並ぶのですが、つまるところ、

サイトの中の静的な箇所は完全に静的ファイル化しておいて、動的な部分はAPIを叩いてよろしくやろうぜ!

ということのようです。

早速入門してみようとしたところ、 Jamstack の入門記事は主に ヘッドレス CMS や SSG (静的サイトジェネレータ)との繋ぎ込みなど 静的ファイル化部分 に主眼が置かれておりました。
動的によろしくやる方法を知りたかったので、自分でやってみることにします。

TL;DR

1クリックで Netlify にデプロイすることができます!

Deploy to Netlify

事前準備として FaunaDB のセットアップと Server secret の取得 が必要です。

デプロイ完了後に Netlify Identity の設定 が必要です。

目次

技術スタック

  • 静的サイトジェネレータ: Next.js
  • ソースコード管理: GitHub
  • ホスティング・CDN: Netlify
  • データベース: FaunaDB
  • ヘッドレスCMS: 利用なし(*動的部分をターゲットとしてるので使いません)

Jamstack の構成としては標準っぽい物を選定しました。

構想

動的サイトといえば ユーザーログインデータ保存が基本となるので、 『ユーザー登録制の掲示板サイトもどき』 を作ってみます。

ユーザーストーリー

  • ユーザーがログインできる
  • ユーザーが自分の名前でメッセージを投稿できる
  • メッセージ一覧を誰でもみれる

画面構成

/ フロントページ(メッセージ一覧)
└/ メッセージ投稿画面

非常にシンプルですね!

最終形態

f:id:unifa_tech:20200918003519g:plain
2人のユーザーによるログインから記事投稿まで

最終成果物

GitHub に公開 しました!
開発手順の詳細も README に記載してあるので、参考にしてみてください。

github.com

開発の流れ

  1. Next.js のセットアップ
  2. GitHub に push
  3. Netlify にデプロイ
  4. Netlify Identity の設定
  5. フロントコーディング
  6. FaunaDB の設定
  7. Netlify Functions コーディング

実装のポイント

フロントエンド

フロントエンドを構成するソースファイルは以下です。

dynamic-jamstack (App root)
├── pages
│   ├── index.js           // ホーム(メッセージ一覧)画面
│   └── new_message.js     // メッセージ投稿画面
├── components
│   ├── Message.js         // 1つのメッセージ表示
│   ├── MessageList.js     // メッセージを一覧で表示&データ取得処理
│   └── MessageForm.js     // メッセージ入力フォーム&データ送信
└── utils
    └── netlifyAuth.js     // Netlify Identityの認証処理

/pages/ 配下は Next.js により静的化されるページです。
デプロイ時に静的化されるため、ここに動的な処理(データ取得&描画)を記述しても想定どおりに動きません。

/components/ 配下は React コンポーネントです。
動的な処理をここに記述し、 pages のファイルで読み込むことで動的な挙動を実現できます。

Netlify Functions (API)

API のロジックは以下で構成されます。

dynamic-jamstack (App root)
└── functions
    ├── messages-create.js       // メッセージ保存
    └── messages-read-all.js     // メッセージ一覧取得

Netlify Functions の中身は AWS Lambda なので、書き方は同じです。

/messages-create はログイン済みのユーザーのみに制限する必要があり、クライアントと Functions のそれぞれで以下の対応が必要です。

クライアント - Header に Netlify Identity Widget から取得した token をセットします。

// components/MessageForm.js

  generateHeaders() {
    const headers = { "Content-Type": "application/json" }
    if (netlifyIdentity.currentUser()) {
      return netlifyIdentity.currentUser().jwt().then((token) => {
        return { ...headers, Authorization: `Bearer ${token}` }
      })
    }
    return Promise.resolve(headers)
  }

Functions - context.clientContext.user でユーザー情報を取得することができます。

// functions/messages-create.js

  const user = context.clientContext && context.clientContext.user;
  if (!user) {
    return callback(null, {
      statusCode: 401,
      body: JSON.stringify({ "error": "You must be signed in to call this function" })
    })
  }

考察

今回は "Jamstack構成で動的な処理を実装する" を目的として Next.js をベースに

  • 動的な処理を React コンポーネントで記述
  • 静的ファイル化される箇所からコンポーネントを呼び出し

として実現しました。

わかったこと

  • Jamstack 構成で動的サイトは実現可能
  • ユーザー認証は Netlify Identity で実現可能
  • ローカル(静的ファイル内)でも API 内でもユーザー情報を取得可能
  • データ保存はサーバーレスのデータストアにより実現可能

課題

1) サイトによる向き不向きがありそう

いわゆる SNS のような動的な処理がメインのサイトの場合、静的ファイル化できる部分が限られるためあまり恩恵を受けられないかもしれません。

メリットを最大化するには静的化する箇所を適切に切り出す必要がありそうです。

例えば弊社サービスのルクミーフォトの販売画面(購入する写真を保護者が選択する画面)などは、販売写真の設定がされたタイミングで静的ファイル化すればハイパフォーマンスのメリットがありそうです。

そのためには incremental build が適切に実行されるようにする、などの複雑な設定も必要になるかと思います。

2) pages 配下は静的ファイル化される、と意識してコーディングする必要がある

Next.js の仕組み上当たり前のことなのですが、ローカルの開発サーバー上でホットビルドをしているとついつい忘れてしまいます。

これは慣れの問題だとは思いますが、 Netlify にデプロイしてから「あれれ?」となることが何度かありました。(笑)

まとめ

Jamstack で動的サイトを作ることが可能なことは分かりましたが、感想としては「ちょっと無理やり感が否めない」といったところです。

とはいえ Netlify などの CDN 経由で静的ファイルを配信できることのメリットは大きいので、サイトの向き不向きは選びますが、活用していければ良いなと思いました。


ユニファでは保育をハックするエンジニアを募集中です。 一緒にスマート保育園を実現しましょう!

www.wantedly.com

Appendix

FaunaDBの設定

https://fauna.com/ からアクセスし、 Signup します。 Netlify のアカウントでも Signup できます。

任意の名前で Database を作成し、以下を設定します。

  • Collection - Name: messages
  • Index - Name: all_messages

SECURITY メニューから key を作成し、 Server secret を取得します。
Server secret は2度と表示されないので、無くさないように保管します。

Netlify Identityの設定

Netlify の dashboard の Site 一覧から対象の Site を選択します。

Identity > Enable Identity の順にクリックしてアドオンを有効化します。

Setting and usage > Registration > External providers で追加したい認証プロバイダーを選択します。

f:id:unifa_tech:20200918025325p:plain
Netlify Identity の External providers

TensorFlow Profilerを用いた学習時間の短縮

こんにちは。R&D改めデータエンジニアリングチームの宮崎です。 普段はTensorFlowを使って、Deep Learningを学習させて画像認識モデルを作ったりしています。

Deep Learningの悩みの一つとして、学習時間が数時間から数日に及び、非常に長いという点が挙げられます。 作業効率やマシンの費用を考えると、少しでも学習時間を短くしたいです。 そこで今回はTensorFlow Profilerを用いてDeep Learningの学習時間を短縮してみたいと思います。

TensorFlow Profilerとは

TensorFlow ProfilerはTensorFlowの計算時に、処理毎の所要時間などパフォーマンス情報を収集し、TensorBoard上で可視化してくれるツールです。 TensorFlow v2.2.0やv2.3.0で機能が強化され、より詳細な分析ができるようになっています。

続きを読む

コンテキストスイッチから思ったこと

こんにちは、プロダクトエンジニアリング部のちょうです。最近ミーティングでコンテキストスイッチというワードが出て、これについて思うことがあり、すこし話したいと思います。

ここのコンテキストスイッチはプログラムのコンテキストスイッチではなく、毎日の仕事や勉強の中、あることをやって、その後また別のことをやる、つまり仕事の切り替えということです。仕事の切り替えがいいとか悪いのかというと、はっきり言えません。仕事の切り替えができないとそもそも仕事ができないというイメージになり、ものすごく切り替えると効率が落ちるに違いありません。

開発メンバーから見て、ミーティングが多くなると、丸一時間、丸二時間の開発時間が取れなくて、「あれ、ミーティング前に俺何をやったっけ」ということもあり、進捗があまり進まないこともあります。とはいえ、ミーティングの時間はみんな空いている(ように見える)時間帯から決めたから、簡単に変えられないです。一つ解決策はあまり要らないミーティングをキャンセルし、任意参加なら時間があるかどうかで決めるのです。残りは自分で仕事をどこまで効率化できるのか。

一番簡単なのか、予定してた時間内で完了するのです。つまりコンテキストスイッチがないということです。仕事を30分内、1時間内で完了できる細かいタスクに分けるのも効果的です。

次は、コンテキストスイッチの問題というと、前回仕事の内容はすぐに思い出せないということです。プログラムのコンテキストスイッチでしたら、切り替える前にいまやっている仕事の内容をどこかに保存します。そのように、次の仕事に入る前に、現在の仕事を保存します。具体的には

  • Macbookでdesktopを活用して、仕事AのDesktopと仕事BのDesktopを分けるようにしましょう。
  • IDEにはチケット単位やブランチ単位で開いたファイルなどを覚えることができます。またはチケットに何をやっているかをコメントするのも良いでしょう。
  • もっと一般的なことはメモなどに書いても問題ないでしょう。
  • 特別に、現在やっている仕事まだ終わってないという気持ちでブラウザのタブを開きすぎるのはよくあると思いますが、あえてOneTabでタブをまとめたり、タブのリンクをメモなど(つまり現在の仕事と関係ないタブをすべて閉じる)に保存するのをおすすめです。あとでタブを探すのが大変のと複数の仕事のタブが混ぜるとお互い邪魔になるからです。

もう一つ効率的に仕事する方法は同じ種類の仕事を連続やるのです。同じ種類だとコンテキストが似ていて、スイッチしても影響は少ないです。具体的にはパソコンの前にやる仕事をまとめやったり、同じプロジェクトの仕事を連続やったりするのです。

いかがでしょうか。すこし自分の仕事の効率どうやって上げるのを分かるようになりましたか。最後に、本記事はいくつの方法を紹介したが、「ミーティングの合間」に頑張るより、連続で影響されない時間があれば一番いいということを忘れないでください。

Amazon ECS+FargateでRailsを動かす際の最適なパラメーターを考えてみる

こんにちは、最近野菜が高いのでもやしばかり食べているWebエンジニアの本間です。 そろそろレタスが食べたい...。

さて、ここ1、2年、ユニファではAmazon ECS+AWS Fargateを使用して、Railsアプリケーションを本番運用することが増えてきました。 stagingでテストしたDockerイメージがそのまま本番で使えて安心だったり、オートスケールが簡単だったりとメリットが多く、大変便利だと感じています。

ただ、そのような環境を構築する中で、vCPU数やメモリ量、およびPumaの並行性に関するパラメーターをどうしようか毎回悩んでいたため、この辺で自分の中で整理しておこうと思います。

続きを読む