---
# System prepended metadata

title: Day14

---

# 預測2317股票來認識LSTM

```python=
import pandas as pd
import numpy as np
from tqdm import auto
df = pd.read_csv("2317.csv")
df.isna().sum()
#%%
df.drop(['Change'], axis=1, inplace=True) #上期比
df.columns = ['date','Open','High','Low','Close','RD','Volume']
df
#%%
# 將日期設為index
df.set_index(['date'], inplace=True)
df
#%%
#應變量
df.RD.plot()
#%%
#先拆分，再正規化
train = df[0:2670]
test = df[2670:]
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
train = pd.DataFrame(scaler.fit_transform(train), columns=df.columns)
test = pd.DataFrame(scaler.fit_transform(test), columns=df.columns)
#%%
#製造X跟Y(RD)
import tqdm
n = 30 #改n即可，資料1/4起，所以能預測的第一個Y為2/3，抓30天
feature_names = list(train.drop('RD', axis=1).columns)
X = []
y = []
indexes = []
norm_data_x = train[feature_names]
for i in auto.tqdm(range(0,len(train)-n)): 
  X.append(norm_data_x.iloc[i:i+n]. values) 
  y.append(train['RD'].iloc[i+n-1]) #現有資料+30天的Y
  indexes.append(train.index[i+n-1]) #Y的日期

print(X[0])
print(y[0])

X=np.array(X) # RD外的6個自變量，記憶體=30，EX:預測12/31的Y，用12/1~12/30的X
y=np.array(y)
print(X.shape)
print(y.shape)
#%%
# Adding the LSTM layer
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
n_steps = 30 
n_features = 5
model = Sequential()
model.add(LSTM(50,activation='relu', return_sequences=False, input_shape = (n_steps, n_features)))
#input_shape = (n_steps, n_features)  幾步, 幾個特徵
# return_sequences預設false，輸出是否為序列? 是: 輸出多個值
model.add(Dense(1))
model.compile(optimizer = 'adam', loss = 'mse' , metrics=['mse'])
#%%
history = model.fit(X,y,batch_size=100,epochs=20)

# 顯示loss
import matplotlib.pyplot as plt

plt.title('train_loss')
plt.ylabel('loss')
plt.xlabel('Epoch')
plt.plot(history.history["loss"])
#%%
#製造X跟Y(RD)
import tqdm
n = 30 #改n即可，資料1/4起，所以能預測的第一個Y為2/3，抓30天
feature_names = list(test.drop('RD', axis=1).columns)
X = []
y = []
indexes = []
norm_data_x = test[feature_names]
for i in tqdm.tqdm_notebook(range(0,len(test)-n)): 
  X.append(norm_data_x.iloc[i:i+n].values) 
  y.append(test['RD'].iloc[i+n-1]) #現有資料+30天的Y
  indexes.append(test.index[i+n-1]) #Y的日期
X=np.array(X) # RD外的6個自變量，記憶體=30，EX:預測12/31的Y，用12/1~12/30的X
y=np.array(y)

predictions = model.predict(X)
predictions = pd.DataFrame(predictions).rename(columns={0: '預測值'})
Y_test = pd.DataFrame(y).rename(columns={0: '實際值'})

final = pd.concat([predictions,Y_test],axis=1)
final['mae'] = abs(final['預測值'] - final['實際值'])
final
norm_data = pd.DataFrame(scaler.inverse_transform(norm_data), columns=df.columns, index=df.index)
```

## 成果
* 從2317.csv中獲取所需數據
![](https://hackmd.io/_uploads/ByNPdLhhn.png)

* 經過20次的訓練可以看到mse已趨近於穩定
![](https://hackmd.io/_uploads/r1B_FI232.png)



