# Multivariable temperature prediction based on LSTM (python)

## 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——

1. Learn to use Anaconda (download python Library) and Jyputer (allow single step execution of code blocks)
2. Through the powerful drawing of python, the correlation features (the things most likely to affect the temperature change) are extracted by naked eye scanning
3. It realizes the segmentation of csv data sets from zero to
4. 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
5. 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
```

```data_path="D:\WorkSpace\jena_climate_2009_2016.csv"

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

``` ```#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

#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()
``` Posted on Tue, 07 Dec 2021 00:20:42 -0500 by FraXTC