RFM分析 – エクセル編

RFM分析 – エクセル編

顧客をグループ化し、その特徴を理解しようとするRFM分析。実践では「常連客」「休眠客」のようなグループ化を目的とせず、「購入金額が高い顧客」でも「最終来店日」「来店頻度」には様々なパタンがあって一括りにはできないことを教えてくれるのがRFM分析なのうだろう。とにかくグループ化が難しい!

データ

会員データ
会員データ

日別・会員別・売上データ
期間:2020年6月1日~2020年11月30日 (6か月間)
会員数:4,159名

実在しない架空のオリジナルデータです。

RFM分析に必要な値

・R (最終購買日)
 会員ごとの「日付」 (購入した日) の最大値で算出

・F (購入頻度)
 データ期間中 (6か月間) の会員ごとの「会員コード」の個数 (重複可) をカウント

・M (購入金額)
 データ期間中 (6か月間) の会員ごとの「売上売価」を合計する

ピボットで値を集計
ピボット

・行は「会員コード」です。

・R (最終購買日)
 「日付」を
 「値フィールドの設定」→「集計方法」→「最大」
・F (購入頻度)
 「会員コード」を
 「値フィールドの設定」→「集計方法」→「個数」
・M (購入金額)
 「売上売価」

日付の値は数値が望ましい
DAX式

 R (最終購買日)が日付形式になっています。
 本日と最終購買日の差分を数値へ変換します。最終購買日から現在までの経過日数を算出します。

・現在を2020年11月30日とします。
・2020年11月30日をシリアル値へ変換すると「44165」です。
・最終購買日をシリアル値へ変換して、現在との差分を算出します。

# DAX式
=44165-DATEVALUE(MAX([日付]))
データ

 RFM分析のもとになるデータはこれで完成です。

グループ化

データを見える化
3変数散布図

 データは3変数です。
・R (最終購買日)
・F (購入頻度)
・M (購入金額)
 3種類の2次元散布図を作成することができます。

 さて・・・どのように顧客をグループ化するのか?

スコアカード方式 (一般的)
スコアR (最終購買日)F (購入頻度)M (購入金額)
51週間以内120回以上300,000円以上
42週間以内90回以上200,000円以上
31か月以内60回以上100,000円以上
22か月以内30回以上30,000円以上
12か月を超える30回未満30,000円未満
スコアカード

 このようなスコアカードを作成します。

合計方式
会員R (最終購買日)F (購入頻度)M (購入金額)合計スコア
A3日100回100,000円
Aのスコア54312
B3日40回300,000円
Bのスコア52512
スコア集計

 会員ごとにスコアを合計し、スコアごとのグループを作成します。

合計スコア会員数会員コード
151010名の具体的なコード
142020名の具体的なコード
134040名の具体的なコード
最低スコア3まで
合計スコア

 合計スコアでグループ化すると、最低スコア3から最高スコア15までの13グループをつくることができます。

 課題は、AもBも同一のグループになることです。
・Aの来店頻度100回にたいしてBは40回
・Aの購入金額10万円にたいしてBは30万円
 感覚的にAとBは違うように思います。

細分化方式
グループR (最終購買日)F (購入頻度)M (購入金額)合計スコア会員コード
155551510名の具体的なコード
14_15541420名の具体的なコード
14_25451415名の具体的なコード
14_34551420名の具体的なコード
13_15531310名の具体的なコード
変数別スコア

 合計スコアをさらに細分化します。
 3変数あるので、
・5×5×5=125グループができます。

 これではグループ数が多すぎます。管理可能なグループ数になるように、いくつかのグループをまとめます。
 そうなると、結局は合計スコアでのグループ化の結果に近づきます。

細分化方式をどのように見える化するのか

<課題>
・変数が3種類ある。
 3次元の見える化が望ましいが表現も理解するのも難しい。

・125グループある。
 表が125行になる。チャートでも125系列になる。それぞれのグループの特徴を表現することが難しい。
 そうなると、会員をグループごとに分類できたとしても具体的なアクションへは至らないだろう。

<解決方法>
・見たいグループだけを抽出して見える化する

 たとえば、
・R (最終購買日) スコアが「1」 (最近の来店実績がない) のグループ
AND
・M (購入金額) スコアが高いグループ

見える化手順

スコア
スコアカード

 スコアカードを作成します。
 今回のスコアとそれぞれの値についての根拠はありません。

 食料品スーパーを想定しているので、
・「トップグループ顧客なら最終購買日は1週間以内だろう」
・「トップグループ顧客なら3日に2回は来店するだろう」
・「トップグループ顧客なら1か月あたり一般的な食料品支出額5万円は購入するだろう」

 これらの想定と、散布図を見ながら決めました。

 スコアカードができたら、会員コードごと・RFMごとにスコアを与えます。

その他の値
スコア合計

・RFMのスコアを合計します。
 スコア合計方式でも分類できるようになります。

・会員コードごとの「日付」の最小値
 会員コードごとの初回購入日になります。
 Aさんは7月に新規会員になった (初回購入した) 、Bさんは8月からの会員・・・ということがわかります。

リレーションシップ
リレーションシップ

・もとデータ (日別・会員別・売上データ) とリレーションシップします。
・リレーションフィールドは「会員コード」です。

会員コードを特定する
スコアを選択

 ピボットテーブルを作成します。
・列が「会員コード」
・値が
「日付」の最大値 (日別・会員別・売上データ)
「R (最終購買日からの日数)」
「F (購入頻度)」
「M (購入金額)」
「会員コード」の重複しない個数
「RFMそれぞれのスコア」
「RFMの合計スコア」

・RFMそれぞれのスコアと合計スコアをスライサーに設定します。

・R (最終購買日) スコアが低いグループを選択
・M (購入金額) が高いグループを選択します。

 かつては高い購入金額、最近は来店購入がなくなった8名の会員をみつけることができました。

・再び来店していただく
・現在の高スコア会員を離脱させない
 これらの対策が必要です。

 この8名が
・過去にどのような商品を購入していたのか?
・住所、年齢、性別などの属性は?
・6か月よりも前に遡って、どのような購買履歴があるのか?

 具体的アクションのヒントが見つかるかもしれません。

チャート
チャート

 グラフを作成します。
・列が「日付の月」(日別・会員別・売上データ)
・値が
「売上売価 (合計)」(日別・会員別・売上データ)、「会員コード (個数)」(日別・会員別・売上データ)
・組み合わせグラフ

 11月は購入額ゼロになってしまった8名の月別購入額・来店回数のグラフです。
 もしも8名が引き続き来店購入されていたら、11月の売上はおよそ30万円アップしていたかも!

 ピボットテーブルを作成します。
・行が「会員コード」
・列が「日付の月」(日別・会員別・売上データ)
・値が「売上売価 (合計)」(日別・会員別・売上データ)
・条件付き書式でアイコンセットを挿入します。

 じわりじわりと購入金額が漸減するということではなく、突然に来店しなくなるパタンが多いようです。

特徴的な会員を発見する
特徴的な会員

 Mのスコアが1、Fのスコアが3です。
 3日に1回は来店購入があります。昨日か一昨日に来店購入があります。1回あたり購入額は500円未満です。この会員は常連客なのかどうか?

 常連客か、否かよりも重要なのは、特徴的な会員から何を発見できるのかということだろうと思います。

・店舗の近所に勤めていてお弁当を購入している

 たとえば、このような発見ができれば

・近隣の事業所へお弁当のチラシを配布する
・お弁当の予約を受け付ける
・数量がまとまれば宅配する
 いくつかのアクションプランを考えることができます。

初回購入日

 RFMのFは購入頻度です。RFM分析の一般的な解説では、
「Fのスコアが低い顧客が少ない場合は新規の顧客が少ない」

 ピンとこないロジックのように思うのですが・・・

新規顧客

 単純に新規顧客は「初回購入日」で見分けることをオススメします。
・軸が「日付の月」(日別・会員別・売上データ)
・値が「売上売価 (合計)」(日別・会員別・売上データ)
・系列が「日付の最小の月」

 6月の売上はすべて6月初回購入日の会員で構成されます。このデータは6月から始まるデータだからそうなります。

 7月の売上は6月初回購入の会員と7月初回購入の会員で構成されます。

 月次で新規会員が上積みされ、過去の会員のうちの一部が消え去り、数か月後に復活することもあります。

 チャートから
・7月、8月の新規会員は安定的に継続購入がある
・9月の新規会員は離脱が目立つ
・10月、11月は新規会員の売上が少ない

グループ化に挑戦

合計スコア
合計スコア

・軸が「合計スコア」
・値がR・F・Mそれぞれの平均
・組み合わせグラフ

 それらしくグループ化できているように見えます。しかし、何か特徴的な事象を発見できるかというと難しいと思います。
 R・F・Mすべての値が合計スコアと完全に比例しているからです。平均を表示しているからなのか。

平均・最大値・最小値

 R・F・Mそれぞれの平均値、最大値、最小値を表示します。

 例えば、本日来店した会員も2か月以上来店していない会員も同一グループになることがあります。
 それぞれの最大値・最小値の幅が大きくグループ化としては厳しいようです。

合計スコア

・行が「合計スコア」
・値が
「日付 (最大)」
「購入金額 (合計)」
「購入金額 (割合の累計)」
「会員コード (個数)」=来店回数
「会員コード (個数の割合の累計)」

 売上構造の全体を眺めるのにはよい方法だと思います。
 やはり、個別会員へドリルダウンするには物足りないようです。

クラスター

クラスターで特徴を捉えることができるのか

 合計スコア方式をつかえば全会員を13のグループにわけることができます。ところが、各グループの特徴が見えてこない。

 R・F・Mの3変数だから・・・クラスターを形成すればどうか!

スコアでクラスター
変数

 R・F・Mそれぞれのスコアを変数にしてクラスタリングを行います。

クラスタリング結果

 結果をプロットします。R・F・Mそれぞれの値は平均です。
 M (平均) 降順に並び替えています。RとFに山あり谷あり、Mの降順と比例しないクラスターがあるあたりが期待できます。

平均値・最大値・最小値

 それぞれの最大値と最小値に大きな幅があるように見えますが、感覚的には結構いい線になっているように見えます。何となくですが。

・スコア表の基準値
・スコアの段階数
・データの期間
・クラスター数
 これらの調整がフィットすれば、いい感じになるような気がします。

スコア別会員数

 今回は特に、Rのスコア基準値が甘くスコア5が多すぎたみたいです。食料品スーパーを想定したデータなので、スコア5の基準値を2日、スコア4の基準値を5日くらいまで厳しく設定すべきでしたか。

スコアを使用しないクラスター
変数

 単純にR・F・Mそれぞれの値を変数に設定してクラスタリングすればよいのでは!

 スコア表が要らないし、ややこしいIF文をタイピングする必要がなくなる!

値からクラスタリング

 パッと見て、合計スコアと同じように見えます。

平均値・最大値・最小値

 内容はM (購入金額) の大小によってクラスタリングされます。ほぼデシルです。

・スコア表の基準値
・スコアの段階数
・データの期間
・クラスター数
 これらの調整でも希望が見えてきません。ちなみに、クラスター数60で試しましたが、残念な結果でした。