【无标题】

  1. 手动输入的矩阵示例
#1.手动输入的矩阵示例,
import numpy as np
#直接影响矩阵A
A = np.array([[0, 3, 3, 3, 1, 2, 3, 3, 3, 3,3,1,0,2,3,1,0],
       [2,0,1,2,2,1,3,1,3,1,3,1,1,2,2,1,1],
       [1,2,0,1,1,2,3,3,3,3,3,1,1,1,0,1,0],
       [1,2,1,0,1,1,2,1,2,1,2,1,2,2,1,1,1],
       [1,2,1,1,0,1,2,1,2,1,2,1,1,1,0,1,0],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [2,2,2,2,2,1,0,1,2,1,2,1,2,1,1,1,1],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [1,3,2,3,2,2,3,1,0,1,2,2,2,2,2,1,2],
       [1,2,1,1,2,2,3,1,2,0,2,1,1,1,1,1,0],
       [1,3,2,3,2,2,3,1,2,2,0,2,2,2,2,1,2],
       [2,2,1,2,2,3,3,1,2,1,2,0,1,3,1,1,1],
       [1,2,1,2,2,2,2,1,2,1,2,1,0,2,1,1,1],
       [1,2,1,2,1,2,2,1,2,1,2,1,1,0,2,2,1],
       [2,2,1,2,1,1,2,1,2,1,2,1,1,2,0,2,1],
       [2,2,1,2,1,1,3,1,1,1,1,1,1,1,2,0,1],
       [0,1,1,0,1,1,2,0,2,0,2,1,1,1,1,1,0]])


#1.第一种方法,利用编程输入矩阵,输出原因,结果,可达矩阵节点

#1.第一种方法,利用编程输入矩阵,输出原因,结果,可达矩阵节点
import numpy as np
import pandas as pd
df = pd.read_excel('C:\\Users\\24278\\Desktop\\安财学习\\5.方法\\14DEMATEL\\DEMATEL矩阵示例.xlsx')
# 将 DataFrame 转换为 NumPy 数组
A = df.to_numpy()
print(A)
#行和最大值归一化,得到规范影响矩阵B
row_sum = np.sum(A, axis = 1)
max_sum = np.max(row_sum)
B = A/max_sum

#综合影响矩阵T
T = np.matmul (B, np.linalg.inv(np.identity(A.shape[0]) - B))

#计算影响度D,被影响度C,中心度M,原因度R
D = np.sum(T, axis = 1)
C = np.sum(T, axis = 0)
M = D + C
R = D - C

#判断输出结果要素和原因要素
causal_factors = ''
result_factors = ''
for i in range(len(R)):
    if R[i] > 0:
            causal_factors = causal_factors + 'x' + str(i + 1) + ' '
    elif R[i] < 0:
            result_factors = result_factors + 'x' + str(i + 1) + ' '
print("原因要素:" + causal_factors)
print("结果要素:" + result_factors)
print("影响度 (D):", D)
print("被影响度 (C):", R)
print("中心度 (M):", M)
print("原因度 (R):", R)

#使用相应的lambda值计算可达矩阵F,并输出节点度排序
E = T + np.identity(A.shape[0])
lbd = 0.20      # 相应的lambda值
F = E
for i in range(A.shape[0]):
    for j in range(A.shape[1]):
        if E[i, j] > lbd:
            F[i,j] = 1
        elif E[i, j] < lbd:
            F[i, j] = 0
node_degree = np.sum(F, axis = 0) + np.sum(F, axis = 1)
#print(sorted(node_degree, reverse=True))

#1.第二种方法,利用手动输入矩阵,输出原因,结果
#导入所需库
import numpy as np
import pandas as pd

#直接影响矩阵A
A = np.array([[0, 3, 3, 3, 1, 2, 3, 3, 3, 3,3,1,0,2,3,1,0],
       [2,0,1,2,2,1,3,1,3,1,3,1,1,2,2,1,1],
       [1,2,0,1,1,2,3,3,3,3,3,1,1,1,0,1,0],
       [1,2,1,0,1,1,2,1,2,1,2,1,2,2,1,1,1],
       [1,2,1,1,0,1,2,1,2,1,2,1,1,1,0,1,0],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [2,2,2,2,2,1,0,1,2,1,2,1,2,1,1,1,1],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [1,3,2,3,2,2,3,1,0,1,2,2,2,2,2,1,2],
       [1,2,1,1,2,2,3,1,2,0,2,1,1,1,1,1,0],
       [1,3,2,3,2,2,3,1,2,2,0,2,2,2,2,1,2],
       [2,2,1,2,2,3,3,1,2,1,2,0,1,3,1,1,1],
       [1,2,1,2,2,2,2,1,2,1,2,1,0,2,1,1,1],
       [1,2,1,2,1,2,2,1,2,1,2,1,1,0,2,2,1],
       [2,2,1,2,1,1,2,1,2,1,2,1,1,2,0,2,1],
       [2,2,1,2,1,1,3,1,1,1,1,1,1,1,2,0,1],
       [0,1,1,0,1,1,2,0,2,0,2,1,1,1,1,1,0]])
#行和最大值归一化,得到规范影响矩阵B
row_sum = np.sum(A, axis = 1)
max_sum = np.max(row_sum)
B = A/max_sum

#综合影响矩阵T
T = np.matmul (B, np.linalg.inv(np.identity(A.shape[0]) - B))

#计算影响度D,被影响度C,中心度M,原因度R
D = np.sum(T, axis = 1)
C = np.sum(T, axis = 0)
M = D + C
R = D - C

#判断输出结果要素和原因要素
causal_factors = ''
result_factors = ''
for i in range(len(R)):
    if R[i] > 0:
            causal_factors = causal_factors + 'x' + str(i + 1) + ' '
    elif R[i] < 0:
            result_factors = result_factors + 'x' + str(i + 1) + ' '
print("原因要素:" + causal_factors)
print("结果要素:" + result_factors)
print("影响度 (D):", D)
print("被影响度 (C):", R)
print("中心度 (M):", M)
print("原因度 (R):", R)
#使用相应的lambda值计算可达矩阵F,并输出节点度排序
E = T + np.identity(A.shape[0])
lbd = 0.20      # 相应的lambda值
F = E
for i in range(A.shape[0]):
    for j in range(A.shape[1]):
        if E[i, j] > lbd:
            F[i,j] = 1
        elif E[i, j] < lbd:
            F[i, j] = 0
node_degree = np.sum(F, axis = 0) + np.sum(F, axis = 1)
#print(sorted(node_degree, reverse=True))
#调用数据库
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["Songti SC"] #设置字体,注意Windows这里可以换成SimHei。(主要是换成自己系统有的字体)
plt.rcParams["axes.unicode_minus"]=False #正常显示负号

def dematel(analytic_matrix):
    """
    执行DEMATEL分析。

    参数:
    - analytic_matrix: numpy数组,表示元素间的直接关系矩阵。

    返回值:
    - D: 表示总关系矩阵行和的numpy数组,指示影响程度。
    - C: 表示总关系矩阵列和的numpy数组,指示被影响程度。
    - M: 表示元素的总重要性的numpy数组;中心度
    - R: 表示元素间因果关系的numpy数组;原因度
    - priority: 权重,D+C的归一化 (注:这个权重应该不能直接理解成重要性;关键影响因素的确定应该综合考虑中心度、原因度、影响度和被影响度,具体确认方法可以参考《情报科学》上的一些论文,例如:DOI,10.13833/j.issn.1007-7634.2023.09.006)
    - status: 字符串,指示分析的成功或失败状态。
    """

    # 步骤1: 标准化矩阵
    # 对每一行求和,找到和的最大值
    max_row_sum = np.max(analytic_matrix.sum(axis=1))
    print(max_row_sum)
    # 使用最大行和的值进行标准化
    normalized_matrix = analytic_matrix / max_row_sum
    
    # 步骤2: 计算总关系矩阵
    identity_matrix = np.eye(len(normalized_matrix))  # 与分析矩阵同维度的单位矩阵
    print(identity_matrix)
    try:
        inv_matrix = np.linalg.inv(identity_matrix - normalized_matrix)  # 计算逆矩阵
        total_relation_matrix = np.dot(normalized_matrix, inv_matrix)  # 计算总关系矩阵
    except np.linalg.LinAlgError:
        return None, None, None, None, "矩阵求逆失败。提供的矩阵可能不可逆。"
    
    # 步骤3: 计算 D, C, M, R
    D = total_relation_matrix.sum(axis=1)  # 行和,影响程度
    C = total_relation_matrix.sum(axis=0)  # 列和,被影响程度
    M = D + C  # 中心度
    priority = M/M.sum() # 权重
    R = D - C  # 原因度
    
    return D, C, M,priority, R, "成功"

# 示例使用

analytic_matrix = np.array([[0, 3, 3, 3, 1, 2, 3, 3, 3, 3,3,1,0,2,3,1,0],
       [2,0,1,2,2,1,3,1,3,1,3,1,1,2,2,1,1],
       [1,2,0,1,1,2,3,3,3,3,3,1,1,1,0,1,0],
       [1,2,1,0,1,1,2,1,2,1,2,1,2,2,1,1,1],
       [1,2,1,1,0,1,2,1,2,1,2,1,1,1,0,1,0],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [2,2,2,2,2,1,0,1,2,1,2,1,2,1,1,1,1],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [1,3,2,3,2,2,3,1,0,1,2,2,2,2,2,1,2],
       [1,2,1,1,2,2,3,1,2,0,2,1,1,1,1,1,0],
       [1,3,2,3,2,2,3,1,2,2,0,2,2,2,2,1,2],
       [2,2,1,2,2,3,3,1,2,1,2,0,1,3,1,1,1],
       [1,2,1,2,2,2,2,1,2,1,2,1,0,2,1,1,1],
       [1,2,1,2,1,2,2,1,2,1,2,1,1,0,2,2,1],
       [2,2,1,2,1,1,2,1,2,1,2,1,1,2,0,2,1],
       [2,2,1,2,1,1,3,1,1,1,1,1,1,1,2,0,1],
       [0,1,1,0,1,1,2,0,2,0,2,1,1,1,1,1,0]])

D, C, M, priority, R, status = dematel(analytic_matrix)

if status == "成功":
    print("影响度 (D):", D)
    print("被影响度 (C):", C)
    print("中心度 (M):", M)
    print("权重priority:",priority)
    print("原因度 (R):", R)
else:
    print(status)
  
# 绘制中心度-原因度因果关系图

# 绘制因果关系图
plt.figure(figsize=(8, 6))
plt.scatter(M, R, color='blue') # 绘制点

# 标注每个点的因素编号(可选)
for i, (x, y) in enumerate(zip(M, R), start=1):
    plt.text(x, y, f'F{i}', fontsize=9)

# 添加轴标签
plt.xlabel('中心度')
plt.ylabel('原因度')

# 绘制中心度和因果度的平均值线(可选)
plt.axvline(x=np.mean(M), color='red', linestyle='--')
plt.axhline(y=np.mean(R), color='red', linestyle='--')

# 设置图表标题
plt.title('因果图 (Causal Diagram)')

# 显示图表
plt.grid(True)
plt.show()

import matplotlib as mpl
import matplotlib.pyplot as plt

#设置图形格式
config = {
            "font.family": 'serif',
            "font.size": 14,
            "mathtext.fontset": 'stix',
            "font.serif": ['SimSun'],
            'axes.unicode_minus': False
          }
mpl.rcParams.update(config)

import numpy as np
import pandas as pd

#直接影响矩阵A
A = np.array([[0, 3, 3, 3, 1, 2, 3, 3, 3, 3,3,1,0,2,3,1,0],
       [2,0,1,2,2,1,3,1,3,1,3,1,1,2,2,1,1],
       [1,2,0,1,1,2,3,3,3,3,3,1,1,1,0,1,0],
       [1,2,1,0,1,1,2,1,2,1,2,1,2,2,1,1,1],
       [1,2,1,1,0,1,2,1,2,1,2,1,1,1,0,1,0],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [2,2,2,2,2,1,0,1,2,1,2,1,2,1,1,1,1],
       [1,1,1,1,2,2,3,0,2,1,1,1,0,1,0,1,0],
       [1,3,2,3,2,2,3,1,0,1,2,2,2,2,2,1,2],
       [1,2,1,1,2,2,3,1,2,0,2,1,1,1,1,1,0],
       [1,3,2,3,2,2,3,1,2,2,0,2,2,2,2,1,2],
       [2,2,1,2,2,3,3,1,2,1,2,0,1,3,1,1,1],
       [1,2,1,2,2,2,2,1,2,1,2,1,0,2,1,1,1],
       [1,2,1,2,1,2,2,1,2,1,2,1,1,0,2,2,1],
       [2,2,1,2,1,1,2,1,2,1,2,1,1,2,0,2,1],
       [2,2,1,2,1,1,3,1,1,1,1,1,1,1,2,0,1],
       [0,1,1,0,1,1,2,0,2,0,2,1,1,1,1,1,0]])
#行和最大值归一化,得到规范影响矩阵B
row_sum = np.sum(A, axis = 1)
max_sum = np.max(row_sum)
B = A/max_sum

#综合影响矩阵T
T = np.matmul (B, np.linalg.inv(np.identity(A.shape[0]) - B))

#计算影响度D,被影响度C,中心度M,原因度R
D = np.sum(T, axis = 1)
C = np.sum(T, axis = 0)
M = D + C
R = D - C
x=M
y=R

#因子名
factors_name = [r'$x_1$', r'$x_2$', r'$x_3$', r'$x_4$', r'$x_5$',
                r'$x_6$', r'$x_7$', r'$x_8$', r'$x_9$', r'$x_{10}$', r'$x_{11}$', r'$x_{12}$',r'$x_{13}$',r'$x_{14}$',r'$x_{15}$',r'$x_{16}$',r'$x_{17}$']

#画散点图,并增加相应名称、线段和调整大小和位置

plt.scatter(x, y, s=3, c='k')
plt.xlabel('中心度')
plt.ylabel('原因度')

# 设置XY轴 相互重叠的坐标点的修改上下移动使图片更加美观
for i in range(len(x)):
    if i == 16:
        plt.text(x[i]+0.125, y[i]-0.1, factors_name[i], fontsize=14)
    elif i == 7:
        plt.text(x[i]+0.025, y[i]+0.12, factors_name[i], fontsize=14)
    elif i == 2:
        plt.text(x[i]-0.18, y[i]-0.1, factors_name[i], fontsize=14)
    elif i == 13:
        plt.text(x[i]+0.18, y[i]-0.1, factors_name[i], fontsize=14)
    elif i == 10:
        plt.text(x[i]-0.18, y[i]-0.1, factors_name[i], fontsize=14)
    elif i == 11:
        plt.text(x[i]-0.15, y[i]-0.12, factors_name[i], fontsize=14)
    else:
        plt.text(x[i]+0.025, y[i]+0.025, factors_name[i], fontsize=14)

# 设置XY轴与虚线
plt.vlines(sum(x)/len(x), -1.8, 1.8, colors='k', linestyles='dashed')
plt.hlines(0, sum(x)/len(x)-2.2, sum(x)/len(x)+2.2, colors='k', linestyles='dashed')
plt.xlim(sum(x)/len(x)-2.2, sum(x)/len(x)+2.2)
plt.ylim(-1.8, 1.8)

# 设置四个象限
plt.text(sum(x)/len(x)+2-0.2, 1.4-0.1, 'Ⅰ')
plt.text(sum(x)/len(x)-2+0.1, 1.4-0.1, 'Ⅱ')
plt.text(sum(x)/len(x)-2+0.1, -1.55+0.1, 'Ⅲ')
plt.text(sum(x)/len(x)+2-0.2, -1.55+0.1, 'Ⅳ')

# 设置图表标题
plt.title('因果图 (Causal Diagram)', fontsize=15)
plt.show()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值