KPIを設定する際に参考にした情報まとめ
某WebサービスのKPIについて議論する機会があったので、その際に得た知識を簡単にまとめておきます。
KPIとは?
KPIと似た用語にKGIという用語がある。両者の違いを理解しておくといろいろ捗る。
KPI: Key Performance Indicator(重要業績評価指標)
目標の達成度合いを計る定量的な指標のこと。目標に向かって日々業務を進めていくにあたり、「何を持って進捗とするのか」を定義するために設定される尺度で、現況を指し示す様々な指標の中から、進捗を表現するのに最も適していると思われるものが選択される。KPIは継続的に測定・監視され、その向上のために日々の活動の改善が行われる。達成すべき目標を定量的な指標で表現したものはKGI(Key Goal Indicator)と呼ばれる。
refs: http://e-words.jp/w/KPI.html
KGI: Key Goal Indicator(重要目標達成指標)
組織やプロジェクトが達成すべき目標を定量的な指標で表したもの。抽象的な理念や目的のようなものではなく、「いつ、どの指標がどのレベルに到達したら目標達成とみなすのか」を定義したもの(例:3年後に売上高を10億円以上にする)で、その際に選択された指標自体(例:売上高)のことをKGIと呼ぶ場合もある。日々の進捗を計る指標としてKPI(Key Performance Indicator)が併用されることが多い。
refs: http://e-words.jp/w/KGI.html
優れたKPIの特徴
- 出来る限り大局的トレンドを良く反映する指標であること
基本的に、何かしらの組織の経営状態であったり経営に関連する指標というのは、もっともっと大局的なトレンドを描いてゆらぐものです。にもかかわらず、毎日グニャグニャせわしくなく上下動する数値をKPIとして選ぶのは、センスがないと言われても仕方ないんじゃないでしょうか?
- 「どうすれば施策で改善or介入できるか分かる」指標であること
Web系サービスのKPIを考える際には"actionability"(行動可能性)と同時に"controlability"(コントロール可能性)を重視するようにしています。
refs: 「Web系サービス運営でKPIを決める時に気を付けるべき3つのポイント」
- 理解しやすいこと
- 比較できること
- 比率や割合であること
- 行動を変えてくれること
refs: 『Lean Analytics』
KPIを設定するための手順
目標(KGI)を明確にする
- 「指標」、「値」、「期間」を明確にする
ビジネスロードマップに図示する
- 「ビジネスロードマップ」とは売上が発生するまでのプロセスを図式化したもの
数値を明らかにする
- ビジネスロードマップに値を記入する
- 取得できていない部分を明確にする
改善ポイントを選定する
- 「規模」、「改善施策の実現度」、「期待効果」の3つの条件で優先順位をつける
目標値を設定する
- 指標は目標値と合わさって初めて「KPI」と言える
- 選んだ指標数「n」に対して、「n-1」の指標を
1/n-1
改善した場合にビジネス目標が達成できる値を設定する1/n-1
とする理由は、施策を実施しても思った通りに改善しなかったり、1つの改善が他の指標を下げてしまうなどのリスクを回避するため
方針をまとめる
- 状態目標を設定する
- 現状を目標を設定した月で、サイトやビジネスがどのように変わっているかを言語化する
- 新たにどのような価値をユーザーに提供しているかなど
- 課題の洗い出し
- 成立条件を定義する
- 状態目標を設定する
refs: 『現場のプロがやさしく書いたWebサイトの分析・改善の教科書』
KPIはいくつ設定すべきか?
いくつか説があるみたいです。どの説にせよ共通していることは、あまりKPIの種類を増やしすぎず、定期的に棚卸しすることが重要であるという点です。
7つまでにすべき
認知心理学の古典的な学説として「Millerの7±2チャンク」というものがあります。要は「人間は一度に7±2個のものまでしか同時に処理できない」という説なんですが、なかなかに説得力があると思います。これに倣って、例えば「KPIは7個まで」とか決めた方が良いかもしれないですね。
refs: 「Web系サービス運営でKPIを決める時に気を付けるべき3つのポイント」
1つだけ設定すべき
スタートアップの成功の鍵は、本当の意味でフォーカスすること、それを持続させるための規律を持つことだ。フォーカスしていないのに成功したとすれば、それは単なる偶然にすぎない。あてもなくさまよい、膨大な時間をムダにして、苦痛や徒労を経験した末の成功だ。... リーンスタートアップの本質は、正しいことに、正しいときに、正しい考え方でフォーカスすることに他ならない。... アナリティクスとデータの世界では、ステップごとに重要な指標をひとつだけ選んでフォーカスする。ぼくたちはこれを「最重要指標(OMTM)」と呼んでいる。
refs: 『Lean Analytics』
その他参考になった情報源
- 「DAUを評価指標から捨てた会社の話」
- 「「毎日の数字を追いかけ、毎日改善する」ことの意外な落とし穴」
- 「「施策を打ったらKPIが上がった!」だけで満足するのは危険」
- 「[分析手法]「サイト基本分析シート」を作ってみた!」
- 「[分析手法]ソシャゲ分析講座 基本編(その2):「DAU」を理解する」
Lean Analytics ―スタートアップのためのデータ解析と活用法 (THE LEAN SERIES)
- 作者: アリステア・クロール,ベンジャミン・ヨスコビッツ,林千晶,エリック・リース,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/01/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
現場のプロがやさしく書いたWebサイトの分析・改善の教科書 ~Googleアナリティクスと、その他ツールを使った実践的ノウハウ~
- 作者: 小川卓
- 出版社/メーカー: マイナビ
- 発売日: 2014/08/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
Railsに初コントリビュート決めた
Rails の`datetime_select`でつくるセレクトボックスを「年」「月」「日」「時」「分」で区切る
日付に関するセレクトボックスを「年」「月」「日」のように日本語で区切りたいことってよくありますよね。
date
に関するセレクトボックスに関しては、 id:inouetakuya さんの「Rails の date_select でつくるセレクトボックスを「年」「月」「日」で区切る」という記事のお陰でそれを実現することができます。
上記記事の方法を少し発展させれば、datetime
に関するセレクトボックスも「年」「月」「日」「時」「分」等で区切ることが可能になるので、やり方をメモしておく。
基本方針は全く同じです。datetime_separator
を使って、
!= sprintf(f.datetime_select(:birth_date, use_month_numbers: true, date_separator: '%s', datetime_separator: '%s'), '年', '月', '日')
もしくは、time_separator
も組み合わせれば、
!= sprintf(f.datetime_select(:created_at, use_month_numbers: true, date_separator: '%s', datetime_separator: '%s', time_separator: '%s'), '年', '月', '日', '時') + '分'
ハックっぽいやり方なので、用法用量を(ry
「Lean Analytics」原著買ったのに和訳版が発売されることになってツラいので、ここまで読んだことをまとめておく
はじめに
「Lean Analytics」に関しては、 yuku_t さんが 「全てのスタートアップ関係者が読むべき良書」という記事で大変わかりやくすまとめてくださいっています。この記事にどこを読めばいいかが書かれているので、それを参考に読み進めるとよいと思います。
また、翻訳者である角征典さんのスライドもslideshareに上がっていて、大変参考になります。
監視しては行けない8つの虚栄の指標
自分たちの今後のアクションには繋がらない自己満足に浸るだけの指標は、取得しても価値はないとして、本書ではバッサリと切り捨てている。 今後のアクションには繋がらない虚栄の指標として、下記の8つの指標を挙げている。
- ヒット数
- PV数
- 広告などのPVに依存したビジネスモデルでなければ、大した意味は無い
- 訪問者数
- 1人のユーザーが100回訪問したのか、100人のユーザーが1回ずつ訪問したのかわからない
- ユニークビジター数
- 回遊したのか、離脱したのかなど、ユーザーが何をしたのかについて何もわからない
- フォロワー数/フレンド数/like数
- 人気コンテスト以上の何者でもない
- 平均滞在時間
- 実際に使われているのかどうかわからない。サポートや苦情のページに多くの時間を過ごしている場合は悪いことだ
- 集めたメールアドレス数
- ダウンロード数
- アクティベーションやアカウント作成などを計測すべき
弊社では「PV」という指標を重要視しすぎているように感じていて、前々から何となくモヤモヤしていたのですが、この辺りに書かれていることを読んでなるほどと思った。
Model One: E-commerce
Lean Analyticsに挙げられる6つのビジネスモデルの中で、例えば「Model One: E-commerce」が弊社のビジネスモデルに近そうだったので読んでみた。 (Model Six: Two-Sided Marketplaces も近いかも)
What Mode of E-commerce Are You?
- annual repurchase rateを知り、自分のビジネスがどのモードかを知る必要がある
- 昨年からの継続ユーザーが40%以下の”Acquisition mode"かなあ
Acquisition mode
- 昨年の購入者の中で今年も購入に至るのは40%以下
- 新規獲得に注力しなさい
- マーケティング戦略の例として、1人のユーザーに複数のメガネを買わせるのではなく、次の顧客にオススメするように促す
- Acquisition modeである場合は、サービスや品物を向上も大切だが、最も注力すべきゴールはいつも新規顧客の獲得である
Hybrid mode
- 昨年の購入者の中で今年も購入に至るのは40-60%以下
Loyality mode
- 昨年の購入者の中で今年も購入に至るのは60%以上
A Practical Example
追いかけるべきkey metrics:
- Conversion rate
- the percentage of visitors to your site who buy something
- 様々な切り口でコンバージョンレートを測定でき、何が購買に繋がっているかが分かる
- 初期のゴールは誰かが何かを購入することを実証することなので、サービス初期ではトータル売上よりコンバージョンレートの方が重要である
- コンバージョンレートに集中しすぎることにはリスクもある
- コンバージョンレートはeコマースビジネスのタイプに強く依存する
- Purchases per year
- Average shopping cart size
- Abandonment
- コンバージョンレートの反対
- Cost of customer acquisition
- Revenue per customer
- Top keywords driving traffic to the site
- Top search terms
- 売上に結びつくものとつかないものの両方
- 検索エンジンやサイト内でのどのキーワードが売上に結びついているか
- Effectiveness of recommendation engines
- Virility
- Word of month, や訪問者毎のシェア率
- Mailing list effectiveness
- CTRや購入者が戻ってきて購入に至る能力
Lean Analytics ―スタートアップのためのデータ解析と活用法 (THE LEAN SERIES)
- 作者: アリステア・クロール,ベンジャミン・ヨスコビッツ,林千晶,エリック・リース,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/01/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
ドリップコーヒー遍歴
yaotti さんの「ドリップコーヒー環境 2015年1月」というエントリに感銘を受けたので、自分のドリップコーヒー環境についても書いてみた。
自宅で美味しいコーヒーが飲みたい
ということで、Amazonで安くてそこそこ評価の良い下記の商品を購入した。
Melitta セレクトグラインド MJ-518 (ブラック)
- 出版社/メーカー: Melitta (メリタ)
- メディア: ホーム&キッチン
- 購入: 3人 クリック: 64回
- この商品を含むブログ (14件) を見る
- 出版社/メーカー: 象印(ZOJIRUSHI)
- 発売日: 2014/09/01
- メディア: ホーム&キッチン
- この商品を含むブログを見る
豆は近所のカルディで購入することもあれば、ROASTER CAFE ぷらす90℃ や 珈琲散歩 などの自家焙煎をしているお店に足を運び調達したりもした。 Amazonで下記の豆などを試した時期もあった。
スターバックス コーヒー豆 ハウスブレンド907g 緑 レギュラーコーヒー
- 出版社/メーカー: スターバックス
- メディア: その他
- 購入: 1人 クリック: 3回
- この商品を含むブログを見る
しかし、上記の手法には欠点があった。
当たり前だが、とにかく面倒臭い。豆を挽くのが面倒臭い。豆の計量が面倒臭い。ガラスポットやミルを洗浄するのが面倒臭い。
美味しいコーヒーを飲むための儀式は、初めは楽しく感じられたが、それを定常作業として日々運用することは自分にはあまりにも面倒臭すぎた。
そこで次の手法を試みることにした。
自動化期
Panasonic 沸騰浄水コーヒーメーカー ブラック NC-A56-K
- 出版社/メーカー: パナソニック(Panasonic)
- 発売日: 2014/10/20
- メディア: ホーム&キッチン
- この商品を含むブログ (1件) を見る
こいつはとにかく有能。豆の挽きからドリップ、ミルの洗浄まで「全自動」でやってくれる。
我々がやることは、ドリッパーやガラスポットの洗浄くらいだ。
しかし私の怠惰な心は、次第にそれすらも面倒臭いと感じるようになっていった。
番外編: バリスタ期
弊社オフィスでは、上司が私物のネスカフェ バリスタを設置しており、100円で1日飲み放題で使用させて頂いている。 こいつはあくまでもインスタントコーヒーなのだが、インスタントコーヒーをそのままお湯で溶かして飲むのと比較すると、2割増しくらいで美味しい。しかも洗浄などの手入れは、ほとんど不要である。
ネスカフェ ゴールドブレンド バリスタ ホワイト PM9631
- 出版社/メーカー: ネスレ日本
- メディア: ホーム&キッチン
- この商品を含むブログを見る
現在
上記の変遷から学ぶべき教訓は、私はとにかく面倒臭がり屋だということだ。日常飲むコーヒーは手間が掛からないことが重要である。 美味しいコーヒーが飲みたくなったら、金を払って美味しいコーヒー屋さんに飲みに行くのが性に合っている。
ということで、それなりに美味しく、かつメンテナンスがほとんど不要であるという理由から、現在は下記のドリップコーヒーを飲むという手法に落ち着いている。
AGF マキシム レギュラーコーヒー ドリップパック ちょっと贅沢な珈琲店 豊かなコクのスペシャルブレンド 100P
- 出版社/メーカー: AGF
- メディア: 食品&飲料
- 購入: 3人 クリック: 41回
- この商品を含むブログ (1件) を見る
Rails で`find_by_id`に渡す引数はString でもいけるんだって
# 普通のやつ User.find_by_id 1 => #<User id: 1, name: "yachibit", ...> # Stringを引数に渡すと... User.find_by_id '1' => #<User id: 1, name: "yachibit", ...> # このへんも同じく User.find '1' => #<User id: 1, name: "yachibit", ...>
SUGEEE!! つい最近知りました。
よくよく考えたらいつも使わせて頂いてたわけなんですが...
パラメーターで渡ってくる値はString なのでController でレコードを引くときに、いつもお世話になっています。
# params[:id] # => '1' User.find params[:id]
Rails さんは本当によく出来ているなあと、ただただ感嘆させられるばかりです。 パラメーターを渡すだけで、いい感じによろしくやってくれるあたりの仕事ぶりは、自分も見習わなければならないなと襟を正されます。
余談はさておき、
User.find "" User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 0 LIMIT 1
WHERE 'users'.'id' = 0
と言ってやがるということは、やはりRails は何処かでto_i
してるはずだ。ぜひとも、お目にかかりたと思い、Rails のコードを読み始めたのですがアレ?? 実際to_i
している箇所は見当たりませんでした(たぶん)。
どうやらActiveRecord::FinderMethods
のこの辺りが怪しそうですが。
うーん、ちょっとよくわからないです。
def find_with_ids(*ids) raise UnknownPrimaryKey.new(@klass) if primary_key.nil? expects_array = ids.first.kind_of?(Array) return ids.first if expects_array && ids.first.empty? ids = ids.flatten.compact.uniq case ids.size when 0 raise RecordNotFound, "Couldn't find #{@klass.name} without an ID" when 1 result = find_one(ids.first) expects_array ? [ result ] : result else find_some(ids) end end def find_one(id) if ActiveRecord::Base === id id = id.id ActiveSupport::Deprecation.warn "You are passing an instance of ActiveRecord::Base to `find`." \ "Please pass the id of the object by calling `.id`" end column = columns_hash[primary_key] substitute = connection.substitute_at(column, bind_values.length) relation = where(table[primary_key].eq(substitute)) relation.bind_values += [[column, id]] record = relation.take raise_record_not_found_exception!(id, 0, 1) unless record record end
落穂拾い
上に載せたfind_one
メソッドの冒頭。
if ActiveRecord::Base === id id = id.id ActiveSupport::Deprecation.warn "You are passing an instance of ActiveRecord::Base to `find`." \ "Please pass the id of the object by calling `.id`" end
はじめて読んだ時この部分がwhut? でした。id = id.id
とかちょっと何言ってるのかw
ですが、なるほどRails はどうも、こういう書き方もできるということなのです。
me = User.find_by_user_name! 'yachibit' User.find me
ただし、この書き方はdeprecated なので、
"Please pass the id of the object by calling .id"
という具合に怒られます。
Crafting Rails 4 Applications: Expert Practices for Everyday Rails Development (The Facets of Ruby)
- 作者: José Valim
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2014/02/04
- メディア: Kindle版
- この商品を含むブログを見る
RubyでHTTPリクエストを投げて返ってくるJSONをParseするとかいうよくあるやつ with Net::HTTP, open-uri
タイトル長えw
さて、HTTP リクエストするとJSON が返ってくるようなAPI でなんやかんや処理をすることが割りとよくあるのだが、すぐに忘れてしまうのでメモメモ。
https://api.example.com/smaple.json にHTTP GET リクエストを投げるとJSON が返ってくる場合を想定します。
Net::HTTP を使うとこんなふうに書ける。
require require 'net/http' require 'uri' require 'json' uri = URI.parse('https://api.example.com/smaple.json') https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true res = https.start { https.get(uri.request_uri) } if res.code == '200' result = JSON.parse(res.body) # Railsだったらこう書ける`require 'json'`なしで # result = ActiveSupport::JSON.decode res.body # resultを使ってなんやかんや処理をする else puts "OMG!! #{res.code} #{res.message}" end
ただし、Ruby にはopen-uri と呼ばれるNet::HTTP やNet::HTTPS をより簡単に利用するためのラッパーがあり、それを使うともっとスッキリ書けます。
require 'open-uri' res = open('https://api.example.com/smaple.json') code, message = res.status # res.status => ["200", "OK"] if code == '200' result = ActiveSupport::JSON.decode res.read # resultを使ってなんやかんや処理をする else puts "OMG!! #{code} #{message}" end
というふうに書けます。
wrapper を"ラッパー"とカタカナで書くと、今にも小気味のよいビートが聞こえてきそうだから不思議なものである。 だいたいこんなような感じ。
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (20件) を見る