PythonでRFM分析の分類結果をグラフで描画してみた

こんにちは。広告システム開発部の小林です。

現在、データ解析の勉強を行っているので、今回はRFM分析のことを記事にしてみました。 なお、本記事はデータを分類しグラフの描画までを行う内容となっています。 分類後の解析などは本記事には含まれていません。

︎RFM分析とは

RFM分析は、Recency (最新購入日)、Frequency (購入頻度)、Monetary (購入金額)の3つの指標でユーザーを分類し、ユーザーの購買情報を解析する手法です。 RFM分析では、以下のような分析ができます。

  • Recency が現在に近いユーザーほど将来の収益に貢献する可能性が高い
  • Recency が同じなら Frequency が多いほど常連客になっている
  • Recency が同じなら Frequency や Monetary が高いほど購買力があるユーザー

サーバー︎環境

  • CentOS 6.7
  • Python 3.5.2

  • Pythonのパッケージ

    • matplotlib 2.0.0 グラフの描画に使用します
    • numpy 1.11.3 数値の計算に使用します
    • pandas 0.19.2 CSVを読み込み、データの集計に使用します

Pythonと各種パッケージのインストールについては割愛させていただきます。

︎分類方法

Python でのデータの分類方法をご紹介します。 集計対象のデータですが、以下のようなCSVを使用します。 データの内容は、2017/01/01 ~ 2017/01/31 の購入情報となります。 集計日を 2017/02/01 とするため前月となる 2017年1月 のデータを用意しています。 ※サンプルデータなので、グラフの描画に適したデータとなるように加工しています。

order_id,uid,amount,time
1,a,100,1483232400
2,b,200,1483318800
3,c,300,1483405200
4,d,400,1483491600
5,e,500,1483578000
6,f,600,1483664400
7,g,700,1483750800
8,h,800,1483837200
9,i,900,1483923600
10,j,1000,1484010000
.
.
.
210,ae,50,1485738000
211,ae,50,1485738000
212,ae,50,1485738000

データの内容

  • order_id : 購入ID(ユニーク)
  • uid : ユーザーID(重複あり)
  • amount : 1回の購入金額
  • time : 購入日(Unixtime)

コードは以下のようになっています。

# 必要なパッケージをimport
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt

# CSVを読み込む
conversion_data = pd.read_csv('blog_sample.csv')
print(conversion_data.head())

#   order_id  uid  amount        time
#0         1    a     100  1483232400
#1         2    b     200  1483318800
#2         3    c     300  1483405200
#3         4    d     400  1483491600
#4         5    e     500  1483578000

# 集計日のtimestampを取得 (今回は2017/02/01に指定します)
NOW = int( dt.datetime(2017,2,1).strftime('%s') )

# uidを元にグループ化して、集計を行う
rfm = conversion_data.groupby('uid').agg({'amount': [np.sum], # 購入金額
                                          'time': lambda x: int( (NOW - x.max()) / 86400 ), # 最新購入日
                                          'order_id': [len] # 購入頻度
                                          })
print(rfm.head())

#    amount     time order_id
#       sum <lambda>      len
#uid
#a      100       30        1
#b      400       27        3
#c      800       24        4
#d      450       22        2
#e     1200       20        2

# グラフ描画用の設定
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter3D(rfm['time'], rfm['order_id'], rfm['amount'])

# ️グラフをファイルに保存
filename = "/tmp/3d_output.png"
plt.savefig(filename)

グループ化している以下の部分は、sum したり 項目の数をカウントするのはすんなりできたのですが、最新購入日の取得に苦労しました。

timestamp のままだと桁数が多いためかグラフ描画時にうまく描画されないので、集計日(2017/02/01)から購入日の timestamp を引いて直近何日前に購入されたかを算出しています。

rfm = conversion_data.groupby('uid').agg({'amount': [np.sum],
                                          'time': lambda x: int( (NOW - x.max()) / 86400 ),
                                          'order_id': [len]
                                          })

コードの実行後に[filename]で指定したパスにグラフが画像ファイルとして描画されます。 上記のコードの場合は、[tmp/3d_output.png]に出力されます。 描画されたグラフは以下のようになります。

rfm_グラフ

項目が書かれていないので、ちょっと見づらく感じます。 補足を追記してみました。

rfm_グラフ_補足

所感

Python を書くのが初めてだったので、とても苦労しました。 データ解析の道のりは長いと感じました。 次回はデータの解析に焦点を当てた記事を書こうと思います。 最後まで読んで頂きありがとうございました。