python之LSTM预测模型

        如果遇到这个错误:ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 1 array(s), but instead got the following list of 25000 arrays: [array([[ 11],...........]]是因为数据大小或者长度等超出了限制而导致的。所以用limit_imdb_datalength(x_train)来限制数据中的数值大小。

1、数据标准化:

        如果使用sigmoid或者tanh作为激活函数的时候,将数据缩放到一个指定范围,避免输入数据的尺度敏感。

        MinMaxScaler将数据缩放到一个指定的最大和最小值(通常是1-0)之间。作用:对方差非常小的属性可以增强其稳定性;维持稀疏矩阵中为0的条目。

from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler=MinMaxScaler()
# scaler.fit(data)
# data=scaler.transform(data)
data=scaler.fit_transform(data)#等于fit加transform,标准化数据
data=scaler.inverse_transform(data)#与fit_transform相反,还原标准化后的数据
# https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html

        正则化,将每个样本缩放到单位范数(每个样本的范数为1), 如果后面要使用如二次型(点积)或者其它核方法计算两个样本之间的相似性这个方法会很有用。normalize,L1范数表示向量中所有元素的绝对值和,L2范数表示欧氏距离,p范数表示向量元素绝对值的p次方和的1/p次幂。

from sklearn.preprocessing import normalize
#L1范数表示向量中所有元素的绝对值和,L2范数表示欧氏距离
x=normalize(data,norm='l1')#norm='l1', 'l2', or 'max', optional ('l2' by default)
# print(x)
# https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.normalize.html#sklearn.preprocessing.normalize

2、LSTM模型数据导入

        IMDB影评数据导入,可以直接从Keras.datasets中进行导入,imdb.load_data()进行在线下载导入(下载好的也可以导入),也可以自己编写数据导入函数进行数据导入,下面包含两个函数,一个是导入函数,一个是对导入的IMDB数据进行截取。

def load_imdb_data(path='imdb.npz',choosedata='train',num_words=None):
    """
    imdb.npz数据提取
    :param path: imdb数据地址
    :param choosedata: {'all','train','test','trainandtest'}
    :param num_words:数据值上限
    :return:x,y:数据标签
    """
    with np.load(path) as f:#提取数据
        x_train, y_train = f['x_train'], f['y_train']
        x_test, y_test = f['x_test'], f['y_test']
    #测试数据提取
    indices = np.arange(len(x_train))#数据长度
    np.random.shuffle(indices)#随机打乱顺序
    x_train = x_train[indices]#提取打乱顺序的训练数据
    y_train = y_train[indices]#提取打乱顺序的训练数据的标签
    #训练数据提取
    indices = np.arange(len(x_test))
    np.random.shuffle(indices)
    x_test = x_test[indices]
    y_test = y_test[indices]
    #去除数据中超过上限的值,下限为0
    if num_words is not None:
        x_train = [[w for w in x if 0 <= w < num_words] for x in x_train]
        x_test = [[w for w in x if 0 <= w < num_words] for x in x_test]
    if choosedata=='train':
        return x_train,y_train
    elif choosedata=='test':
        return x_test,y_test
    elif choosedata=='trainandtest':
        return (x_train,y_train),(x_test,y_test)
    elif choosedata=='all':
        #数据拼接
        xs = np.concatenate([x_train, x_test])
        ys = np.concatenate([y_train, y_test])
        return xs,ys

def limit_imdb_datalength(datax,maxlen=500,truncating='post',dtype='int32'):
    """
    限定数据集的长度,对过长的进行剪切,不足的用0填充
    :param datax:输入数据二维数组
    :param maxlen:限定数据集的长度
    :param truncating:前向限定还是后向限定{'pre','post'}
    :param dtype:数据类型
    :return:x:处理后的数据
    """
    #构建一个相同的矩阵来装改变后的数据
    num_samples=len(datax)
    x = np.full((num_samples, maxlen), 0., dtype=dtype)
    #对数据进行长度判断,并将处理后的数据装在新数组x中
    for idx, s in enumerate(datax):
        if not len(s):
            continue
        if len(s)>maxlen:
            if truncating == 'post':
                trunc = s[:maxlen]
                x[idx, :len(trunc)] = trunc
            elif truncating == 'pre':
                trunc = s[-maxlen:]
                x[idx, -len(trunc):] = trunc
        else:
            trunc=s
            if truncating == 'post':
                x[idx, :len(trunc)] = trunc
            elif truncating == 'pre':
                x[idx, -len(trunc):] = trunc
    return x

        国际旅行人数预测的数据导入,需要从网上下载international-airline-passengers.csv数据,当然也可以写函数进行导入,也可以直接通过pandas函数中的read_csv函数进行导入,CSV格式可以直接通过office打开,看着和xls差不多,自己写导入函数的话可以根据Excel表格读取的数据特点来进行程序编写。在此直接调用read_csv进行数据导入,并对导入的数据进行归一化。

data=read_csv('international-airline-passengers.csv',usecols=[1],engine='python',skipfooter=3)
data=data.values.astype('float32')
scaler=MinMaxScaler()
dataset=scaler.fit_transform(data)#归一化

        如果用国际旅行人数来进行预测模型建立的话,导入的数据还需要进行处理,导入的数据只是不同时间的人数,我们需要让不同时间段的人数有关系,将数据关联起来,如果当前时间是t,需要知道前两个时间t-1,t-2,来预测下一个时间t+1;并对导入的数据进行了训练数据和测试数据的分割,用一定数据的数据来进行训练,用一定数据的数据来进行预测。

def create_data(data,look_back=3,splitsize=0.7):
    """
    给定当前时间t,预测t+1,使用数据(t-2,t-1,t)
    :param data:数据
    :param look_back:输出数据集的格式,默认3[1,2,3],如果改成4则为[1,2,3,4]
    :return: (x_train,y_train),(x_test,y_test):实际数据,结果,训练数据,结果
    """
    datax,datay=[],[]
    for i in range(len(data)-look_back-1):
        x=data[i:i+look_back,0]#每次去look_back个数据
        datax.append(x)
        y=data[i+look_back,0]#如果x是0,1,2,则y是3
        datay.append(y)
    train_size=int(len(datax)*splitsize)
    # test_size=int(len(datax)-train_size)
    # 前半截数据用于训练,后半截数据用于测试
    x_train,y_train=np.array(datax[0:train_size]),np.array(datay[0:train_size])
    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))#样本、时间步长、特征
    x_test,y_test=np.array(datax[train_size:len(datax)]),np.array(datay[train_size:len(datax)])
    x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
    return (x_train,y_train),(x_test,y_test)

        数据的相关导入可以参考:https://blog.csdn.net/zx520113/article/details/84557459

3、国际旅行人数预测模型建立

        拿到了数据,我们需要根据数据来建立相应的模型。为了方便模型下次使用,可以通过save_model保存模型,get_model载入训练好的模型。可参考:https://blog.csdn.net/zx520113/article/details/84789427

def perceptron_model():
    #多层感知器模型,hidden_layer_num隐藏层层数
    """这里导入的数据不需要进行reshpe改变,直接用datax.append(x),datay.append(y)的数据就行"""
    model=Sequential()
    model.add(Dense(units=hidden_layer_num,input_dim=look_back,activation='relu'))
    model.add(Dense(units=hidden_layer_num, activation='relu'))
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error',optimizer='adam')
    return model

def time_model():
    #LSTM搭建的LSTM回归模型
    model=Sequential()
    model.add(LSTM(units=hidden_layer_num,input_shape=(1,look_back)))#四个隐藏层或者更多
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error',optimizer='adam')
    return model

def time_step_model():
    #使用时间步长的LSTM回归模型
    model=Sequential()
    model.add(LSTM(units=hidden_layer_num,input_shape=(look_back,1)))
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error',optimizer='adam')
    return model

def memory_batches_model():
    #LSTM的批次时间记忆模型
    model=Sequential()
    # 通过设置stateful为True来保证LSTM层内部的状态,从而获得更好的控制
    model.add(LSTM(units=hidden_layer_num,batch_input_shape=(batch_size,look_back,1),stateful=True))
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error',optimizer='adam')
    return model

def stack_memory_batches_model():
    # 两个叠加的LSTM的批次时间记忆模型
    model=Sequential()
    #通过设施return_sequences等于True来完成每个LSTM层之前的LSTM层必须返回序列,将LSTM扩展位两层
    model.add(LSTM(units=hidden_layer_num,batch_input_shape=(batch_size,look_back,1),stateful=True,return_sequences=True))
    # 通过设置stateful为True来保证LSTM层内部的状态,从而获得更好的控制
    model.add(LSTM(units=hidden_layer_num,input_shape=(batch_size,look_back,1),stateful=True))
    model.add(Dense(units=1))
    model.compile(loss='mean_squared_error',optimizer='adam')
    return model

4、IMDB预测模型建立

        最简单的IMDB模型,有一个词嵌入层,一个LSTM层,一个输出层组成,为提高准确率,可以加入Dropout损失,卷积池化等,搭建复杂的网络。

def easy_imdb_model():
    model=Sequential()
    model.add(Embedding(top_words,out_dimension,input_length=max_words))
    model.add(LSTM(units=100))
    model.add(Dense(units=1,activation='sigmoid'))
    model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
    model.summary()
    return model

def dropout_imdb_model():
    model=Sequential()
    model.add(Embedding(top_words,out_dimension,input_length=max_words))
    model.add(Dropout(dropout_rate))
    model.add(LSTM(units=100))
    # model.add(LSTM(units=100,dropout=0.2,recurrent_dropout=0.2))
    model.add(Dropout(dropout_rate))
    model.add(Dense(units=1,activation='sigmoid'))
    model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
    model.summary()
    return model

def lstm_cnn_imdb_model():
    model=Sequential()
    model.add(Embedding(top_words,out_dimension,input_length=max_words))
    model.add(Conv1D(filters=32,kernel_size=3,padding='same',activation='relu'))
    model.add(MaxPooling1D(pool_size=2))
    model.add(LSTM(units=100))
    model.add(Dense(units=1,activation='sigmoid'))
    model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
    model.summary()
    return model

5、训练测试模型

        通过model.fit()传入相应的数据,参数对模型进行训练。模型训练好后,通过model.predict()传入x数据对模型进行预测,对预测出来的y数据进行scaler.inverse_transform反转,因为我们在最开始对数据进行了处理,所以要得到原来的数据我们需要用相反的方法处理一下预测出来的数据结果。然后对数据进行绘制比对,图像的绘制可以通过matplotlib,plt实现。matplotlib的使用可以参考:https://blog.csdn.net/zx520113/article/details/84103437

model=memory_batches_model()
for i in range(epochs):
    history = model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=0, shuffle=False)
    mean_loss = np.mean(history.history['loss'])
    print('mean loss %.5f for loop %s' % (mean_loss, str(i)))
    model.reset_states()#重置模型中所有层的状态
    (x_train,y_train),(x_test,y_test) = load_imdb_data(choosedata='trainandtest',num_words=max_words)
    x_train = limit_imdb_datalength(x_train,truncating='pre')
    x_test = limit_imdb_datalength(x_test,truncating='pre')
    model=easy_imdb_model()
    model.fit(x_train,y_train,batch_size=batch_size,epochs=epochs,verbose=2)
    scores=model.evaluate(x_test,y_test,verbose=2)
    print("Accuracy:%.2f%%"%(scores[1]*100))

        完整的python代码和数据连接:https://download.csdn.net/download/zx520113/10833491

 

  • 8
    点赞
  • 156
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下为一个简单的LSTM预测模型示例: ```python import numpy as np import pandas as pd import tensorflow as tf from sklearn.preprocessing import MinMaxScaler # 读取数据 data = pd.read_csv('data.csv') # 数据预处理 scaler = MinMaxScaler() data['scaled'] = scaler.fit_transform(data['value'].values.reshape(-1, 1)) # 划分训练集和测试集 train_size = int(len(data) * 0.8) test_size = len(data) - train_size train, test = data.iloc[0:train_size], data.iloc[train_size:len(data)] print(train.shape, test.shape) # 定义函数,用于生成序列数据 def create_dataset(dataset, look_back=1): X, Y = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back), 0] X.append(a) Y.append(dataset[i + look_back, 0]) return np.array(X), np.array(Y) # 生成训练集和测试集的序列数据 look_back = 3 train_X, train_Y = create_dataset(train['scaled'].values.reshape(-1, 1), look_back) test_X, test_Y = create_dataset(test['scaled'].values.reshape(-1, 1), look_back) # 转化为TensorFlow的可用数据格式 train_X = train_X.reshape(-1, look_back, 1) test_X = test_X.reshape(-1, look_back, 1) # 定义LSTM模型 model = tf.keras.Sequential([ tf.keras.layers.LSTM(50, input_shape=(look_back, 1)), tf.keras.layers.Dense(1) ]) # 编译模型 model.compile(loss='mean_squared_error', optimizer='adam') # 训练模型 model.fit(train_X, train_Y, epochs=100, batch_size=1, verbose=2) # 预测 train_predict = model.predict(train_X) test_predict = model.predict(test_X) # 反归一化 train_predict = scaler.inverse_transform(train_predict) train_Y = scaler.inverse_transform([train_Y]) test_predict = scaler.inverse_transform(test_predict) test_Y = scaler.inverse_transform([test_Y]) # 计算误差 train_score = np.sqrt(np.mean((train_predict - train_Y)**2)) test_score = np.sqrt(np.mean((test_predict - test_Y)**2)) print('Train Score: %.2f RMSE' % (train_score)) print('Test Score: %.2f RMSE' % (test_score)) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值