メインコンテンツへスキップ
ブログ一覧に戻る
SEO・マーケティング

顧客リテンション戦略完全ガイド:既存顧客の価値を活かす実践手法

2025年11月15日
最終更新: 2026年10月8日
12分で読めます

この記事でわかること

顧客リテンションを、同じ顧客群と観測期間の維持率から考える実践ガイド。新規顧客や未成熟な期間を混ぜない集計、個別提案・特典・定期連絡、RFMと支援の優先順位を整理します。六つのオフラインJavaScript教材と架空の費用比較で、率だけでは分からない価値や負担、利用目的・広告メールの確認、改善の進め方まで解説します。

2026年10月8日に、GA4のTraffic acquisition、traffic-sourceのscope、個人情報保護委員会の通則ガイドライン、消費者庁の特定電子メール法資料を再読しました。リテンション率は対象顧客、期間、継続の定義、重複除外、利用目的を明示し、費用・苦情・停止希望と合わせて判断します。個人情報の区分や広告メールの要件を、施策の成果や適法性の保証へ読み替えません。

30秒で要点

  • リテンションは、顧客が必要な価値を受け取り、利用や購入を続けられる状態を支える取り組みです。連絡回数や囲い込みの強さでは評価しません。
  • 維持率は、同じ顧客群・期間・継続条件で計算します。新規顧客を混ぜた期末人数や、観測期間が足りない群を比べないでください。
  • 個別提案、特典、定期連絡の前に、初期利用、商品品質、支援の詰まりを確認します。率が上がっても割引や対応費を含む正味額が下がる場合があります。

新規顧客を増やしても、利用を続ける理由や支援が不足していれば、事業は安定しません。一方、すべての顧客へ同じ頻度で連絡したり、退会を難しくしたりすることも、良い関係を作る方法とはいえません。誰が、どの価値を得られず、何を改善すればよいのかを分けて考えます。

維持したい顧客と、継続の意味を先に決める

定期契約なら契約の継続、ECなら一定期間内の再購入、業務ツールなら必要な仕事を完了できたことなど、事業によって継続の定義が違います。ログインしただけでは、価値を受け取ったとは限りません。

「既存顧客は新規顧客の何倍も価値がある」「維持率を少し上げれば利益が一定割合増える」という数字を、どの事業にも使える前提にはしません。商品ごとの粗利、利用期間、支援負荷、獲得費用で結果が変わります。まず、自社の継続がどの収益や利用価値につながるかを説明します。

表が収まらない場合は、横にスクロールできます

事業の例継続と呼ぶ状態見落としやすい点
月額サービス対象契約が翌月末も有効休止・未払い・無料延長の扱い
消耗品のEC初回購入から一定日数内に再購入本来の買替周期、返品、複数注文
業務ソフト同じ組織が必要な業務を継続して完了利用者交代、閲覧だけの活動
専門サービス必要な時期に再相談・契約更新利用が不要になった良い終了もある

解約した人を全員「離脱対策の失敗」としないことも大切です。目的を達成した、事業が変わった、商品が合わなかったなど、理由を区別します。不要な継続を促すより、説明や解約を分かりやすくする方が望ましい場面があります。

同じ群を追う維持率と、期末の人数を分ける

説明用に、期首の対象顧客が1,000人、そのうち期末まで継続した人が850人、継続しなかった人が150人とします。この定義では維持率85%、離脱率15%です。期間中に新規200人が加わっても、期首群の維持率の分子へ足しません。

表が収まらない場合は、横にスクロールできます

架空の期首群人数期首1,000人に対する割合
継続した人850人85%
継続しなかった人150人15%
期間中の新規顧客200人この維持率には含めない

期末の全顧客は1,050人になり得ますが、1,050÷1,000=105%を、この群の維持率とは呼びません。また、再加入を継続に含めるか、同じ組織の契約変更をどう扱うかを先に決めます。

期首1000人から継続850人と離脱150人を分け、新規200人は別群に置く架空例と、維持率の後に割引費と対応費を確認する順序を示す図
図1:同じ群の継続を追う説明用の架空値です。人数の定義をそろえた後、顧客が得た価値と、施策費を含む事業側の負担を確認します。

教材1:人数の定義と空の群を検査する

以下の6つのJavaScript例は、Node.jsで一つずつ実行できるオフライン教材です。実データ取得やメール送信を行いません。入力は説明用に限定し、本番の認可、記録保存、配信停止処理などを実装したものではありません。

function cohortRates(startIds, retainedIds) {
  if (![startIds, retainedIds].every(xs => Array.isArray(xs) &&
      xs.every(x => typeof x === 'string' && x.length > 0))) {
    throw new TypeError('IDs must be non-empty strings');
  }
  const start = new Set(startIds), retained = new Set(retainedIds);
  if (start.size !== startIds.length || retained.size !== retainedIds.length) {
    throw new Error('Duplicate customer ID');
  }
  if ([...retained].some(id => !start.has(id))) {
    throw new Error('Retained customers must belong to the starting cohort');
  }
  if (start.size === 0) return { retention: null, churn: null };
  return { retention: retained.size / start.size * 100,
    churn: (start.size - retained.size) / start.size * 100 };
}
const initial = Array.from({ length: 1000 }, (_, i) => `c${i}`);
console.log(cohortRates(initial, initial.slice(0, 850))); // 85 / 15
console.log(cohortRates([], [])); // null / null:対象なし

この教材では、継続と非継続が期首群を二分します。収益ベースの維持率や、全期間中の利用回数を測る場合は別の定義が必要です。空の群を0%とすると、顧客が全員離れた場合と区別できなくなるため、対象なしを返します。

コホートは観測期間と復帰条件をそろえる

コホートは、初回購入月などの共通条件でまとめた群です。初回から30日以内の再購入を見るなら、まだ10日しかたっていない群を、30日観測した群と比べません。未成熟な期間は未確定として残します。

GA4のコホート探索では、加入条件、復帰条件、期間の粒度を設定します。各期間に戻った人、そこまで毎期間戻った人、期間内に一度でも戻った人では計算が違います。また、公式説明では端末データを使い、コホート作成でUser-IDを考慮しないため、顧客台帳と同一とは限りません。Googleのコホート探索の説明

対策の前に、利用が止まる理由を分ける

同じ「30日利用がない」でも、年に数回使う商品と毎日必要な業務ソフトでは意味が違います。アクセス履歴だけで退会意思を断定せず、契約周期、利用目的、支援履歴、本人の申出を合わせて確認します。

表が収まらない場合は、横にスクロールできます

観測した状態確認したい仮説対応の例
登録後に初期設定が終わらない操作や前提情報が分からない初期利用の手順と支援先を整理
特定の機能で問い合わせが続く不具合や説明不足がある原因修正を優先し、宣伝を増やさない
更新時だけ解約が増える料金・利用価値・契約条件が合わない更新前の説明と選択肢を確認
メール停止が増える内容や頻度が期待と違う希望する内容・頻度と停止方法を見直す

教材2:解約予測ではなく、確認順を決める

次の点数は自作の仮ルールです。解約確率や学習済みモデルではありません。支援チケットの多さは熱心な利用の表れかもしれず、支払遅延も請求処理の不備かもしれません。点数だけで契約を止めたり、不利な扱いをしたりしないでください。

function supportPriority(u) {
  for (const k of ['inactiveDays', 'tickets']) {
    if (!Number.isInteger(u[k]) || u[k] < 0) throw new RangeError(k);
  }
  if (!Number.isFinite(u.engagement) || u.engagement < 0 || u.engagement > 1 ||
      typeof u.paymentDelayed !== 'boolean') throw new TypeError('Invalid input');
  const score = (u.inactiveDays > 30 ? 30 : 0) +
    (u.engagement < 0.3 ? 25 : 0) + (u.tickets > 3 ? 20 : 0) +
    (u.paymentDelayed ? 25 : 0);
  return { score, priority: score > 50 ? 'high' : score > 30 ? 'medium' : 'low' };
}
console.log(supportPriority({ inactiveDays: 31, engagement: 0.2,
  tickets: 0, paymentDelayed: false })); // 55 / high

30日、0.3、3件という境界は教材の仮定です。自社に導入するなら、対象業務と確認できる誤判定、担当者が見られる件数を決めてから試します。低い点数の人を放置してよいという意味でもありません。

三つの施策を、顧客の必要と負担で選ぶ

個別提案は、目的と配信可否を先に確認する

パーソナライズは、顧客が探している内容を見つけやすくするための手段です。多くの情報を集めること自体を目的にしません。個人情報の利用目的は、本人が用途を合理的に想定できるよう具体化し、目的を超えた利用の条件を確認します。個人情報保護委員会の通則編3-1

広告メールは、原則として事前同意、表示、受信拒否への対応が必要です。例外や他法との関係があるため、既存顧客なら一律に送れるとも、以下のフラグだけで適法とも考えないでください。消費者庁の説明資料・物理1~5ページ

教材3:送信せず、提案の候補だけを作る

function recommendationDraft(user, catalog) {
  if (user.marketingConsent !== true || user.unsubscribed === true) return null;
  if (!Array.isArray(user.interests) || !Array.isArray(catalog)) {
    throw new TypeError('Arrays required');
  }
  const items = catalog.filter(p => p.available === true &&
    user.interests.includes(p.category)).map(p => p.name);
  return items.length ? { subject: '希望された分野のご案内', items } : null;
}
const customer = { marketingConsent: true, unsubscribed: false,
  interests: ['repair'] };
const catalog = [{ name: '修理の相談窓口', category: 'repair', available: true },
  { name: '新商品の紹介', category: 'new', available: true }];
console.log(recommendationDraft(customer, catalog)); // 修理の相談窓口のみ

これは送信本文の完成版ではありません。本番では同意の取得経緯、最新の停止状態、送信者表示、内容の妥当性などを確認する工程が別に必要です。候補がないなら、無理に何かを薦めず連絡を見送る選択を残します。

特典は継続の価値と費用を明らかにする

ポイントや会員特典は、条件が分かりやすく、顧客が必要な価値に結び付くときに検討します。購入額だけで人の価値を評価したり、達成できない条件を期待させたりしないようにします。付与、利用、失効、返品時の扱い、支援費用まで見積もります。

教材4:ポイント計算を小さな関数にする

次は「整数円の1%を切り捨て、初回だけ100点」という架空の制度です。金銭的な有利さや、制度の法的な区分を認定する例ではありません。

function loyaltyPoints(amountYen, isFirstPurchase) {
  if (!Number.isSafeInteger(amountYen) || amountYen < 0 ||
      typeof isFirstPurchase !== 'boolean') throw new TypeError('Invalid purchase');
  return Math.floor(amountYen / 100) + (isFirstPurchase ? 100 : 0);
}
function membershipTier(totalPoints) {
  if (!Number.isSafeInteger(totalPoints) || totalPoints < 0) throw new RangeError('points');
  return totalPoints >= 1000 ? 'gold' : totalPoints >= 500 ? 'silver' : 'basic';
}
const earned = loyaltyPoints(12500, true);
console.log(earned, membershipTier(400 + earned)); // 225 / silver

本番では初回購入を重複判定しない仕組みや、返品時の調整が必要です。この関数が計算できることと、台帳全体が正しいことを分けて確認します。

定期連絡は、役立つ内容があるときに行う

定期的な連絡は、使い方の支援、変更の説明、必要な時期の案内など、顧客が期待する内容に結び付けます。月一回なら適切という普遍的な頻度はありません。配信停止、苦情、問い合わせ増加なども合わせて見ます。

教材5:日付を固定して、連絡候補を判定する

function communicationPlan({ consent, stopped, hasUsefulUpdate, lastSentDay }, todayDay) {
  if (!Number.isInteger(todayDay) || !Number.isInteger(lastSentDay) ||
      todayDay < lastSentDay) throw new RangeError('Invalid day index');
  if (consent !== true || stopped === true || hasUsefulUpdate !== true) return 'hold';
  return todayDay - lastSentDay >= 30 ? 'review-draft' : 'hold';
}
console.log(communicationPlan({ consent: true, stopped: false,
  hasUsefulUpdate: true, lastSentDay: 100 }, 130)); // review-draft

日付の代わりに固定の日番号を渡し、30日未満・ちょうど30日・未来の入力を検査できる形にしました。30日は仮の間隔です。返り値も「送信」ではなく「下書きを確認する候補」であり、契約上必要な通知と広告メールを同じ判定へ押し込めるものではありません。

RFMと行動データで、支援の違いを調べる

RFMは、最近の購入からの経過(Recency)、期間内の回数(Frequency)、期間内の金額(Monetary)を並べる整理法です。三つの軸を分けると、最近初めて買った人と、長く買っていたが最近購入がない人を区別しやすくなります。

同じ観測日と集計期間、注文・返品の扱いをそろえます。高額購入者だけを「良い顧客」とする方法ではなく、必要な支援を考える材料です。サイトの行動、問い合わせ、本人の希望も合わせます。

教材6:RFMの境界を見える形にする

function rfm({ daysSincePurchase, ordersInWindow, netYenInWindow }) {
  if (![daysSincePurchase, ordersInWindow, netYenInWindow].every(
    n => Number.isSafeInteger(n) && n >= 0)) throw new RangeError('Invalid RFM input');
  return {
    recency: daysSincePurchase < 30 ? 'recent' : daysSincePurchase < 90 ? 'middle' : 'older',
    frequency: ordersInWindow > 10 ? 'high' : ordersInWindow > 5 ? 'middle' : 'low',
    monetary: netYenInWindow > 50000 ? 'high' : netYenInWindow > 20000 ? 'middle' : 'low'
  };
}
console.log(rfm({ daysSincePurchase: 30, ordersInWindow: 10,
  netYenInWindow: 50000 })); // middle / middle / middle

これは購入済み顧客を対象とし、直近365日など、入力を作る側で同じ窓を決める教材です。未購入者や、返品で期間純額が負になる顧客は、この例へ無理に通さず別に扱います。30日や5万円の境界は事業に合わせて検討する仮定で、汎用の推奨値ではありません。

維持率が改善しても、利益が増えたとは限らない

説明用の比率変化を整理すると、70%から85%は15ポイント増、元の70%に対して約21.4%の相対増です。60%から75%は15ポイント増・相対25%、40%から60%は20ポイント増・相対50%です。どれも架空計算で、SaaSやECで実現した事例ではありません。

維持率からLTV(顧客との取引全体の価値)を直接決めることもできません。購入単価、粗利、利用期間、支援費、割引が変わるためです。

表が収まらない場合は、横にスクロールできます

架空の同期間比較施策群比較群
対象顧客100人100人
再購入者(各1注文)30人25人
再購入率30%25%
割引前の注文あたり貢献2,000円2,000円
注文による貢献の合計60,000円50,000円
割引総額9,000円0円
追加作業費3,000円0円
この比較の正味額48,000円50,000円

この例では再購入率が高い施策群の正味額が2,000円低くなります。割引は30人全員に300円ずつ適用する仮定で、増えた5人だけの費用にしていません。2,000円の貢献は割引・追加作業費をまだ引いていない金額です。二重計上にも注意します。

実際には無作為に群を分けていない、商品や時期が違う、長期の継続が分からないといった条件もあります。この表だけで施策の因果効果や、打ち切るべきかまで確定しません。比較の条件と、許容する負担を先に決めます。

心理的な働きかけより、利用の納得を優先する

特典を失いたくない気持ち、他の利用者の声、小さな行動から続けやすくなることなどを施策の仮説にする場合も、効果を決めつけません。顧客が理解したうえで選べる条件が先です。

架空の人気表示、誇張した残り時間、見つけにくい解約手続、不要な連絡の継続は、率だけを上げても信頼を損ねる可能性があります。利用を続けない選択も尊重し、商品品質や支援の不足を心理的な仕掛けで覆わないようにします。

最初の5分で決めることと、その後の検証

最初の5分では、次の三つを一枚に書きます。施策効果の判定まで5分でできるという意味ではありません。

  1. 誰の、どの継続を見るか。 契約、再購入、必要業務の完了などを決めます。
  2. どの群を、いつまで追うか。 加入条件、観測窓、未成熟期間、除外理由を残します。
  3. 何が不足し、どこまで負担できるか。 支援仮説、担当、費用、配信停止や苦情などの中止条件を決めます。

次に、集計から少数の例をたどり、継続・新規・離脱の分類が正しいか確認します。その後で一つの改善を試し、同じ定義の件数と率、費用、顧客の不利益を見直します。担当が変わっても判断を追えるよう、変更日と判断理由を残します。

再購入と事業の全体設計をつなぐ

よくある質問(FAQ)