一个实例掌握tensorflow版本 LSTM(持续更新)

         基于LSTM的大规模资金流入流出的大数据预测实例 

目录:

一:数据预处理

二:构建神经网络

三:训练神经网络(神经网络的保存)

四:使用LSTM算法进行预测(神经网络的恢复)

前言:

       作为一名大二的学生,接触ML&DL的时间也还没超过一年,写下博客只是用于记录自己的学习成果,以方便日后查找、应用,水平及其有限,不讳言很多东西都是CTRL+C 、CTRL+V的,但我会尽量写下我在学习过程中遇到的难点或者说是困惑点吧,并记下我的解决方法。

阅读完本文后你将会掌握: 

  • 如何将原始数据转化为适合处理时序预测问题的数据格式; 
  • 如何准备数据并搭建LSTM来处理时序预测问题; 
  • 如何利用模型预测。

项目说明 
【问题说明】 
蚂蚁金服拥有上亿会员并且业务场景中每天都涉及大量的资金流入和流出,面对如此庞大的用户群,资金管理压力会非常大。在既保证资金流动性风险最小,又满足日常业务运转的情况下,精准地预测资金的流入流出情况变得尤为重要。通过对例如余额宝用户的申购赎回数据的把握,精准预测未来每日的资金流入流出情况。对货币基金而言,资金流入意味着申购行为,资金流出为赎回行为。命题中使用的数据主要包含四个部分,分别为用户基本信息数据 user_profile_table、用户申购赎回数据 user_balance_table、收益率表 mfd_day_share_interest 和银行间拆借利率表 mfd_bank_shibor。 

数据下载戳 ,提取码:79c2
【用户期望】 
期望通过对例如余额宝用户的申购赎回数据的把握,精准预测未来每日的资金流入流出情况。对货币基金而言,资金流入意味着申购行为,资金流出为赎回行为。通过提交结果表 tc_comp_predict_table,对每一天对申购、赎回总额的预测值,金额数据,精确到分。  

【开发说明】 
期望选手对未来 30 天内每一天申购和赎回的总量数据预测的越准越好,同时考虑到可能存在的多种情况。

晾一张预测图(蓝色为真实值,红色为预测值)

blue:true dataset     red:predict
bule:true dataset     red:predict

为什么选择LSTM(Long short-term memory)?

  1. LSTM网络用来处理带“序列”(sequence)性质的数据。比如时间序列的数据,像每天的股价走势情况,机械振动信号的时域波形,以及类似于自然语言这种本身带有顺序性质的由有序单词组合的数据。 
  2. LSTM本身不是一个独立存在的网络结构,只是整个神经网络的一部分,即由LSTM结构取代原始网络中的隐层单元部分。 
  3. LSTM网络具有“记忆性”。其原因在于不同“时间点”之间的网络存在连接,而不是单个时间点处的网络存在前馈或者反馈。如下图2中的LSTM单元(隐层单元)所示。图3是不同时刻情况下的网络展开图。图中虚线连接代表时刻,“本身的网络”结构连接用实线表示LSTM网络最大的特点就是它有输入门、输出门、忘记门三个控制单元(“cell”),随着信息的进入该模型,LSTM中的cell会对该信息进行判断,符合规则的信息会被留下,不符合的信息会被遗忘,这使得它对时间序列的的数据有趋势“记忆”以及预测的能力,大量的训练数据可以使模型“记忆”每年、每月、每周的数据趋势,或者说具有周期性的趋势,这样可以提高时间序列数据预测的准确性。

如果您对LSTM原理还不太理解请戳:理解LSTM原理

一、数据预处理:

打开dataset你会发现有5个cvs表格

但是本例只用到一个表格,就是用户申购赎回数据(user_balance_table.csv)

 

列名

类型

含义

示例

user_id

bigint

用户 id

1234

report_date

string

日期

20140407

tBalance

bigint

今日余额

109004

yBalance

bigint

昨日余额

97389

total_purchase_amt

bigint

今日总购买量 = 直接购买 + 收益

21876

direct_purchase_amt

bigint

今日直接购买量

21863

purchase_bal_amt

bigint

今日支付宝余额购买量

0

purchase_bank_amt

bigint

今日银行卡购买量

21863

total_redeem_amt

bigint

今日总赎回量 = 消费 + 转出

10261

consume_amt

bigint

今日消费总量

0

transfer_amt

bigint

今日转出总量

10261

tftobal_amt

bigint

今日转出到支付宝余额总量

0

tftocard_amt

bigint

今日转出到银行卡总量

10261

share_amt

bigint

今日收益

13

category1

bigint

今日类目 1 消费总额

0

category2

bigint

今日类目 2 消费总额

0

category3

bigint

今日类目 3 消费总额

0

category4

bigint

今日类目 4 消费总额

0

1、原始数据集粗处理:先除去14个月总操作数记录低于5次或者总申购值和总赎回值低于10次的用户,

2、剔除无用数据和缺少值处理:检查是否存在缺失值(可以很容易发现这是上表是缺值的)

3、离散化、标准化和均衡化

 分别对总申购值、总赎回值按天进行汇总,得到1个2x427维的数据集

在427天中选取一个连续的30天作为测试集(test-data),剩下的作为训练集(train-data)

需要对数据进行预处理,包括:噪音清洗、归一化、编码等

在本例中,作为一个小白,我先试用来,Keras的lstm直接建模,但是在反归一化的时候遇到了关于维度的问题,一时半会没能解决,所以曲线救国我尝试了tensorflow版本的LSTM,算是成了。废话不多说,开始吧!

第一步是将数据以日期整合到一起以便我们可以将日期用作Pandas的索引。

在数据集中还有几个分散的“NA”值;我们现在可以用0值标记它们。

code1: Load_Dataset

# Mingjoy/ 2019/4/20
# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
import pandas as pd

# Load_dataset
user_balance = pd.read_csv('user_balance_table.csv', parse_dates = ['report_date'])

timeGroup = user_balance.groupby(['report_date']) # groupby()聚类函数,将数据日期整合
purchaseRedeemTotal = timeGroup['total_purchase_amt', 'total_redeem_amt'].sum()  # 累加每一天的申购、赎回总值
purchaseRedeemTotal.plot()
plt.show()

# Save file
purchaseRedeemTotal.to_csv('purchaseRedeemTotal.csv')

为了便于理解LSTM我们先使用一个特征输入,把每日 total_purchase_amt 作为输入特征[x],后一天的最高价最为标签[y] 

 

 

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

import matplotlib.pyplot as plt
import pandas as pd
import math


# load data(user_balance_table.csv)
user_balance = pd.read_csv('user_balance_table.csv', parse_dates = ['report_date'])
timeGroup = user_balance.groupby(['report_date'])   # groupby()聚类函数
purchaseRedeemTotal = timeGroup['total_purchase_amt', 'total_redeem_amt'].sum()
purchaseRedeemTotal.plot()
plt.show()
# save to file
purchaseRedeemTotal.to_csv('purchaseRedeemTotal.csv')

tensorflow.python.framework.errors_impl. 

代码2 

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import numpy
import matplotlib.pyplot as plt
from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from sklearn.preprocessing import LabelEncoder, MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
import math

# 将序列转换为监督学习问题
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j + 1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j + 1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j + 1, i)) for j in range(n_vars)]
    # put it all togethe
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg


# 加载数据集
dataset = read_csv('purchaseData.csv', header=0, index_col=0)
dataset = dataset.fillna(value=0)
values = dataset.values
# 整数编码
encoder = LabelEncoder()
values[:, 1] = encoder.fit_transform(values[:, 1])
# 确保所有数据是浮动的
values = values.astype('float32')
# 归一化特征
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(values)

# 构建监督学习问题
reframed = series_to_supervised(scaled, 5, 5)
print(reframed.shape)                        # output:(418,120)

# 分为训练集和测试集
values = reframed.values
n_train_days = 397
train = values[:n_train_days, :] # day1 to day397
test = values[n_train_days:, :]  # day398 to day 427
# 分为输入和输出
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
print(train_X.shape, len(train_X), train_y.shape)     # (397, 119) 397 (397,)

# 重塑为3D形状 [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape) #(397, 1, 119) (397,) (21, 1, 119) (21,)

# 设计网络
model = Sequential()
model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')
# 拟合神经网络模型
history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2,
                    shuffle=False)
# 绘制历史数据
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='test')
pyplot.legend()
pyplot.show()

print(test_X.shape) #(21, 1, 119)
# 作出预测
yhat = model.predict(test_X)
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
print(yhat.shape)   #(21, 1)
print(test_X.shape) #(21, 119)

# 反向缩放预测值
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
print(inv_yhat.shape)#(21, 119)
# inv_yhat = inv_yhat.reshape((len(inv_yhat),12))
inv_yhat = inv_yhat.reshape((test_X.shape[0], test_X.shape[1]))
inv_yhat = scaler.inverse_transform(inv_yhat)  # X : array-like, shape [n_samples, n_features]
inv_yhat = inv_yhat[:,0]
# 反向缩放实际值
test_y = test_y.reshape((len(test_y), 1))
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
inv_y = scaler.inverse_transform(inv_y)       # X : array-like, shape [n_samples, n_features]
inv_y = inv_y[:,0]

# 计算RMSE
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
print('Test RMSE: %.3f' % rmse)
plt.plot(inv_yhat)
plt.plot(yhat)
plt.show()

 代码3

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import csv
import codecs

#——————————————————导入数据——————————————————————
f=open('purchase.csv')
df=pd.read_csv(f)
data=np.array(df['total_purchase_amt'])   #获取最高价序列
#以折线图展示data
plt.figure()
plt.plot(data)
plt.show()
normalize_data=(data-np.mean(data))/np.std(data)  #标准化
normalize_data=normalize_data[:,np.newaxis]       #增加维度


#生成训练集
#设置常量
time_step=20      #时间步
rnn_unit=10       #hidden layer units
batch_size=60     #每一批次训练多少个样例
input_size=1      #输入层维度
output_size=1     #输出层维度
lr=0.0006         #学习率
train_x,train_y=[],[]   #训练集
for i in range(len(normalize_data)-time_step-1):
    x=normalize_data[i:i+time_step]
    y=normalize_data[i+1:i+time_step+1]  #后一天的total_purchase_amt最为标签[y]
    train_x.append(x.tolist())
    train_y.append(y.tolist()) 

def data_write_csv(file_name, datas):#file_name为写入CSV文件的路径,datas为要写入数据列表
    file_csv = codecs.open(file_name,'w+','utf-8')#追加
    writer = csv.writer(file_csv, delimiter=' ', quotechar=' ', quoting=csv.QUOTE_MINIMAL)
    for data in datas:
        writer.writerow(data)
    print("保存文件成功,处理结束")



#——————————————————定义神经网络变量——————————————————
X=tf.placeholder(tf.float32, [None,time_step,input_size])    #每批次输入网络的tensor
Y=tf.placeholder(tf.float32, [None,time_step,output_size])   #每批次tensor对应的标签
#输入层、输出层权重、偏置
weights={
         'in':tf.Variable(tf.random_normal([input_size,rnn_unit])),
         'out':tf.Variable(tf.random_normal([rnn_unit,1]))
         }
biases={
        'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])),
        'out':tf.Variable(tf.constant(0.1,shape=[1,]))
        }



#——————————————————定义神经网络变量——————————————————
def lstm(batch):      #参数:输入网络批次数目
    w_in=weights['in']
    b_in=biases['in']
    input=tf.reshape(X,[-1,input_size])  #需要将tensor转成2维进行计算,计算后的结果作为隐藏层的输入
    input_rnn=tf.matmul(input,w_in)+b_in
    input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit])  #将tensor转成3维,作为lstm cell的输入
    cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit)
    init_state=cell.zero_state(batch,dtype=tf.float32)
    output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)  #output_rnn是记录lstm每个输出节点的结果,final_states是最后一个cell的结果
    output=tf.reshape(output_rnn,[-1,rnn_unit]) #作为输出层的输入
    w_out=weights['out']
    b_out=biases['out']
    pred=tf.matmul(output,w_out)+b_out
    return pred,final_states



#——————————————————训练模型——————————————————
def train_lstm():
    global batch_size
    pred,_=lstm(batch_size)
    #损失函数
    loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))
    train_op=tf.train.AdamOptimizer(lr).minimize(loss)
    saver=tf.train.Saver(tf.global_variables())   # 创建一个Saver对象
    # base_path = r'C:\Users\mdz\Desktop\Forecast\lstm'
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        #重复训练10000次
        for i in range(4000):
            step=0
            start=0
            end=start+batch_size
            while(end<len(train_x)):
                _,loss_=sess.run([train_op,loss],feed_dict={X:train_x[start:end],Y:train_y[start:end]})
                start+=batch_size
                end=start+batch_size
                #迭代1000次之后保存模型
                saver.save(sess,'C:\\Users\\mdz\\Desktop\\Forecast\\my_test_model',global_step=1000)


with tf.variable_scope('train'):
    train_lstm()
print('train finsh')
#————————————————预测模型————————————————————
def prediction():
    pred,_=lstm(1)      #预测时只输入[1,time_step,input_size]的测试数据
    saver = tf.train.Saver(tf.global_variables())  # 创建一个Saver对象
    """
    导入一个预先训练模式:
    a)创建网络结构图: 导入原始网络结构图
    b)加载的(变量)参数: 使用restore()方法恢复模型的变量参数。
    """
    with tf.Session() as sess:
        # saver = tf.train.import_meta_graph(r'C:\Users\mdz\Desktop\Forecast\my_test_model-1000.meta')
        saver .restore(sess,tf.train.latest_checkpoint('./'))

        #取训练集最后一行为测试样本。shape=[1,time_step,input_size]
        prev_seq=train_x[-1]
        predict=[]
        #得到之后30个预测结果
        for i in range(30):
            next_seq=sess.run(pred,feed_dict={X:[prev_seq]})
            predict.append(next_seq[-1])
            #每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
            prev_seq=np.vstack((prev_seq[1:],next_seq[-1]))
        #以折线图表示结果
        plt.figure()
        plt.plot(list(range(len(normalize_data))), normalize_data, color='b')
        plt.plot(list(range(len(normalize_data), len(normalize_data) + len(predict))), predict, color='r')
        plt.show()
        # 将预测数据保存到文件中
        print(predict)



with tf.variable_scope('train',reuse=True):
    prediction()

Reference

《TensorFlow: 实战Google深度学习框架》 对于小白规范化自己的代码,增强代码的复用性很有必要看看

使用Keras进行LSTM实战

Tensorflow实例:利用LSTM预测股票每日最高价(一)

Tensorflow实例:利用LSTM预测股票每日最高价(二)

 

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个使用 TensorFlow 实现 LSTM 的简单代码: ```python import tensorflow as tf # 定义超参数 input_dim = 28 hidden_dim = 100 output_dim = 10 sequence_length = 28 learning_rate = 0.01 batch_size = 128 num_epochs = 10 # 定义输入和输出占位符 inputs = tf.placeholder(tf.float32, [None, sequence_length, input_dim]) targets = tf.placeholder(tf.float32, [None, output_dim]) # 定义 LSTMlstm_cell = tf.nn.rnn_cell.LSTMCell(hidden_dim) outputs, _ = tf.nn.dynamic_rnn(lstm_cell, inputs, dtype=tf.float32) # 定义输出层 weights = tf.Variable(tf.truncated_normal([hidden_dim, output_dim], stddev=0.1)) biases = tf.Variable(tf.constant(0.1, shape=[output_dim])) final_output = tf.matmul(outputs[:, -1, :], weights) + biases # 定义损失函数和优化器 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=final_output, labels=targets)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss) # 定义准确率 correct_prediction = tf.equal(tf.argmax(final_output, 1), tf.argmax(targets, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 训练模型 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for epoch in range(num_epochs): for batch in range(len(train_data) // batch_size): batch_inputs, batch_targets = get_batch(train_data, batch_size, batch) sess.run(optimizer, feed_dict={inputs: batch_inputs, targets: batch_targets}) acc = sess.run(accuracy, feed_dict={inputs: test_data, targets: test_labels}) print('Epoch', epoch+1, 'accuracy', acc) ``` 其中,`inputs` 和 `targets` 是输入和输出占位符,`lstm_cell` 是 LSTM 层,`weights` 和 `biases` 是输出层的权重和偏置,`final_output` 是最终的输出,`loss` 是损失函数,`optimizer` 是优化器,`accuracy` 是准确率。在训练过程中,我们需要使用 `feed_dict` 将训练数据和标签传入模型中。 请注意,这只是一个简单的实现,您可以根据自己的需要进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值