初步了解算法概念
算法作为抽象概念,在实际生活中发挥了极大的具象作用:打工人如何保证最节省时间又花费最少来选择每天必须的通勤路径及方式,如何调度员工在有限时间内更高效的完成大量需要交付的项目,每天手机上所显示的天气情况以及地图上显示的实时路况等这些我们早已习惯了规划和预测的场景都用到了算法。算法从宏观概念上可以分为不需要机器学习的基本类算法及需要训练模型的机器学习类算法。本篇文章将会分享机器学习中较为经典的长短期记忆人工神经网络(LSTM)算法,希望感兴趣的朋友通过我的分享也可以尝试着自己利用代码实现。
了解LSTM概念
在了解LSTM之前,首先需要了解循环神经网络(RNN)的概念,RNN由输入层、隐藏层、输出层组成。
下图展示了RNN的神经网络模型:
数据通过输入层输入,经过隐藏层的变换和数据特征提取,整个过程不断循环,最终输出层决定输出。举一个较为通俗理解的例子,在平时的工作中,通过大量的先前信息,我们建立了语言模型,当听到了以“周一早上”开头的句子时,提取了很多数据特征,所以当大家看到“周一早上…”作为输入时,过去的语言场景作为隐藏层,预测出 “召开例会”则会作为最终的输出。但是对于跨度较长的长期问题,RNN会遗漏一些重要信息,可能会造成梯度消失的问题,这个时候就要引入LSTM来处理长期依赖的问题了。
构建LSTM神经网络时,包含遗忘门,输入门,输出门。每个门都有对应的作用,遗忘门的作用是读取上一个输入和当前输入,做一个Sigmoid的非线性映射,最终选择将细胞状态中的一些信息遗忘,限制前面的信息对后面造成影响,在周例会的例子中,将输入变为“2022年的周一早上…”,“2022年”和“周一早上”都可作为时间点,但是当处理到“周一早上”时,会选择将“2022年”遗忘,或者减少“2022年”对后面词的作用,更会关注“周一早上”;输入门的作用是将新的信息更新到细胞状态中,Sigmoid层做非线性映射,决定有多少信息需要更新,这里Sigmoid作为激活函数的作用是更好的过滤信息,举个易于理解的例子:当我们在高中掌握了新的解题方法时,初中的解题方法我们很大可能就不会再用了,所以激活函数能够帮助神经网络记住更重要的信息,更好的过滤信息,在周例会的例子中,我们需要增加新的时间类别到细胞状态中,所以处理到“周一早上”时,将会把该时间点更新到细胞状态中。输出门确定最终需要输出的部分,在周例会例子中,时间节点后需要跟一个具体事件,所以我们可预测出“召开例会”为输出的可能性较大。
实现LSTM算法
首先,实现LSTM算法我选用的语言是Python,具体的业务方向是异常诊断。实现需要三个部分:首先输入数据,处理的数据为时间序列数据。将数据按训练集和测试集分好类,有监督学习算法中会将输入分类为训练集和测试集。
有监督的概念
例如我们小时候刚开始建立认知,家长会告诉我们这个是书本,这个是玩具,这个过程就是有监督训练的过程,当我们长大了,看到书本则知道是书本。
无监督的概念
从输入中寻找规律,例如我们去看画展,看到一些画可能并不知道具体的是哪个画家所作,或者画的名称是什么,但是看得多了就知道大概哪些作品描绘的是同类型的事物。训练集就像我们为了参加考试所做的练习题,模考试卷,做的试卷越多,题型越复杂最终的考试成绩可能越为理想。
以下是处理数据的代码:
# 获取数据
def getdata(columns_one, columns_two, modelname):
results = pd.DataFrame({'columnone': columns_one, 'columntwo': columns_two})
bigdata = results.copy()
# 划分测试集、训练集
data_for_use = results.copy()
training_start = int(len(results) * 0.2)
testing_end = int(len(results) * 0.2)
train = results.iloc[training_start:]
test = results.iloc[0:testing_end]
# 归一化
scaler = MinMaxScaler().fit(train[['columntwo']])
joblib.dump(scaler, 'scaler.gz')
scaler = joblib.load('scaler.gz')
train = scale_samples(train.copy(), train.columns[0], scaler)
test = scale_samples(test.copy(), test.columns[0], scaler)
X_train, y_train = shift_samples(train[['columntwo']], train.columns[0])
X_test, y_test = shift_samples(test[['columntwo']], test.columns[0])
tsteps = X_train.shape[1]
nfeatures = X_train.shape[2]
np.savez(config.model_address, tsteps=tsteps, nfeatures=nfeatures,
X_train=X_train, y_train=y_train, X_test=X_test, y_test=y_test, bigdata=np.array(bigdata))
test.to_csv('test.csv')
train.to_csv('train.csv')
处理完数据后,需要构建LSTM神经网络模型,含有训练层数,神经元个数,激活函数、损失函数等,训练完成后保存模型。
以下为训练模型和保存模型代码:
# 建立异常点检测模型
model = Sequential()
model.add(layers.LSTM(units=batch_size, input_shape=(tsteps, nfeatures), dropout=dropout))
model.add(layers.Dropout(rate=0.2))
model.add(layers.RepeatVector(tsteps))
model.add(layers.LSTM(units=batch_size, return_sequences=True, dropout=dropout))
model.add(layers.Dropout(rate=0.2))
model.add(layers.TimeDistributed(layers.Dense(nfeatures)))
model.compile(loss=loss, optimizer=optimizer)
model.summary()
# 画出损失函数图像
# loss下降,validationloss下降,正在学习;
# loss下降,validationloss不变,网络过拟合;
# loss不变,validationloss不变,需要减少学习率或批处理大小
# loss不变,validationloss下降,数据集100%有问题
# loss上升,validationloss上升,模型设计不当,超参数设置不当,程序有bug
verbose = int(algorithm_param['verbose'])
epochs = int(algorithm_param['epochs'])
validation_split = float(algorithm_param['validation_split'])
checkpoint = ModelCheckpoint(modelname + '.hdf5', monitor='val_loss', verbose=verbose, save_best_only=True,
mode='auto', period=1)
model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=verbose,
validation_split=validation_split, callbacks=[checkpoint], shuffle=False)
模型保存后,需要调用模型,首先通过对训练集的学习,预测出后续趋势,再将预测趋势与实际测试集作差,画出残差的正态分布图,设定合适阈值,大于阈值的则表明预测趋势与实际测试集相差较大,可能为异常点。
以下为调用模型诊断异常代码:
def startdetect(columns_one, columns_two, query_param,algorithm_param):
# 调用模型 输入数据
modelname = query_param['modelName']
paramCodes = query_param['paramCodes']
paramCode = paramCodes[0]
satelliteMid = query_param['satelliteMid']
bigdata = pd.DataFrame({'columnone': columns_one, 'columntwo': columns_two})
test = bigdata
X_test, y_test = shift_samples(test[['columntwo']],column_name=columns_two,look_back=1)
model = load_model(modelname + '.hdf5')
X_test_pred = model.predict(X_test)
loss_mae = np.mean(np.abs(X_test_pred - X_test), axis=1)
# 设定阈值
threshold = float(0.85*(max(loss_mae))+0.15*(min(loss_mae)))
non_scaled_bigdata = bigdata.copy()
non_scaled_bigdata.fillna(method='bfill', inplace=True)
non_scaled_bigdata = non_scaled_bigdata[:-1]
non_scaled_bigdata['loss_mae'] = loss_mae
non_scaled_bigdata['threshold'] = threshold
# 将每一条数据与阈值比对
non_scaled_bigdata['anomaly'] = non_scaled_bigdata.loss_mae > non_scaled_bigdata.threshold
bigdata_outliers = non_scaled_bigdata[non_scaled_bigdata['anomaly'] == True]
以上则为关于LSTM的简单介绍,希望能够帮助到感兴趣的朋友,下次我们再做详细介绍。
标签:loss,bigdata,实践,算法,train,test,LSTM,model,columns From: https://blog.51cto.com/shanxihualu/5745946