本レポートでは、CRMを実行して収益性を向上させるという実務的課題を背景に、顧客idに基づいた購買データを分析する。したがって、研究課題は以下のものである。自社にとって、重要な顧客/顧客グループを特定する。ただし、ここで言う重要な顧客/顧客グループとは、購買額と購買頻度が高く、直近の購買日からの経過日数が少ない顧客/顧客グループとする。
本レポートにおけるデータは、2022idpos2.csvとid_data2.csvの2つのデータを用いたものである。前者は「顧客id、購買日、購買額、クーポン利用額」の変数を含み、2019年09月01日から2019年10月01日までの取引ごとに集計されたデータである。後者は3000人分の会員登録済み顧客情報であり、「顧客id、性別、年齢、家族構成」の変数を含むデータである。
分析アプローチの方針としては、RFM分析を採用する。RFM分析とは、最新の購買日、購買頻度、累積購買額を指標として分析する方法で、離反している可能性が低く、ロイヤルティが高い顧客を特定することができる。上述のように、本レポートでは、購買額と購買頻度が高く、直近の購買日からの経過日数が少ない顧客/顧客グループを特定するため、RFM分析は今回の分析目的を鑑みると、比較的適した分析アプローチであると言える。
以下の手順で分析を進める。 1. 累積購買額が高い顧客を特定する。 2. 購買頻度が高い顧客を特定する。 3. 最新の購買日が近い顧客を特定する。
まず、2022idpos2.csvデータを用いて、累積購買額が高い顧客を特定する。2022idpos2.csvは上述のように取引ごとに集計されているデータなので、そのままの状態では重要顧客を特定しづらい。そこで、取引データを顧客idごとに集計して、顧客ベースのデータに変換する。その際、購買額の合計を「累積購買額」、顧客idの出現回数を「購買頻度」、2019年10月02日から最新購買日を引いたものを「最新購買日からの経過日数」として新たにな変数として定義して用いる。 累積購買額が高い顧客を特定するにあたって、デシル分析を用いる。デシル分析とは、累積購買額が高い順に10個のグループに分けて、ランクを割り振る分析である。本レポートでは、累積購買額が高いほど、高いランクを割り振った。その結果、上から2つのランク(10,9)に属する顧客グループで過半数の累積購買額を占めていることが判明した。また、最高ランク(10)に属する顧客群は圧倒的に累積購買額の割合が多いことが判明した。
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readr)
library(readxl)
idpos <- read_csv("/Users/maru_r14/Desktop/経営データ分析/マーケティング/mkt-reseach/simulation_data/2022idpos2.csv", na = ".")
## Rows: 5000 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): date
## dbl (3): id, spent, coupon
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
idpos$datediff <- as.numeric(difftime("2019-10-02", idpos$date, units = "days"))
head(idpos)
## # A tibble: 6 × 5
## id date spent coupon datediff
## <dbl> <chr> <dbl> <dbl> <dbl>
## 1 38 2019/9/30 9265 926. 2
## 2 31 2019/9/10 7037 704. 22
## 3 20 2019/9/10 1790 179 22
## 4 30 2019/9/19 8450 0 13
## 5 42 2019/9/26 7052 0 6
## 6 41 2019/9/7 9340 934 25
idpos_cust <- idpos %>%
group_by(id) %>%
summarise(frequency = n(),
monetary = sum(spent),
cherry = sum(coupon),
recency = min(datediff))
idpos_cust_m <- idpos_cust %>%
arrange(desc(monetary))
id_data <- read_csv("/Users/maru_r14/Desktop/経営データ分析/マーケティング/mkt-reseach/simulation_data/id_data2.csv")
## Rows: 5000 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): gender
## dbl (3): id, age, famsize
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
str(id_data)
## spc_tbl_ [5,000 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:5000] 1 2 3 4 5 6 7 8 9 10 ...
## $ gender : chr [1:5000] "female" "female" "male" "female" ...
## $ age : num [1:5000] 32 37 22 21 49 43 46 46 56 56 ...
## $ famsize: num [1:5000] 4 1 1 3 5 4 4 3 3 4 ...
## - attr(*, "spec")=
## .. cols(
## .. id = col_double(),
## .. gender = col_character(),
## .. age = col_double(),
## .. famsize = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
idpos_cust <- left_join(idpos_cust, id_data, by = "id")
idpos_cust_m <- idpos_cust %>%
arrange(desc(monetary))
idpos_cust_m$decile_rank <-
cut(idpos_cust_m$monetary,
quantile(idpos_cust_m$monetary, (0:10)/10,na.rm=TRUE),
label=FALSE,include.lowest=TRUE)
decile <- idpos_cust_m %>%
group_by(decile_rank) %>%
summarize(freq = n(),
monetary = sum(monetary))
total <- sum(decile$monetary)
decile2 <- decile %>%
mutate(percent = monetary/total*100) %>%
arrange(desc(decile_rank))
decile2
## # A tibble: 10 × 4
## decile_rank freq monetary percent
## <int> <int> <dbl> <dbl>
## 1 10 279 14933505 36.4
## 2 9 278 5642335 13.8
## 3 8 277 4332863 10.6
## 4 7 280 3793579 9.25
## 5 6 278 3289525 8.02
## 6 5 278 2823416 6.89
## 7 4 279 2351358 5.73
## 8 3 278 1820053 4.44
## 9 2 278 1292088 3.15
## 10 1 279 722426 1.76
theme_set(theme_gray(base_size = 10, base_family = "HiraMinProN-W3"))
head(idpos_cust_m)
## # A tibble: 6 × 9
## id frequency monetary cherry recency gender age famsize decile_rank
## <dbl> <int> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <int>
## 1 32 34 311439 21435. 1 male 45 5 10
## 2 49 34 241323 12250. 1 male 43 2 10
## 3 29 26 240559 8915. 1 male 45 2 10
## 4 38 24 215760 8644. 1 female 29 4 10
## 5 45 24 214573 7828. 1 female 29 3 10
## 6 10 28 214040 11258. 1 female 56 4 10
p2 <- ggplot(decile2, mapping = aes(x = decile_rank, y = percent))
p2 + geom_point() + labs(x = "ランク", y = "累積購買額割合", title = "散布図:ランクと累積購買額割合")
購買頻度が高い顧客を特定するにあたって、以下の仮説を置く。
仮説:累積購買額が高いほど、購買頻度が高い。
この仮説を検証するために、累積購買額と購買頻度の関係を調べる。横軸に累積購買額、縦軸に購買頻度をとって、図に表したものが以下である。
p4 <- ggplot(idpos_cust_m, mapping = aes(x = monetary, y = frequency))
p4 + geom_point() + labs(x = "累積購買額", y = "購買頻度", title = "散布図:購買額と購買頻度")
図からわかるように、購買頻度は累積購買額とかなり強い正の相関関係にあるので、上記の仮説は正しいと言えるだろう。
最新購買日は顧客が離反したか否かを表す指標であるが、まずは上述のように、2019年10月2日を基準として、最新購買日からの経過日数の分布を確認する。
p0 <- idpos_cust_m %>% ggplot(mapping = aes(x = recency))
p0 + geom_histogram() + labs(x = "経過日数", y = "頻度",title = "ヒストグラム1:最新購買日からの経過日数")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
上図からわかるように、かなりバラツキが大きいが、およそ半数以上は最新購買日からの経過日数が15日を過ぎていないことがわかる。
次に、最新購買日からの経過日数と購買頻度の関係を見ていく。その際に、デシルランクを用いて、色分けを試みた。
p5 <- ggplot(idpos_cust_m, mapping = aes(x = recency, y = frequency, color = decile_rank))
p5 + geom_point() + labs(x = "最新購買日からの経過日数", y = "購買頻度", title = "散布図:経過日数と購買頻度")
上図からわかるように、概ね、購買頻度が高いほど、最新購買日からの経過日数は小さいと考えられる。また、全体の傾向として、デシルランクが高いほど、最新購買日からの経過日数は小さいと言える。しかし、若干名デシルランクが高いにもかかわらず、最新購買日からの経過日数が大きい顧客がいる。具体的には、最新購買日からの経過日数が21日と28日の顧客群の中に数名存在する。これらの顧客は、1回の購買でかなりの購買額を費やすことが考えられるので、該当顧客の購買頻度を上昇させることで収益性の向上が見込めるとも言える。
基本的には、デシルランクが高い顧客が、購買額と購買頻度が高く、直近の購買日からの経過日数が少ない顧客グループに該当する。しかし、上述のように、一定数、デシルランクが高いにもかかわらず、購買頻度が低い顧客群が存在することも判明した。
ゆえに、以下の方策を提言しようと思う。
1.デシルランクが高い顧客の累積購買金額をさらに向上させる施策を実行する 2.デシルランクが高いのにもかかわらず、購買頻度が低い顧客群の詳細な特徴を把握して、購買頻度を向上させる施策を実行する