破いて捨てたノート

Webやテクノロジーやそれ以外に関する思いつき

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を設定するための手順

  1. 目標(KGI)を明確にする

    • 「指標」、「値」、「期間」を明確にする
  2. ビジネスロードマップに図示する

    • 「ビジネスロードマップ」とは売上が発生するまでのプロセスを図式化したもの
  3. 数値を明らかにする

    • ビジネスロードマップに値を記入する
    • 取得できていない部分を明確にする
  4. 改善ポイントを選定する

    • 「規模」、「改善施策の実現度」、「期待効果」の3つの条件で優先順位をつける
  5. 目標値を設定する

    • 指標は目標値と合わさって初めて「KPI」と言える
    • 選んだ指標数「n」に対して、「n-1」の指標を 1/n-1 改善した場合にビジネス目標が達成できる値を設定する
      • 1/n-1とする理由は、施策を実施しても思った通りに改善しなかったり、1つの改善が他の指標を下げてしまうなどのリスクを回避するため
  6. 方針をまとめる

    • 状態目標を設定する
      • 現状を目標を設定した月で、サイトやビジネスがどのように変わっているかを言語化する
      • 新たにどのような価値をユーザーに提供しているかなど
    • 課題の洗い出し
    • 成立条件を定義する

refs: 『現場のプロがやさしく書いたWebサイトの分析・改善の教科書

KPIはいくつ設定すべきか?

いくつか説があるみたいです。どの説にせよ共通していることは、あまりKPIの種類を増やしすぎず、定期的に棚卸しすることが重要であるという点です。

7つまでにすべき

認知心理学の古典的な学説として「Millerの7±2チャンク」というものがあります。要は「人間は一度に7±2個のものまでしか同時に処理できない」という説なんですが、なかなかに説得力があると思います。これに倣って、例えば「KPIは7個まで」とか決めた方が良いかもしれないですね。

refs: 「Web系サービス運営でKPIを決める時に気を付けるべき3つのポイント

1つだけ設定すべき

スタートアップの成功の鍵は、本当の意味でフォーカスすること、それを持続させるための規律を持つことだ。フォーカスしていないのに成功したとすれば、それは単なる偶然にすぎない。あてもなくさまよい、膨大な時間をムダにして、苦痛や徒労を経験した末の成功だ。... リーンスタートアップの本質は、正しいことに、正しいときに、正しい考え方でフォーカスすることに他ならない。... アナリティクスとデータの世界では、ステップごとに重要な指標をひとつだけ選んでフォーカスする。ぼくたちはこれを「最重要指標(OMTM)」と呼んでいる。

refs: 『Lean Analytics

その他参考になった情報源

Lean Analytics ―スタートアップのためのデータ解析と活用法 (THE LEAN SERIES)

Lean Analytics ―スタートアップのためのデータ解析と活用法 (THE LEAN SERIES)

Railsに初コントリビュート決めた

これまでRailsに何度かPull Requestを投げてはRejectされを繰り返していたが、この度、初めてcommitをmergeして頂けた。documentationの大したことないcommitだけど嬉しい。

Rails Contributors - #2125 yachibit - All time

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'), '', '', '')

f:id:yachibit:20150125152229p:plain

もしくは、time_separatorも組み合わせれば、

  != sprintf(f.datetime_select(:created_at, use_month_numbers: true, date_separator: '%s', datetime_separator: '%s', time_separator: '%s'), '', '', '', '') + ''

f:id:yachibit:20150125152805p:plain

ハックっぽいやり方なので、用法用量を(ry

「Lean Analytics」原著買ったのに和訳版が発売されることになってツラいので、ここまで読んだことをまとめておく

はじめに

「Lean Analytics」に関しては、 yuku_t さんが 「全てのスタートアップ関係者が読むべき良書」という記事で大変わかりやくすまとめてくださいっています。この記事にどこを読めばいいかが書かれているので、それを参考に読み進めるとよいと思います。

また、翻訳者である角征典さんのスライドもslideshareに上がっていて、大変参考になります。

監視しては行けない8つの虚栄の指標

自分たちの今後のアクションには繋がらない自己満足に浸るだけの指標は、取得しても価値はないとして、本書ではバッサリと切り捨てている。 今後のアクションには繋がらない虚栄の指標として、下記の8つの指標を挙げている。

  1. ヒット数
  2. PV数
    • 広告などのPVに依存したビジネスモデルでなければ、大した意味は無い
  3. 訪問者数
    • 1人のユーザーが100回訪問したのか、100人のユーザーが1回ずつ訪問したのかわからない
  4. ユニークビジター数
    • 回遊したのか、離脱したのかなど、ユーザーが何をしたのかについて何もわからない
  5. フォロワー数/フレンド数/like数
    • 人気コンテスト以上の何者でもない
  6. 平均滞在時間
    • 実際に使われているのかどうかわからない。サポートや苦情のページに多くの時間を過ごしている場合は悪いことだ
  7. 集めたメールアドレス数
  8. ダウンロード数

弊社では「PV」という指標を重要視しすぎているように感じていて、前々から何となくモヤモヤしていたのですが、この辺りに書かれていることを読んでなるほどと思った。

Model One: E-commerce

Lean Analyticsに挙げられる6つのビジネスモデルの中で、例えば「Model One: E-commerce」が弊社のビジネスモデルに近そうだったので読んでみた。 (Model Six: Two-Sided Marketplaces も近いかも)

  • サイト内だけのファンネルを追うのは幾分時代遅れ
  • 購入はソーシャルやメール、オンラインコミュニティーなどWebサイトの遥か遠くから始まっていて、それは購入プロセスのトラッキングを困難にしている

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)

Lean Analytics ―スタートアップのためのデータ解析と活用法 (THE LEAN SERIES)

ドリップコーヒー遍歴

yaotti さんの「ドリップコーヒー環境 2015年1月」というエントリに感銘を受けたので、自分のドリップコーヒー環境についても書いてみた。

自宅で美味しいコーヒーが飲みたい

ということで、Amazonで安くてそこそこ評価の良い下記の商品を購入した。

Melitta セレクトグラインド MJ-518 (ブラック)

Melitta セレクトグラインド MJ-518 (ブラック)

象印 【4杯】コーヒーメーカー EC-TC40-TA

象印 【4杯】コーヒーメーカー EC-TC40-TA

豆は近所のカルディで購入することもあれば、ROASTER CAFE ぷらす90℃珈琲散歩 などの自家焙煎をしているお店に足を運び調達したりもした。 Amazonで下記の豆などを試した時期もあった。

しかし、上記の手法には欠点があった。
当たり前だが、とにかく面倒臭い。豆を挽くのが面倒臭い。豆の計量が面倒臭い。ガラスポットやミルを洗浄するのが面倒臭い。
美味しいコーヒーを飲むための儀式は、初めは楽しく感じられたが、それを定常作業として日々運用することは自分にはあまりにも面倒臭すぎた。 そこで次の手法を試みることにした。

自動化期

こいつはとにかく有能。豆の挽きからドリップ、ミルの洗浄まで「全自動」でやってくれる。 我々がやることは、ドリッパーやガラスポットの洗浄くらいだ。
しかし私の怠惰な心は、次第にそれすらも面倒臭いと感じるようになっていった。

番外編: バリスタ

弊社オフィスでは、上司が私物のネスカフェ バリスタを設置しており、100円で1日飲み放題で使用させて頂いている。 こいつはあくまでもインスタントコーヒーなのだが、インスタントコーヒーをそのままお湯で溶かして飲むのと比較すると、2割増しくらいで美味しい。しかも洗浄などの手入れは、ほとんど不要である。

現在

上記の変遷から学ぶべき教訓は、私はとにかく面倒臭がり屋だということだ。日常飲むコーヒーは手間が掛からないことが重要である。 美味しいコーヒーが飲みたくなったら、金を払って美味しいコーヒー屋さんに飲みに行くのが性に合っている。

ということで、それなりに美味しく、かつメンテナンスがほとんど不要であるという理由から、現在は下記のドリップコーヒーを飲むという手法に落ち着いている。

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"
という具合に怒られます。

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 (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)