干货分享:基于 LSTM 的广告库存预估算法

news2025/1/10 23:26:07

近年来,随着互联网的发展,在线广告营销成为一种非常重要的商业模式。出于广告流量商业化售卖和日常业务投放精细化运营的目的,需要对广告流量进行更精准的预估,从而更精细的进行广告库存管理。

因此,携程广告纵横平台实践了LSTM(Long Short-Term Memory,长短时记忆网络)模型结合Embedding的广告库存预估深度学习算法,在节省训练资源的同时,构建更具泛化性的模型,支持根据不同地域分布、人口学属性标签等进行库存变动预估,并能体现出节假日特征对库存波动的影响,从而对广告库存进行更为精确的预估。

技术交流

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

相关文件及代码都已上传,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、添加微信号:dkl88194,备注:来自CSDN + 加群
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

问题和挑战

广告库存预估实现有诸多挑战:

  • 现实中对广告库存的影响因素非常多,比如节假日、周末、自然灾害等等;

  • 广告库存样本周期以天为单位,训练样本很少;

  • 需要支持不同维度交叉进行广告预估,例如同时选择地域、年龄、性别、会员等级等定向交叉,预估未来N天的库存情况;

  • 广告库存日新月异,随时间推移,不断有新的库存样本生成,模型更新频率要求较高。

这些因素让广告库存预估工作从资源和效率等角度都带来压力。

算法简述

RNN(Recurrent Neural Network,循环神经网络)是一种特殊的神经网络,被广泛应用于序列数据的建模和预测,如自然语言处理、语音识别、时间序列预测等领域。RNN对时间序列的数据有着强大的提取能力,也被称作记忆能力。相对于传统的前馈神经网络,RNN具有循环连接,可以将前一时刻的输出作为当前时刻的输入,从而使得网络可以处理任意长度的序列数据,捕捉序列数据中的长期依赖关系。

图片

图 3-1

LSTM(Long Short-Term Memory,长短时记忆网络)是一种特殊的 RNN,它通过引入门控机制和记忆单元等结构来增强 RNN 的记忆能力和表达能力。

LSTM 的基本结构包括一个循环单元和三个门控单元:输入门、遗忘门和输出门。循环单元接受当前时刻的输入和前一时刻的输出作为输入,并输出当前时刻的输出和传递到下一时刻的状态。输入门控制当前时刻的输入对状态的影响,遗忘门控制前一时刻的状态对当前状态的影响,输出门控制当前状态对输出的影响。记忆单元则用于存储和传递长期的信息。基于此,使得LSTM具有长期的记忆能力,并且具有防止梯度消失的特点,故我们选择LSTM作为库存预估模型的训练基础。

图片

图 3-2

Embedding是一种特征处理方式,它可以将我们的某个特征数据向量化,可以将离散的整数序列映射为连续的实向量,它通常用于自然语言处理中的词嵌入(Word Embedding)任务,用于将每个单词映射为一个实向量,从而使得单词之间的语义关系可以在向量空间中进行计算。

在本文中,我们是使用它进行实体嵌入(Entity Embedding) 任务,也就是将我们的特征实体进行向量化,通过大量的数据训练,得到实体向量之前的细微关系,从而帮助模型更清晰的识别不同实体对广告库存的影响,进而提高模型的泛化能力。

数据处理

4.1 特征定义

基础特征为下图所示:

图片

图 4-1

由于节假日的特殊性,我们又将其细分为以下维度,保证模型抓住节前和节后购票效应。

图片

图 4-2

4.2 归一化

在深度学习中,对数据进行归一化主要目的是将数据缩放到一个合适的范围内,便于神经网络的训练和优化。对数据进行归一化可以改善梯度下降、加速收敛、提高模型的泛化能力。

我们选择Z-score标准化方法对数据进行处理,Z-score 标准化(也称为标准差标准化)是一种常见的数据归一化方法,其基本思想是将原始数据转换为标准正态分布,即均值为 0,标准差为 1。公式如下图所示,是一个实测值与平均数的差再除以标准差的过程。

图片

4.3 数据聚类

我们在第二章节问题和挑战中聊到过,广告库存预估需要对多个维度支持预估功能,不同维度交叉组合后,库存量千差万别,导致我们的样本数据中标签值min和max差距非常大。

如图4-3所示,本图Y轴表示某组合维度标签值的库存数据量级,库存数据量较小的组合维度占有很大一部分,而库存数据量较大的组合维度相对较少,仅凭数据归一化手段,数据压缩的效果非常不明显,如果强行一起训练会互相影响,导致模型难以拟合,训练中的损失函数如图4-4所示,训练时模型无法正常拟合,损失值不能够正常下降,训练出的模型效果可想而知,无法支持正常的预估功能。

图片

图 4-3

图片

图 4-4

所以,我们以库存样本的标签值为依据,使用K-means算法对不同维度的库存进行数据聚类,将近似类别的维度放在一起进行训练,提高模型的拟合速度和泛化能力。

我们选择“肘部法则”来确认本数据集的最佳分类数,也就是K-means的簇数K的具体值。随着K的增加,聚类效果不断提高,但是当K到达某个值的时候,聚类效果的提高变得越来越慢,此时再增加K已经不能明显提高聚类效果,因此这个点就是最佳的K值。具体过程如下:

  1. 对数据集进行K-Means聚类,分别尝试不同的簇数K。

  2. 对于每个簇数K,计算该簇数下的SSE(Sum of Squared Errors),即每个数据点到其所属簇中心的距离的平方和,保存SSE 到数组。

  3. 使用numpy库中的diff函数计算相邻两点的差异并除以最大值,得到变化率。然后,我们使用numpy库中的argmax函数找到最大斜率的位置,加上n即为肘部点的位置。

  4. n的取值要考虑自身数据集,一般来说,K的值至少要为2,不然没有分类意义,而且argmax计算出来的是数组的索引位置,小于真实位置1个点位,综合考虑,我们将n设置为2。

# 计算不同聚类个数下的聚类误差
    n = 2
    sse = []
    for k in range(1, 10):
        kmeans = KMeans(n_clusters=k, random_state=0).fit(data)
        sse.append(kmeans.inertia_)

    # 自动寻找肘部点
    diff = np.diff(sse)
    diff_r = diff[1:] / diff[:-1]
    nice_k = np.argmin(diff_r) + n
#绘制SSE随簇数变化的曲线(如图4-5),观察曲线的形状。
    plt.plot(range(1, 10), sse, 'bx-')
    plt.xlabel('Number of Clusters')
    plt.ylabel('SSE')
    plt.title('Elbow Method for Optimal k')
    plt.show()

图片

图 4-5

经过K值选择后,我们将样本数据集进行聚类得到如下图4-6所示结果,Y轴为某组合维度的标签值,X轴为某组合维度出现在样本数据集数组中的索引位置。其中最右侧最高的点,明显是没有任何维度交叉的全部广告库存,其他位置都是经过维度交叉后的库存,最终我们将其分成了3份进行训练。

图片

图 4-6

经过聚类处理后,模型训练时损失函数输出的损失值如下图所示,出现了正常的损失值下降的过程,并逐渐趋于稳定。

图片

图 4-7

五、网络结构定义与训练

5.1 网络结构定义

1)网络模型结构图

图片

图 5-1

2)网络模型定义

我们将各维度组装特征数据和标签数据的数据经过Embedding 实体嵌入,输入到LSTM学习并提取历史库存的时间序列特性,最终经过激活函数和全连接层输出与标签值进行损失值计算,不断拟合,直到损失值接近稳定或到达最大训练批次。

import torch
from torch import nn


class LSTM(nn.Module):
    def __init__(self, emb_dims, out_dim, hidden_dim, mid_layers):
        super(LSTM, self).__init__()
        self.emb_layers = nn.ModuleList([nn.Embedding(x, y) for x, y in emb_dims])
        self.rnn = nn.LSTM([sum(x) for x in zip(*emb_dims)][1] + 1, hidden_dim, mid_layers, batch_first=False)
        self.reg = nn.Sequential(
            nn.Linear(hidden_dim, hidden_dim),
            nn.Tanh(),
            nn.Linear(hidden_dim, out_dim),
        )

    def forward(self, cat_data):
        var_x = []
        for cat in cat_data:
            x = self.emb_layer(cat)
            var_x.append(x)
        stack = torch.stack(var_x)
        y = self.rnn(stack)
        return y

5.2 训练

1)组织数据

我们获取任意维度历史N天数据作为训练集,如下图所示,我们设定滑动窗口时间为七天,定义广告请求数为标签数据。使用DataLoader组织数据,shuffle设为True保证样本是随机获取的,仅需保证滑动窗口内部有序即可,这样训练可以提高模型的泛化能力。

loader = Data.DataLoader(dataset=set, batch_size=size, shuffle=True, num_workers=numWorkers)

需要注意的是,LSTM要求的入参顺序为(seq_length, batch_size, input_size)即:序列长度、批次量数、特征维度,然而DataLoade组织出的数据第一个维度是batch_size,因此设置batch_first = true,即可解决问题,继续正常的使用LSTM模型训练数据。但是这会拉低训练效率,原因是NVIDIA cuDNN 的RNN API 设置的batch_size参数就是在第二个位置,这样设置的原因如下:

举个例子1,假设输入序列的长度seq_length等于3,batch_size等于2,假设一个batch的数据是[[“A”, “B”, “C”], [“D”, “E”, “F”]],如图5-2所示。由于RNN是序列模型,只有T1时刻计算完成,才能进入T2时刻,而"batch"就体现在每个时刻Ti的计算过程中,图1中T1时刻将[“A”, “D”]作为当前时刻的batch数据,T2时刻将[“B”, “E”]作为当前时刻的batch数据,可想而知,“A"与"D"在内存中相邻比"A"与"B"相邻更合理,这样取数据时才更高效。

而不论Tensor的维度是多少,在内存中都以一维数组的形式存储,batch first意味着Tensor在内存中存储时,先存储第一个sequence,再存储第二个… 而如果是seq_length first,模型的输入在内存中,先存储所有sequence的第一个元素,然后是第二个元素… 两种区别如图5-3所示,seq_length first意味着不同sequence中同一个时刻对应的输入元素(比如"A”, “D” )在内存中是毗邻的,这样可以快速读取数据。

图片

图 5-2

图片

图 5-3

因此,使用batch_first = true并不是好的选择,可以选择permute函数解决此问题:

batch_x = batch_x.permute((1, 0, 2))

使用此方法改变数组的shape,以适应原始LSTM模型的入参要求,在不影响训练速度的原则下解决参数顺序问题。

2)训练步骤

输入: 任意维度前七天组成的窗口数据,包括所有的特征数据 + 标签数据

输出: 第八天的标签数据

第N步

图片

图 5-4

第N+1步:

图片

图 5-5

3)离线与在线增量训练

第二章节问题和挑战中提到,由于广告样本数据每天都在产生,而且影响其因素非常多,所以历史模型仅凭历史库存学到的时间序列特性预估出的未来库存,除了可以带有假期周末等时间特征的正向影响外,很难紧跟近期的库存数量级。

所以,这要求我们要高频次的更新广告库存预估模型,但这也加大了维护成本,如果仅采用离线训练的方式,每次都拉取全量历史库存样本数据训练出新的优质模型,无疑是不可取的,所以我们选择一次离线训练+N次在线增量训练的方式解决此问题。

a. 离线训练

首先使用Spark Sql组织广告库存Hive表中现存所有的历史数据导入CSV文件,使用GPU训练此样本数据,由于是各维度交叉训练,一般在这个阶段数据量在亿级别,如果资源有限,离线训练可以拆分广告位分别进行。经过多次训练选择优质的离线模型文件,作为基础预估模型,可以用于短期的库存预估工作。此时我们需要将优质模型以字节的形式存储至Redis,便于后面的预估服务和在线训练脚本使用。

此时需要注意的是,我们需要将模型和优化器打包为一个字典,以二进制的方式读取模型文件并保存在Redis中。

#保存模型:
#net:模型
#optimizer:优化器
 
state = {'net': net.state_dict(), 'optimizer': optimizer.state_dict()}
torch.save(state, netPath)
         
#存储至Redis:
def saveModel(modelName, netPath):
    with open(modelPath, "rb") as f:
        pth_model = f.read()
    result = redis.set(modelName, pth_model)

b. 在线训练:经过离线训练后,我们得到了一个优质的预估模型,此时我们需要开发两个脚本:

① PySpark 拉取hive表中昨天的库存样本存储在GPU机器实时文件目录。

② 读取实时文件目录,获取近八个文件,前七个作为一个滑动窗口数据,第八个作为标签值组成单次训练样本,在Redis中获取并加载预存的模型和优化器,进行一次在线训练,再将其覆盖保存至redis中。

# 在Redis中加载模型
def readModel(modelName, path):
    pthByte = redis.get(modelName)
    with open(path, 'wb') as f:
        f.write(pthByte)
    return torch.load(path, map_location=lambda storage, loc: storage)
 
 
# 加载模型和优化器状态,用于训练
 
# 读取字典
model = readModel(modelName, path)

# 加载模型
net = LSTM(emb_dims, out_dim, mid_dim, mid_layers).to(device)
net.load_state_dict(model['net'])

# 加载优化器
optimizer = torch.optim.Adam(net.parameters(), lr=1e-2)
optimizer.load_state_dict(model['optimizer'])

最终,我们将以上两个脚本配置在携程大数据定时任务,设置每天0点后执行,即可实现不断的在线训练,保证模型在优质状态的基础上,使用最新的库存数据对模型进行微调修正,使用Redis保存模型可以快速存取模型文件流,保证在线训练结束后,预估服务可以立刻反应,获取到新的模型用于预估工作,无需对预估服务做任何改动。根据以上方案可以不断维持模型提供精准的预估能力。

4)早停机制

训练过程中,为防止过拟合,也为提高效率,当loss 不再明显变化时终止训练,输出模型,每次训练不断记录并更新loss最小值,当loss 连续N次小于x时,视为可触发早停机制。

class EarlyStopping:
         
    def __call__(self, val_loss):
        score = val_loss
        if self.best_score is None:
            self.best_score = score
        elif score > self.best_score:
            if score <= x:
                self.counter += 1
            if self.counter >= self.patience:
                self.early_stop = True
        else:
            self.best_score = score
            self.counter = 0

下图为早停效果图,设置的训练批次为150批, 此模型训练至115批截至,可以观察到loss已经非常低, 已经没有下降空间,符合早停预期。

图片

图 5-6

5)指标验证

经过模型的构建和训练后,我们需要对模型做出评估,以决定模型是否可以推到线上使用,因为基础数据量较小,所以本次模型未设置验证集,训练集和测试集 9 :1。评估指标采用WMAPE(加权偏差率):

图片

TorchMetrics 类库对80 多个PyTorch 指标做了实现.

这里我们直接调用api : WeightedMeanAbsolutePercentageError

import torchmetrics

error = torchmetrics.WeightedMeanAbsolutePercentageError()
# 调用模型得到预估值
predict = net(valid_x)
# 计算偏差
error = error(predict, valid_y)
error_list.append(error.item())

指标验证可以更科学的观察到模型对所有维度的测试集的预估能力, 可以更科学的验证模型是否符合我们的预期,指导我们进行调参,控制唯一变量并观察指标变化。某广告位置调参验证示例如下, 比较不同批次训练模型后指标比较, 明显表现出200批次的模型指标更好。

Group Model 1: 150批次 测试集ERROR: 0.09729844331741333 200批次 测试集ERROR: 0.08846557699143887

Group Model 2: 150批次 测试集ERROR: 0.10297603532671928 200批次 测试集ERROR: 0.09801376238465309

Group Model 3: 150批次 测试集ERROR: 0.0748182088136673 200批次 测试集ERROR: 0.07573202252388

6)内存释放

在大数据量的深度神经网络训练过程中,内存是我们的一大瓶颈,在组织数据过程中,python的List由于不能确定其存储内容的数据类型,不支持快速切割结构,我们经常需要将List转换为数组再做处理,此时需要copy一份数据,那么List就成了闲置内存,这种类似的闲置内存我们可以操作主动释放,以快速释放无用内存,让我们的机器可以在有限的内存空间中支持更大数据量的训练。

不同的数据类型的释放方式如下(假设变量名称为 X ):

# 1、List
del X[:]
# 2、数组
X = []
# 3、字典
X.clear()
# 4、Tensor(此方式需要调用gc.collect()触发GC才可以真正清除内存)
del X
# 5、清理CUDA显存
import torch
torch.cuda.empty_cache()

下图5-7为训练过程中主动释放内存操作后,得到的内存释放监控反馈。

图片

图 5-7

5.3 预估验证

1)历史预估

整体模型训练完成,需要对模型做预估测试,我们选择2022年的10月作为测试样本,10月1日国庆节有特殊的节假日特性,可以考量模型预估能力。以携程启动页广告位为例,图 5-8 分别展示了全量库存、某特征定向和两种会员等级定向不同维度的预估效果,都成功表达出10月1日的节假日上涨特性,与实际值的走势相似,证明我们训练出的模型具有预估未来广告库存的能力。

图片

图 5-8

2)未来预估

以下是对未来库存的预估效果示例,从未来预估示例中,可以直观看出在4月26-29左右有流量的高峰,经过5月1日后高峰下跌,回归正常值,符五一的节假日效应。

图5-9 定向交叉为:某年龄段、某地

图片

图 5-9

图5-10 定向交叉为:某年龄段、某类会员

图片

图 5-10

图5-11 定向交叉为:某地、某类会员

图片

图 5-11

六、模型部署

6.1 python 服务部署

使用python flask组件开发部署restful接口,支持预估服务。

from flask import Flask
from flask import request, jsonify

@app.route('/model/ad/forecast', methods=['post'])
def forecast():
    # 在clickhouse中实时获取前七天的标签值,传入接口
    prepareData = request.json.get('prepareData')
    return forecast(prepareData)

从Redis中读取对应维度的模型文件流,加载到内存生成模型对象,将前7天的标签值和对应其他特征组织好输入模型得到预估结果。

# 在Redis中加载模型

def readModel(modelName, path):
    pthByte = redis.get(modelName)
    with open(path, 'wb') as f:
        f.write(pthByte)
    return torch.load(path, map_location=lambda storage, loc: storage)

七、总结

通过使用LSTM算法结合Embedding特征处理方式训练得到优质的广告库存预估模型,能够捕捉库存时间样本数据中的长期依赖关系,表达节假日、周末等特殊时间点对库存变化的影响,更具泛化能力,支持地域、年龄、会员等级、性别等定向交叉预估,对比早期使用全量库存乘以定向比例的预估库存方式,此方式更能体现出不同维度之间的相互影响关系,更贴近事实,预估准确度高。

使用离线与在线增量训练相结合的训练方式,使模型更具活力,每天在优选出的广告库存模型基础上进行微调,可以不断维持模型提供精准的预估能力。后续我们会继续优化和探索更优秀的模型和特征处理方式,优化方向考虑在Embedding层 与 LSTM 层之间增加CNN 卷积层,提高模型的特征提取能力,进而提高广告库存模型的泛化能力、预估精准度。

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

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

相关文章

全新干货!一招教你迅速提升流量主收入!包你轻松月入过万

也不怕大家笑话&#xff0c;才哥以前收入每天才一块钱&#xff0c;连瓶水都买不了&#xff0c; 可是自从我开始接触老年粉私域后&#xff0c;一个搬运公众号的流量主收益两个月后就可以用“浴火重生”来形容了。 一个搬运公众号一天的流量主收益比我原创两年的个人公众号收益还…

【Linux】多路IO复用技术②——poll详解如何使用poll模型在本地主机实现简易的一对多服务器(附图解与代码实现)

在阅读本篇博客之前&#xff0c;建议大家先去看一下我之前写的这篇博客&#xff0c;否则你很可能会一头雾水 【Linux】多路IO复用技术①——select详解&如何使用select模型在本地主机实现简易的一对多服务器&#xff08;附图解与代码实现&#xff09;http://t.csdnimg.cn/…

数据库实验:SQL的数据更新

目录 实验目的实验内容实验要求实验步骤实验过程总结 再次书接上文&#xff0c;sql基础的增删改查 实验目的 (1) 掌握DBMS的数据查询功能 (2) 掌握SQL语言的数据更新功能 实验内容 (1) update 语句用于对表进行更新 (2) delete 语句用于对表进行删除 (3) insert 语句用于对表…

Postman接口测试工具,提高SpringBoot开发效率

文章目录 &#x1f33a;工具—postman⭐作用&#x1f3f3;️‍&#x1f308;安装&#x1f388;创建工作空间 &#x1f384;简单参数⭐原始方式&#x1f388;我们建立springboot项目&#xff0c;输入下面的代码&#x1f388;运行 ⭐SpringBoot方式 &#x1f384;实体参数&#x…

最新版星火官方搬运工具6.0,高级搬运,100%过原创,短视频上热门搬运软件黑科技【搬运脚本+使用技术教程】

软件介绍&#xff1a; 高级搬运&#xff0c;条条过原创 短视频暴力热门搬运黑科技 自研摄像头内录突破性技术6.0 无需任何繁琐准备工作安装即用 无需复杂售后培训看教程即可学会 直装直用自研技术更好卖 无需root 无需框架 更方便 无需xposed 无需vcam更安全 适配99%以…

【SoC基础】Arduino从零入门

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

C#知识总结 基础篇(下)

目录 5类和继承 5.1类继承 5.2访问继承的成员 5.3屏蔽基类的成员 5.4访问基类的成员 5.5虚方法与覆写方法 5.6构造函数的执行顺序 5.7成员访问修饰符 5.8抽象类 5.9密封类与静态类 6.表达式与运算符 6.1运算符和重载 7.结构 7.1结构体的感念。 7.2结构构造函数与…

为Web3生态创新赋能,ETH Hong Kong 2023圆满落幕

摘要&#xff1a;10月22日至24日&#xff0c;由以太坊原生zkEVM扩容方案Scroll与Web3技术风投公司Newman Group共同举办的首届以太坊香港盛会“ETH Hong Kong 2023”在数码港成功举行&#xff0c;、ABCDE和852Web3作为筹委会参与其中。本次活动三天内吸引了2500名与会者参与&am…

生活是自己的,尽情打扮、尽情可爱

充满创意色彩的撞色插肩卫衣 穿上它就是妥妥的时尚小达人 蓝橙紫三种色彩相互交织 胸前时尚字母元素罗纹收口 满满的设计感&#xff01;真的墙裂推荐哦&#xff01;

好用的文献引用方法(借助谷歌\火狐浏览器-需要vpn)

1 火狐浏览器-扩展-管理扩展-搜索“Google学术搜索按钮”-安装 2 vpn之后-在www.google.com谷歌官网-搜索论文题目- 点击扩展-点Google学术搜索按钮 3 直接得到结果-点击引用 4 得到引用bib

Selenium处理Cookie

01、cookie介绍 HTTP协议是无状态的协议。一旦数据交换完毕&#xff0c;客户端与服务器端的连接就会关闭&#xff0c;再次交换数据需要建立新的连接&#xff0c;这就意味着服务器无法从连接上跟踪会话。也就是说即使第一次和服务器连接后并且登录成功后&#xff0c;第二次请求…

虚幻引擎:RPC:远端调用

1.如何区当前是服务器还是在客服端 2.如何修改一个actor的所有权 修改所有权必须 在服务器上进行修改,不允许在客户端进行修改

2024天津理工大学中环信息学院专升本机械设计自动化专业考试题型

天津理工大学中环信息学院2024年高职升本科机械设计制造及其自动化专业课各科考试题型 2024年天津理工大学中环信息学院高职升本科机械设计制造及其自动化专业课考试大纲已发布。机械设计制造及其自动化专业需考《机械设计》、《机械制图》。具体大纲已下发可进行查看。各科考试…

linux下安装Zabbix教程

笔记&#xff1a; 监控设备 对各种设备的统一管理 Esight 了解开源监控工具 eg Promerthos: Zabbix &#xff1a;集中式系统 大型企业 可视化,高大上、 查看日志 安装zibox软件 安装数据库 进入数据库 进入Zabbox 密码 password 账号Admin 密码zabbix 解决乱码问题 将…

数字城市运行监测主题指标设计思路探讨

随着信息技术的飞速发展&#xff0c;数字城市已成为我国城市发展的新趋势。城市运行监测作为数字城市建设的重要环节&#xff0c;通过实时采集、处理和分析城市各个方面的数据&#xff0c;为政府决策提供科学依据。在这一过程中&#xff0c;主题指标设计成为关键环节。本文结合…

【密评】商用密码应用安全性评估从业人员考核题库(二十-完结)

商用密码应用安全性评估从业人员考核题库&#xff08;二十-完结&#xff09; 国密局给的参考题库5000道只是基础题&#xff0c;后续更新完5000还会继续更其他高质量题库&#xff0c;持续学习&#xff0c;共同进步。 4640 单项选择题 在测评过程中遇到的PEM编码格式&#xff0c…

基于STM32CubeMX和keil采用USART/UART实现非中断以及中断方式数据回环测试借助CH340以及XCOM

文章目录 前言1. 接口概述1.1 USART/UART接口1.2 串口通信参数1.3 波特率计算 2. 传输函数3. 回环测试3.1 上位机环境配置3.2 阻塞模式3.3 中断模式 4. STM32CubeMX配置4.1 时钟配置4.2 调试配置4.3 串口引脚配置4.4 工程配置 5. 测试效果6. 不借助上位机回环测试总结 前言 这…

HNU程序设计 练习五-函数(强化)

1.土地分割 【问题描述】 对于一块mn 的地块&#xff0c;需要将其划分为若干个相同正方形的方块&#xff0c;且每个方块的边长尽量地长。 【输入形式】 输入 m 和 n ( 1 ≤ m、 n ≤0.5109), 分别表示地块的长和宽。 【输出形式】 输出两个整数&#xff0c;表示划分以后的正方…

Docker的简单安装

安装环境 CentOS Linux release 8.1.1911 (Core)内核4.18.0-147.el8.x86_64Mini Installation 安装前的准备工作 切换国内源 由于centos源已经过期&#xff0c;所以切换为阿里云的yum源&#xff0c;第二个是docker的仓库 wget -O /etc/yum.repos.d/CentOS-Base.repo https:…

【Java】三种方案实现 Redis 分布式锁

序言 setnx、Redisson、RedLock 都可以实现分布式锁&#xff0c;从易到难得排序为&#xff1a;setnx < Redisson < RedLock。一般情况下&#xff0c;直接使用 Redisson 就可以啦&#xff0c;有很多逻辑框架的作者都已经考虑到了。 方案一&#xff1a;setnx 1.1、简单实…