基于SARIMA、XGBoost和CNN-LSTM的时间序列预测对比

news2025/1/16 5:56:03

利用统计测试和机器学习分析和预测太阳能发电的性能测试和对比

本文将讨论通过使用假设测试、特征工程、时间序列建模方法等从数据集中获得有形价值的技术。我还将解决不同时间序列模型的数据泄漏和数据准备等问题,并且对常见的三种时间序列预测进行对比测试。

介绍

时间序列预测是一个经常被研究的话题,我们这里使用使用两个太阳能电站的数据,研究其规律进行建模。首先将它们归纳为两个问题来解决这些问题:

  1. 是否有可能识别出性能欠佳的太阳能组件?
  2. 是否可以预报两天的太阳能发电量?

在继续回答这些问题之前,让我们先了解太阳能发电厂是如何发电的。

上图描述了从太阳能电池板模块到电网的发电过程。太阳能通过光电效应直接转化为电能。当硅(太阳能电池板中最常见的半导体材料)等材料暴露在光线下时,光子(电磁能量的亚原子粒子)被吸收并释放自由电子,从而产生直流电(DC)。使用逆变器,直流电被转换成交流电(AC)并发送到电网,在那里它可以被分配到家庭。

数据

原始数据由每个太阳能发电厂的两个逗号分隔值(CSV)文件组成。一份文件显示了发电过程,另一份文件显示了太阳能发电厂传感器记录的测量数据。每个太阳能发电厂的两个数据集都被整理成一个pandas的df。

太阳能发电厂1号(SP1)和太阳能发电厂2号(SP2)的数据每15分钟收集一次,从2020年5月15日到2020年6月18日。SP1和SP2数据集都包含相同的变量。

  • Date Time -间隔15分钟
  • Ambient temperature-模块周围空气的温度
  • Module temperature-模块的温度
  • Irradiation——模块上的辐射
  • DC Power (kW) -直流
  • AC Power (kW) -交流
  • Daily Yield-每日发电量总和
  • Total Yield-逆变器的累计产量
  • Plant ID -太阳能电站的唯一标识
  • Module ID -每个模块的唯一标识

天气传感器用于记录每个太阳能发电厂的环境温度、组件温度和辐射。

对于这个数据集直流功率将是因变量(目标变量)。我们目标是的试图找到性能不佳的太阳能模块。

两个独立的df用于分析和预测。唯一的区别是用于预测的数据被重新采样为每小时的间隔,而用于分析的数据帧包含15分钟的间隔。

首先我们删除Plant ID,因为它对试图回答上述问题没有任何价值。Module ID也从预测数据集中删除。表1和表2显示了数据示例。

在继续分析数据之前,我们对太阳能发电厂做了一些假设,包括:

  • 数据采集仪器无故障
  • 模块定期清洗(忽略维护的影响)
  • 两个太阳能电站周围都没有遮挡问题

探索性数据分析(EDA)

对于数据科学的新手来说,EDA是通过绘图可视化和执行统计测试来理解数据的关键一步。我们首先通过绘制SP1和SP2的DC和AC,可以观察到每个太阳能发电厂的性能。

SP1显示的直流功率比sp2高一个数量级。假设SP1采集的数据是正确的,用于记录数据的仪器没有故障,这就说明SP1中逆变器需要进行更深入的研究

通过按每个模块的日频率聚合AC和DC功率,图3显示了SP1中所有模块的逆变器效率。根据领域内知识,太阳能逆变器的效率应该在93-96%之间。由于所有模块的效率范围为9.76% - 9.79%,这里可以说明需要调查逆变器的性能,以及是否需要更换。

由于SP1显示了逆变器的问题,因此仅在SP2上进行了进一步的分析。

尽管这一小段分析是我们花了更多的时间对逆变器进行研究,但它并没有回答确定太阳能模块性能的主要问题。

由于SP2的逆变器正常工作,可以通过深入挖掘数据,来识别和调查任何异常情况。

图4中显示了模块温度和环境温度之间的关系,并且有模块温度极高的情况。

这看起来似乎违反我们的认知,但是可以看到高温对太阳能电池板的确有负面影响。当光子与太阳能电池内的电子接触时,它们会释放自由电子,但在更高的温度下,更多的电子已经处于激发态,这降低了电池板可以产生的电压,进而降低了效率。

考虑到这一现象,下面的图5显示了SP2的模块温度和直流功率(环境温度低于模块温度的数据点和模块运行数量较少的一天中的时间已经过过滤,以防止数据倾斜)。

在图5中,红线表示平均温度。这里可以看到有一个明确的临界点和直流电源停滞的迹象。在~52°C开始平稳。为了找到性能次优的太阳能模块,所有显示模块温度超过52°C的行都被删除。

下面的图6显示了SP2中每个模块在一天中的直流功率。这样就基本符合了预期,午间发电量较大。但是还有个问题,在运行高峰时期,发电量较低。我们很难总结造成这种情况的原因,因为当天的天气条件可能很差,或者SP2可能需要进行日常的维护等等。

图6中也有低性能模块的迹象。它们可以被识别为图上偏离最近群集的模块(单个数据点)。

为了确定哪些模块表现不佳,我们可以进行统计测试,同时将每个模块的性能与其他模块进行比较,从而确定性能。

每隔15分钟,不同模块的直流电源在同一时间的分布是正态分布,通过假设检验可以确定哪些模块表现不佳。计数是指模块落在99.9%置信区间之外且p值< 0.001的次数。

图7按降序显示了每个模块在统计上显著低于同期其他模块的次数。

从图7中可以清楚地看出,模块’ Quc1TzYxW2pYoWX '是有问题的。这些信息可以提供给SP2的相关工作人员,调查原因。

建模

下面我们开始使用三种不同的时间序列算法:SARIMA、XGBoost和CNN-LSTM,进行建模并比较

对于所有三个模型,都使用预测下一个数据点进行预测。Walk-forward验证是一种用于时间序列建模的技术,因为随着时间的推移,预测会变得不那么准确,因此更实用的方法是在实际数据可用时,用实际数据重新训练模型。

在建模之前需要更详细地研究数据。图8显示了SP2数据集中所有特征的相关热图。热图显示了因变量直流功率,与模块温度、辐照和环境温度的强相关性。这些特征可能在预测中发挥重要作用。

在下面的热图中,交流功率显示皮尔森相关系数为1。为了防止数据泄漏问题,我们将直流功率从数据中删除。

SARIMA

季节自回归综合移动平均(SARIMA)是一种单变量时间序列预测方法。由于目标变量显示出24小时循环周期的迹象,SARIMA是一个有效的建模选项,因为它考虑了季节影响。这可以从下面的季节分解图中观察到。

SARIMA算法要求数据是平稳的。有多种方法来检验数据是否平稳,例如统计检验(增强迪基-福勒检验),汇总统计(比较数据的不同部分的均值/方差)和可视化分析数据。在建模之前进行多次测试是很重要的。

增强迪基-富勒(ADF)检验是一种“单位根检验”,用于确定时间序列是否平稳。从根本上说,这是一个统计显著性检验,其中存在一个零假设和替代假设,并根据得出的p值得出结论。

零假设:时间序列数据是非平稳的。

替代假设:时间序列数据是平稳的。

在我们的例子中,如果p值≤0.05,我们可以拒绝原假设,并确认数据没有单位根。

 from statsmodels.tsa.stattools import adfuller
 
 result = adfuller(plant2_dcpower.values)
 
 print('ADF Statistic: %f' % result[0])
 print('p-value: %f' % result[1])
 print('Critical Values:')
 for key, value in result[4].items():
     print('\t%s: %.3f' % (key, value))

从ADF检验来看,p值为0.000553,< 0.05。根据这一统计数据,可以认为该数据是稳定的。然而,查看图2(最上面的图),有明显的季节性迹象(对于被认为是平稳的时间序列数据,不应该有季节性和趋势的迹象),这说明数据是非平稳的。因此,运行多个测试非常重要。

为了用SARIMA对因变量建模,时间序列需要是平稳的。如图9(第一个和第三个图)所示,直流电有明显的季节性迹象。取第一个差值[t-(t-1)]去除季节性成分,如图10所示,因为它看起来类似于正态分布。数据现在是平稳的,适用于SARIMA算法。

SARIMA的超参数包括p(自回归阶数)、d(差阶数)、q(移动平均阶数)、p(季节自回归阶数)、d(季节差阶数)、q(季节移动平均阶数)、m(季节周期的时间步长)、trend(确定性趋势)。

图11显示了自相关(ACF)、部分自相关(PACF)和季节性ACF/PACF图。ACF图显示了时间序列与其延迟版本之间的相关性。PACF显示了时间序列与其滞后版本之间的直接相关性。蓝色阴影区域表示置信区间。SACF和SPACF可以通过从原始数据中取季节差(m)来计算,在本例中为24,因为在ACF图中有一个明显的24小时的季节效应。

根据我们的直觉,超参数的起点可以从ACF和PACF图中推导出来。如ACF和PACF均呈逐渐下降的趋势,即自回归阶数§和移动平均阶数(q)均大于0。p和p可以通过分别观察PCF和SPCF图,并计算滞后值不显著之前具有统计学显著性的滞后数来确定。同样,q和q可以在ACF和SACF图中找到。

差阶(d)可以通过使数据平稳的差的数量来确定。季节差异阶数(D)是根据从时间序列中去除季节性成分所需的差异数来估计的。

这些超参数选择可以看这篇文章:https://arauto.readthedocs.io/en/latest/how_to_choose_terms.html

也可以采用网格搜索方法进行超参数优化,根据最小均方误差(MSE)选择最优超参数,包括p = 2, d = 0, q = 4, p = 2, d = 1, q = 6, m = 24, trend = ’ n '(无趋势)。

 from time import time
 from sklearn.metrics import mean_squared_error
 from statsmodels.tsa.statespace.sarimax import SARIMAX
 
 configg = [(2, 1, 4), (2, 1, 6, 24), 'n']
 
 def train_test_split(data, test_len=48):
     """
     Split data into training and testing.
     """
     train, test = data[:-test_len], data[-test_len:]
     return train, test
 
 def sarima_model(data, cfg, test_len, i):
     """
     SARIMA model which outputs prediction and model. 
     """
     order, s_order, t = cfg[0], cfg[1], cfg[2]
     model = SARIMAX(data, order=order, seasonal_order=s_order, trend=t, 
                    enforce_stationarity=False, enfore_invertibility=False)
     model_fit = model.fit(disp=False)
     yhat = model_fit.predict(len(data))
     
     if i + 1 == test_len:
         return yhat, model_fit
     else:
         return yhat
 
 def walk_forward_val(data, cfg):
     """
     A walk forward validation technique used for time series data. Takes current value of x_test and predicts 
     value. x_test is then fed back into history for the next prediction.
     """
     train, test = train_test_split(data)
     pred = []
     history = [i for i in train] 
     test_len = len(test)
     
     for i in range(test_len):
         if i + 1 == test_len:
             yhat, s_model = sarima_model(history, cfg, test_len, i)
             pred.append(yhat)
             mse = mean_squared_error(test, pred)
             return pred, mse, s_model
         else:
             yhat = sarima_model(history, cfg, test_len, i)
             pred.append(yhat)
             history.append(test[i])
     pass 
 
 if __name__ == '__main__':
     start_time = time()
     sarima_pred_plant2, sarima_mse, s_model = walk_forward_val(plant2_dcpower, configg)
     time_len = time() - start_time
 
     print(f'SARIMA runtime: {round(time_len/60,2)} mins')

图12显示了SARIMA模型的预测值与SP2 2天内记录的直流功率的比较。

为了分析模型的性能,图13显示了模型诊断。相关图显示在第一个滞后后几乎没有相关性,下面的直方图显示在平均值为零附近的正态分布。由此我们可以说模型无法从数据中收集到进一步的信息。

XGBoost

XGBoost (eXtreme Gradient Boosting)是一种梯度增强决策树算法。它使用集成方法,其中添加新的决策树模型来修改现有的决策树分数。与SARIMA不同的是,XGBoost是一种多元机器学习算法,这意味着该模型可以采用多特征来提高模型性能。

我们采用特征工程提高模型精度。还创建了3个附加特性,其中包括AC和DC功率的滞后版本,分别为S1_AC_POWER和S1_DC_POWER,以及通过交流功率除以直流功率的总体效率EFF。并将AC_POWER和MODULE_TEMPERATURE从数据中删除。图14通过增益(使用一个特征的分割的平均增益)和权重(一个特征在树中出现的次数)显示了特征的重要性级别。

通过网格搜索确定建模使用的超参数,结果为:*learning rate = 0.01, number of estimators = 1200, subsample = 0.8, colsample by tree = 1, colsample by level = 1, min child weight = 20 and max depth = 10

我们使用MinMaxScaler将训练数据缩放到0到1之间(也可以试验其他缩放器,如log-transform和standard-scaler,这取决于数据的分布)。通过将所有自变量向后移动一段时间,将数据转换为监督学习数据集。

 import numpy as np 
 import pandas as pd
 import xgboost as xgb
 from sklearn.preprocessing import MinMaxScaler
 from time import time
 
 def train_test_split(df, test_len=48):
     """
     split data into training and testing.
     """
     train, test = df[:-test_len], df[-test_len:]
     return train, test
 
 def data_to_supervised(df, shift_by=1, target_var='DC_POWER'):
     """
     Convert data into a supervised learning problem.
     """
     target = df[target_var][shift_by:].values
     dep = df.drop(target_var, axis=1).shift(-shift_by).dropna().values
     data = np.column_stack((dep, target))
     return data
 
 
 def xgb_forecast(train, x_test):
     """
     XGBOOST model which outputs prediction and model.
     """
     x_train, y_train = train[:,:-1], train[:,-1]
     xgb_model = xgb.XGBRegressor(learning_rate=0.01, n_estimators=1500, subsample=0.8,
                                  colsample_bytree=1, colsample_bylevel=1,
                                  min_child_weight=20, max_depth=14, objective='reg:squarederror')
     xgb_model.fit(x_train, y_train)
     yhat = xgb_model.predict([x_test])
     return yhat[0], xgb_model
 
 def walk_forward_validation(df):
     """
     A walk forward validation approach by scaling the data and changing into a supervised learning problem.
     """
     preds = []
     train, test = train_test_split(df)
     
     scaler = MinMaxScaler(feature_range=(0,1))
     train_scaled = scaler.fit_transform(train)
     test_scaled = scaler.transform(test)
     
     train_scaled_df = pd.DataFrame(train_scaled, columns = train.columns, index=train.index)
     test_scaled_df = pd.DataFrame(test_scaled, columns = test.columns, index=test.index)
     
     train_scaled_sup, test_scaled_sup = data_to_supervised(train_scaled_df), data_to_supervised(test_scaled_df)
     history = np.array([x for x in train_scaled_sup])
     
     for i in range(len(test_scaled_sup)):
         test_x, test_y = test_scaled_sup[i][:-1], test_scaled_sup[i][-1]
         yhat, xgb_model = xgb_forecast(history, test_x)
         preds.append(yhat)
         np.append(history,[test_scaled_sup[i]], axis=0)
         
     pred_array = test_scaled_df.drop("DC_POWER", axis=1).to_numpy()
     pred_num = np.array([pred])
     pred_array = np.concatenate((pred_array, pred_num.T), axis=1)
     result = scaler.inverse_transform(pred_array)
     
     return result, test, xgb_model
 
 if __name__ == '__main__':
     start_time = time()
     xgb_pred, actual, xgb_model = walk_forward_validation(dropped_df_cat)
     time_len = time() - start_time
 
     print(f'XGBOOST runtime: {round(time_len/60,2)} mins')

图15显示了XGBoost模型的预测值与SP2 2天内记录的直流功率的比较。

CNN-LSTM

CNN-LSTM (convolutional Neural Network Long - Short-Term Memory)是两种神经网络模型的混合模型。CNN是一种前馈神经网络,在图像处理和自然语言处理方面表现出了良好的性能。它还可以有效地应用于时间序列数据的预测。LSTM是一种序列到序列的神经网络模型,旨在解决长期存在的梯度爆炸/消失问题,使用内部存储系统,允许它在输入序列上积累状态。

在本例中,使用CNN-LSTM作为编码器-解码器体系结构。由于CNN不直接支持序列输入,所以我们通过1D CNN读取序列输入并自动学习重要特征。然后LSTM进行解码。与XGBoost模型类似,使用scikitlearn的MinMaxScaler使用相同的数据并进行缩放,但范围在-1到1之间。对于CNN-LSTM,需要将数据重新整理为所需的结构:[samples, subsequences, timesteps, features],以便可以将其作为输入传递给模型。

由于我们希望为每个子序列重用相同的CNN模型,因此使用timedidistributedwrapper对每个输入子序列应用一次整个模型。在下面的图16中可以看到最终模型中使用的不同层的模型摘要。

在将数据分解为训练数据和测试数据之后,将训练数据分解为训练数据和验证数据集。在所有训练数据(包括验证数据)的每次迭代之后,模型可以进一步使用这一点来评估模型的性能。

学习曲线是深度学习中使用的一个很好的诊断工具,它显示了模型在每个阶段之后的表现。下面的图17显示了模型如何从数据中学习,并显示了验证数据与训练数据的收敛。这是良好模特训练的标志。

 import pandas as pd 
 import numpy as np
 from sklearn.metrics import mean_squared_error
 from sklearn.preprocessing import MinMaxScaler
 import keras
 from keras.models import Sequential
 from keras.layers.convolutional import Conv1D, MaxPooling1D
 from keras.layers import LSTM, TimeDistributed, RepeatVector, Dense, Flatten
 from keras.optimizers import Adam
 
 n_steps = 1
 subseq = 1
 
 def train_test_split(df, test_len=48):
     """
     Split data in training and testing. Use 48 hours as testing.
     """
     train, test = df[:-test_len], df[-test_len:]
     return train, test
 
 def split_data(sequences, n_steps):
     """
     Preprocess data returning two arrays.
     """
     x, y = [], []
     for i in range(len(sequences)):
         end_x = i + n_steps
         
         if end_x > len(sequences):
             break
         x.append(sequences[i:end_x, :-1]) 
         y.append(sequences[end_x-1, -1])
         
     return np.array(x), np.array(y)
   
   def CNN_LSTM(x, y, x_val, y_val):
     """
     CNN-LSTM model.
     """
     model = Sequential()
     model.add(TimeDistributed(Conv1D(filters=14, kernel_size=1, activation="sigmoid", 
                                      input_shape=(None, x.shape[2], x.shape[3]))))
     model.add(TimeDistributed(MaxPooling1D(pool_size=1)))
     model.add(TimeDistributed(Flatten()))
     model.add(LSTM(21, activation="tanh", return_sequences=True))
     model.add(LSTM(14, activation="tanh", return_sequences=True))
     model.add(LSTM(7, activation="tanh"))
     model.add(Dense(3, activation="sigmoid"))
     model.add(Dense(1))
     
     model.compile(optimizer=Adam(learning_rate=0.001), loss="mse", metrics=['mse'])
     history = model.fit(x, y, epochs=250, batch_size=36,
                         verbose=0, validation_data=(x_val, y_val))
     
     return model, history
   
 # split and resahpe data
 train, test = train_test_split(dropped_df_cat)  
 
 train_x = train.drop(columns="DC_POWER", axis=1).to_numpy()
 train_y = train["DC_POWER"].to_numpy().reshape(len(train), 1)
 
 test_x = test.drop(columns="DC_POWER", axis=1).to_numpy()
 test_y = test["DC_POWER"].to_numpy().reshape(len(test), 1)
 
 #scale data  
 scaler_x = MinMaxScaler(feature_range=(-1,1))
 scaler_y = MinMaxScaler(feature_range=(-1,1))
 
 train_x = scaler_x.fit_transform(train_x)
 train_y = scaler_y.fit_transform(train_y) 
 
 test_x = scaler_x.transform(test_x)
 test_y = scaler_y.transform(test_y)
 
 
 # shape data into CNN-LSTM format [samples, subsequences, timesteps, features] ORIGINAL
 train_data_np = np.hstack((train_x, train_y))
 x, y = split_data(train_data_np, n_steps)
 x_subseq = x.reshape(x.shape[0], subseq, x.shape[1], x.shape[2])
 
 # create validation set
 x_val, y_val = x_subseq[-24:], y[-24:]
 x_train, y_train = x_subseq[:-24], y[:-24]
 
 n_features = x.shape[2]
 actual = scaler_y.inverse_transform(test_y)
 
 # run CNN-LSTM model 
 if __name__ == '__main__':
     start_time = time()
 
     model, history = CNN_LSTM(x_train, y_train, x_val, y_val)
     prediction = []
     
     for i in range(len(test_x)):
         test_input = test_x[i].reshape(1, subseq, n_steps, n_features)
         yhat = model.predict(test_input, verbose=0)
         yhat_IT = scaler_y.inverse_transform(yhat)
         prediction.append(yhat_IT[0][0])
 
     time_len = time() - start_time
     mse = mean_squared_error(actual.flatten(), prediction)
     
     print(f'CNN-LSTM runtime: {round(time_len/60,2)} mins')
     print(f"CNN-LSTM MSE: {round(mse,2)}")

图18显示了CNN-LSTM模型的预测值与SP2 2天内记录的直流功率的对比。

由于CNN-LSTM的随机性,该模型运行10次,并记录一个平均MSE值作为最终值,以判断模型的性能。图19显示了为所有模型运行记录的mse的范围。

结果对比

下表显示了每个模型的MSE (CNN-LSTM的平均MSE)和每个模型的运行时间(以分钟为单位)。

从表中可以看出,XGBoost的MSE最低、运行时第二快,并且与所有其他模型相比具有最佳性能。由于该模型显示了一个可以接受的每小时预测的运行时,它可以成为帮助运营经理决策过程的强大工具。

总结

在本文中我们分析了SP1和SP2,确定SP1性能较低。所以对SP2的进一步调查显示,并且查看了SP2中那些模块性能可能有问题,并使用假设检验来计算每个模块在统计上明显表现不佳的次数,’ Quc1TzYxW2pYoWX '模块显示了约850次低性能计数。

我们使用数据训练三个模型:SARIMA、XGBoost和CNN-LSTM。SARIMA表现最差,XGBOOST表现最好,MSE为16.9,运行时间为1.43 min。所以可以说XGBoost在表格数据中还是最优先得选择。

https://avoid.overfit.cn/post/b6403a2eb89247dfb3a1b927519f58c0

作者:Amit Bharadwa

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/74358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RNSScreenStackHeaderConfig“ was not found in the UIManager.解决办法!!亲测有效

Invariant Violation: requireNativeComponent: "RNSScreenStackHeaderConfig" was not found in the UIManager. 原因&#xff1a;RN项目中&#xff0c;开发服务器端已经使用npm i下载了某个模块&#xff0c;但是只有服务器端有&#xff0c;该模块并没有打包安装到手…

Cache与MMU的爱恨纠缠

首先声明本文不准备详细地介绍Cache和MMU的概念和用法&#xff0c;主要是为了厘清两者之间的相互关系和依赖。 1. MMU管理cache访问属性 在没有MMU的时候&#xff0c;cache本身的模型比较简单&#xff0c;如下所示&#xff0c;在使用的时候重点关注Cache数据的一致性问题。 …

linux高可用小知识点汇总-行云管家

不少运维小伙伴对于linux高可用相关知识不是很了解&#xff0c;今天我们小编就给大家汇总了一些&#xff0c;希望可以加深大家的了解。仅供参考哦&#xff01; linux高可用小知识点汇总-行云管家 一、Linux是什么系统&#xff1f; 【回答】&#xff1a;Linux全称GNU/Linux&am…

小蓝本 第一本《因式分解技巧》 第二章 应用公式 笔记(第二天)

小蓝本 第一本《因式分解技巧》 第二章 应用公式 笔记&#xff08;第二天&#xff09;前言二代——应用公式常见公式公式场景公式分类基本间接推导公式(9)、(10)的推导问题分解方法方法1方法2公式推导总结&#xff1a;对照思想小技巧与注意事项习题2题目题解经验前言 第二天op…

基于贝叶斯网络的考虑不确定性的短期电能负荷预测(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

元年SecDevOps的实践之路

随着DevOps的发展&#xff0c;企业的数字化转型的需求也愈发强烈&#xff0c;DevOps大幅提升了企业应用迭代的速度。但同时&#xff0c;安全如果不能跟上步伐&#xff0c;不仅会抵消DevOps变革带来的提升&#xff0c;拖慢企业数字化转型的进程&#xff0c;还会导致漏洞与风险不…

Virtual Private Network

VPN技术的运行机制与发展 虚拟专用网络(Virtual Private Network,VPN)是利用不可靠的公用互联网络作为信息传输媒介&#xff0c;通过附加的安全隧道、用户认证和访问控制等技术实现与专用网络相类似的安全性能&#xff0c;从而实现对重要信息的安全传输。 根据技术应用环境的…

kotlin之循环控制

for循环 for 循环可以对任何提供迭代器&#xff08;iterator&#xff09;的对象进行遍历 java for循环写法 public static void main(String[] args) {int i 10;for (int j 0; j < i; j) {System.out.println(j);}} int[] q{1,2,3,4,5,6,7,8,9,10};for (int j:q) {System…

lammps笔记-入门

1 输入文件 输入脚本文件&#xff08;命令文件&#xff1f;&#xff09;要包含五个部分&#xff1a; # 1) Initialization # 2) System definition # 3) Simulation settings # 4) Visualization # 5) Run 这五个部分不一定全都需要&#xff0c;也不一定完全按如下顺序。…

html在线商城购物网站制作——基于HTML+CSS+JavaScript鲜花礼品电商网站

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

目标检测算法——图像分割数据集汇总 2(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f384;&#x1f384;近期&#xff0c;小海带在空闲之余&#xff0c;收集整理了一批图像分割数据集供大家参考。 整理不易&#xff0c;小伙伴们记得一键三连喔&#xff01;&#xff01;&#xff01;&am…

为什么 React 中使用控制反转不会触发重新渲染

控制反转&#xff0c;是面向对象编程中的一种设计原则&#xff0c;可以用来减低计算机代码之间的耦合度。 控制反转的应用 首先来看一段常见的 React 代码 import { useState } from "react"const Father () > {const [count, setCount] useState(0);console.…

目标检测的中的指标的含义及其实现

目录 一、Precision和Recall 二、IoU (Intersection over Union) 三、top5、top1 四、Average Precision 五、COCO数据集的评价指标 1、Average Precision (AP) 2、Evaluation Code 3、Analysis Code 一、Precision和Recall Precision是查准率、精确率的意思。预测为正…

基于储能电站服务的冷热电多微网系统双层优化配置附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

QT 系统学习 day04 事件 HTTP网络请求, 音乐播放器,上位机串口通行

1.HTTP 网络 1.头文件 &#xff1a; 网络 /***** HTTP 网络相关模块 *****/ #include <QNetworkAccessManager> /** 网络访问类 **/ #include <QNetworkRequest> /** 网络请求数据类 **/ #include <QNetworkReply> /** 网络结果…

Spring学习:五、AOP 面向切面编程、Spring与Mybatis整合

7. AOP 面向切面编程 7.1 AOP概述 ​ AOP英文名为Aspect Oriented Programming&#xff0c;意为面向切面编程&#xff0c;通过预编译方式和运行期间动态代理实现程序功能统一维护的一种技术。AOP是OOP的延续&#xff0c;是Spring框架中的一个重要内容&#xff0c;利用AOP可以…

C++不知算法系列之排序从玩转冒泡算法开始

1. 前言 所谓排序&#xff0c;指把数据群体按个体数据的特征按从大到小或从小到大的顺序存放。 排序在应用开发中很常见&#xff0c;如对商品按价格、人气、购买数量等排序&#xff0c;便于使用者快速找到数据。 常见的排序算法分为两大类&#xff1a; 比较类&#xff1a;通…

springboot奖助学金评审系统的设计与实现毕业设计源码031035

奖助学金评审系统的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用…

③【Maven】创建Maven工程,解读核心配置。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 创建Maven工程&#xff0c;解读核心配置。一、…

React render 的原理和触发时机

一、原理 在类组件和函数组件中&#xff0c;render函数的形式是不同的。 在类组件中render函数指的就是render方法&#xff1b;而在函数组件中&#xff0c;指的就是整个函数组件。 class Foo extends React.Component {render() { //类组件中return <h1> Foo </h1&…