TT Lab
はじめる
学ぶ 学習パス コース

開発者の起業 — 作る前に検証する

継続率三角表を作り三つの罠を数字で見る

TT Labで続きを見る

目標

「モアノート」の週次の登録コホートで、継続率の三角表を作り、分母・空欄・生存者という3つの落とし穴を数字で確認したうえで、正しい加重継続率と、登録経路別の継続率で判断します。

なぜ重要なのか

全体のアクティブ数は、新しく入ってくる人と、去る人を、1つの数字に混ぜます。同じ週に登録した人を別々に追いかけて初めて、製品が人を引き留めているかどうかが見えます。そして、その計算は、分母を変えたり、空欄を0で埋めたりするだけで、簡単に良くなったり悪くなったりします。広告費とロードマップがかかった数字なので、定義どおりに計算し直されなければなりません。

用意するものと定義

ステップ

  1. /root/founder/cohort/sizes.jsonに、コホートごとの登録者数を、{"0": n, ..., "11": n}で書く。
  2. /root/founder/cohort/cohort.pyに、retention(fix, max_n)を作る: {"0": [r0, r1, ..., r_max_n], ...}、観測前の欄はNone。
  3. /root/founder/cohort/denominator.jsonに、コホート4の4週目の継続率を、2つの分母で書く: rate_cohort_size(正しい分母)、rate_week0_active(0週目の活動者を分母にする。わざと犯す間違い)。
  4. /root/founder/cohort/censor.jsonに、6週目の継続率を、2つの方法で書く: pooled_rate(観測が終わったコホートだけ、人数で加重)、naive_rate_with_zeros(すべてのコホート、観測前の欄を0として)、そしてeligible_cohorts(観測が終わったコホートの数)。
  5. /root/founder/cohort/survivor.jsonに、4週目の継続率を、2つの名簿で書く: all_users_rate(コホート0–11の全員、観測が終わったコホートだけ)、survivors_only_rate(15週目に活動した人だけを選んで、同じ計算)、survivors(その人数)。
  6. cohort.pyに、pooled(fix, n, unbounded=False)を加える: 観測が終わったコホートだけを集めた、人数で加重した継続率{"cohorts": k, "users": u, "retained": r, "rate": 0.0000}。unboundedが真なら、「c+N週目以降のどの週でも(c+Nを含む)活動」として数える。
  7. /root/founder/cohort/channel.jsonに、登録経路(最後の接点)別の4週目の加重継続率を、{"organic_search": r, ...}の5つのチャネルで書く。
  8. /root/founder/cohort/report.jsonに、curve(n=0..8のbounded加重継続率9個)、week4、week4_unbounded、flatten_week(前の週に比べた低下が0.02未満になる最初のn、1以上)、best_channel、worst_channelを書く。

参考

コホートごとの登録者数

/root/founder/cohort/sizes.jsonに、登録週(0–11)ごとの外部の登録者数を、文字列のキーで書く。

signup_atをソウル時刻に変えて、2026-03-02から何日かを7で割った商が、コホートです。社内アカウントは除きます。

継続率の三角表: 観測前の欄はNone

/root/founder/cohort/cohort.pyに、retention(fix, max_n)を作る。コホートの文字列キー → n=0..max_nの継続率のリスト、c+n>15の欄はNone。

人ごとに、session_startがあった週の集合を先に作ってください。分母は、コホートの登録者数で、観測が終わっていない欄は、0ではなくNoneです。

分母を変えると、継続率が良く見える

/root/founder/cohort/denominator.jsonに、コホート4の4週目の継続率を、rate_cohort_sizeとrate_week0_activeの2つの分母で書く。

分子は同じです(週8に活動したコホート4の人)。分母だけを、登録者数と、0週目(週4)の活動者数に変えてみます。

観測前の欄を0で埋めると、曲線が偽物のように折れる

/root/founder/cohort/censor.jsonに、6週目の継続率のpooled_rate・naive_rate_with_zeros・eligible_cohortsを書く。

正しいほうは、c+6 ≤ 15のコホートだけを集めて、全体の継続者 ÷ 全体の登録者です。間違ったほうは、すべてのコホートの登録者を分母に入れます(観測前の人は、継続0として数えられます)。

いま残っている人だけを見ると、過去が良く見える

/root/founder/cohort/survivor.jsonに、4週目の加重継続率を、all_users_rate(全員)とsurvivors_only_rate(15週目の活動者だけ)で、そしてsurvivors(その人数)を書く。

2つの計算は、コホート・週のルールが同じで、人の名簿だけが違います。名簿は登録時点で固定するのが原則なので、2つ目の数字は、わざと犯す間違いです。

加重継続率の関数: boundedとunbounded

cohort.pyに、pooled(fix, n, unbounded=False)を加える。観測が終わったコホートだけ、人数で加重、{cohorts, users, retained, rate}を返す。

コホートの比率の単純平均ではなく、継続者の合計 ÷ 登録者の合計です。unboundedは、c+n週目と、その後のどの週でも活動したかどうかを見ます。

登録経路別の4週目の継続率

/root/founder/cohort/channel.jsonに、最後の接点のチャネル5つそれぞれの、4週目の加重継続率を書く。

touches.csvで、人ごとにtsが最も遅い行のchannelが、登録経路です。名簿だけを、そのチャネルの人に絞って、pooledと同じ計算を行います。

曲線と判断を1枚に

/root/founder/cohort/report.jsonに、curve(n=0..8)、week4、week4_unbounded、flatten_week、best_channel、worst_channelを書く。

flatten_weekは、n=1から見て、curve[n-1] − curve[n] < 0.02となる最初のnです。チャネルは、ステップ7の結果で、最も高いものと低いものです。