アンケートの集計システムを作った

 アンケートの集計システムを作った

M3 Tech Meetup #5

De059f612e2f68589831e4bde0f15c83?s=128

Jumpei Takiyasu

December 06, 2018
Tweet

Transcript

  1. アンケート集計システム をつくった Jumpei Takiyasu @juntaki M3, Inc. 2018-12-06 M3 Tech

    Meetup #5
  2. name <- "Jumpei Takiyasu" company <- "M3, Inc." web <-

    "https://juntaki.com" Me
  3. 今日話すこと 1. エムスリーのアンケートシステム 2. 集計システムのデータ構造 3. 集計システムの要件 4. Go/GAEのアーキテクチャ 5.

    要素技術
  4. エムスリーの アンケートシステム

  5. Webリサーチのビジネス オーダーメイドのアンケートでは、作成・集計ともに個別対応が必要

  6. アンケート作成システム アンケートを「作る」プロセスは、柔軟性が高く効率的

  7. 集計システム   2018年10月リリース  

  8. データ構造の整理

  9. アンケート設問の種類 # 種類 アンケート用語でいうと 1 プルダウン SA (Single Answer) 2

    ラジオ SA (Single Answer) 3 チェックボックス MA (Multiple Answer) 4 数値入力 数値回答 (FAの一種) 5 テキスト入力 FA (Free Answer) # 形式 1 単一設問 2 マトリクス設問 5 × 2 = 10通りのパターンがある! こんなかんじ
  10. 設問の種類…多すぎ…? Booleanマトリクスと、数値マトリクスだけと考えることができる # 種類 整理すると・・ 1 プルダウン Booleanの配列 2 ラジオ

    3 チェックボックス 4 数値入力 数値の配列 5 テキスト入力 集計対象外(生データには必要) # 形式 1 単一設問 要素数1のマトリクス設問 2 マトリクス設問 ←
  11. 整理されたアンケートの生データ構造 深い階層構造になる アンケート 設問 マトリクス行 選択肢 回答 最終出力時以外いらない 回答数に比例して大きくなる 全部マトリクスにしたので、

    階層の深さは一致する Q1 Q1__1_1 Q1__1 設問定義 回答 アンケート
  12. 整理された最終出力の集計データ構造 いくつかの集計表のカタマリが出力 全設問の集計表一覧 設問ごとの集計表群 集計表(合計、回答者数、割合・・) 集計軸ごとの集計値 集計対象の選択肢

  13. 集計ツールのInput/Output 集計 ツール アンケート 設問A マトリクス行 選択肢 回答 設問B マトリクス行

    マトリクス行 選択肢 選択肢 選択肢 選択肢 選択肢 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 true/false/数値 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 true/false/数値 Q1集計表(SA) Q2集計表(マトリクスSA) アンケートABC (集計軸:Q10, Q11, Q12) Q3 ….
  14. 要件の洗い出し

  15. 分析の作業は2フェーズに分割できる 加工:「設問 × 回答者のデータ」を編集する 集計:「集計値のデータ」を集計条件設定により計算する

  16. 「加工」で主にやりたいこと 新しい設問を計算によって作り出す アンケート 設問A マトリクス行 選択肢 回答 設問B マトリクス行 マトリクス行

    選択肢 選択肢 選択肢 選択肢 選択肢 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 true/false/数値 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 回答 回答 回答 回答 回答 回答 回答 医師ごとの回答 true/false/数値 設問Aと設問Bの合成 (単一設問として) Aの選択肢1を選んだ かつ Bの選択肢1を選んだ Aの選択肢2を選んだ かつ Bの選択肢3を選んだ 医師ごとの回答は ←から計算できる 医師ごとの回答は ←から計算できる 例: • 男性かつ30代 • 関東(東京、埼玉…) • 患者数n人以上
  17. 「加工」の実現方針 • 基本操作を網羅し、組み合わせによって複雑な操作を可能にする • 頻出操作を関数化する(+ その基盤づくり) 論理演算 四則演算 MA選択数カウント SAの数値マッピング

    カテゴリ化 Boolean 数値
  18. 「集計」でやりたいこと 基本的には、クロス集計ができればOK 軸0個(=単純集計) 〜 軸3個の三重クロス集計まで対応 軸となる設問B 集計対象 の設問A 選択肢3 選択肢2

    集計値 B-3を選んだ人の、A-2 の… • 回答の合計値 • 回答の平均 • 回答者数 …などなど
  19. 「集計」のケースごとの要件と実現方法 設問の形式・内容によって、整理したい観点が異なる。たとえば・・ シェア計算をしたい   回答が、とある数を母数としたときに何%にあたるか   例:薬品の処方数/患者数、回答結果/回答者数 TOP-nを出したい   例:「そう思う」、「ややそう思う」の合計を知りたい → 集計表全体の設定と、表ごとの設定として整理

  20. アーキテクチャ

  21. システム構成 エムスリー初の Goプロダクト! (GAEも初) フロントエンドまで 型がある

  22. データの流れ 加工 集計 アンケート 定義 計算式を追加 除外IDを設定 集計軸を設定 集計対象を設定 加工設定

    集計設定 #2 集計設定 #1 アンケート システム アンケート 回答 アンケート 回答 計算結果 納品用集計表 Readonlyなので 元データは壊れない
  23. Go API Architecture クリーンアーキテクチャ的な考え方で依存方向を厳密に決めた 実装変更の影響範囲が明確になる:  途中で、MySQL→Datastoreに移行した  →インターン生の課題として数日で実装完了 パッケージの循環参照はおきない 詳しくは、”Layered architecture

    Go API implementation”参照 http://s.juntaki.com/WtS
  24. 要素技術

  25. 「加工」はこんな感じになった 1つの選択肢を1変数として、DSLで数式をかけるようにした ※これはWebアプリの画面です

  26. 計算結果を透過的に変数として扱う 再帰的に値を取得して計算(循環参照は回数制限で回避) 設問定義 RawData RawDataへの参照 DSL 式 変数名からデータ構 造のひきあて 再帰的に値を取得し

    てDSLを計算
  27. DSLの実装 - Knetic/govaluate 当初、文字列をGoとしてtypes.Eval()する方法を検討した →ファイルに書き出さずにメモリ上で関数の定義をするのは難しそう 独自でパーサまで実装しているKnetic/govaluateを利用 • 四則演算、論理演算、関数定義はOK • 変数もfloat64,

    boolがつかえる 関数は可変長のinterface{}しか受け取れない制限がある →Goで同等の関数を書いて、ラップする(型チェックは自前) バリデーションは ホワイトリスト的に やってます
  28. 「集計」はこんなかんじ Webでサクッとプレビューできて、Excelファイルとしてダウンロード

  29. 「集計」はこんなかんじ 表ごとの設定は個別入力できる

  30. Excelの出力 - 360EntSecGroup-Skylar/excelize 薄くラップしてエムスリー仕様を実現: • 色、幅、フォント、数字の書式など細かい指定がある(納品物なので) • 内部むけのIDなどは、納品に入れたくないが、確認用に出したい、など

  31. Golden file testing + データ自動生成 juntaki/fix https://github.com/juntaki/fix 前と変わってない、ということだけを確認するテスト。初回確認は画面でやる

  32. Golden file testingを使ったテストの雰囲気 アンケートシステム バックエンドAPI go-vcr テスト対象: Application層 のハンドラ インテグレーションテ

    スト RequestのObjectは人手で作る 外部APIの Response YAMLファイル juntaki/fix.Fix() 集計システムAPI のResponse バイナリ/JSON ハンドラへのインプットを作るだけでテストが量産できます リグレッションテストとしてはコスパ高い! ※網羅性などをきちんと考えた、他のユニットテストとの併用がおすすめ
  33. まとめ 設計・開発期間: 2018/4月 - 10月 GAEでインフラ構築はかんたん、序盤からデモしやすい TypeScript + protobuf +

    Goで一貫した型がある おすすめ構成です
  34. Thank you! Jumpei Takiyasu @juntaki M3, Inc. https://juntaki.com