10.RFM分析&矩阵分析

1.RFM分析

根据客户活跃程度和交易金额贡献,进行客户价值细分的方法。

指标 解释 意义
Recency近度 客户最近一次交易时间到现在的间隔 R越大,越久未发生交易;R越小,越近有交易发生
Frequency频度 客户最近一段时间内交易的次数 F越大,客户交易越频繁;F越小,客户不够活跃
Monetary额度 客户最近一段时间内交易的金额 M越大,客户价值越高;M越小,客户价值越低
屏幕快照 2018-07-07 17.08.24.png
R_S分类 F_S分类 M_S分类 客户类型
高价值客户
重点保持客户
重点发展客户
重点挽留客户
一般价值客户
一般保持客户
一般发展客户
潜在客户

1.1 RFM分析过程

1.计算RFM各项分值

  • R_S:距离当前日期越近,得分越高,最高5分,最低1分。
  • F_S:交易频率越高,得分越高,最高5分,最低1分。
  • M_S:交易金额越高,得分越高,最高5分,最低1分。

2.汇总RFM分值

RFM=100*R_S+10*F_S+1*M_S

3.根据RFM分值对客户划分8种类型

1.2 RFM分析前提

1.最近有过交易行为的客户,再次发生交易的可能性要高于最近没有交易行为的客户。
2.交易频率较高的客户比交易频率较低的客户,更有可能再次发生交易行为。
3.过去所有交易总金额较多的客户,比交易总金额较少的客户,更有消费积极性。

1.3 RFM计算过程

import pandas
import numpy
data = pandas.read_csv(
    '/users/bakufu/desktop/5.7/data.csv'        
)
Out[37]: 
       OrderID  CustomerID DealDateTime  Sales
0         4529       34858   2014-05-14    807
1         4532       14597   2014-05-14    160
2         4533       24598   2014-05-14    418
3         4534       14600   2014-05-14    401
4         4535       24798   2014-05-14    234
5         4536       44856   2014-05-14    102
6         4558       34695   2014-05-14    130
7         4559       24764   2014-05-14    377
8         4566       34765   2014-05-15    466
9         4567       34581   2014-05-15    821
10        4568       44637   2014-05-15     84
       ...         ...          ...    ...
15866    54843       24686   2015-09-25    683
[15867 rows x 4 columns]

data['DealDateTime'] = pandas.to_datetime(
    data.DealDateTime,
    format='%Y/%m/%d'        
)
Out[37]: 
       OrderID  CustomerID DealDateTime  Sales
0         4529       34858   2014-05-14    807
1         4532       14597   2014-05-14    160
2         4533       24598   2014-05-14    418
3         4534       14600   2014-05-14    401
4         4535       24798   2014-05-14    234
5         4536       44856   2014-05-14    102
6         4558       34695   2014-05-14    130
7         4559       24764   2014-05-14    377
8         4566       34765   2014-05-15    466
9         4567       34581   2014-05-15    821
10        4568       44637   2014-05-15     84
       ...         ...          ...    ...
15866    54843       24686   2015-09-25    683
[15867 rows x 4 columns]

data['DateDiff'] = pandas.to_datetime(
    'today'        
) - data['DealDateTime']
Out[41]: 
       OrderID  CustomerID DealDateTime  Sales  DateDiff
0         4529       34858   2014-05-14    807 1515 days
1         4532       14597   2014-05-14    160 1515 days
2         4533       24598   2014-05-14    418 1515 days
3         4534       14600   2014-05-14    401 1515 days
4         4535       24798   2014-05-14    234 1515 days
5         4536       44856   2014-05-14    102 1515 days
6         4558       34695   2014-05-14    130 1515 days
7         4559       24764   2014-05-14    377 1515 days
8         4566       34765   2014-05-15    466 1514 days
9         4567       34581   2014-05-15    821 1514 days
10        4568       44637   2014-05-15     84 1514 days
       ...         ...          ...    ...       ...
15866    54843       24686   2015-09-25    683 1016 days
[15867 rows x 5 columns]

data['DateDiff'] = data['DateDiff'].dt.days
Out[43]: 
       OrderID  CustomerID DealDateTime  Sales  DateDiff
0         4529       34858   2014-05-14    807      1515
1         4532       14597   2014-05-14    160      1515
2         4533       24598   2014-05-14    418      1515
3         4534       14600   2014-05-14    401      1515
4         4535       24798   2014-05-14    234      1515
5         4536       44856   2014-05-14    102      1515
6         4558       34695   2014-05-14    130      1515
7         4559       24764   2014-05-14    377      1515
8         4566       34765   2014-05-15    466      1514
9         4567       34581   2014-05-15    821      1514
10        4568       44637   2014-05-15     84      1514
       ...         ...          ...    ...       ...
15866    54843       24686   2015-09-25    683      1016
[15867 rows x 5 columns]

R_Agg = data.groupby(
    by=['CustomerID']        
)['DateDiff'].agg({
    'RecencyAgg': numpy.min        
})
Out[45]: 
            RecencyAgg
CustomerID
14568             1024
14569             1114
14570             1044
14571             1084
14572             1108
14573             1094
14574             1019
14575             1019
14576             1069
14577             1030
...                ...
44867             1107
[1200 rows x 1 columns]

F_Agg = data.groupby(
    by=['CustomerID']        
)['OrderID'].agg({
    'FrequencyAgg': numpy.size        
})
Out[47]: 
              RecencyAgg
CustomerID
14568                 15
14569                 12
14570                 15
14571                 15
14572                  8
14573                 10
14574                 15
14575                 17
14576                 13
14577                  8
...                ...
44867                 10
[1200 rows x 1 columns]

M_Agg = data.groupby(
    by=['CustomerID']        
)['Sales'].agg({
    'MonetaryAgg': numpy.sum        
})
Out[49]: 
            MonetaryAgg
CustomerID             
14568              6255
14569              5420
14570              8261
14571              8124
14572              3334
14573              4358
14574              8506
14575              7432
14576              6481
14577              2737
...                ...
44867              4187
[1200 rows x 1 columns]

aggData = R_Agg.join(F_Agg).join(M_Agg)
Out[51]: 
            RecencyAgg  FrequencyAgg  MonetaryAgg
CustomerID                                       
14568             1024            15         6255
14569             1114            12         5420
14570             1044            15         8261
14571             1084            15         8124
14572             1108             8         3334
14573             1094            10         4358
14574             1019            15         8506
14575             1019            17         7432
14576             1069            13         6481
14577             1030             8         2737
               ...           ...          ...
44867             1107            10         4187
[1200 rows x 3 columns]

bins = aggData.RecencyAgg.quantile(
    q=[0, 0.2, 0.4, 0.6, 0.8, 1],
    interpolation='nearest'        
)
Out[53]: 
0.0    1016
0.2    1023
0.4    1035
0.6    1050
0.8    1069
1.0    1281
Name: RecencyAgg, dtype: int64

bins[0] = 0
labels = [5, 4, 3, 2, 1]
R_S = pandas.cut(
    aggData.RecencyAgg,
    bins, labels=labels     
)
Out[56]: 
0.0       0
0.2    1023
0.4    1035
0.6    1050
0.8    1069
1.0    1281
Name: RecencyAgg, dtype: int64

bins = aggData.FrequencyAgg.quantile(
    q=[0, 0.2, 0.4, 0.6, 0.8, 1],
    interpolation='nearest'        
)
Out[58]: 
0.0     4
0.2    10
0.4    12
0.6    14
0.8    16
1.0    25
Name: FrequencyAgg, dtype: int64

bins[0] = 0;
labels = [1, 2, 3, 4, 5];
F_S = pandas.cut(
    aggData.FrequencyAgg,
    bins, labels=labels        
)
Out[60]: 
0.0     0
0.2    10
0.4    12
0.6    14
0.8    16
1.0    25
Name: FrequencyAgg, dtype: int64

bins = aggData.MonetaryAgg.quantile(
    q=[0, 0.2, 0.4, 0.6, 0.8, 1],
    interpolation='nearest'        
)
Out[62]: 
0.0      735
0.2     4840
0.4     5890
0.6     7036
0.8     8283
1.0    13460
Name: MonetaryAgg, dtype: int64

bins[0] = 0;
labels = [1, 2, 3, 4, 5]
M_S = pandas.cut(
    aggData.MonetaryAgg,
    bins, labels=labels        
)
Out[64]: 
0.0        0
0.2     4840
0.4     5890
0.6     7036
0.8     8283
1.0    13460
Name: MonetaryAgg, dtype: int64

aggData['R_S']=R_S
aggData['F_S']=F_S
aggData['M_S']=M_S
Out[66]: 
            RecencyAgg  FrequencyAgg  MonetaryAgg R_S F_S M_S
CustomerID                                                   
14568             1024            15         6255   4   4   3
14569             1114            12         5420   1   2   2
14570             1044            15         8261   3   4   4
14571             1084            15         8124   1   4   4
14572             1108             8         3334   1   1   1
14573             1094            10         4358   1   1   1
14574             1019            15         8506   5   4   5
14575             1019            17         7432   5   5   4
14576             1069            13         6481   2   3   3
14577             1030             8         2737   4   1   1
               ...           ...          ...  ..  ..  ..
44867             1107            10         4187   1   1   1
[1200 rows x 6 columns]

aggData['RFM'] = 100*R_S.astype(int) + 10*F_S.astype(int) + 1*M_S.astype(int)
Out[68]: 
            RecencyAgg  FrequencyAgg  MonetaryAgg R_S F_S M_S  RFM
CustomerID                                                        
14568             1024            15         6255   4   4   3  443
14569             1114            12         5420   1   2   2  122
14570             1044            15         8261   3   4   4  344
14571             1084            15         8124   1   4   4  144
14572             1108             8         3334   1   1   1  111
14573             1094            10         4358   1   1   1  111
14574             1019            15         8506   5   4   5  545
14575             1019            17         7432   5   5   4  554
14576             1069            13         6481   2   3   3  233
14577             1030             8         2737   4   1   1  411
               ...           ...          ...  ..  ..  ..  ...
44867             1107            10         4187   1   1   1  111
[1200 rows x 7 columns]

bins = aggData.RFM.quantile(
    q=[
        0, 0.125, 0.25, 0.375, 0.5,
        0.625, 0.75, 0.875, 1
    ],
    interpolation='nearest'
)
Out[70]: 
0.000    111
0.125    131
0.250    222
0.375    254
0.500    334
0.625    422
0.750    454
0.875    532
1.000    555
Name: RFM, dtype: int64

bins[0] = 0
labels = [1, 2, 3, 4, 5, 6, 7, 8]
aggData['level'] = pandas.cut(
    aggData.RFM,
    bins, labels=labels        
)
Out[72]: 
0.000      0
0.125    131
0.250    222
0.375    254
0.500    334
0.625    422
0.750    454
0.875    532
1.000    555
Name: RFM, dtype: int64

aggData = aggData.reset_index()
Out[74]: 
      CustomerID  RecencyAgg  FrequencyAgg  MonetaryAgg R_S F_S M_S  RFM level
0          14568        1024            15         6255   4   4   3  443     6
1          14569        1114            12         5420   1   2   2  122     1
2          14570        1044            15         8261   3   4   4  344     5
3          14571        1084            15         8124   1   4   4  144     2
4          14572        1108             8         3334   1   1   1  111     1
5          14573        1094            10         4358   1   1   1  111     1
6          14574        1019            15         8506   5   4   5  545     8
7          14575        1019            17         7432   5   5   4  554     8
8          14576        1069            13         6481   2   3   3  233     3
9          14577        1030             8         2737   4   1   1  411     5
         ...         ...           ...          ...  ..  ..  ..  ...   ...
1199       44867        1107            10         4187   1   1   1  111     1
[1200 rows x 9 columns]

aggData.sort_values(
    ['level', 'RFM'],
    ascending=[1, 1]
)
Out[75]: 
      CustomerID  RecencyAgg  FrequencyAgg  MonetaryAgg R_S F_S M_S  RFM level
4          14572        1108             8         3334   1   1   1  111     1
5          14573        1094            10         4358   1   1   1  111     1
42         14610        1075             7         3685   1   1   1  111     1
59         14627        1076             8         3809   1   1   1  111     1
81         14649        1092             5          735   1   1   1  111     1
82         14650        1122             6         3074   1   1   1  111     1
101        14669        1106             6         2708   1   1   1  111     1
117        14685        1078             9         3839   1   1   1  111     1
123        14691        1091            10         3538   1   1   1  111     1
144        14712        1142             8         3788   1   1   1  111     1
         ...         ...           ...          ...  ..  ..  ..  ...   ...
1188       44856        1017            23        10852   5   5   5  555     8
[1200 rows x 9 columns]

aggData.groupby(
    by=['level']        
)['CustomerID'].agg({
    'size': numpy.size
})
Out[76]: 
       size
level      
1       153
2       164
3       135
4       153
5       154
6       142
7       151
8       148

2.矩阵分析

根据事物(如产品、服务等)等两个重要指标作为分析依据,进行关联分析,找出解决问题等一种分析方法。


屏幕快照 2018-07-07 20.38.02.png
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pandas
import matplotlib
import matplotlib.pyplot as plt

#定义主题颜色,使用RGB方式
mainColor = (42/256, 87/256, 141/256, 1);

#设置字体
font = {
    'family': 'Menlo',
    'size': 20        
}
matplotlib.rc('font', **font);

data = pandas.read_csv(
    '/users/bakufu/desktop/5.8/data.csv'        
)
Out[2]: 
       province  GDP      population
0        天津  1572247       14945
1        北京  2133083       21332
2        上海  2356094       24204
3        江苏  6508832       79498
4        浙江  4015350       55030
5       内蒙古  1776951       25012
6        辽宁  2862658       43907
7        福建  2405576       37900
8        广东  6779224      106840
9        山东  5942659       97614
10       吉林  1380381       27518
11       重庆  1426540       29807
12       湖北  2736704       58075
13       陕西  1768994       37696
14       宁夏   275210        6579
15       新疆   926410       22814
16       湖南  2704846       67139
17       河北  2942115       73582
18       青海   230112        5806
19      黑龙江  1503938       38446
20       海南   350072        8994
21       四川  2853666       81236
22       山西  1275944       36389
23       河南  3493938      100377
24       江西  1570859       45322
25       安徽  2084875       60564
26       广西  1567297       47365
27       西藏    92083        3148
28       云南  1281459       47003
29       甘肃   683527       25865
30       贵州   925101       35051

#如果数据点很多可以调大尺寸
fig = plt.figure(
    figsize=(30, 20),
    dpi=80        
)

#将图形分为一行一列, 当前操作第一个子图
sp = fig.add_subplot(111)

sp.set_xlim([
    0,
    data.GDP.max()*1.1        
])

sp.set_ylim([
    0,
    data.population.max()*1.1        
])
image.png
#关闭坐标轴、坐标轴的刻度值
#sp.axis('off')
sp.get_xaxis().set_ticks([])
sp.get_yaxis().set_ticks([])

#画点
sp.scatter(
    data.GDP, data.population,
    alpha=0.5, s=200, marker="o",
    edgecolors=mainColor, linewidths=5        
)

#画均值线
sp.axvline(
    x=data.GDP.mean(),
    linewidth=1, color=mainColor
)

sp.axhline(
    y=data.population.mean(),
    linewidth=1, color=mainColor       
)

sp.axvline(
    x=0,
    linewidth=3, color=mainColor        
)

sp.axhline(
    y=0,
    linewidth=3, color=mainColor
)

sp.set_xlabel('GDP')
sp.set_ylabel('人口')

#画标签
data.apply(
    lambda row: plt.text(
            row.GDP,
            row.population,
            row.province,
            fontsize=15
            ),
    axis=1
)

plt.show()
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容