Multivariable temperature prediction based on LSTM (python)
——I guarantee that he can run and the results will satisfy you (if you are a novice like me)
1, Why should I write this?
Because of the crazy course assignment, my team chose a topic on multivariable prediction. When I was a junior, I had basically not been exposed to Python data processing, and even only heard about neural networks, this thing was as difficult as heaven.
Then it is gratifying that there are a lot of ready-made code on the Internet that is worthy of quick simulation, but the painful thing is that it is chaotic and lack of explanation, and the final result can not explain the problem (the result is very bad, I don't know why).
Therefore, I collect the online multivariable example code, combined with my superficial opinions, and make the following summary. At the same time, it is also convenient to remind myself - after all, it is something quick in a week... I hope it can support me to complete the course homework.
2, What did you do?
Combined with various experiences, mainly
- Station B teacher Tang Guoliang's TensoFlow2 based on LSTM multivariable shared bicycle usage prediction (through this, I quickly introduced some concepts)
- Link to this article: https://blog.csdn.net/weixin_39653948/article/details/105927085 (tf.keras 11: LSTM weather prediction of time series prediction) most of the examples on the Internet are this
- And the article - this article link: https://blog.csdn.net/weixin_38346042/article/details/119983658 (based on LSTM temperature time series prediction, the features are further filtered than the above example)
Then I combine some superficial understanding with the examples of these big men——
- Learn to use Anaconda (download python Library) and Jyputer (allow single step execution of code blocks)
- Through the powerful drawing of python, the correlation features (the things most likely to affect the temperature change) are extracted by naked eye scanning
- It realizes the segmentation of csv data sets from zero to
- Build a neural network structure with no parameters (or copy) with one hand. 3-layer LSTM - one hand is because I eat when I use cv method
- Successfully trained a model to accurately predict the temperature of the next hour by using the data of the first three hours, with an accuracy of 99% (it may be because the time span is short, I don't understand it, but it can run the results)
3, The source code is segmented and annotated. Please criticize and correct (● '◡' ●) ﾉ
PS: the code is run on Jyputer, and the library used is downloaded by Anaconda
If there is a cute person who knows this, it is recommended to know. Don't mess with the copy code, and then there is no library. Then, when configuring, he angrily throws the keyboard because of the tensorflow and python version problems, related library update problems, and inexplicable error reports.
1. block1 import related packages
import tensorflow as tf import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import os import pandas as pd import seaborn as sns from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import r2_score from tensorflow.keras import utils,losses,layers,Sequential from tensorflow.keras.callbacks import ModelCheckpoint,TensorBoard
2. Read the csv dataset and search jena_climate_2009_2016 dataset, you need to download it yourself
data_path="D:\WorkSpace\jena_climate_2009_2016.csv" dataset=pd.read_csv(data_path,parse_dates=['Date Time'],index_col=['Date Time']) dataset.shape#Output array shape (420551, 14) (row, column) dataset.tail()#Output last 5 columns dataset.head()#The data structure is as follows, with 5 columns in the output head dataset.info()
3. Draw a picture to see the correlation and extract the effective feature set
#Naked eye observation - the following three pieces can not be used plt.figure(figsize=(16,8)) #Auxiliary drawing library sns.lineplot(x='p (mbar)',y='T (degC)',data=dataset[:10000]) plt.show() plt.figure(figsize=(16,8)) sns.lineplot(x='Tdew (degC)',y='T (degC)',data=dataset[:10000]) plt.show() plt.figure(figsize=(16,8)) sns.lineplot(x='max. wv (m/s)',y='T (degC)',data=dataset[:50000]) plt.show() #The above is the relationship between T (degC) and p (mbar) and Tdew (degC)
#Insert a new column into the dataset, which is the corresponding time value of the Data Time column dataset['year']=dataset.index.year dataset['hour']=dataset.index.hour dataset['month']=dataset.index.month dataset.head()
#Relationship between time and temperature plt.figure(figsize=(16,8)) sns.pointplot(x='hour',y='T (degC)',data=dataset[0:50000],hue='month') plt.show()
This is the best picture in the experiment
#Since the temperature is related to the daily hourly change, and 0-23 is a cycle, the cycle information is extracted by trigonometric function. sin and cos are used at the same time to ensure that 24 hours is a cycle - it is over (it is recommended to refer to relevant materials) dataset['sin(h)']=[np.sin((x) * (2 * np.pi / 24)) for x in dataset['hour']] dataset['cos(h)']=[np.cos((x) * (2 * np.pi / 24)) for x in dataset['hour']]
4. Divide the dataset function into the form of x . Shape (i1, i2) - > y . Shape (1), indicating that i1 historical data each contains i2 feature elements - "corresponds to 1 target detection value (or multiple, depending on the following settings)
#future=['sin(h)','cos(h)','month','max. wv (m/s)','p (mbar)','T (degC)'] #Define the segmentation function. X is the example table composed of the selected features, and Y is the label column (x=dataset[future =], y=dataset['T (degC) ']) #train_dataset,train_labels=multivariate_data(x_train,y_train,0,100000,3,1,1,True) #The above usage means: count from 0 to 100000, and put three pieces of X data as an element into data - < 1 piece of Y data as an element into labels. step=1 means that each piece of data is packaged once according to the above, such as data=x[0, 1, 2] - > labels  = y ; data=x[1,2,3]->labels=y; #single_step means that only one future state of the target is predicted, and only one hour after prediction. Set to false to predict 0 to target in the future_ The temperature within 24 hours. def multivariate_data(x,y, start_index, end_index, history_size, target_size, step, single_step): data =  labels =  start_index = start_index + history_size if end_index is None: end_index = len(dataset) - target_size for i in range(start_index, end_index): indices = range(i-history_size, i, step) # Step represents the sliding step mid_data=x.iloc[indices] data.append(mid_data) if single_step: mid_data=y.iloc[i+target_size] labels.append(mid_data) else: labels.append(y.iloc[i:i+target_size]) return np.array(data), np.array(labels)
5. Normalization of data processing
future=['sin(h)','cos(h)','month','max. wv (m/s)','p (mbar)','T (degC)'] #Data normalization. Since sin and cos are - 1 to 1, normalization is not required for col in future: scaler=MinMaxScaler() if(col not in ['sin(h)','cos(h)']): dataset[col]=scaler.fit_transform(dataset[col].values.reshape(-1,1))
# start_index=0 # end_index=100000 # history_size=3 # target_size=1 # step=1 # train_data,train_label=multivariate_data(dataset, start_index, end_index, history_size,target_size, step) #Get training features and training Tags x=dataset[future] y=dataset['T (degC)'] #View specific format x.shape y.shape #Through 3-7 division of training set and test set, 70% are training sets x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.7,shuffle=False,random_state=13) x_train.shape #Obtain the format of training set and test set -- (3,6) - > (1,) predict the target of 1 row and 1 column through 3 rows of historical data and 7 columns of target characteristics train_dataset,train_labels=multivariate_data(x_train,y_train,0,100000,3,1,1,True) test_dataset,test_labels=multivariate_data(x_test,y_test,0,100000,3,1,1,True)
6. Format conversion, grouping and disruption
#Create training group, internal batch_size，buffer_size, shuffle, batch suggest Baidu #The goal of this function is to convert the newly built training set / test set into tensorflow data set format, disrupt the grouping and facilitate the training model def create_batch_dataset(x,y,train=True,buffer_size=1000,batch_size=128): batch_data=tf.data.Dataset.from_tensor_slices((tf.constant(x),tf.constant(y))) if train: return batch_data.cache().shuffle(buffer_size).batch(batch_size) else: return batch_data.batch(batch_size) #Use the above function train_batch_dataset=create_batch_dataset(train_dataset,train_labels) test_batch_dataset=create_batch_dataset(test_dataset,test_labels,train=False) #Take a test set element to see the format list(test_batch_dataset.as_numpy_iterator())
7. Please refer to Baidu for the role of relevant parameters in model establishment
#Establish neural network model - three layers LSTM and one output layer model= tf.keras.models.Sequential([ tf.keras.layers.LSTM(256, input_shape=train_dataset.shape[-2:],return_sequences=True), # input_shape=(20,1) does not contain batch dimensions tf.keras.layers.Dropout(0.4), tf.keras.layers.LSTM(128, return_sequences=True), tf.keras.layers.Dropout(0.3), tf.keras.layers.LSTM(32), tf.keras.layers.Dense(1) ]) #Optimizer and loss function settings model.compile(optimizer='adam',loss='mse') #Settings related to model saving utils.plot_model(model) checkpoint_file='test_model.hdf5' checkpoint_callback=ModelCheckpoint(filepath=checkpoint_file,monitor='loss',moode='min',save_best_only=True,save_weights_only=True) #model training history=model.fit(train_batch_dataset,epochs=30,validation_data=test_batch_dataset,callbacks=[checkpoint_callback])
8. Result inspection——
#The favorite drawing link is to obtain the results of each step of the model training loss and val through history_ loss plt.figure(figsize=(8,8),dpi=200) plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('model train vs validation loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train','validation'], loc='best') plt.show()
test_dataset.shape #Prediction by entering a set of data test_preds=model.predict(test_dataset,verbose=1) test_preds[:10] #Convert a set of predicted data into one dimension for comparison test_preds=test_preds[:,0] test_preds[:10] test_labels.shape #r2 test, the closer it is to 1, the better the effect. A negative number means it's completely useless score=r2_score(test_labels,test_preds) print(score) #Make a curve comparison between the predicted results and the actual results, and use 1000 results for comparison plt.figure(figsize=(16,8)) plt.plot(test_labels[:1000],label="True value") plt.plot(test_preds[:1000],label="Pred value") plt.legend(loc='best') plt.show()