UUUM攻殻機動隊(エンジニアブログ)

UUUMのエンジニアによる技術ブログです

Swagger OpenAPIでAPI Referenceを書く

こんにちは、@takeokunn です。

yamlyml の違いってなんだろーと調べたところ Please use “.yaml” when possible. って公式のfaqに書いてあったのでなるべく .yaml を使っていこうと思った今日このごろです。

今回はOpenAPIの実装例について書いていこうと思います。

Dockerで構築

docker-compose.yml はこんな感じ。

version: "3.3"
services:
  swagger-editor:
    image: swaggerapi/swagger-editor
    container_name: "swagger-editor"
    ports:
      - "19881:8080"
  swagger-ui:
    image: swaggerapi/swagger-ui
    container_name: "swagger-ui"
    ports:
      - "19882:8080"
    volumes:
      - ./openapi.yaml:/usr/share/nginx/html/openapi.yaml
    environment:
      API_URL: openapi.yaml
  swagger-api:
    image: stoplight/prism:3
    container_name: "swagger-api"
    ports:
      - "19883:4010"
    command: mock -h 0.0.0.0 /openapi.yaml
    volumes:
      - ./openapi.yaml:/openapi.yaml

swagger-uiswagger-editor は転がってるコードをそのままペタっと貼り付けました。

以前は danielgtaylor/apisprout を使っていたのですが、どうもOpenAPIの最新の仕様に追いついていなかった(要出典)ので今回は stoplight/prism を使いました。

下のサンプルの get: /colors を試しに叩いてみるとこんな感じ。簡単にmockが作れて良いですね。

~/.g/g/t/.emacs.d (*´ω`*) < curl "http://localhost:19883/colors" -H "Authorization: Bearer xxx"
{"message":200,"colors":[{"id":1,"name":"赤","created_at":"2002/05/12 20:30:15","updated_at":"2002/05/12 20:30:15"}]}

実際に openapi.yaml を書いてみる

Specifitcation とにらめっこして書けば大体できます。

試しに2つのendpointを作ってみました。

  • get: /colors: 色を取得する
  • post: /colors: 色を作成する

Bearer token を必要とする場合でも簡単に記述てきてとても良いです。

openapi: 3.0.5
info:
  title: OpenAPIテスト
  version: 1.0.0
  description: OpenAPIテスト
servers:
  - url: http://localhost:3000/api/v1
    description: Local server
  - url: https://staging.test.tokyo/api/v1
    description: Staging server
security:
  - bearerAuth: []
paths:
  /colors:
    get:
      summary: Get colors
      description: 色一覧を取得
      responses:
        200:
          description: 色一覧を返す
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: 200
                  colors:
                    type: array
                    items:
                      $ref: '#/components/schemas/ColorModel'
    post:
      summary: Create color
      description: 色を作成
      requestBody:
        content:
          application/json:
            schema:
              required:
                - name
              properties:
                name:
                  type: string
                  example:responses:
        201:
          description: 作成した色を返す
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Success
                  color:
                    type: object
                    $ref: '#/components/schemas/ColorModel'
        400:
          description: 作成エラー
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Failure
components:
  schemas:
    ColorModel:
      type: object
      properties:
        id:
          type: integer
          example: 1
          description: primary id
        name:
          type: string
          example:description: 名前
        created_at:
          type: string
          example: 2002/05/12 20:30:15
          description: 作成日
        updated_at:
          type: string
          example: 2002/05/12 20:30:15
          description: 作成日
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API Key

emacsで快適に openapi.yaml を書く

emacsで快適にyamlを書くためにいくつかpluginを入れました。

openapi-yaml-mode

url: magoyette/openapi-yaml-mode

MELPAで公開されていないが、顧客が欲しかった感じのEmacsLispが書かれているので導入した。completionや簡易的なhighlightなどが入っている。

f:id:bararararatty:20200225222634p:plain
openapi

;; cask
(depends-on "openapi-yaml-mode" :git "https://github.com/magoyette/openapi-yaml-mode.git")

;; config
(use-package openapi-yaml-mode
  :mode (("\\openapi.yaml$" . openapi-yaml-mode))
  :config
  (setq openapi-yaml-use-yaml-mode-syntax-highlight t))

DarthFennec/highlight-indent-guides

url: DarthFennec/highlight-indent-guides

highlight-indent-guides

yaml のインデントを可視化してくれるplugin。以下のようにconfigを書いた。

(use-package highlight-indent-guides
  :diminish
  :hook
  ((prog-mode yaml-mode) . highlight-indent-guides-mode)
  :custom
  (highlight-indent-guides-auto-enabled t)
  (highlight-indent-guides-responsive t)
  (highlight-indent-guides-method 'character))

終わりに

openapi.yaml 職人の方は是非弊社で一緒にyamlをかきましょう!!!

www.wantedly.com

vimサークル活動報告 #1

こんにちは、弊社唯一のemacsユーザの @takeokunn です。

最近ブログを書いていなかったのでそろそろやらねば...ということで筆を取りました。

はじめに

UUUMには 会社公認サークル #circle-vim というものがあります。

サークルメンバーはvim歴が浅い人が多く約10人(幽霊含み)いて、日々 BTO会長 を中心に素vim力を高めるべく精進をしていました。

が、BTO会長の会社卒業を期にneovimで闇の力を得ようと様々なpluginを突っ込んで新たな力を得ようという方針になってきているので、今回はその活動報告をしていこうと思います。

neovimを使えるようにする

homebrewでサクッと入ります。

$ brew install --HEAD neovim

ちなみに、僕はubuntuユーザなので自前でbuildをしました。

$ ghq get https://github.com/neovim/neovim
$ cd ~/.ghq/github.com/neovim/neovim
$ make -j
$ sudo make install

dotfilesを整える

我らがvimサー会長BTOさんの 汎用性・拡張性の高い dotfiles 環境を作る という記事を参考に皆各々dotfilesを作っています。

僕はvimとnvimを以下のように使い分けて管理しています

  • vim: サーバに入って設定ファイルを弄る用、ほぼ素vim
  • neovim: ガッツリカスタマイズして日常使いを目指す

plugin紹介

swoop

url: pelodelfuego/vim-swoop

言わずと知れた検索/置換ライブラリ。emacsでは愛用していたのでnvimでも是非入れたかった逸品。

swoop公式画像

vim-swoopでは検索し終わった後にbufferを消してくれなかったのでしょうがなくkeybindにdeleteする処理を追加しました。

また、現在のカーソルの文字列を取得して検索する自前の関数を作りました。

function! MySwoop()
  let word = expand('<cword>')
  if len(word) > 0
    call SwoopPattern(word)
  else
    call Swoop()
  end
endfunction

nnoremap <silent> ,s :call MySwoop()<CR>
nnoremap <silent> ,q :bdelete! swoopBuf<CR>

EmacsLispだとこんな感じ

(use-package swoop
  :config
  (setq swoop-minibuffer-input-dilay 0.4)
  (defun my/swoop-from-isearch ()
    (interactive)
    (let* ((symbol (thing-at-point 'symbol 'no-properties)))
      (swoop symbol))))

(define-key ivy-mode-map (kbd "C-o") 'my/swoop-from-isearch)

vim-multiple-cursors

url: terryma/vim-multiple-cursors

terryma/vim-multiple-cursors

みんな大好きmultiple cursor。良いですね大好きです。

emacsだと smartrepmultiple-cursors を組み合わせてやるしかなくて結構たいへんです。

(use-package multiple-cursors
  :init
  (require 'smartrep)
  (declare-function smartrep-define-key "smartrep")
  (bind-key "C-M-c" 'mc/edit-lines)
  (bind-key "C-M-r" 'mc/mark-all-in-region)
  (global-unset-key (kbd "C-t"))
  (smartrep-define-key global-map "C-t"
    '(("C-t" . 'mc/mark-next-like-this)
      ("n"   . 'mc/mark-next-like-this)
      ("p"   . 'mc/mark-previous-like-this)
      ("m"   . 'mc/mark-more-like-this-extended)
      ("u"   . 'mc/unmark-next-like-this)
      ("U"   . 'mc/unmark-previous-like-this)
      ("s"   . 'mc/skip-to-next-like-this)
      ("S"   . 'mc/skip-to-previous-like-this)
      ("*"   . 'mc/mark-all-like-this)
      ("d"   . 'mc/mark-all-like-this-dwim)
      ("i"   . 'mc/insert-numbers)
      ("o"   . 'mc/sort-regions)
      ("O"   . 'mc/reverse-regions))))

Shougo/denite.nvim

url: Shougo/denite.nvim

denite.nvim

最高のPlugin、とにかく最高のplugin。顧客が求めていた全てが詰まっている最高のPluginです。

bufferの検索、project内grep、file検索、outline検索など欲しかったものを全て提供してくれています。

「これがあればfzf要らないんじゃね?」と思ったが、共存の道を探っている部員もいます。

" config
autocmd FileType denite call s:denite_my_settings()
function! s:denite_my_settings() abort
  nnoremap <silent><buffer><expr> <CR>
        \ denite#do_map('do_action')
  nnoremap <silent><buffer><expr> d
        \ denite#do_map('do_action', 'delete')
  nnoremap <silent><buffer><expr> p
        \ denite#do_map('do_action', 'preview')
  nnoremap <silent><buffer><expr> q
        \ denite#do_map('quit')
  nnoremap <silent><buffer><expr> <Esc>
        \ denite#do_map('quit')
  nnoremap <silent><buffer><expr> i
        \ denite#do_map('open_filter_buffer')
  nnoremap <silent><buffer><expr> <Space>
        \ denite#do_map('toggle_select').'j'
endfunction

" keybind
nnoremap <silent> ,k :Denite file/rec<CR>
nnoremap <silent> ,b :Denite buffer<CR>
nnoremap <silent> ,o :Denite outline<CR>
nnoremap <silent> ,r :Denite file/old<CR>
nnoremap <silent> ,h :Denite command_history<CR>
nnoremap <silent> ,g :Denite grep<CR>

emacsだと abo-abo/swiper がこれに当たるのですが、こういうインターフェースで提供できたら最高だなって思わされました。

終わりに

「emacsのこのpluignや機能、nvimでもほしいな」「nvimのこのpluignや機能、emacsでもほしいな」といった感じでお互いを高めあえれば最高だと思いました。

dark poweredシリーズやLSPなどの設定をもっともっとやって快適なvimライフを送りたいです。

弊社ではvim/neovimを完全に理解しているプログラマを募集しています。

www.wantedly.com

UUUM System Meetup #2

f:id:chibiProgrammer:20191224133138j:plain こんにちは、エンジニアの中村です。

12月13日にUUUM System Meet Up#2を開催したので、その様子を書いてみました!

今回も前回に引き続き沢山の人がきてくださいました。

前回よりもかなり盛り上がってとてもいい会になりました。

今回のイベントは、社内外の技術者たちと交流を深めたいということと、 社外の人に自社のシステムを紹介しようという目的の元開催いたしました!

今回のイベントの発表内容はこちらです。 今回は元UUUMエンジニアのnazoさんをお呼びして、発表していただきました!

発表者 役職 タイトル
obara_t エンジニア UUUMエンジニアの日常
ishihara_k エンジニア UUUM攻殻機動隊に入隊しました
fujisawa_y エンジニア CREAS
nazo エンジニア レガシープロダクトを改善していくための戦い方

最初の会社説明の後に、 obara_tさんの発表「UUUMエンジニアの日常」

f:id:chibiProgrammer:20191224134605j:plain
UUUMエンジニアの日常

obara_tさんは、社内システムについてと、UUUMエンジニアの日常を紹介してくださいました。 技術選定の話や、技術的なチャレンジは責任持ってやってくれればOKなど、自由なシステムの雰囲気を紹介してくださいました。

社内外で勉強会もよくしていて、 直近だと「お前らはDockerを1mmも理解していない」という勉強会が開かれ、 ピザパや焼肉をみんなで食べに行ったりなど、とても楽しそうな雰囲気が参加者に伝わったように思います。

次は、 ishihara_kさんの「UUUM攻殻機動隊に入隊しました」

f:id:chibiProgrammer:20191224141316j:plain
UUUM攻殻機動隊に入隊しました

ishihara_kさんはUUUMに入ってまだ2ヶ月目ですが、入ってすぐの目線で見たシステムについて話してくださいました。

ishihara_kさんの1つ前の会社がとてもブラックで、1年で300日オフィスで寝泊まりで作業していたという話を聞いて恐ろしいなぁと思いました。

UUUMはめちゃめちゃホワイトなので安心してくださいね!

次に、fujisawa_yさんの「UUUMと開発の話」

f:id:chibiProgrammer:20191224160429j:plain
UUUMと開発の話

fujisawa_yさんはCREASという、UUUMクリエイター限定サイトの紹介と、エンジニア×YouTuberについて発表してくださいました。

CREASを支える技術や、実際の作業内容を話してくださいました。CREASについて詳しく知りたい方は、「UUUM限定サイト」と検索してみてください!

また、エンジニア×YouTuberの話では、Githubのフォロワー数7位はエンジニアであったり、海外ではエンジニアでYouTuberの人のチャンネルがとても伸びていることを初めて知りました。

最後は、nazoさんの「レガシープロダクトを改善していくための戦い方」

f:id:chibiProgrammer:20191224145532j:plain
レガシープロダクトを改善していくための戦い方

nazoさんは元UUUMエンジニアの方で、初期からずっとシステムを支えてくださった方です(とてもすごい人です)。

今回は、レガシーコードとの向き合い方・心構えについて発表してくださいました。

レガシープロダクトを悪い状態を続けないために、CI/CDの設備、Lintの導入、環境構築をしやすい状態にしておくなど、 気をつけておかないといけない部分を紹介してくださり、自分が見えていない部分を色々と学ばさせていただきました。

とてもためになりました!登壇してくださり、本当にありがとうございました!

懇談会では、ケータリングを囲んでわいわい技術の話で盛り上がりました。 今回のイベントでUUUMに興味を持ってくださった方も沢山いて、とても楽しかったです。

f:id:chibiProgrammer:20191224151744j:plain
懇談会での様子

f:id:chibiProgrammer:20191224152651j:plain
ケータリング

f:id:chibiProgrammer:20191224153107j:plain
ケータリング

f:id:chibiProgrammer:20191224152404j:plain
全体写真

イベント参加者の皆さま本当にありがとうございました。1回目よりもとてもいいイベントになりました。 第3回も行いますので、その際はぜひ遊びにきてください!

プロダクトマネージャーカンファレンス2019

こんにちは。PMチームのしだです。
会社のカンファレンス参加精度を利用して、2019年11月12、13日に行われたプロダクトマネージャーカンファレンス2019に参加してきました。

2019.pmconf.jp

参加した9つのセッションの中から、
「PMが学ぶべき、最低限のデータ活用スキルとは」
についてレポートします。

レポート

セッション概要

『PMが学ぶべき、最低限のデータ活用スキルとは』
株式会社Hakali代表取締役
小川 晋一郎

データは分析するだけでは意味がなく、ユーザーのために活用されてはじめて価値が生まれます。ですのでユーザーのことを日々真剣に考え、新たな価値提供を生みたいと常に思っているPMの人たちこそデータ活用スキルを身につけるべきです。しかし、かといって統計学を一から学んで、、、とか、機械学習の講座を受けて、、、では遠すぎます。必要最低限のデータ活用スキルを身につけて、ユーザーへの価値提供力を高めましょう。

https://2019.pmconf.jp/sessions/2019/11/13/S2-003/

はじめに

  • よくある事例

    • 数字を今すぐ見たいPM VS 忙しいエンジニア
    • 説明をしたいPM(ユーザーに嫌がられるのでユーザーへのメール数を減らしたい) VS 話の通じない上司(減らして売上あがるの?)
    • 自分でデータを扱えればこんな事例に対応できる
  • 実際に対応した事例

    • Before:機能ベースのKPI設定で現場が疲弊
    • After:意味ベースのKPIを設定したことで、中長期的な目線での戦略が打てるように
  • =受注の背景には何があるのかを見つけて意味ある指標を設定する

  • ふまえて今回のテーマは

    • 意思決定のためのデータ活用手順
    • 具体的なスキルとその身につけ方

意思決定のためのデータ活用手順

f:id:shidm00:20191122114032j:plain

  • データ活用に最も大切なテーマ
    • データというコミュニケーション言語をつかって、解くべき「課題」をチームで合意する
      • 事業インパクト
      • 解決コスト
      • 戦略の方向性
      • 部門ごとの視点
      • 組織のcapability

指標が相手や営業に刺さらない場合はだいたい「課題の設定」がずれている
そのためにPMとしては
解くべき「課題」を決めるための合意形成プロセスに責任をもち、
議論が進むための素材を準備する

  • おすすめのデータ活用モデル
    • OODAループ
      • Observe 見る
      • Orient わかる
      • Decide きめる
      • Act うごく
    • PDCAだとPlanが先にくるが、Planを立てるということは難しいこと
    • なので、まずは観察することから始める
    • 先の読めない、リーンな開発には特に合う

f:id:shidm00:20191122114102j:plain

Observe(見る)
  • 現場感覚(インタビュー) と 生データ
  • ユーザー(顧客)と接点ある人達から課題感を聞いて整理
  • 現場のモヤモヤはだいたい正しい
  • モヤモヤ会議で課題を集めてみる

代案のない提案をするなとか代案出さずに不満だけ言うななどと言われがちだが、モヤモヤにある課題が何なのかの見極めも、その解決も難易度はとても高い
代案が出せない場合ずっとももやもやを抱えている状態が続くことになる
なのでまずは現場のモヤモヤを吸い上げて整理するのが大事
モヤモヤ集めで課題認識が擦り合うだけで、現場の協力が得られるようになり、その後の議論がスムーズになるケースもある

  • 生データを見てみる
    • 分析手法をつかってかっこよく鮮やかな正解を出す…とかいうよりも、とにかく生データを見ること
    • エクセルでの数値管理はつまりサマリなので、生データからあたってみるだけでもかなり違う
Orient(分かる)
  • モデル化
    • 現実の見方や捉え方を言語化、可視化してKPIツリーに紐付けること

KPIツリーに出てきにくいが「スピード」が重要な指標となることは多い(例えばマッチング後の面接設定メールなど)
スピードを加味したモデル作りをする

  • 総数問題のモデル化
    • 一般的に「総数」が増えると「次のファネルへの移行期待値」が上がるが、閾値がある
      • 増やせば増える、には限界がある
    • 適切なところを指標に設定する必要がある

f:id:shidm00:20191122114121j:plain

  • 総数問題に関連して…
  • 冒頭ちらっと出したユーザーへのメール爆打ち問題のモデル化

    • それが起きやすいのは、送れば送るほどKPIツリーの数字が増えるモデルにしているから
    • そういう状態にしないために、KPIの中にネガティブ要素を含める必要がある
    • 例えば、数打ちすぎると退会率があがる、開封率が下がるなどが考えられるので、退会率や開封率も組み合わせるなど
    • トータルの売上を意識している人と同じ言語でデータで語る必要がある
  • 細分化の罠

    • 細かいパターン分類に走っても、打ち手を細かく打つコストが高いことが多い
    • KPIツリーのマクロデータのみで思考すると起こりがち
Decide(きめる)
  • マクロで見たときの施策インパクトは常に確認する
    • PMが「やりたい」ことが、案外マクロでみたらインパクトが小さいことは少なくない
    • 率改善が売上にどうインパクトするのかという視点を常に持つ
  • 比較

    • 比較がないと良い悪いの判断ができないが、比較するものによって見える結論は変わることを自覚する必要がある
  • WEBサービスの外のモデルが大切なこともあって見落としやすい

    • WEBサービスのことばかり見ていて、一連の作業の流れなど大きなところをみることを忘れると見落としが発生しがち
    • ユーザーの行動全体をみる
  • その他気をつけること

    • 普段会議にいないキーマンの観点を考慮できていないと意思決定できないこともあるので注意
    • 常に視座を高く持っておくことが大切
まとめ
  • チームでデータを扱いながらOODAループを回すことで、事業クリティカルな課題を1つずつクリアしていく
    • OODAループ
      • Observe 見る
      • Orient わかる
      • Decide きめる
      • Act うごく

具体的なスキルとその身につけ方

たくさん覚えるのではなく、必要最低限で生き延びること
=サバイバル

データ活用のために押さえること

WebサービスのPMであればまずはSQLを覚えるべし

  • 実践がないと頑張れないので、準備より本番
    • データ定例を作って関係者を週次であつめる
    • もやもやを話してもらって宿題化する
    • 宿題を解くことで力をつけていく
  • 試行錯誤しやすい環境を構築することも必要

  • 概念的に理解すべきポイント

    • データをDatabaseとして「テーブル」の概念で扱えるかどうかは大きな分岐点
    • 人間が読むことではなく、システムが読める形で扱う
  • おすすめのSQL修業ステップ

    • ちゃんとした人(エンジニア、データサイエンティスト)が書いたクエリを読み込み、一部だけいじって出してみる
    • 自分で簡単な文法で書いて抽出したものを、BIツール等外で加工して利用
    • WINDOW関数やサブクエリ等、ある程度複雑なものもSQLで表現
  • DBのテーブルにどんなデータが入っているのかを読みとけるようになると自走力は上がる
分析手法として 何をしっておくと良いのか

分析はrawdataの意味を取りやすくしたもの

  • rawdata

    • 量が多い
    • 全体の意味が読み取りづらい
    • 予算のモデルにしづらい
  • 統計処理

    • 全体の意味を読みやすく集計しているにすぎない
    • データ全体を一言で表現;代表値(平均値、中央値)
    • まとまったパターンに集約:クラスタリング
    • 可視化:各種グラフ
  • 分析手法:分布

    • 平均値より中央値
    • でも意味を考えるならまずは「分布」を眺めたほうがいい
  • クラスタリング

    • タイプごとの中央値みたいなイメージ
    • 共有するときには、データの裏付けを元に「意味」ベースでラベリングすると議論しやすい

まとめ

とにかくやり続けられる環境を作ることが大事
やり続ければいつかスキルは上がる

データ抽出スキルがあることで世界は広がる
Web業界であればまずはSQLを学ぶこと

生情報(インタビュー、rawdata)を元に事象をモデル化して、チームでOODAループを回す

カンファレンス全体通しての感想

  • 会社の状況や文化、事業の内容、一緒に仕事をする人やチームの体制によってPMがやらなければならないことにはかなり差がある
  • 共通しているのは『担当プロダクトの価値を上げること』がミッションで、そのためにできることは何でもするという点(解像度低め)
  • 一般的に定義されているPMの役割について知っておくのは、考える糸口として必要
  • ただ、それにむりやり当てはめるとうまく行かない場合が多そう
  • たくさんの事例を知っておくのは臨機応変な対応をする上で重要

初参加でしたが、普段知ることができないたくさんの企業の様々な事例とその対応を知ることができ、大変有意義な勉強をさせて頂きました。

LEGOブロックで スクラム入門勉強会

10月25日(金)にワイクル株式会社の角 征典様( @kdmsnr )をお招きし、LEGOブロックでスクラム入門の勉強会を行いました。
弊社ではスクラム開発しているプロダクトとそうでいないプロダクト双方あり、私が担当しているプロダクトではスクラムを導入していなかったため、いろいろ発見のある勉強会でした。

第1部:スクラムの歴史〜基礎の説明

第1部ではアジャイル開発の歴史から始まり、現在の複雑化したシステム開発の実態、スクラム開発とはどういったものなのか、わかり易く説明がありました。
その中でアジャイルとは傘に喩えられるように骨組みであり、特に中身は無いものであると言うこと。それを補完すために様々な開発手法が存在し、スクラムもその中の一種であると説明がありました。
また、スクラムをすることでチーム内の知識・経験を蓄積することができ、より強固なチームへ進化させていくものだということがわかりました。

第2部:LEGOで街づくりをしながらスクラム体験

座学終了後、レゴを使用してのスクラム開発の体験です!
この勉強会では開発側・顧客側を体験できるように設計してあるため、自分たちが設計した街を他チームが、他チームが設計した街を自分たちが作っていきます。

まず各チームが家族という設定で欲しい建造物をカードに書き出していき、模造紙を使い理想の街の設計図を作っていきます。
設計図作りが終わったらカード毎に優先度をつけて並び替えていきます。その後、開発者として他のチームへ移動します。

f:id:a-hiro35:20191031172047j:plain
私達チームの街は商店街は駅近に、公共施設は自然の近くに配置しました。

f:id:a-hiro35:20191031172015j:plain
他のチームのイラストレベルが高すぎてびっくりしたり。。。

移動したら、他チームの設計図を元に、①見積もり、②スプリント、③レビュー・振返りを繰りを繰り返して街を完成させていきます。

まずはプランニングポーカーでざっくりと工数見積もりをします。見積もる際に出てきた疑問点は相手チームのプロダクトオーナーに相談して進めていきます。
その後、3回のスプリントで全てを完成できるように、Velocityを算出。
予想値ピッタリになるように、プロダクトバックログの上から順番に実現できそうなころまでストーリーを引き、開発していきます。

1回目のスプリントでは顧客の要望をきちんと把握できておらず、顧客の望む通りの建物をうまく作り上げることができない人が出てきました(私です)。
その結果、Velocityの予想値をかなり下回り、不本意な結果に終わってしまいました。

2回目のスプリントでは1回目の振り返りを基に再見積もりをし、新たにVelocityを設定していきます。
前回の反省を踏まえ、工数が大きなものは複数人で開発するように変更しました。

f:id:a-hiro35:20191031171729j:plain

前回中途半端に終ってしまったモノは顧客が求める建物としての要素を追加していき、また工数が大きいモノも複数人で開発することで時間内に完成することができました。
顧客レビューでは全ての建物に対して合格をいただき、予想値通りの開発をおこなうことができました。

f:id:a-hiro35:20191031172115j:plain

f:id:a-hiro35:20191031171817j:plain
最後に、チームで作成した傑作の油田です。

まとめ

勉強会を終えて、1回目ではバラバラだったチームに一体感が生まれるのを感じ、開発スピードも上がっているのを実感することができました。
また、顧客の要望を適切に理解する必要性、どう叶えるかをチームで考えることで一体感が生まれたのを感じました。
メリットを多く感じたので、自分のチームでもスクラム開発をしたい!と思える会でした!

Docker + MeCab + JupyterLabによる分析環境の構築

こんにちは、分析チームの門脇です。

日頃クリエイターに関するデータ分析業務を行う際、環境ごとのライブラリの管理が面倒だったり、形態素解析エンジンの導入、notebookの設定をやり直す必要があるなど何かと不便でした。

そこで今回は、Dockerを利用して、簡単にクリエイター分析環境を構築してみました。

Dockerについて

Dockerはコンテナ型の仮想化環境のことで、Dockerfileに仮想環境に取り入れたいものの処理を記述することで、簡単に同一環境を再現でき、環境ごとに設定をやり直さなくて済むといったメリットがあります。

Dockerによる環境構築ついて詳しく知りたい方はこちらにわかりやすくまとめられています。

今回は記事の中でも紹介されているKaggleが提供しているDockerイメージをベースにDokerfileを作成していきます。

MeCabについて

クリエイターについて分析を行う際に、テキストデータを単語ごとに分割して関連ワードを取得したいことがあります。

MeCabは日本語の形態素解析エンジンの中では最もよく使用されていて、mecab-ipadic-NEologdというシステム辞書があり、新語・固有表現に強い単語を分割する際に有効です。

例として、『 ブンブンハローYouTube、どうもヒカキンです!』を調べてみます。

  • MeCab標準辞書のとき f:id:guajfv:20191017141259p:plain

『ブンブンハローYouTube』について

  • ブンブン
  • ハロー
  • YouTube

それぞれ別の単語として認識されてしまいます。

  • mecab-ipadic-NEologdのとき f:id:guajfv:20191017141223p:plain

『ブンブンハローYouTube』として固有名詞として分割でき、『ヒカキン』も固有名詞として認識されます。

日々新しい用語が生まれるYouTubeにおいて、mecab-ipadic-NEologdを使うことで、簡単に対応することができます。

JupyterLabについて

みんな大好き『Jupyter notebook』の後継機のIDEで、オープンソースとして公開されています。

『Jupyter notebook』をより使いやすくしたものであり、こちらで便利機能が詳しく紹介されています。また、自分好みに拡張機能を追加することができ、作業効率を上げることができます。実際にDockerfileへ拡張機能の導入を取り入れてみました。

作成したDockerfile + docker-compose.yml

Dockerfile

# Kaggleが提供しているDockerイメージをベース
FROM gcr.io/kaggle-images/python:v67


RUN pip install -U pip && \
    pip install fastprogress japanize-matplotlib

# mecabとmecab-ipadic-NEologdの導入
RUN apt-get update \
    && apt-get install -y mecab \
    && apt-get install -y libmecab-dev \
    && apt-get install -y mecab-ipadic-utf8 \
    && apt-get install -y git \
    && apt-get install -y make \
    && apt-get install -y curl \
    && apt-get install -y xz-utils \
    && apt-get install -y file \
    && apt-get install -y sudo


RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git \
    && cd mecab-ipadic-neologd \
    && bin/install-mecab-ipadic-neologd -n -y

RUN pip install mecab-python3

# nodejsの導入
RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - \
    && sudo apt-get install -y nodejs

## JupyterLabの拡張機能

# 変数や行列の中身を確認
RUN jupyter labextension install @lckr/jupyterlab_variableinspector

# 自動整形
RUN pip install autopep8 \
    && pip install jupyterlab_code_formatter \
    && jupyter labextension install @ryantam626/jupyterlab_code_formatter \
    && jupyter serverextension enable --py jupyterlab_code_formatter
  • Kaggleが提供しているDockerイメージは最新のものを指定しています。(2019/10/17時点)
    また、こちらから適宜最新のイメージを確認していただければと思います。

  • mecab-ipadic-NEologdのインストールはこちらに記載されているライブラリを入れます。また、PythonからMeCabを使用するために mecab-python3もインストールします。

  • JupyterLabの拡張機能の利用についてはNode.jsが必要となるのでインストールします。また、今回は個人的に便利だと思ったものを拡張機能としてインストールしています。

docker-compose.yml

version: "3"
services:
  jupyterlab:
    build: .
    volumes:
      - $PWD:/content
    working_dir: /content
    ports:
      - 8888:8888
    command: jupyter lab --ip=0.0.0.0 --allow-root --no-browser

ここでは、コンテナ起動時にjupyter labが起動するよう設定しています。

下記コマンドで、コンテナを作成して、起動します。--buildを指定することで事前にイメージを作成してくれます。

$ docker-compose up --build

するとコンソール上に結果が表示されます。

jupyterlab_1  |     Copy/paste this URL into your browser when you connect for the first time,
jupyterlab_1  |     to login with a token:
jupyterlab_1  |         http://7147a0639219:8888/?token=××××××××××××××

あとはホスト名をlocalhostにして、ブラウザでログインするだけです。

  • MeCabをPythonで使うとき
    • 辞書のインストール先はJupyterLab上で下記コマンドにより確認できます。
      !echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
    • 今回は、/usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologdにインストールされたことが確認できたのでコードを書く際は、インストール先を指定します。
import MeCab

tagger = MeCab.Tagger(
    '-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd'
)
print(tagger.parse('ブンブンハローYouTube、どうもヒカキンです!'))

すると、先ほど示した例のようなmecab-ipadic-NEologdを使用したときの結果が出力されます。

まとめ

Dockerを利用することで自分好みの分析環境をサクッと作れちゃいます。環境構築という煩わしいことに時間をかけずに分析に集中できるのでとってもオススメです!

みなさんも自分好みの環境を作成してみてはいかがでしょうか!!!

参考文献

UUUM System Meetup #1

f:id:chibiProgrammer:20190919015916j:plain こんにちは、エンジニアの中村です。

9月6日にUUUM System Meet Upを開催したので、 その様子を書いてみました。

uuum.connpass.com

今回は約30人以上もの人がイベントに参加してくださいました。

攻殻機動隊の初イベントにも関わらず

たくさん集まってくださって嬉しかったです!

今回のイベントは、UUUMを支えるテクノロジーや

普段から学んでいることをアウトプットし、

社内外の技術者たちと交流を深めたい!という目的の元開催いたしました。

イベントの発表内容はこんな感じです。 今回は発表者を何人かピックアップしてご紹介したいと思います。

発表内容

発表者 役職 タイトル
nakatsuka_d マネージャー UUUM満開~なんで私が登壇に!?~
myaunraitau エンジニア プラットフォームのデータを解析するお話
sabomasa エンジニア 再生回数のデータを予測するお話
btomasato CTO ぼくのかんがえたさいきょうの GAS かいはつかんきょう
killyishuguro PM デザイン思考と初心者PM
MaxYasuda エンジニア インフラ勉強初めて1ヶ月なのでECS FARGATEでrails構築した

まず最初はnakatsuka_dさんの「UUUM満開~なんで私が登壇に!?~ 」

f:id:chibiProgrammer:20190917193124j:plain
UUUM満開~なんで私が登壇に!?~

オタサーの姫を作ると営業と仲良くなれるという話や、UUUMのことを面白おかしく紹介してくださったりと、会場もとても盛り上がりました。

次はmyaunraitauさんの「プラットフォームのデータを解析するお話」

f:id:chibiProgrammer:20190918112052j:plain
プラットフォームのデータを解析するお話

機械学習を用いてクリエイター間の類似度算出を行うという発表でした。

機械学習をあまり知らない私でも雰囲気を掴めるようなわかりやすいスライドで、機械学習って色んなことに使えるんだなぁという気付きにもなり、とても楽しかったです。

次はsabomasaさんの「再生回数のデータを予測するお話」

f:id:chibiProgrammer:20190918112048j:plain
再生回数のデータを予測するお話

sabomasaさんもmyaunraitauさんに続いて、機械学習を用いたデータ解析の発表でした。

内容は機械学習を用いてYouTubeの再生回数を予測するという感じでした。 再生回数を予測することが出来るなんてびっくりしたし、機械学習やってみたくなりました笑

次に我らがCTO、BTOさんの「ぼくのかんがえたさいきょうの GAS かいはつかんきょう」

f:id:chibiProgrammer:20190919013324j:plain
ぼくのかんがえたさいきょうの GAS かいはつかんきょう

今UUUMに入って業務改善でGASを使っていますが、いつも自分がやっていることよりもっと踏み込んだ話で 私もGASマスターしたいと切実に思いました!

懇談会はピザを囲んでわいわい技術の話などで盛り上がりました。 UUUM以外のエンジニアやPM、デザイナーの方とお話ができて本当に楽しかったです。

f:id:chibiProgrammer:20190919014511j:plain
懇談会の様子

f:id:chibiProgrammer:20190917192721j:plain
全体写真

とても楽しいイベントとなり、本当に良かったです。 イベントに参加して下さった皆様本当にありがとうございました!

第2回も12月頃に行いますので、是非遊びにきてください!