> 文档中心 > 用Python实现DT算法

用Python实现DT算法

目录

一、前言

二、示例数据

三、DT法分级步骤

四、Python实现

五、结果


一、前言

DT法是由我国学者林韵梅于 1988 年提出的,首先应用于围岩稳定性动态分级的一种方法。该方法的核心思想来源于多元统计分析中的动态聚类法,是根据“物以类聚”的道理,对样本或指标进行分类。动态聚类的基本思路是,所有样本应被划分到与之最接近的类别当中。首先根据样本的基础特性给出多个凝聚点,即欲形成“类”的中心,计算各样本到凝聚点的距离,将样本划入最近的凝聚点,形成一个粗糙的初始分类,然后按照一定的原则,调整初始分类,直到分类合理时,输出分类结果。在调整分类的过程中就是样本间的距离误差被不断修正,当误差达到可接受的范围,即可得到相对准确的结果。在反复修改过程中,样本的级别允许动态调整,可以与初始分级有所变化,这和静态分级方法中,样本一旦划入某个类以后就不再改变的处理方法有明显的不同。

二、示例数据

矿岩名称 抗压强度RcMPa 容重ρg/cm3 完整系数 炸药单耗qkg/m3
阳起石英岩 226.76 2.94 0.18 0.88
细粒斜长角闪岩 153.6 3.03 0.2 0.76
花岗岩 106.05 2.69 0.21 0.59
伟晶岩 95.46 2.69 0.19 0.59
辉绿岩 69.58 3.01 0.15 0.6
绿泥角闪岩 78.17 2.97 0.38 0.77
赤铁磁铁石英岩 144.26 3.37 0.37 0.74
磁铁石英岩 129.86 3.42 0.36 0.82
第六层铁矿 250.4 3.48 0.2 1.08
第五层铁矿 193.56 3.42 0.23 0.96
第二层铁矿 186.05 3.49 0.29 0.98
第三层铁矿 168.78 3.41 0.15 0.89
赤铁石英岩 205.5 3.38 0.89 0.7
石英岩 200.4 2.69 0.95 0.6
绿泥岩 39 2.93 0.94 0.3
混合岩 68.6 2.58 0.91 0.5
赤铁石英岩 192.71 3.48 0.38 0.63
底盘角闪岩2 60.4 2.88 0.39 0.75
矽石山石英岩 160.68 2.63 0.34 0.74

三、DT法分级步骤

来源:基于DT法的石油化工码头储罐区危险源动态分级研究_崔益源[D]

 

四、Python实现

import pandas as pdimport numpy as npfrom numpy import *import sympy as spimport matplotlib.pyplot as pltimport numpy as npfrom sympy import *import mathfrom pylab import *plt.rcParams['axes.unicode_minus']=False  #用于解决不能显示负号的问题mpl.rcParams['font.sans-serif'] = ['SimHei']
data =  pd.read_excel("DT分析样本.xlsx",index_col="矿岩名称")  S = np.sqrt(((data-data.mean())**2).sum()/(len(data.index)-1))x2_2 = (data - data.mean())/SS_i = x2_2.sum(axis=1)AMAX = max(S_i)AMIN = min(S_i)K = 19
NC_i = np.floor(((K-1)*(AMAX-S_i)/(AMAX-AMIN))+0.5)+1NC_i = pd.DataFrame(NC_i)NC_i.columns = ["NC"]data = data.add(NC_i,fill_value=0)
x = []y = []for K in range(2,20):    data =  pd.read_excel("DT分析样本.xlsx",index_col="矿岩名称")      S = np.sqrt(((data-data.mean())**2).sum()/len(data.index))    x2_2 = (data - data.mean())/S    data = (data - data.mean())/S    S_i = x2_2.sum(axis=1)    AMAX = max(S_i)    AMIN = min(S_i)    NC_i = np.floor(((K-1)*(AMAX-S_i)/(AMAX-AMIN))+0.5)+1    NC_i = pd.DataFrame(NC_i)    NC_i.columns = ["NC"]    data = data.add(NC_i,fill_value=0)    for i in range(300):#  print(K,i) temp = data["NC"].copy() value = pd.DataFrame(columns=["type","num","value"]) for eachIndex in data.index:     for each in set(data["NC"]):  value = value.append({"type":eachIndex,"num":each,"value":np.sqrt(((data.loc[eachIndex] - data[data["NC"] ==each].mean())**2).sum())},ignore_index=True) value = value.set_index(["type"]) for index in set(value.index):     data.loc[index]["NC"] = value.loc[index].sort_values("value").iloc[0]["num"] if (temp-data["NC"]).abs().sum() < 0.001:     sum = 0     for index in data.index:  sum += value.loc[index][value.loc[index]["num"]==data.loc[index]["NC"]]["value"].sum()     x.append(K)     y.append(sum)     print(K,sum)     break

  PS:在线多项式拟合网站 

plt.figure(figsize=(8,4))x_1 = np.linspace(2,19,500)y_1 = 33.1714313933564 - 2.6804554847376*x_1 + 0.0626813808370871*x_1**2 + 0.00359821535505567*x_1**3 - 0.00018026487545368*x_1**4plt.scatter(x,y,label="理论值",linewidth=2,color="r")plt.plot(x_1,y_1,linewidth=2,label="拟合曲线")plt.xlabel("分类数目K",fontsize=20)plt.ylabel("分类函数值DS",fontsize=20)plt.yticks([5,10,15,20,25])plt.xticks([2,4,6,8,10,12,14,16,18,20])plt.legend(fontsize=15)plt.tick_params(labelsize=20)plt.savefig("DS",dpi=300,bbox_inches ="tight")

五、结果