python在Keras中使用LSTM解决序列问题

news2024/11/16 17:47:59

 时间序列预测是指我们必须根据时间相关的输入来预测结果的问题类型。时间序列数据的典型示例是股市数据,其中股价随时间变化。 最近我们被客户要求撰写关于LSTM的研究报告,包括一些图形和统计输出。

递归神经网络(RNN)已被证明可以有效解决序列问题。特别地,作为RNN的变体的长期短期记忆网络(LSTM)当前正在各种领域中用于解决序列问题。

相关视频:LSTM神经网络架构和工作原理及其在Python中的预测应用

LSTM神经网络架构和原理及其在Python中的预测应用

序列问题的类型

序列问题可以大致分为以下几类:

  1. 一对一:其中有一个输入和一个输出。一对一序列问题的典型示例是您拥有一幅图像并且想要为该图像预测单个标签的情况。
  2. 多对一:在多对一序列问题中,我们将数据序列作为输入,并且必须预测单个输出。文本分类是多对一序列问题的主要示例,其中我们有一个单词输入序列,并且我们希望预测一个输出标签。
  3. 一对多:在一对多序列问题中,我们只有一个输入和一个输出序列。典型示例是图像及其相应的说明。
  4. 多对多:多对多序列问题涉及序列输入和序列输出。例如,将7天的股票价格作为输入,并将接下来7天的股票价格作为输出。聊天机器人还是多对多序列问题的一个示例,其中文本序列是输入,而另一个文本序列是输出。

 在本文中,我们将了解如何使用LSTM及其不同的变体来解决一对一和多对一的序列问题。 

阅读本文后,您将能够基于历史数据解决诸如股价预测,天气预报等问题。由于文本也是单词序列,因此本文中获得的知识也可以用于解决自然语言处理任务,例如文本分类,语言生成等。

一对一序列问题

正如我之前所说,在一对一序列问题中,只有一个输入和一个输出。在本节中,我们将看到两种类型的序列问题。首先,我们将了解如何使用单个特征解决一对一的序列问题,然后我们将了解如何使用多个特征解决一对一的序列问题。

单一特征的一对一序列问题

在本节中,我们将看到如何解决每个时间步都有一个特征的一对一序列问题。

首先,我们导入将在本文中使用的必需库:

from numpy import array
from keras.preprocessing.text import one_hot
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers.core import Activation, Dropout, Dense
from keras.layers import Flatten, LSTM
from keras.layers import GlobalMaxPooling1D
from keras.models import Model
from keras.layers.embeddings import Embedding
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer
from keras.layers import Input
from keras.layers.merge import Concatenate
from keras.layers import Bidirectional

import pandas as pd
import numpy as np
import re

import matplotlib.pyplot as plt

创建数据集

在下一步中,我们将准备本节要使用的数据集。

X = list()
Y = list()
X = [x+1 for x in range(20)]
Y = [y * 15 for y in X]

print(X)
print(Y)

在上面的脚本中,我们创建20个输入和20个输出。每个输入都包含一个时间步,而该时间步又包含一个特征。每个输出值是相应输入值的15倍。如果运行上面的脚本,应该看到如下所示的输入和输出值:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300]

LSTM层的输入应为3D形状,即(样本,时间步长,特征)。样本是输入数据中样本的数量。输入中有20个样本。时间步长是每个样本的时间步长数。我们有1个时间步。最后,特征对应于每个时间步的特征数量。每个时间步都有一个特征。

 X = array(X).reshape(20, 1, 1)

通过简单LSTM解决方案

现在,我们可以创建具有一个LSTM层的简单LSTM模型。

model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(1, 1)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
print(model.summary())

在上面的脚本中,我们创建了一个LSTM模型,该模型具有一层包含50个神经元和relu激活函数的LSTM层。您可以看到输入形状为(1,1),因为我们的数据具有一个特征的时间步长。 

Layer (type)                 Output Shape              Param #
=================================================================
lstm_16 (LSTM)               (None, 50)                10400
_________________________________________________________________
dense_15 (Dense)             (None, 1)                 51
=================================================================
Total params: 10,451
Trainable params: 10,451
Non-trainable params: 0

现在让我们训练模型:

model.fit(X, Y, epochs=2000, validation_split=0.2, batch_size=5)

我们为2000个时期训练模型,批大小为5。您可以选择任何数字。训练模型后,我们可以对新实例进行预测。

假设我们要预测输入为30的输出。实际输出应为30 x 15 =450。 首先,我们需要按照LSTM的要求将测试数据转换为正确的形状,即3D形状。以下 预测数字30的输出:


print(test_output)

我得到的输出值437.86略小于450。

 通过堆叠LSTM解决方案

现在让我们创建一个堆叠的LSTM,看看是否可以获得更好的结果。数据集将保持不变,模型将被更改。看下面的脚本:


print(model.summary())

在上面的模型中,我们有两个LSTM层。注意,第一个LSTM层的参数return_sequences设置为True。当返回序列设置True为时,每个神经元隐藏状态的输出将用作下一个LSTM层的输入。以上模型的摘要如下:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
lstm_33 (LSTM)               (None, 1, 50)             10400
_________________________________________________________________
lstm_34 (LSTM)               (None, 50)                20200
_________________________________________________________________
dense_24 (Dense)             (None, 1)                 51
=================================================================
Total params: 30,651
Trainable params: 30,651
Non-trainable params: 0
________________________

接下来,我们需要训练我们的模型,如以下脚本所示:

print(test_output)

我得到的输出为459.85,好于我们通过单个LSTM层获得的数字437。

具有多个特征的一对一序列问题

在最后一节中,每个输入样本都有一个时间步,其中每个时间步都有一个特征。在本节中,我们将看到如何解决输入时间步长具有多个特征的一对一序列问题。

创建数据集

首先创建数据集。看下面的脚本:

nums = 25

X1 = list()
X2 = list()
X = list()
Y = list()


print(X1)
print(X2)
print(Y)

在上面的脚本中,我们创建三个列表:X1X2,和Y。每个列表包含25个元素,这意味着总样本大小为25。最后,Y包含输出。X1X2以及Y列表已输出在下面:

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75]
[6, 24, 54, 96, 150, 216, 294, 384, 486, 600, 726, 864, 1014, 1176, 1350, 1536, 1734, 1944, 2166, 2400, 2646, 2904, 3174, 3456, 3750]

输出列表中的每个元素基本上都是X1和 X2列表中相应元素的乘积。例如,输出列表中的第二个元素是24,这是列表中的第二个元素(X1即4)和列表中的第二个元素(X2即6 )的乘积。

输入将由X1X2列表的组合组成,其中每个列表将表示为一列。以下脚本创建最终输入:

X = np.column_stack((X1, X2))
print(X)

这是输出:

[[ 2  3]
 [ 4  6]
 [ 6  9]
 [ 8 12]
 [10 15]
 [12 18]
 [14 21]
 [16 24]
 [18 27]
 [20 30]
 [22 33]
 [24 36]
 [26 39]
 [28 42]
 [30 45]
 [32 48]
 [34 51]
 [36 54]
 [38 57]
 [40 60]
 [42 63]
 [44 66]
 [46 69]
 [48 72]
 [50 75]]

 可以看到它包含两列,即每个输入两个特征。如前所述,我们需要将输入转换为3维形状。我们的输入有25个样本,其中每个样本包含1个时间步,每个时间步包含2个特征。以下脚本可重塑输入。

X = array(X).reshape(25, 1, 2)

通过简单LSTM解决方案

我们现在准备训练我们的LSTM模型。让我们首先像上一节中那样开发一个LSTM模型:

model = Sequential()
model.add(LSTM(80, activation='relu', input_shape=(1, 2)))

print(model.summary())

在这里,我们的LSTM层包含80个神经元。我们有两个神经层,其中第一层包含10个神经元,第二个密集层(也作为输出层)包含1个神经元。该模型的摘要如下:

Layer (type)                 Output Shape              Param #
=================================================================
lstm_38 (LSTM)               (None, 80)                26560
_________________________________________________________________
dense_29 (Dense)             (None, 10)                810
_________________________________________________________________
dense_30 (Dense)             (None, 1)                 11
=================================================================
Total params: 27,381
Trainable params: 27,381
Non-trainable params: 0
_________________________________________________________________
None

以下脚本训练模型:

model.fit(X, Y, epochs=2000, validation_split=0.2, batch_size=5)

让我们在一个新的数据点上测试我们训练有素的模型。我们的数据点将具有两个特征,即(55,80)实际输出应为55 x 80 =4400。让我们看看我们的算法预测了什么。执行以下脚本:


print(test_output)

我的输出为3263.44,与实际输出相差甚远。

通过堆叠LSTM解决方案

现在,让我们创建一个具有多个LSTM和密集层的更复杂的LSTM,看看是否可以改善我们的结果:

model = Sequential()

print(model.summary())

模型摘要如下:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
lstm_53 (LSTM)               (None, 1, 200)            162400
_________________________________________________________________
lstm_54 (LSTM)               (None, 1, 100)            120400
_________________________________________________________________
lstm_55 (LSTM)               (None, 1, 50)             30200
_________________________________________________________________
lstm_56 (LSTM)               (None, 25)                7600
_________________________________________________________________
dense_43 (Dense)             (None, 20)                520
_________________________________________________________________
dense_44 (Dense)             (None, 10)                210
_________________________________________________________________
dense_45 (Dense)             (None, 1)                 11
=================================================================
Total params: 321,341
Trainable params: 321,341
Non-trainable params: 0

下一步是训练我们的模型,并在测试数据点(即(55,80))上对其进行测试。

为了提高准确性,我们将减小批量大小,并且由于我们的模型更加复杂,现在我们还可以减少时期数。以下脚本训练LSTM模型并在测试数据点上进行预测。


print(test_output)

在输出中,我得到的值3705.33仍小于4400,但比以前使用单个LSTM层获得的3263.44的值好得多。您可以将LSTM层,密集层,批处理大小和时期数进行不同的组合,以查看是否获得更好的结果。

多对一序列问题

在前面的部分中,我们看到了如何使用LSTM解决一对一的序列问题。在一对一序列问题中,每个样本都包含一个或多个特征的单个时间步长。具有单个时间步长的数据实际上不能视为序列数据。事实证明,密集连接的神经网络在单个时间步长数据下表现更好。

实际序列数据包含多个时间步长,例如过去7天的股票市场价格,包含多个单词的句子等等。

在本节中,我们将看到如何解决多对一序列问题。在多对一序列问题中,每个输入样本具有多个时间步长,但是输出由单个元素组成。输入中的每个时间步都可以具有一个或多个特征。我们将从具有一个特征的多对一序列问题开始,然后我们将了解如何解决输入时间步长具有多个特征的多对一问题。

具有单个特征的多对一序列问题

首先创建数据集。我们的数据集将包含15个样本。每个样本将具有3个时间步长,其中每个时间步长将包含一个单一特征,即一个数字。每个样本的输出将是三个时间步长中每个步长的数字之和。例如,如果我们的样本包含序列4,5,6,则输出将为4 + 5 + 6 = 10。

创建数据集

首先创建一个从1到45的整数列表。由于我们要在数据集中获得15个样本,因此我们将对包含前45个整数的整数列表进行整理。

X = np.array([x+1 for x in range(45)])
print(X)

在输出中,您应该看到前45个整数:

[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45]

我们可以使用以下函数将其整理为样本数,时间步长和特征:

X = X.reshape(15,3,1)
print(X)

 

上面的脚本将列表X转换为带有15个样本,3个时间步长和1个特征的3维形状。上面的脚本还输出了调整后的数据。

[[[ 1]
  [ 2]
  [ 3]]

 [[ 4]
  [ 5]
  [ 6]]

 [[ 7]
  [ 8]
  [ 9]]

 [[10]
  [11]
  [12]]

 [[13]
  [14]
  [15]]

 [[16]
  [17]
  [18]]

 [[19]
  [20]
  [21]]

 [[22]
  [23]
  [24]]

 [[25]
  [26]
  [27]]

 [[28]
  [29]
  [30]]

 [[31]
  [32]
  [33]]

 [[34]
  [35]
  [36]]

 [[37]
  [38]
  [39]]

 [[40]
  [41]
  [42]]

 [[43]
  [44]
  [45]]]

我们已经将输入数据转换为正确的格式,现在让我们创建输出向量。正如我之前所说,输出中的每个元素将等于相应输入样本中时间步长中的值之和。以下脚本创建输出向量:

Y = list()
for x in X:

print(Y)

输出数组Y如下所示:

[  6  15  24  33  42  51  60  69  78  87  96 105 114 123 132]

通过简单LSTM解决方案

现在让我们用一个LSTM层创建模型。

model = Sequential()

model.compile(optimizer='adam', loss='mse')

以下脚本训练了我们的模型:

history = model.fit(...)

训练完模型后,我们就可以使用它对测试数据点进行预测。让我们预测数字序列50、51、52的输出。实际输出应为50 + 51 + 52 =153。以下脚本将我们的测试点转换为3维形状,然后预测输出:


print(test_output)

我的输出为145.96,比实际输出值153少7点。

通过堆叠LSTM解决方案

现在,让我们创建一个具有多层的复杂LSTM模型,看看是否可以获得更好的结果。执行以下脚本来创建和训练具有多个LSTM和密集层的复杂模型:

model = Sequential()

model.compile(optimizer='adam', loss='mse')

history = model.fit(X, Y, epochs=1000, validation_split=0.2, verbose=1)

现在让我们在测试序列(即50、51、52)上测试模型:

 print(test_output)

我在这里得到的答案是155.37,比我们之前得到的145.96更好。在这种情况下,我们与153的实际差值只有2分。

通过双向LSTM解决方案

双向LSTM是一种LSTM,可以从正向和反向两个方向的输入序列中学习。最终的序列解释是向前和向后学习遍历。让我们看看使用双向LSTM是否可以获得更好的结果。

以下脚本创建了一个双向LSTM模型,该模型具有一个双向层和一个作为模型输出的密集层。

from keras.layers import Bidirectional
 
model.compile(optimizer='adam', loss='mse')

以下脚本训练模型并根据测试序列50、51和52进行预测。


print(test_output)

我得到的结果是152.26,仅比实际结果少一小部分。因此,我们可以得出结论,对于我们的数据集,具有单层的双向LSTM的性能优于单层和堆叠的单向LSTM。

具有多个特征的多对一序列问题

在多对一序列问题中,我们有一个输入,其中每个时间步均包含多个特征。输出可以是一个值或多个值,在输入时间步长中每个特征一个。我们将在本节中介绍这两种情况。

创建数据集

我们的数据集将包含15个样本。每个样本将包含3个时间步。

让我们创建两个列表。一个将包含3的倍数,直到135,即总共45个元素。第二个列表将包含5的倍数,从1到225。第二个列表也将总共包含45个元素。以下脚本创建这两个列表:

X1 = np.array([x+3 for x in range(0, 135, 3)])

print(X2)

您可以在以下输出中看到列表的内容:

[  3   6   9  12  15  18  21  24  27  30  33  36  39  42  45  48  51  54
  57  60  63  66  69  72  75  78  81  84  87  90  93  96  99 102 105 108
 111 114 117 120 123 126 129 132 135]
[  5  10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90
  95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180
 185 190 195 200 205 210 215 220 225]

上面的每个列表代表时间样本中的一个特征。可以通过合并两个列表来创建聚合数据集,如下所示:

X = np.column_stack((X1, X2))
print(X)

输出显示汇总的数据集:

 [  6  10]
 [  9  15]
 [ 12  20]
 [ 15  25]
 [ 18  30]
 [ 21  35]
 [ 24  40]
 [ 27  45]
 [ 30  50]
 [ 33  55]
 [ 36  60]
 [ 39  65]
 [ 42  70]
 [ 45  75]
 [ 48  80]
 [ 51  85]
 [ 54  90]
 [ 57  95]
 [ 60 100]
 [ 63 105]
 [ 66 110]
 [ 69 115]
 [ 72 120]
 [ 75 125]
 [ 78 130]
 [ 81 135]
 [ 84 140]
 [ 87 145]
 [ 90 150]
 [ 93 155]
 [ 96 160]
 [ 99 165]
 [102 170]
 [105 175]
 [108 180]
 [111 185]
 [114 190]
 [117 195]
 [120 200]
 [123 205]
 [126 210]
 [129 215]
 [132 220]
 [135 225]]

我们需要将数据重塑为三个维度,以便LSTM可以使用它。我们的数据集有45行,两列。我们将数据集整理为15个样本,3个时间步长和两个特征。

X = array(X).reshape(15, 3, 2)
print(X)

您可以在以下输出中看到15个样本:

[[[  3   5]
  [  6  10]
  [  9  15]]

 [[ 12  20]
  [ 15  25]
  [ 18  30]]

 [[ 21  35]
  [ 24  40]
  [ 27  45]]

 [[ 30  50]
  [ 33  55]
  [ 36  60]]

 [[ 39  65]
  [ 42  70]
  [ 45  75]]

 [[ 48  80]
  [ 51  85]
  [ 54  90]]

 [[ 57  95]
  [ 60 100]
  [ 63 105]]

 [[ 66 110]
  [ 69 115]
  [ 72 120]]

 [[ 75 125]
  [ 78 130]
  [ 81 135]]

 [[ 84 140]
  [ 87 145]
  [ 90 150]]

 [[ 93 155]
  [ 96 160]
  [ 99 165]]

 [[102 170]
  [105 175]
  [108 180]]

 [[111 185]
  [114 190]
  [117 195]]

 [[120 200]
  [123 205]
  [126 210]]

 [[129 215]
  [132 220]
  [135 225]]]

输出还将具有对应于15个输入样本的15个值。输出中的每个值将是每个输入样本的第三时间步中两个特征值的总和。例如,第一个样本的第三时间步长具有特征9和15,因此输出将为24。类似地,第二个样本的第三时间步长中的两个特征值分别为18和30;第二个时间步长中的两个特征值分别为18和30。相应的输出将是48,依此类推。

以下脚本创建并显示输出向量:

[ 24  48  72  96 120 144 168 192 216 240 264 288 312 336 360]

现在让我们通过简单的,堆叠的和双向的LSTM解决多对一序列问题。

通过简单LSTM解决方案

model = Sequential()

history = model.fit(X, Y, epochs=1000, validation_split=0.2, verbose=1)

模型经过训练。我们将创建一个测试数据点,然后将使用我们的模型对测试点进行预测。


print(test_output)

输入的第三时间步长的两个特征的总和为14 + 61 =75。我们的带有一个LSTM层的模型预测为73.41,这非常接近。

通过堆叠LSTM解决方案

以下脚本训练堆叠的LSTM并在测试点上进行预测:

model = Sequential()
model.add(LSTM(200, activation='relu', return_sequences=True, input_shape=(3, 2)))

print(test_output)

我收到的输出为71.56,比简单的LSTM差。似乎我们堆叠的LSTM过度拟合。

通过双向LSTM解决方案

这是简单双向LSTM的训练脚本,以及用于对测试数据点进行预测的代码:

from keras.layers import Bidirectional

model = Sequential()

print(test_output)

输出为76.82,非常接近75。同样,双向LSTM似乎胜过其余算法。

到目前为止,我们已经基于来自不同时间步长的多个要素值预测了单个值。在多对一序列的另一种情况下,您希望在时间步长中为每个特征预测一个值。例如,我们在本节中使用的数据集具有三个时间步,每个时间步具有两个特征。我们可能希望预测每个特征系列的单独价值。下面的示例很清楚,假设我们有以下输入:

[[[  3   5]
  [  6  10]
  [  9  15]]

在输出中,我们需要一个具有两个特征的时间步长,如下所示:

[12, 20]

您可以看到输出中的第一个值是第一个序列的延续,第二个值是第二个序列的延续。我们可以通过简单地将输出密集层中神经元的数量更改为我们想要的输出中的特征值的数量来解决此类问题。但是,首先我们需要更新输出向量Y。输入向量将保持不变:

Y = list()
for x in X:

print(Y)

上面的脚本创建一个更新的输出向量并将其输出,输出如下所示:

[[ 12  20]
 [ 21  35]
 [ 30  50]
 [ 39  65]
 [ 48  80]
 [ 57  95]
 [ 66 110]
 [ 75 125]
 [ 84 140]
 [ 93 155]
 [102 170]
 [111 185]
 [120 200]
 [129 215]
 [138 230]]

现在,让我们在数据集上训练我们的简单,堆叠和双向LSTM网络。以下脚本训练了一个简单的LSTM:

model = Sequential()
...
history = model.fit(X, Y, epochs=1000, validation_split=0.2, verbose=1)

下一步是在测试数据点上测试我们的模型。以下脚本创建一个测试数据点:

test_input = array([[20,34],
                    [23,39],
                    [26,44]])
...
print(test_output)

实际输出为[29,45]。我们的模型预测[29.089157,48.469097],这非常接近。

现在让我们训练一个堆叠的LSTM并预测测试数据点的输出:

model = Sequential()
model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(3, 2)))
...
print(test_output)

输出为[29.170143,48.688267],再次非常接近实际输出。

最后,我们可以训练双向LSTM并在测试点上进行预测:

from keras.layers import Bidirectional

model = Sequential()
...
print(test_output)

输出为[29.2071,48.737988]。

您可以再次看到双向LSTM做出最准确的预测。

结论

简单的神经网络不适用于解决序列问题,因为在序列问题中,除了当前输入之外,我们还需要跟踪先前的输入。具有某种记忆的神经网络更适合解决序列问题。LSTM就是这样一种网络。

  


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

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

相关文章

D-026 LVDS硬件电路设计

LVDS硬件接口电路设计1 简介2 硬件设计实战3 硬件设计要点4 Layout注意事项5 MIPI与LVDS的区别1 简介 LVDS(Low-Voltage Differential Singnaling,低电压差分信号)可以实现点对点或者一点对多点的连接,具有低功耗、低误码率、低串…

蓝桥杯比赛 NOC竞赛C++项目,选择题真题和模拟题汇总答案解析

题目来源:第10届蓝桥杯青少年组C选拔赛 1、下面哪个密码最安全 D A. 111111 B. 123456 C. qwerty D. Z2a8Q1 2、如果今天是星期六,再过60天是星期几?A A. 星期三 B. 星期四 C. 星期五 D. 星期六 3、90到100之间有几个素数&#xff1f…

HTML学生作业网页 传统端午节节日 学生节日网页设计作业源码(HTML+CSS+JS)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

Android Studio的ADV无法启动解决办法【IDEA 的ADV无法启动解决办法】

Android Studio的ADV无法启动解决办法【IDEA 的ADV无法启动解决办法】 开发者指南:https://developer.android.google.cn/guide 一、BIOS开启Intel VT-x 这一步如果在创建Android项目时,可以启动的话,证明已经开启了,可以忽略 1. 开始菜单&am…

新鲜出炉!阿里内部开源SpringCloud Alibaba全解(全彩版)全网首发

第一章微服务介绍 第二章微服务环境搭建 第三章Nacos Discovery–服务治理 自定义实现负载均衡 第四章Sentinel–服务容错 第五章Gateway–服务网关 Gateway核心架构 第六章Sleuth-链路追踪 ![新鲜出炉!阿里内部开源SpringCloud Alibaba全解(全彩版&…

基于OpenLayers实现导航地图上(起/终)点的交互式图标显示

目录 1、准备 2、瓦片地图显示 3、增加矢量图层 4、利用click实现鼠标点击效果 在常见的导航软件中,往往都存在标记起/止点的需求。毕竟路径规划中的重要传入参数就是起止点坐标。在常用的不管是移动端还是PC端,导航地图上一般在选择起止点位置会留…

大数据 | Spark安装及测试

一、安装 Spark On Yarn 在公司中,通常采用Yarn进行资源调度,故此处采用Yarn模式的集群部署。 采用Yarn部署模式时,需要保证集群中已经安装好Hadoop集群,在此基础上才能实现Yarn模式的部署。 在Yarn模式中,Spark应用…

Python学习-8.2.1 库(jieba库的基础与实例-中文分词库)

jieba库的安装见上篇:Python学习-8.库(第三方库介绍与下载安装) jieba库概述 由于中文文本中的单词不像英文那样,并不是根据空格或者标点符号进行分割的,而是存在一个重要的分词问题。因此引入了jieba库。 分词原理&…

chrome Google无法翻译?腾讯已经出手了,一劳永逸!

谷歌翻译中国版和谷歌地图中国版同时停服,此次停服也影响到谷歌浏览器翻译功能的使用。谷歌给出的官方回应是谷歌翻译和谷歌地图的中国版使用率都太低,既然使用率太低那直接停服也情有可原(笑笑)。 只是谷歌浏览器内置的翻译功能…

前端开发:JS中使用到的贪心算法场景

前言 在前端开发过程中,除了一般的逻辑使用之外,也会涉及到算法相关的知识,比如冒泡排序、数组去重/合并、贪心算法、八皇后算法等等,这些都是比较常用的前端算法相关的知识点。关于前端实际开发中用到的算法,虽然没有…

Studio Controls COM 64 for MFC 组合套件-dbi-tech

dbi-tech Studio Controls COM 64 - 新功能... Studio 控制 COM 64 位 v6.0 ctxCalendar - (v4.0.0.0) DBI Technologies Inc. 是一家创新的商业软件开发公司,专注于为应用程序开发人员提供最佳的端到端供应链可见性组件软件。DBI 以其屡获殊荣的组件软件产品和服务…

华为机试_HJ62 查找输入整数二进制中1的个数【简单】【收藏】

目录 描述 输入描述: 输出描述: 解题过程 提交代码一(常规方法) 提交代码二(位运算方法) 学习代码 代码一 代码二 收藏点 描述 输入一个正整数,计算它在二进制下的1的个数。 注意多…

kubernetes学习之路--基础概念以及搭建

写在前面:代码审计太难了,不想学了摆烂了,开始学云安全了。。。。 一.云介绍 云分类:公有云、私有云、混合云 云有三种服务模式:Laas、Paas 和 Saas Laas:基础设施即服务(Infrastructure-as…

[附源码]计算机毕业设计酒店客房管理信息系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Git版本控制器

文章目录1.Git介绍1.1.什么是Git?1.2.Git的历史1.3.版本控制分类1.3.1.集中式版本控制1.3.2.分布式版本控制1.4.Github(Git服务器)1.5.Git原理2.使用前的准备2.1.准备Git2.1.1.安装Git2.1.2.配置环境变量2.1.3.IEDA配置Git2.1.4.安装git插件&#xff08…

java面向对象 final static 关键字

目录 关键字:static 类属性、类方法的设计思想 类变量(class Variable) 静态变量的内存解析 类方法(class method) 单例 (Singleton)设计模式 理解main方法的语法 代码块 关键字:final 总结 关键字:static 当我们编写一个类时&…

Vue.js设计与实现,读书笔记第一章

第一章:权衡的艺术 1.1命令式和声明式 jq是命令式,关注过程,jq针对简化dom 而产生的 vue是 声明式,关注实现,不严格地说就像是在命令式(关注过程)基础上再对标签进行了一次封装(关注实现) jQuery命令式…

干货 | Jmeter 如何保证抢购、秒杀活动正常运行?

1. 前言 平常为了保证运营促销、抽奖活动能正常运行,我们一般都需要使用 Jmeter、LoadRunner 对接口进行压力测试 使用它可以模拟一定量的用户同时去参与促销抽奖活动,最后生成测试报告,以此判系统接口的稳定性 本篇文章以抢购商品为例&am…

清华毕业大佬用了一个项目就把SpringMVC+Spring+MyBatis给讲完了

前言 时间飞逝,转眼间毕业七年多,从事 Java 开发也六年了。我在想,也是时候将自己的 Java 整理成一套体系。 这一次的知识体系面试题涉及到 Java 知识部分、性能优化、微服务、并发编程、开源框架、分布式等多个方面的知识点。 写这一套 Ja…

R语言学习笔记——入门篇:第五章-高级数据管理

R语言 R语言学习笔记——入门篇:第五章-高级数据管理 文章目录R语言一、数值与字符处理函数1.1、数学函数1.2、统计函数1.3、概率函数1.4、字符处理函数1.5、其他实用函数1.6、将函数应用于矩阵与数据框二、控制流2.1、循环(for,while&#…