はじめに
こちらイシューからはじめるデータ分析②データ加工編の続きとなります。
イシュー編で作ったストーリーラインに沿って分析していきます。
全体の流れ
ストーリーラインの①②③を検証していきます。
① 新規顧客の獲得より既存顧客の継続を優先させるべきである
② 売り上げはここ1年一定で伸び悩んでいる
③ その要因は新規顧客売上の減少ではなく、既存顧客売上の減少である
分析
使用ライブラリ
# standard
import datetime as dt
from dateutil.relativedelta import relativedelta
# third-party
import numpy as np
import pandas as pd
pd.set_option("max_rows", 500, "max_colwidth", 500, "max_columns", 500)
pd.options.plotting.backend = "plotly"
売り上げはここ1年一定で伸び悩んでいる
月ごとのログ集計を行なっていきます。
# 月毎のログ集計
monthly_logs = logs.groupby(["customer_id", "use_month"]).log_id.count().reset_index()
monthly_logs.rename(columns={"log_id": "count"}, inplace=True)
# 顧客情報と結合
monthly_logs = monthly_logs.merge(customer, how="left", on="customer_id")
monthly_logs["start_month"] = monthly_logs.start_date.apply(lambda d: d.replace(day=1))
monthly_logs.head()
# 入会月なら1, そうでなければ0
monthly_logs["is_new"] = (monthly_logs["use_month"] == monthly_logs["start_month"]).astype("int")
# ピボット集計
monthly_sales = monthly_logs.pivot_table(
index="use_month", columns="is_new", values="price", aggfunc="sum")
monthly_sales.columns = ["existing", "new"]
monthly_sales
新規顧客の売上と既存顧客の売上を積み上げ棒グラフで可視化します。
monthly_sales.plot.bar(
title="月別売上",
labels=dict(value="売上(百万)", usemonth="月", variable="既存 or 新規")
)
売り上げは多少増減はあるものの、約1年を通して伸び悩んでるようですね。。
これだけでは**「既存顧客の継続施策を優先させるべきである」**と主張できないため、理想の売上(顧客が退会しない場合)をみてみます。
monthly_sales["ideal"] = monthly_sales["new"].shift(1)
monthly_sales.loc["2018-04-01", "ideal"] = monthly_sales.loc["2018-04-01", "existing"]
monthly_sales["ideal"] = monthly_sales["ideal"].cumsum()
monthly_sales.plot.bar(
title="理想月別売上",
y=["ideal", "new"],
labels=dict(value="売上(百万)", usemonth="月(18年4月~19年1月)", variable="既存(理想) or 新規")
)
既存顧客が100%継続すると仮定するとかなり売上が伸びますね!
もう少し深く掘り下げていきます。
$今月の売上 = 今月の新規売上 + 先月の新規売上 + α × 先月の既存売上$
退会は退会申請の翌月になり、先月の新規売り上げは必ず今月の既存売上に入ります。
そのため上記のように売上を定義して①②で総売上を比較してみます。
① 新規売上が20%UPした場合
② αが2%UPした場合
そのためまずαを計算します。
monthly_sales.drop(columns=["ideal"], inplace=True)
monthly_sales["alpha"] = (monthly_sales.existing - monthly_sales.new.shift(1)) / monthly_sales.existing.shift(1)
monthly_sales
売り上げをシュミレートする関数を作り、検算します。
def simulate_sales(df, new_muti, alpha_add):
pre_existing = df.loc["2018-04-01", "existing"]
pre_new = df.loc["2018-04-01", "new"]
sales = [pre_existing + pre_new]
# 2018-05-01から計算
for idx, series in enumerate(df.iloc[1:,:].itertuples()):
pre_existing = (series.alpha + alpha_add) * pre_existing + pre_new * new_muti
pred_sale = series.new * new_muti + pre_existing
sales.append(pred_sale)
# 更新
pre_new = series.new
return sum(sales)
print(simulate_sales(monthly_sales,1, 0) == (monthly_sales.existing.sum() + monthly_sales.new.sum()))
True
①②で総売上を比較してみます。
pattern1_sale = simulate_sales(monthly_sales, 1.2, 0)
pattern2_sale = simulate_sales(monthly_sales, 1, 0.02)
print("①新規売上が20%UPした場合の総売上:", pattern1_sale, "円")
print("②αが2%UPした場合: ", pattern2_sale, "円")
print("② - ①:", pattern2_sale - pattern1_sale, "円")
①新規売上が20%UPした場合の総売上: 169646864 円
②αが2%UPした場合: 170331638 円
② - ①: 684774 円
約70万円と思ったよりインパクトなかったですね。。
ですが新規売上を20%UPさせるには広告やキャンペーンを打ったりとその分費用がかかります。
逆にαを2%UPさせるには「以前よりだいぶ引き締まりましてね!」「最近お忙しかったですか?」と声掛けを徹底するだけでも変わってきそうではないですか?
またαを高める意識はユーザー体験の向上につながり、「ここのジムめっちゃいいから来ない?」など勧めるユーザーも現れ、費用のかからない広告になるのではないでしょうか?
(説得できる!とはとても言い難いですが、納得してもらえたと仮定して進みます。)
まとめ
今回は新規顧客の獲得より既存顧客の継続を優先させるべきである
というイシューに答えを出しました。
以降は既存顧客の退会要因を特定し、退会予測モデルの構築を行っていきます。