Pmdarima实现单变量时序预测与交叉验证

目录

1. pmdarima实现单变量时间序列预测

2. 时间序列交叉验证

2.1 滚动交叉验证(RollingForecastCV)

2.2 滑窗交叉验证(SildingWindowForecastCV)


1. pmdarima实现单变量时间序列预测

        Pmdarima是以statsmodel和autoarima为基础、封装研发出的Python时序分析库、也是现在市面上封装程度最高、代码最为简洁的时序预测库之一。Pmdarima由sklearn团队开发,沿袭了sklearn库的代码习惯、并保留了一切接入sklearn的接口,是非常方便机器学习学习者学习的工具。该库包括了以R语言为基础的autoarima所有的功能,并且能够处理平稳性、季节性、周期性等问题,可以执行差分、交叉验证等运算,以及内容丰富的官方说明文档。以下是使用Pmdarima实现一个简单预测的过程:

import pmdarima as pm
from pmdarima import model_selection
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
import warnings
warnings.filterwarnings("ignore")data = pm.datasets.load_wineind()
len(data) #176fig=plt.figure(figsize=(16,5))
plt.plot(range(data.shape[0]),data)
plt.grid()

#使用pm分割数据,遵循时序规则,不会打乱时间顺序
train, test = model_selection.train_test_split(data, train_size=152)
#自动化建模,只支持SARIMAX混合模型,不支持VARMAX系列模型
arima = pm.auto_arima(train, trace=True, #训练数据,是否打印训练过程?error_action='ignore', suppress_warnings=True, #无视警告和错误maxiter=5, #允许的最大迭代次数seasonal=True, m=12 #是否使用季节性因子?如果使用的话,多步预测的步数是多少?)
Performing stepwise search to minimize aicARIMA(2,1,2)(1,0,1)[12] intercept   : AIC=2955.247, Time=0.46 secARIMA(0,1,0)(0,0,0)[12] intercept   : AIC=3090.160, Time=0.02 secARIMA(1,1,0)(1,0,0)[12] intercept   : AIC=2993.480, Time=0.08 secARIMA(0,1,1)(0,0,1)[12] intercept   : AIC=2985.395, Time=0.09 secARIMA(0,1,0)(0,0,0)[12]             : AIC=3088.177, Time=0.02 secARIMA(2,1,2)(0,0,1)[12] intercept   : AIC=2978.426, Time=0.16 secARIMA(2,1,2)(1,0,0)[12] intercept   : AIC=2954.744, Time=0.18 secARIMA(2,1,2)(0,0,0)[12] intercept   : AIC=3025.510, Time=0.10 secARIMA(2,1,2)(2,0,0)[12] intercept   : AIC=2954.236, Time=0.49 secARIMA(2,1,2)(2,0,1)[12] intercept   : AIC=2958.264, Time=0.49 secARIMA(1,1,2)(2,0,0)[12] intercept   : AIC=2964.588, Time=0.38 secARIMA(2,1,1)(2,0,0)[12] intercept   : AIC=2950.034, Time=0.53 secARIMA(2,1,1)(1,0,0)[12] intercept   : AIC=2950.338, Time=0.24 secARIMA(2,1,1)(2,0,1)[12] intercept   : AIC=2953.291, Time=0.45 secARIMA(2,1,1)(1,0,1)[12] intercept   : AIC=2951.569, Time=0.21 secARIMA(1,1,1)(2,0,0)[12] intercept   : AIC=2958.953, Time=0.32 secARIMA(2,1,0)(2,0,0)[12] intercept   : AIC=2966.286, Time=0.35 secARIMA(3,1,1)(2,0,0)[12] intercept   : AIC=2951.433, Time=0.50 secARIMA(1,1,0)(2,0,0)[12] intercept   : AIC=2993.310, Time=0.39 secARIMA(3,1,0)(2,0,0)[12] intercept   : AIC=2952.990, Time=0.47 secARIMA(3,1,2)(2,0,0)[12] intercept   : AIC=2953.842, Time=0.58 secARIMA(2,1,1)(2,0,0)[12]             : AIC=2946.471, Time=0.45 secARIMA(2,1,1)(1,0,0)[12]             : AIC=2947.171, Time=0.17 secARIMA(2,1,1)(2,0,1)[12]             : AIC=2948.216, Time=0.42 secARIMA(2,1,1)(1,0,1)[12]             : AIC=2946.151, Time=0.29 secARIMA(2,1,1)(0,0,1)[12]             : AIC=2971.736, Time=0.14 secARIMA(2,1,1)(1,0,2)[12]             : AIC=2948.085, Time=0.50 secARIMA(2,1,1)(0,0,0)[12]             : AIC=3019.258, Time=0.06 secARIMA(2,1,1)(0,0,2)[12]             : AIC=2959.185, Time=0.36 secARIMA(2,1,1)(2,0,2)[12]             : AIC=2950.098, Time=0.52 secARIMA(1,1,1)(1,0,1)[12]             : AIC=2953.184, Time=0.14 secARIMA(2,1,0)(1,0,1)[12]             : AIC=2964.069, Time=0.14 secARIMA(3,1,1)(1,0,1)[12]             : AIC=2949.076, Time=0.16 secARIMA(2,1,2)(1,0,1)[12]             : AIC=2951.826, Time=0.16 secARIMA(1,1,0)(1,0,1)[12]             : AIC=2991.086, Time=0.09 secARIMA(1,1,2)(1,0,1)[12]             : AIC=2960.917, Time=0.14 secARIMA(3,1,0)(1,0,1)[12]             : AIC=2950.719, Time=0.13 secARIMA(3,1,2)(1,0,1)[12]             : AIC=2952.019, Time=0.17 secBest model:  ARIMA(2,1,1)(1,0,1)[12]          
Total fit time: 11.698 seconds
#预测
preds = arima.predict(n_periods=test.shape[0])
preds #按照测试集的日期进行预测
array([25809.09822027, 27111.50500611, 30145.84346715, 35069.09860267,19044.09098919, 22734.07766136, 24370.14476344, 24468.4989244 ,24661.71940304, 24465.6250753 , 29285.02123954, 25607.32326197,26131.79439226, 26937.20321329, 29632.82588046, 33904.51565498,20207.31393733, 23342.10936251, 24741.41755828, 24828.6385991 ,24993.22466868, 24825.14042152, 28939.23990247, 25799.92370898])
fig=plt.figure(figsize=(16,5))
plt.plot(range(test.shape[0]),test)
plt.plot(range(test.shape[0]),preds)
plt.grid()

模型评估指标可共有sklearn的评估指标,也可调用特定的时序指标AIC:

np.sqrt(mean_squared_error(test, preds))
2550.8826581401277
arima.aic()
2946.1506587436375
arima.summary()

枚举式搜索合适的参数,从效率角度来说远远超过statsmodel,遗憾的是,从上述代码不难看出pmdarima的代码思路是更最近机器学习而不是统计学的,因此pmd.auto arima跑出的结果往往无法满足统计学上的各类检验要求,因此泛化能力无法被保证。同时也很容易发现,由于数据集分割的缘故,autoarima选择出的最佳模型可能无法被复现,例如我们使用autoarima选择出的最佳模型建立单模:

model=pm.ARIMA(order=(2,1,1),seasonal_order=(1,0,1,12),max_iter=500)
model.fit(train)fig=plt.figure(figsize=(16,5))
plt.plot(range(test.shape[0]),test)
plt.plot(range(test.shape[0]),model.predict(n_periods=test.shape[0]))
plt.grid()

np.sqrt(mean_squared_error(test, model.predict(n_periods=test.shape[0])))
3081.3401428137163
model.aic()
2936.648256262213

        既然pmdarima是基于statsmodel搭建,也能够使用基于R语言的autoarima所有的功能,pmdarima自然也能够支持相应的各类统计学检验以及相关系数计算,更多的详情都可以参考pmdarima的官方说明文档。一般在使用pmdarima建模后,还需要使用统计学中的一系列检验来选择模型、找出能够通过所有检验的模型。

2. 时间序列交叉验证

        在时序模型的选择过程中,可以借助交叉验证来帮助我们选择更好的模型。时间序列的交叉验证非常特殊,因为时间序列数据必须遵守“过去预测未来”、“训练中时间顺序不能打乱"等基本原则,因此传统机器学习中的k折交叉验证无法使用。
        在时间序列的世界中,有以下两种常见的交叉验证方式:滚动交叉验证(RollingForecastCV) 和滑窗交叉验证 (SlidingWindowForecastCV),当提到“时序交叉验证”时,一般特指滚动交叉验证。下面具体来看一下两种交叉验证的操作:

2.1 滚动交叉验证(RollingForecastCV)

        滚动交叉验证是在验证过程中不断增加训练集、并让验证集越来越靠近未来的验证方式,这一方式既能保证我们一定是在用“过去预测未来”,同时也能够保证需要预测的未来和过去真实标签之间的是足够近的,因为越靠近未来的数据对未来的影响越大。这一交叉验证方式很像“多步预测”,但是该方式却不会存在多步预测中的“错误累计"问题,因为在训练过程中我们一直是在使用客观存在的真实标签。
        在pmdarima中,我们使用类 RollingForecastCV和 cross_validate 来实现交叉验证,很明显pmdarima的思路借鉴了sklearn (事实上,pmdarima在所有统计学相关内容上是借鉴并依赖于statsmodel进行运行,在所有机器学习相关内容上是借鉴sklearn进行运行)。sklearn中的交叉验证:

cv = KFold(n_splits=5,shuffle=True,random_state=1412)
results = cross_validate(reg,Xtrain,Ytrain,cv=cv)

其中cv是交叉验证具体的模式,cross_validate则负责执行交叉验证本身。在pmdarima运行交叉验证时,类RollingForecastCV的地位等同于普通机器学习交叉验证中的 KFold 类。RollingForecastCv 也只能规定交叉验证的模式,不负责执行交叉验证本身。特别的是,普通K折交叉验证是由折数来控制的,但时序交叉验证其实是以单个样本为单位的。一般来说,时序交叉验证的验证集可以是多个时间点,也可以为单个时间点。当验证集为1个时间点时,滚动交叉验证如下所示:

在pmdarima当中,使用RollingForecastCV来完成交叉验证:

class pmdarima.model selection.RollingForecastCV(h=1,step=1,initial=None)

h:验证集中的样本数量,可以输入[1,n_samples]的整数。
step:训练集中每次增加的样本数量,必须为大于等于1的正整数。
initial:第一次交叉验证时的训练集样本量,如果不填写则按1/3处理。

 取h=1,step=1,initial=10

data = pm.datasets.load_wineind()
cv=model_selection.RollingForecastCV(h=1,step=1,initial=10)
cv_generator=cv.split(data)
next(cv_generator)#根据initial初始训练集有10个样本,验证集遵循参数h的设置,只包含一个样本
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), array([10]))
next(cv_generator)#根据step的设置,训练集每次增加1个样本,验证集继续包含一个样本
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10]), array([11]))
next(cv_generator)
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]), array([12]))

取h=10,step=5,initial=10

cv=model_selection.RollingForecastCV(h=10,step=5,initial=10)
cv_generator=cv.split(data)
next(cv_generator)
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]))
next(cv_generator)
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14]),array([15, 16, 17, 18, 19, 20, 21, 22, 23, 24]))
next(cv_generator)
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19]),array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29]))

不难发现,在pmdarima中实现滚动交叉验证时,验证集实际上是可以重复的,因此滚动交叉验证可以在有限的数据上进行多轮验证集重合的交叉验证,只要满足“过去预测未来”的基本条例,时序交叉验证其实可以相对自由的进行(即验证集与验证集之间不是互斥的)。也因此,时序交叉验证的实际运行时间往往会很长,当数据量巨大时交叉验证的负担也会更大。

# 沿用上面的数据和模型
model=pm.ARIMA(order=(2,1,1),seasonal_order=(1,0,1,12),max_iter=500)
cv=model_selection.RollingForecastCV(h=24,step=12,initial=36)
predictions=model_selection.cross_validate(model,data,cv=cv,scoring="mean_squared_error",verbose=2,error_score="raise")
[CV] fold=0 ..........................................................
[CV] fold=1 ..........................................................
[CV] fold=2 ..........................................................
[CV] fold=3 ..........................................................
[CV] fold=4 ..........................................................
[CV] fold=5 ..........................................................
[CV] fold=6 ..........................................................
[CV] fold=7 ..........................................................
[CV] fold=8 ..........................................................
[CV] fold=9 ..........................................................
predictions
{'test_score': array([1.35362847e+08, 1.08110482e+08, 2.18376249e+07, 1.97805181e+07,6.16138893e+07, 1.42418110e+07, 1.32432958e+07, 1.31182597e+07,3.57071218e+07, 5.79654872e+06]),'fit_time': array([0.2784729 , 0.12543654, 0.62335014, 0.64258695, 0.75659704,0.73791075, 0.82430649, 0.92007995, 0.98767185, 1.03166628]),'score_time': array([0.01047397, 0.        , 0.00223732, 0.        , 0.        ,0.        , 0.01564431, 0.        , 0.01562428, 0.01562572])}
np.sqrt(predictions["test_score"])
array([11634.55400113, 10397.61906654,  4673.07446159,  4447.52944078,7849.45153132,  3773.83240719,  3639.13393689,  3621.91381986,5975.54363899,  2407.60227639])

可以看到,交叉验证的测试集中得到的RMSE大部分都大于之前自动化建模时得到的RMSE(2550),并且训练数据越少时,测试集上的RMSE会越大,这可能说明在前几折交叉验证时,训练集的数据量太少,因此可以考虑增大initial当中的设置来避免这个问题。

2.2 滑窗交叉验证(SildingWindowForecastCV)

        滑窗交叉验证是借助滑窗技巧完成的交叉验证。滑窗是时间序列中常见的技巧,具体操作如下:

Sliding window——>——>

在时间序列预测时,常常使用窗内的样本作为训练样本、窗右侧(或下方)的第一个样本做为被预测的样本。滑窗技巧在时间序列的各个领域都应用广泛,是时间序列的基础之一。很显然,滑窗交叉验证就是使用窗内的样本作为训练集,窗右侧(或下方)的样本作为验证集而进行的交叉验证。

与滚动交叉验证一样,滑窗交叉验证中的验证集也可以是单一样本,也可以是一系列数据集。相比起滚动交叉验证,滑窗交叉验证的优势在于训练集不会越来越大、每次训练时都使用了理论上对当前验证集来说最有效的信息。但同时,这个优势也会带来问题,由于训练集往往较小,因此滑窗交叉验证需要进行的建模次数异常地多,这可能导致交叉验证模型变得非常缓慢。

在pmdarima当中,使用 SlidingWindowForecastCV 来完成滑窗交叉验证
class pmdarima.model_selection.SlidingWindowForecastCV(h=1,step=1,window size=None)

h:验证集中的样本数量,可以输入[1,n_samples]的整数
step:每次向未来滑窗的样本数量,必须为大于等于1的正整数
window_size:滑窗的尺寸大小,如果填写None则按照样本量整除5得到的数来决定

取h=1,step=1,window_size=10

cv=model_selection.SlidingWindowForecastCV(h=1,step=1,window_size=10)
cv_generator=cv.split(data)
next(cv_generator)#首次进行交叉验证时的数据分割情况
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), array([10]))
next(cv_generator)#第二次交叉验证时的数据分割情况
(array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10]), array([11]))

 取h=10,step=5,window_size=10

cv=model_selection.SlidingWindowForecastCV(h=10,step=5,window_size=10)
cv_generator=cv.split(data)
next(cv_generator)
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]))
next(cv_generator)
(array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14]),array([15, 16, 17, 18, 19, 20, 21, 22, 23, 24]))
# 沿用上面的数据和模型
model=pm.ARIMA(order=(2,1,1),seasonal_order=(1,0,1,12),max_iter=500)
cv=model_selection.SlidingWindowForecastCV(h=24,step=12,window_size=36)
predictions=model_selection.cross_validate(model,data,cv=cv,scoring="mean_squared_error",verbose=2,error_score="raise")
[CV] fold=0 ..........................................................
[CV] fold=1 ..........................................................
[CV] fold=2 ..........................................................
[CV] fold=3 ..........................................................
[CV] fold=4 ..........................................................
[CV] fold=5 ..........................................................
[CV] fold=6 ..........................................................
[CV] fold=7 ..........................................................
[CV] fold=8 ..........................................................
[CV] fold=9 ..........................................................
predictions
{'test_score': array([1.35362847e+08, 1.20867167e+08, 1.48347243e+08, 2.49879706e+08,2.32217899e+08, 4.01511152e+08, 1.92061264e+08, 2.51755311e+08,1.50798724e+08, 1.92747682e+08]),'fit_time': array([0.28506732, 0.16709971, 0.17653751, 0.12498903, 0.1408143 ,0.16088152, 0.22708297, 0.33786058, 0.1593399 , 0.27807832]),'score_time': array([0.00801778, 0.        , 0.01562667, 0.        , 0.01132369,0.        , 0.01562595, 0.        , 0.01562929, 0.        ])}
np.sqrt(predictions["test_score"])
array([11634.55400113, 10993.96047191, 12179.78831408, 15807.58382521,15238.69740534, 20037.7431982 , 13858.61697326, 15866.79900091,12280.01317219, 13883.35991075])

从结果来看,使用更少的训练集进行训练后,模型输出的RMSE大幅上升了,并且也没有变得更稳定,这说明当前模型下更大的训练集会更有利于模型的训练(不是每个时间序列都是这样)。尝试调整滑窗的window_size,就会发现RMSE下降到了与滚动交叉验证时相似的水平:

model=pm.ARIMA(order=(2,1,1),seasonal_order=(1,0,1,12),max_iter=500)
cv=model_selection.SlidingWindowForecastCV(h=24,step=1,window_size=132)
predictions=model_selection.cross_validate(model,data,cv=cv,scoring="mean_squared_error",verbose=2,error_score="raise")
[CV] fold=0 ..........................................................
[CV] fold=1 ..........................................................
[CV] fold=2 ..........................................................
[CV] fold=3 ..........................................................
[CV] fold=4 ..........................................................
[CV] fold=5 ..........................................................
[CV] fold=6 ..........................................................
[CV] fold=7 ..........................................................
[CV] fold=8 ..........................................................
[CV] fold=9 ..........................................................
[CV] fold=10 .........................................................
[CV] fold=11 .........................................................
[CV] fold=12 .........................................................
[CV] fold=13 .........................................................
[CV] fold=14 .........................................................
[CV] fold=15 .........................................................
[CV] fold=16 .........................................................
[CV] fold=17 .........................................................
[CV] fold=18 .........................................................
[CV] fold=19 .........................................................
[CV] fold=20 .........................................................
predictions
{'test_score': array([35707121.78143389, 66176325.69903485, 40630659.97659013,78576782.28645307, 23666490.55159284, 20310751.60353827,2841898.1720445 ,  4484619.0619739 , 18925627.1367884 ,3231920.46993413, 55955063.23334328,  5769421.1274077 ,12204785.2577201 , 81763866.37114508, 86166090.62031393,4308494.01384212,  4472068.45984436, 80544390.23157245,95444224.35956413,  4356301.4101477 , 41312817.67528097]),'fit_time': array([0.98685646, 1.00776458, 0.98309445, 0.98523855, 0.99820113,0.88483882, 1.14556432, 0.94388413, 0.95140123, 1.01311779,1.01590633, 1.06021142, 1.05152464, 1.06878543, 1.08534598,1.07379961, 0.96942186, 0.92225981, 0.95834565, 1.33569884,0.91161823]),'score_time': array([0.01562262, 0.01562762, 0.        , 0.00460625, 0.        ,0.00678897, 0.00810504, 0.01536226, 0.01825047, 0.00629425,0.00742435, 0.01564217, 0.        , 0.        , 0.        ,0.        , 0.00800204, 0.01618385, 0.        , 0.01562595,0.        ])}
np.sqrt(predictions["test_score"])
array([5975.54363899, 8134.88326278, 6374.21838162, 8864.35458939,4864.82173893, 4506.74512298, 1685.79303951, 2117.69191857,4350.35942616, 1797.75428519, 7480.31170696, 2401.96193296,3493.53477981, 9042.33743958, 9282.56918209, 2075.69121351,2114.72656858, 8974.65265242, 9769.55599603, 2087.17546223,6427.50477832])

此时RMSE的均值大幅下降了,但是模型还是不稳定(波动较大),这说明当前时间序列各时间段上的差异较大,当前模型的拟合结果一般。虽然通过增加训练集的数据量可以让模型表现提升,但极其不稳定的结果展示当前模型的泛化能力是缺失的。和使用AIC时一样,我们只能选择表现更好的时序模型(只能择优),而无法选择完美的时序模型。当我们将auto_arima选出的最佳参数放弃、而选择带有其他参数的模型,说不定得到的结果会更加不稳定。

        你是否注意到一个细节?时序交叉验证不会返回训练集上的分数,同时pmdarima的预测功能predict中也不接受对过去进行预测。通常来说我们判断过拟合的标准是训练集上的结果远远好于测试集,但时序交叉验证却不返回训练集分数,因此时间序列数据无法通过对比训练集和测试集结果来判断是否过拟合。但在时间序列的世界中,依然存在着”过拟合”这个概念,我们可以通过交叉验证的结果来判断不同参数下的时间序列模型哪个过拟合程度更轻。
        通常来说,验证集上的分数最佳的模型过拟合风险往往最小,因为当一个模型学习能够足够强、且既不过拟合又不欠拟合的时候,模型的训练集和验证集分数应该是高度接近的,所以验证集分数越好,验证集的分数就越可能更接近训练集上的分数。因此在多个模型对比的情况下,我们可以只通过观察测试集上的分数来选定最佳模型。这个最佳模型即是表现最佳的模型,也是过拟合风险最小的模型(不是绝对)。
 

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

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

相关文章

故障诊断模型 | Maltab实现GRU门控循环单元故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现GRU门控循环单元故障诊断 模型描述 利用各种检查和测试方法,发现系统和设备是否存在故障的过程是故障检测;而进一步确定故障所在大致部位的过程是故障定位。故障检测和故障定位…

3ds Max2022安装教程(最新最详细)

目录 一.简介 二.安装步骤 网盘资源见文末 一.简介 3DS Max是由Autodesk公司开发的一款专业三维建模、动画和渲染软件,广泛应用于影视、游戏、建筑和工业设计等领域。 3DS Max的主要特点和功能包括: 三维建模:3DS Max提供了各种强大的建…

如何用思维导图开会

在办公室和会议室使用思维导图会有无数好处。今天我们就聊聊思维导图在开会中的作用? 为什么要在会议中使用思维导图? 思维导图可以帮助我们整理思路。会议通常涉及到复杂的议题和讨论,使用思维导图可以帮助整合和梳理参与者的思路和观点。通…

Vue项目搭建及使用vue-cli创建项目、创建登录页面、与后台进行交互,以及安装和使用axios、qs和vue-axios

目录 1. 搭建项目 1.1 使用vue-cli创建项目 1.2 通过npm安装element-ui 1.3 导入组件 2 创建登录页面 2.1 创建登录组件 2.2 引入css(css.txt) 2.3 配置路由 2.5 运行效果 3. 后台交互 3.1 引入axios 3.2 axios/qs/vue-axios安装与使用 3.2…

priority_queue 的模拟实现

priority_queue 的底层结构 我们已经学习过栈和队列了,他们都是用一种容器适配出来的。今天我们要学习的 prority_queue 也是一个容器适配器。在 priority_queue 的使用部分我们已经知道想要适配出 priority_queue,这个底层的容器必须有以下接口&#x…

安装Python环境

Python 安装包下载地址:https://www.python.org/downloads/ 打开该链接,可以看到有两个版本的 Python,分别是 Python 3.x 和 Python 2.x,如下图所示: Python下载页面截图 图 1 Python 下载页面截图(包含…

基于单片机设计的防煤气泄漏装置

一、前言 煤气泄漏是一个严重的安全隐患,可能导致火灾、爆炸以及对人体健康的威胁。为了提高家庭和工业环境中煤气泄漏的检测和预防能力,设计了一种基于单片机的防煤气泄漏装置。 单片机选择STC89C52作为主控芯片。为了检测煤气泄漏,采用了…

cocosCreator 调用wxAPI 及后台授权设置、获取用户昵称和头像

版本: 3.8.0 语言: TypeScript 环境: Mac 官方文档: 微信官方文档 - 开放能力 微信 API 小游戏环境 在cocosCreator的3.x版本项目开发中,TypeScript最终会被转换为JavaScript语言。 JavaScript的运行时调用的API…

联发科MT6893(天玑1200)_MTK5G芯片规格参数性能_安卓手机主板方案

联发科天玑1200集成MediaTek 5G调制解调器,通过包含6大维度、72个场景测试的德国莱茵TV Rheinland认证,支持高性能5G连接,带给用户全场景的高品质5G连网体验。 进入5G时代,AI多媒体成为主流应用,天玑1200以强劲的平台…

【高效开发工具系列】你真的会使用Mac吗?

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

uniapp实现瀑布流

首先我们要先了解什么是瀑布流: 瀑布流(Waterfall Flow)是一种常见的网页布局方式,也被称为瀑布式布局或砌砖式布局。它通常用于展示图片、博客文章、商品等多个不同大小和高度的元素。 瀑布流布局的特点是每个元素按照从上到下…

现代的简洁,诠释轻奢的精致!福州中宅装饰,福州装修

轻奢风是一种生活新时尚 优雅、低调、舒适、简单,不断地推陈出新 站在时尚的前沿,引领潮流 中宅装饰集团轻奢风格产品 追求高品质生活细节 以设计精致的空间构造营造出 一种优雅、时尚生活氛围 将低调奢华之美注入现代家居设计中 客厅|The Sitt…

世界电信日 | 人大金仓助力中国移动租赁核算系统升级上线

世界电信日 5月17日恰逢第五十四个世界电信日,运营商作为新型基础设施建设以及维护网信安全的主力军,掌握关键核心技术,实现科技自立自强刻不容缓。 作为数据库领域国家队,人大金仓坚持原始创新,低难度、低成本、低风…

早安心语微语早读,保持一颗平常心,坐看云起落花开谢得之淡然

1、保持一颗平常心,坐看云起落花开谢得之淡然,失之坦然,让生命中每一天都充满着阳光和希望! 2、每个人都一样,都有一段独行的日子,或长或短,这都是无可回避的。不必总觉得生命空空荡荡&#xf…

ArcGIS计算土地现状容积率

本文讲解在ArcGIS中,基于建筑数据和地籍边界数据,计算土地容积率。 一、容积率介绍 容积率(Plot Ratio/Floor Area Ratio/Volume Fraction)是指一个小区的地上建筑总面积与净用地面积的比率。又称建筑面积毛密度。 二、数据分析 (1)建筑数据(dwg) (2)地籍边界数据…

利用AI Chat 将电子书自动截屏并保存成pdf文件

电子书如果要下载下来,无非就两种类型的方法,一种是从内部破解,通常是某些极客将软件破解成免费版,但是风险也大。另一种是从外部破解,就是截屏保存,然后将所有图片拼成pdf文件。 如果要将整本电子书截屏保…

LeetCode刷题---简单组(六)

文章目录 🍒题目一 69. x 的平方根🍒解法一🍒解法二🍒题目二 70. 爬楼梯🍒解法一 🍒题目一 69. x 的平方根 🍒解法一 class Solution(object):def mySqrt(self, x):""":type x:…

制作一个简单的C语言词法分析程序

1.分析组成 C语言的程序中,有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表,给出对应的识别码,然后跟据对应的表格来写出程序 2.程序设计 程序主要有循环判断构成。不需推理即可产生的符号我…

SSM培训报名管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 培训报名管理系统是一套完善的信息系统,结合SSM框架完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库,系统主 要采用B/S模式开…

Windows2008系统怎么隐藏或打开文件后缀

打开服务器的控制面板-选择小图标-文件夹选项 在文件夹选项那边点击查看-隐藏一直文件类型的扩展名 选择勾选(隐藏一直文件类型的扩展名)-下图示文件后缀不显示 选择不勾选(隐藏一直文件类型的扩展名)-下图示文件后缀显示