AHP基本思路
AHP通常用于决策判断的重要依据,在某些方面具有很好的指导作用,尤其是定性判断指标转化为定量数据时。比如我们打算新建一座商场,初步认定了A、B、C三地,这三个地区的各项指标都非常接近,此时决策者在做判断时基本就会以拍脑袋为主,这样得出的结论缺乏科学性和说服力,因此这里我们就可以考虑引入AHP来解决这个问题,AHP通过将目标和选择项分别放于最上层和最底层,中间为评价指标,将各指标值按照一定权值加起来得到一个最终的分数,选取分数最大的项为最终结果项,如下图:
层次分析法(AHP)

AHP项目应用:
1.介绍完AHP的基本思路后,接下来使用AHP计算用户价值贡献度。
(1)按照用户涉及到的各项业务进行分层,这里我根据项目需要将各项指标分成了三层,第一层为大类指标,主要包含基本属性、行为属性和业务属性,第一层下面为第二层,主要是对第一层的细分,如基本属性下包括信息完整度、认证状况、GPS使用状况等,第三层则为第二层的进一步细分,这类指标通常都为定量数据,或可转化为定量数据的定性数据;
(2)从下往上计算每一层各项指标的权值w,在该项目中只需从第二层开始计算即可;
(3)各层指标值乘以对应权值的累加和即为其大类的值,这一步需要从最底层即第三层开始计算,最后将所有的指标结果加起来便为各个用户的价值贡献度。

2.AHP最核心的部分在于各中间层指标的权值求取,在此过程中其参考了1-9评分规则,将各层间属于同类的指标进行两两比较,由相关的业务人员判断对比的指标哪一项对当前项目结果更重要。

指标a a极度重要 a非常重要 a重要 a稍微重要 同等重要 b极度重要 b非常重要 b重要 b稍微重要 指标b
信息完整度 1 认证状况
信息完整度 GPS使用
认证状况 GPS使用

业务人员可通过以上表格对指标进行比较,若觉得信息完整度比认证状况重要很多,则可在第一行对应的‘a非常重要’一栏标注为1。
3.将对比结果转化为相应的评分矩阵

def convert_martix(data):
    compute_pos = []
    pos_to_value = []
    data_shape = data.shape
    matrix = np.eye(indicates)
    #获取对比指标的评分值做在位置
    for i in range(data_shape[0]):
        for j in range(data_shape[1]):
            if data[i][j] == 1:
                compute_pos.append([i,j])
    pos_shape = np.array(compute_pos).shape
    for i in range(pos_shape[0]):
        value = 0.0
        if compute_pos[i][1] == 1:
            value = 9
        elif compute_pos[i][1] == 2:
            value = 7
        elif compute_pos[i][1] == 3:
            value = 5
        elif compute_pos[i][1] == 4:
            value = 3
        elif compute_pos[i][1] == 5:
            value = 1
        elif compute_pos[i][1] == 6:
            value = 1.0 / 3
        elif compute_pos[i][1] == 7:
            value = 1.0 / 5
        elif compute_pos[i][1] == 8:
            value = 1.0 / 7
        elif compute_pos[i][1] == 9:
            value = 1.0 / 9
        pos_to_value.append(value)

    if indicates == 3:
        #对称轴上三角
        matrix[0][1] = pos_to_value[0]
        matrix[0][2] = pos_to_value[1]
        matrix[1][2] = pos_to_value[2]
        # 对称轴下三角
        matrix[1][0] = 1.0 / matrix[0][1]
        matrix[2][0] = 1.0 / matrix[0][2]
        matrix[2][1] = 1.0 / matrix[1][2]
    elif indicates == 4:
        matrix[0][1] = pos_to_value[0]
        matrix[0][2] = pos_to_value[1]
        matrix[0][3] = pos_to_value[2]
        matrix[1][2] = pos_to_value[3]
        matrix[1][3] = pos_to_value[4]
        matrix[2][3] = pos_to_value[5]
        matrix[1][0] = 1.0 / matrix[0][1]
        matrix[2][0] = 1.0 / matrix[0][2]
        matrix[3][0] = 1.0 / matrix[0][3]
        matrix[2][1] = 1.0 / matrix[1][2]
        matrix[3][1] = 1.0 / matrix[1][3]
        matrix[3][2] = 1.0 / matrix[2][3]
    elif indicates == 5:
        matrix[0][1] = pos_to_value[0]
        matrix[0][2] = pos_to_value[1]
        matrix[0][3] = pos_to_value[2]
        matrix[0][4] = pos_to_value[3]
        matrix[1][2] = pos_to_value[4]
        matrix[1][3] = pos_to_value[5]
        matrix[1][4] = pos_to_value[6]
        matrix[2][3] = pos_to_value[7]
        matrix[2][4] = pos_to_value[8]
        matrix[3][4] = pos_to_value[9]
        matrix[1][0] = 1.0 / matrix[0][1]
        matrix[2][0] = 1.0 / matrix[0][2]
        matrix[3][0] = 1.0 / matrix[0][3]
        matrix[4][0] = 1.0 / matrix[0][4]
        matrix[2][1] = 1.0 / matrix[1][2]
        matrix[3][1] = 1.0 / matrix[1][3]
        matrix[4][1] = 1.0 / matrix[1][4]
        matrix[3][2] = 1.0 / matrix[2][3]
        matrix[4][2] = 1.0 / matrix[2][4]
        matrix[4][3] = 1.0 / matrix[3][4]
    elif indicates == 6:
        matrix[0][1] = pos_to_value[0]
        matrix[0][2] = pos_to_value[1]
        matrix[0][3] = pos_to_value[2]
        matrix[0][4] = pos_to_value[3]
        matrix[0][5] = pos_to_value[4]
        matrix[1][2] = pos_to_value[5]
        matrix[1][3] = pos_to_value[6]
        matrix[1][4] = pos_to_value[7]
        matrix[1][5] = pos_to_value[8]
        matrix[2][3] = pos_to_value[9]
        matrix[2][4] = pos_to_value[10]
        matrix[2][5] = pos_to_value[11]
        matrix[3][4] = pos_to_value[12]
        matrix[3][5] = pos_to_value[13]
        matrix[4][5] = pos_to_value[14]
        matrix[1][0] = 1.0 / matrix[0][1]
        matrix[2][0] = 1.0 / matrix[0][2]
        matrix[3][0] = 1.0 / matrix[0][3]
        matrix[4][0] = 1.0 / matrix[0][4]
        matrix[5][0] = 1.0 / matrix[0][5]
        matrix[2][1] = 1.0 / matrix[1][2]
        matrix[3][1] = 1.0 / matrix[1][3]
        matrix[4][1] = 1.0 / matrix[1][4]
        matrix[5][1] = 1.0 / matrix[1][5]
        matrix[3][2] = 1.0 / matrix[2][3]
        matrix[4][2] = 1.0 / matrix[2][4]
        matrix[5][2] = 1.0 / matrix[2][5]
        matrix[4][3] = 1.0 / matrix[3][4]
        matrix[5][3] = 1.0 / matrix[3][5]
        matrix[5][4] = 1.0 / matrix[4][5]
    return matrix

4.对矩阵各纵轴求和

def compute_weight(matrix):
    column_sum = []
    matrix_shape = matrix.shape
    for i in range(matrix_shape[1]):
        column_sum.append(matrix[:,i].sum())
    return column_sum

5.指标权值计算及一致性检验,一致性检验在AHP中具有很重要的地位,它可以矫正业务人员在评分时的随意性,通常要求一致性水平CR小于等于0.1,CR = CI / RI,其中CI = (矩阵特征值 - n) / (n-1) ,n为矩阵中指标个数,RI的值与矩阵阶数有关,参照下表:
层次分析法(AHP)

RI = {3:0.51, 4:0.89, 5:1.12, 6:1.25, 7:1.35, 8:1.42, 9:1.45, 10:1.49, 11:1.52}
def consis_check(data_arraty,n,ri,guide_line=0.1):
    #计算CI及相应权值
    x = convert_martix(data_arraty)
    y = np.mat(martix_col_sum(x))
    c = x / y
    w = np.mat(c.sum(axis=1) / n)
    CI = (np.dot(y, w) - n) / (n - 1)
    CI = CI[0][0]
    RI = ri
    CR = CI / RI
    if CR <= guide_line:
        print '一致性检验通过,指标依次权值为:'
        print w.T
    else:
        print '\n*****一致性检验未通过,请重新评估*****'
        print CR

6.最后上传各指标对比数据,并依序执行上面的函数,可获得对应的指标权值

def data_loads():
    columns = ['a','aExtreme','aVery','aImport','aLittle','equal','bLittle','bExtreme','bVery','bImport','b']
    data = pd.read_excel('D:\\ahp.xlsx',skiprows=1,names=columns)
    indicates = len([x for x in data['a'].append(data['b']).duplicated() if x == False])
    print indicates
    data_arraty = np.array(data)
    return data_arraty,indicates

data_arraty,indicates = data_loads()
consis_check(data_arraty,indicates,RI[indicates])

最终得到结果如下:

一致性检验通过,指标依次权值为:
[[ 0.74558145  0.12011708  0.13430147]]