用Python实现DT算法

目录

一、前言

二、示例数据

三、DT法分级步骤

四、Python实现

五、结果


一、前言

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

二、示例数据

矿岩名称抗压强度RcMPa容重ρg/cm3完整系数炸药单耗qkg/m3
阳起石英岩226.762.940.180.88
细粒斜长角闪岩153.63.030.20.76
花岗岩106.052.690.210.59
伟晶岩95.462.690.190.59
辉绿岩69.583.010.150.6
绿泥角闪岩78.172.970.380.77
赤铁磁铁石英岩144.263.370.370.74
磁铁石英岩129.863.420.360.82
第六层铁矿250.43.480.21.08
第五层铁矿193.563.420.230.96
第二层铁矿186.053.490.290.98
第三层铁矿168.783.410.150.89
赤铁石英岩205.53.380.890.7
石英岩200.42.690.950.6
绿泥岩392.930.940.3
混合岩68.62.580.910.5
赤铁石英岩192.713.480.380.63
底盘角闪岩260.42.880.390.75
矽石山石英岩160.682.630.340.74


三、DT法分级步骤

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

 

四、Python实现

import pandas as pd
import numpy as np
from numpy import *
import sympy as sp

import matplotlib.pyplot as plt
import numpy as np
from sympy import *
import math

from 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())/S
S_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)+1
NC_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**4

plt.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")

五、结果

### 回答1: PID算法是一种用于控制系统的算法。在Python实现PID算法需要使用数学库numpy和scipy。 示例代码如下: ```python from scipy import signal import numpy as np class PID: def __init__(self, Kp, Ki, Kd): self.Kp = Kp self.Ki = Ki self.Kd = Kd self.prev_error = 0 self.integral = 0 def update(self, error, dt): self.integral += error * dt derivative = (error - self.prev_error) / dt output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative self.prev_error = error return output ``` 然后可以使用如下方式使用它: ```python pid = PID(1, 0.1, 0.05) output = pid.update(error, dt) ``` 这里只是一个简单的例子,实际应用中可能需要根据系统的特点进行调整和优化。 ### 回答2: PID算法是一种控制系统中常用的反馈控制算法,用于调整系统输出值,使其尽可能接近给定的目标值。Python实现PID算法时可以按照以下步骤进行: 1. 首先,需要定义PID控制算法所需的三个参数:比例系数(P),积分系数(I)和微分系数(D)。这些参数可以根据具体的控制需求进行初始化。 2. 接下来,在每次控制循环中,根据当前的系统输出值和目标值,计算比例项、积分项和微分项的值。 3. 比例项(P项)是系统输出值与目标值之差乘以比例系数。它决定了系统对误差的快速反应能力。 4. 积分项(I项)是过去一段时间内误差的累积乘以积分系数。它可以用来消除系统的稳态误差。 5. 微分项(D项)是当前误差与上一次误差之差乘以微分系数。它可以用来减小系统的超调量和震荡。 6. 将比例项、积分项和微分项的值相加,得到最终的PID输出值。 7. 最后,根据PID算法得到的输出值,通过控制器将其转换为控制信号,作用于被控制的系统。 Python提供了丰富的数学库和控制库可以用于实现PID算法。可以根据具体需求选择合适的库进行使用,如numpy、scipy等。编写PID算法的代码时,需要注意数学计算的准确性和代码的可读性与可维护性。可以使用函数、类等方式进行代码的组织和封装,使其易于理解和调试。 总结:Python实现PID算法需要定义三个参数,并在每次控制循环中计算比例项、积分项和微分项的值,然后将它们相加得到最终的PID输出值,再通过控制器转换为控制信号。使用适合的数学库和控制库可以简化算法实现,同时注意代码的可读性和可维护性。 ### 回答3: PID算法是一种常用的控制算法,被广泛应用于工业自动化和控制系统中。Python语言提供了丰富的工具和库,可以方便地实现PID算法。 要实现PID算法,首先需要定义三个参数:比例增益(proportional gain,Kp)、积分增益(integral gain,Ki)和微分增益(derivative gain,Kd)。这些参数将根据实际的控制需求进行调整。 在编写代码时,需要设置一个目标值(setpoint)和一个反馈值(feedback),分别表示期望的输出和实际的输出。根据差异和时间的变化率,依次计算比例项、积分项和微分项,并将它们加权相加,得到最后的控制输出。伪代码如下: ``` previous_error = 0 integral = 0 while True: error = setpoint - feedback proportional = Kp * error integral += Ki * error derivative = Kd * (error - previous_error) output = proportional + integral + derivative previous_error = error # 再次获取反馈值 # 控制输出 ``` 在实际实现中,还需考虑到采样时间的选择、积分项的限制和输出范围的调整等问题。同时,还可以利用Python的库如NumPy、matplotlib等,进行数据处理和图形化展示,以方便调试和分析。 总之,使用Python可以方便地实现PID算法,并根据具体需求进行参数调整和优化,实现精确的控制。它具有编码简洁、易于调试和迭代的优点,使得它成为工程师们的首选语言之一。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿木霖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值