入门文献复现——Combining belief functions based on distance of evidence Deng Yonga,2, Shi WenKanga, Zhu Zhe

2023-10-26

这个Paper结合BOE之间的距离的思想,对Murphy的方法进行了改进
代码注解:虽然代码写的还是一如既往的臭,仅仅知识为了获得运行结果而写,但还是基本复现了Paper。
#基于加权质量的平均法
#1. 计算BOE之间的距离d(m_i,m_j)
##1.1. 计算m_i∪m_j
##1.2. 利用并集的基数构建向量矩阵 vector_m_i,vector_m_j
##1.3. 构建D=矩阵,大小为|m_i∪m_j|*|m_i∪m_j|
##1.4. 利用公式求d(m_i,m_j)

#2. 利用上面的距离导出BOE之间的相似度Sim(m_i,m_j)

#3.利用相似度Sim(m_i,m_j)构建相似矩阵SMM

#4. 计算各个BOE的支持度 Sup(m_i)

#5. 将支持度Sup(m_i)进行规范化转为权重因子 Crd_i

#6. 计算出加权的平均质量(BPA)

#7. 利用Murphy的方法进行迭代计算
#*********************切割线*****************************#
import pandas as pd
import numpy as np
#数据类型规定#
#1、初始状态的BOE的数据类型为字典dict,例如boe1={"A":0.5,"B":0.2,"C":0.3}
# boe1={"A":0.5,"B":0.2,"C":0.3}
# boe2={"A":0,"B":0.9,"C":0.1}
# boe3={"A":0.55,"B":0.1,"AC":0.35}
# boe4={"A":0.55,"B":0.1,"AC":0.35}
# boe5={"A":0.6,"B":0.1,"AC":0.3}
########准备函数区#################
#抽取字典中的key值,并装进集合中,并且返回集合
def focal_Element(boe):
    key_m=[];
    m_key=boe.keys();
    for item in m_key:
        key_m.append(item)
    keym_set=set(key_m);
    return keym_set;
#*********************切割线*****************************#
#计算任意两个BOE中的并集
def setUnion(boeI,boeJ):
    #提取集合
    setBoe1=focal_Element(boeI);
    setBoe2=focal_Element(boeJ);
    return setBoe1.union(setBoe2);
#构建列向量,生成n*2的矩阵
#第一列:vector(boeI)
#第二列:vector(boeJ)
def columnVector(boeI,boeJ):
    unionSets=setUnion(boeI,boeJ);
    list_name=["key","boeI","boeII"];#这是矩阵的第一行
    list_matrix=[];
    list_matrix.append(list_name);
    for item in unionSets:
        list_value = list();
        list_value.append(item)
        if item in boeI.keys():
            value_I=boeI[item];
        else:
            value_I=0;
        list_value.append(value_I);
        if item in boeJ.keys():
            value_J=boeJ[item];
        else:
            value_J=0;
        list_value.append(value_J);
        list_matrix.append(list_value);#将所有的列表装入
    return np.array(list_matrix);
#返回vector_1-vector_2的结果
def vectorDifference(boeI,boeJ):
    vector_1_2=columnVector(boeI,boeJ);#生成记录两个列向量的矩阵
    #下面进行切片操作
    vector_1=vector_1_2[:,(0,1)];#第一个列向量
    vector_2=vector_1_2[:,(0,2)];#第二个列向量
    line,column=vector_1.shape;
    for i in range(1,line):
        for j in range(1,line):
            if(vector_1[i,0]==vector_2[j,0]):
                vector_1[i,1]=float(vector_1[i,1])-float(vector_2[j,1]);
    vector_1[0,1]="boe"
    return vector_1;
#初始化D==矩阵
def initMatrixD(boeI,boeJ):
    vertorDif=vectorDifference(boeI,boeJ);#两个列向量的插值
    lines,columns=vertorDif.shape;
    set_Key=set();
    #获取m1∪m2的值
    for i in range(1,lines):
        set_Key.add(vertorDif[i,0]);
    line_one=["0"];
    for item in set_Key:
        line_one.append(item);
    listD=[];#首先都装入一个矩阵当中
    listD.append(line_one);
    #开始初始化D=矩阵
    for i in range(1,lines):
        tmp_list=[];#临时列表
        tmp_list.append(line_one[i])
        for j in range(1,lines):
            tmp_list.append(0)
        listD.append(tmp_list)
    dMatrix=np.array(listD);#此时dmatrix是初始的矩阵
    return dMatrix;
#对D=矩阵进行赋值,并返回D=矩阵
def matrixD(boeI,boeJ):
    initMatrix=initMatrixD(boeI,boeJ);#生成一个初始化的矩阵
    #下面生成矩阵中的值。
    lines,columns=initMatrix.shape;
    initMatrix=initMatrix[initMatrix[:,0].argsort()]#对行进行排序
    initMatrix=initMatrix[:,initMatrix[0].argsort()]#在对列进行排序
    if(lines!=columns):
        print("初始化矩阵出现错误");
        return;
    #这是两个临时集合。
    list_m=[]
    for i in range(1,lines):
        str_0=initMatrix[i, 0][:]
        set_column=set(str_0)
        list_t = []
        for j in range(1,lines):
            str_1=initMatrix[0,j][:];
            set_line=set(str_1);
            interChild=len(set_line.intersection(set_column));#交集元素的个数做分子
            unionMother=len(set_line.union(set_column));#并集元素的个数做分母
            sum=interChild/unionMother;
            list_t.append(sum)
            set_line.clear();
        list_m.append(list_t)
        set_column.clear();
    initMatrix=np.array(list_m)
    return initMatrix;
#获取两个BOE之间的距离,d(m1,m2)
def getDistance(boeI,boeJ):
    vector_column=vectorDifference(boeI,boeJ);#这是(vector(m1)-vector(m2))的结果,列向量
    x, y = vector_column.shape;
    vector_column=vector_column[1:x,:]#去除第一行
    vector_column=vector_column[vector_column[:,0].argsort()]#按照第0列排序并扩展到其它区域
    x,y=vector_column.shape;
    vector_=vector_column[:,y-1];
    x=vector_.shape[0];
    vector_=vector_.reshape(x,1)
    x,y=vector_.shape;
    list_tmp=[];#将向量中的值的类型改变为float型
    for i in range(0,x):
        sum=float(vector_[i, y - 1])
        list_tmp.append(sum);
    vector_0=np.array(list_tmp).reshape(x,1);#列向量
    vector_T=vector_0.reshape(1,x);#行向量
    #到这里,已经抽取完了两个向量。
    dMatrix=matrixD(boeI,boeJ);#这是D=矩阵,已经按照顺序排好
    result_0=np.dot(vector_T,dMatrix);
    result_1=result_0.dot(vector_0);
    result_finall=(1/2)*result_1[0][0]
    distance=pow(result_finall,1/2);
    return distance;
#获得两个BOE之间的相似度
def getSimilar(boeI,boeJ):
    return 1-getDistance(boeI,boeJ);
#构建相似度矩阵
#*args为可变参数,代表一个元组tuple
def SMM(n,*args):
    SMM_=np.zeros((n,n),dtype=float);#初始化一个矩阵
    for i in range(0,n):
        for j in range(0,n):
            SMM_[i,j]=getSimilar(args[i],args[j]);#赋值,构建SMM矩阵
    return SMM_;
#计算BOE的支持度,并且返回支持率Crdi
#数据类型为字典
def Crdi(n,*args):
    smm=SMM(n,*args);
    if n<1:
        print("Crdi 错误")
        exit(0);
    str_0="m"
    dictSup=dict();#字典,记录支持
    totalSup=0.00
    for i in range(0,n):
        sup= 0.00
        for j in range(0,n):
            if j!=i:
                sup+=smm[i,j]
        str_1 = str_0 + str(i + 1);
        totalSup+=sup;
        if str_1 in dictSup.keys():
            dictSup[str_1]=sup;
        else:
            dictSup[str_1]=sup;
    #将SUP转化为支持率Crdi
    for item in dictSup.keys():
        crdi=dictSup[item]/totalSup;
        dictSup[item]=crdi;
    return dictSup
#计算出加权平均质量
def MAE(n,*args):
    dictCrdi=Crdi(n,*args);#这是支持率
    #print(dictCrdi)
    #首先获得并集,装进列表中
    keysList=[];
    for item in args:
        keysList.append(focal_Element(item));
    #求这几个的并集
    keySet=set();
    for item in keysList:
        keySet=keySet.union(item);
    keysList=list(keySet);
    keysList.sort()#排序
    #首先统一元素,不存的值为0
    for item_key in keysList:
        for item_fun in args:
            if item_key not in item_fun.keys():
                item_fun[item_key]=0;
    str_0="m"
    dict_Result = dict();
    for item_key in keysList:
        i = 0;
        values=0.00
        for item_fun in args:
            i = i + 1;
            str_1=str_0+str(i);
            if item_key in item_fun.keys():
                if str_1 in dictCrdi.keys():
                    values+=item_fun[item_key]*dictCrdi[str_1]
        if item_key in dict_Result.keys():
            dict_Result[item_key]=values;
        else:
            dict_Result[item_key] = values;
    #print(dict_Result);
    return dict_Result;
#计算m_empty,直接返回值
def computeEmpty(m_1,m_2):
    F1=focal_Element(m_1);
    F2=focal_Element(m_2);
    # 构造空集合
    theta_set1 = set();
    theta_set2 = set();
    empty = set();
    m_empty = 0.00
    for item1 in F1:
        theta_set1.update(item1);
        for item2 in F2:
            theta_set2.update(item2);
            if (theta_set1.intersection(theta_set2) == empty):
                m_empty += m_1[item1] * m_2[item2];
            theta_set2.clear();
        theta_set1.clear();
    return m_empty;
#计算 m_intersection,返回计算好的。
def computeInter(m_1,m_2):
    F1=focal_Element(m_1);
    F2=focal_Element(m_2);
    thetaSet=F2;
    #空集合
    f1_set=set();
    f2_set=set();
    strSet=set();
    inter=dict();
    for item0 in thetaSet:
        strSet.update(item0);
        sum=0.00
        for item1 in F1:
            f1_set.update(item1);
            for item2 in F2:
                f2_set.update(item2);
                if(f1_set.intersection(f2_set)==strSet):
                    sum+=m_1[item1]*m_2[item2];
                f2_set.clear();
            f1_set.clear();
        if item0 in inter:
            inter[item0]=sum;
        else:
            inter[item0] = sum;
        #inter.update(dict.fromkeys(item0,sum));
        strSet.clear();
    return inter;
# n:迭代次数
# avgSet:初始的average
def weightAvg(n,avgSet):
    for i in range(1,n):
        if(i==1):
            diedai=computeInter(avgSet,avgSet);#返回没有归一化的交集
            k=computeEmpty(avgSet,avgSet);#冲突质量
            k=1/(1-k);#归一化处理
            for item in diedai.keys():
                if item in diedai:
                    value_=round(diedai[item]*k,4);
                    diedai[item]=value_;
            diedai_0 = diedai;
            print("第 {0} 次迭代结果:{1}".format(i,diedai));
        else:
            diedai_1=computeInter(diedai_0,avgSet);
            k=computeEmpty(diedai_0,avgSet);
            k=1/(1-k);#归一化处理
            for item in diedai_1:
                if item in diedai_1:
                    value_=round(diedai_1[item]*k,4);
                    diedai_1[item]=value_;
            #diedai_0.clear();
            print("第 {0} 次迭代结果:{1}".format(i, diedai_1));
            diedai_0=diedai_1;
            #diedai_1.clear();
if __name__ == '__main__':
    boe1={"A":0.5,"B":0.2,"C":0.3}
    boe2={"A":0,"B":0.9,"C":0.1}
    boe3={"A":0.55,"B":0.1,"AC":0.35}
    boe4={"A":0.55,"B":0.1,"AC":0.35}
    boe5={"A":0.6,"B":0.1,"AC":0.3}
    n=5
    avgSet=MAE(n,boe1,boe2,boe3,boe4,boe5);
    weightAvg(n,avgSet)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

入门文献复现——Combining belief functions based on distance of evidence Deng Yonga,2, Shi WenKanga, Zhu Zhe 的相关文章

随机推荐