项目成果:客户细分

在客户关系分析中,常用RFM模型(近度、频度、价值)分为以下两个步骤:

  1. 计算特征权重:层次分析法(Analytic hierarchy process)
  2. 客户分类:调用聚类模型(Kmeans)

本项目实现的是编写算法模块(层次分析法)。

关键词:成对比较矩阵,1-9标度方法,一致性检验,R.I.随机一致性指标查询表

In [ ]:
# 编写AHP方法模块
import numpy as np
class AHP():
    '''
    模块名称:
        层次分析法
    模块用途:
        get_weights():计算权重
        check_consisitency():检验一致性
        main():主函数(可直接调用此函数获得全部结果)
    '''
    # 类变量(常量)
    RI_DICT = {1: 0, 2: 0, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49}
    # 输入评分矩阵(成对比较矩阵)
    def __init__(self, array):
        self.array = array # 成对比较矩阵(维度评分表)
        self.n = array.shape[0] # 矩阵维数
    # 计算权重
    def get_weights(self): 
        sum_col = self.array.sum(axis=0) # 每列求和
        divided_col = self.array/sum_col # 计算维度间相对权重
        w = divided_col.sum(axis=1)/self.n # 计算各维度权重平均值
        return w
    # 检验一致性
    def check_consisitency(self):
        a, b = np.linalg.eig(self.array) # a为特征值,b为特征向量,仅提取实数部分
        CI = (max(a) - self.n)/ (self.n - 1) # 非一致性指标CI
        RI = self.RI_DICT[self.n] # 随机一致性指标RI
        CR = CI / RI # 非一致性比率CR
        if CR < 0.1:
            w = self.get_weights() # 内部调用
            print('评分矩阵通过一致性检验,CR值为 % .2f' %CR)
            print('最大特征值:%.2f,矩阵维数:%s' %(np.real(max(a)), self.n))
            print('评分矩阵的指标权重:%s' % w)
            return w
        else:
            print('未通过一致性检验,需调整评分矩阵。CR值为 % .2f' %CR)
            print('最大特征值:%.2f,矩阵维数:%s' %(np.real(max(a)), self.n))
            result = ['None']
            return result*self.n
    # 检查输入格式
    def main(self):
        if type(self.array) is np.ndarray:
            return self.check_consisitency() # 内部调用
        else:
            print('请输入numpy数组')
In [12]:
# 查看模块
import module_analytic
print(module_analytic.AHP.__doc__) # 显示模块内置说明
print(module_analytic.AHP.RI_DICT) # 显示类变量RI_DICT
print(module_analytic.AHP.__dict__) # 显示类包含的所有预定义属性名称、类变量、函数
print(module_analytic.AHP.__name__) # 显示类名称
print(module_analytic.AHP.__bases__) # 显示继承的父类
print(module_analytic.AHP.__module__) # 显示所属模块名称
    模块名称:
        层次分析法
    模块用途:
        get_weights():计算权重
        check_consisitency():检验一致性
        main():主函数(可直接调用此函数获得全部结果)
    
{1: 0, 2: 0, 3: 0.58, 4: 0.9, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49}
{'__module__': 'module_analytic', '__doc__': '\n    模块名称:\n        层次分析法\n    模块用途:\n        get_weights():计算权重\n        check_consisitency():检验一致性\n        main():主函数(可直接调用此函数获得全部结果)\n    ', 'RI_DICT': {1: 0, 2: 0, 3: 0.58, 4: 0.9, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49}, '__init__': <function AHP.__init__ at 0x0000016204BB96A8>, 'get_weights': <function AHP.get_weights at 0x0000016204BB9730>, 'check_consisitency': <function AHP.check_consisitency at 0x0000016204BB97B8>, 'main': <function AHP.main at 0x0000016204BB9840>, '__dict__': <attribute '__dict__' of 'AHP' objects>, '__weakref__': <attribute '__weakref__' of 'AHP' objects>}
AHP
(<class 'object'>,)
module_analytic
In [5]:
# test_case
import numpy as np
x = np.array([[1, 1/8, 1/5, 1/2, 1/8, 1/5, 1/2],
            [8,1,1/2,1,1/2,1/2,1],
            [5,2,1,1,1/2,1,1],
            [2,1,1,1,1/4,1/2,1],
            [8,2,2,4,1,0.5,1],
            [5,2,1,2,2,1,1/2],
            [2,1,1,1,1,2,1]])

test_ahp = module_analytic.AHP(x) # 创建实例
test_ahp.main() #调用类的内部函数
评分矩阵通过一致性检验,CR值为  0.08
最大特征值:7.67,矩阵维数:7
评分矩阵的指标权重:[0.03787191 0.12641825 0.15144125 0.10278494 0.22816213 0.19300904
 0.16031248]
C:\Users\spark\Documents\工作准备0728\module_analytic.py:40: ComplexWarning: Casting complex values to real discards the imaginary part
  print('评分矩阵通过一致性检验,CR值为 % .2f' %CR)
Out[5]:
array([0.03787191, 0.12641825, 0.15144125, 0.10278494, 0.22816213,
       0.19300904, 0.16031248])
In [7]:
# 读取文件
import pandas as pd
score = pd.read_excel(r'C:\Users\spark\Documents\for_practice\weights_matrix.xlsx', sheet_name='Sheet1')
array = np.array(score.ix[:,1:])
# 获取权重结果
rfm = module_analytic.AHP(array) # 创建实例rfm(即初始化)
weights = pd.DataFrame([rfm.main()], index=['weighs'], columns=score.columns.values[1:])
print(weights)
评分矩阵通过一致性检验,CR值为  0.06
最大特征值:3.06,矩阵维数:3
评分矩阵的指标权重:[0.64338887 0.28283902 0.07377211]
         recency  frequency  monetary
weighs  0.643389   0.282839  0.073772
C:\Users\spark\Anaconda3\lib\site-packages\ipykernel_launcher.py:4: DeprecationWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
  after removing the cwd from sys.path.
C:\Users\spark\Documents\工作准备0728\module_analytic.py:40: ComplexWarning: Casting complex values to real discards the imaginary part
  print('评分矩阵通过一致性检验,CR值为 % .2f' %CR)