我正试图通过调整curiosily的代码,使用神经网络来解决回归问题
tutorial
在训练/测试阶段之后,我想将预测结果(来自神经网络)与预期值一起绘制出来。但我总是得到预测结果的常数值。
以下是我的数据示例:
y x1 x2 x3 x4 x5 \
Date
2015-03-02 1.000000 0.326808 0.954789 0.345128 0.809366 0.401721
2015-03-09 0.469589 0.323142 0.676289 0.000000 0.791904 0.337875
2015-03-16 0.783375 0.211984 0.801912 0.312489 0.283238 0.628224
2015-03-23 0.837088 0.099067 0.662923 0.028891 0.334150 0.455690
2015-03-30 0.576463 0.000000 0.694937 0.376173 0.147238 0.784254
2016-03-07 0.520800 0.652797 1.000000 0.501365 0.698179 0.498709
2016-03-14 0.492543 0.658820 0.830122 0.219795 0.814204 0.330795
2016-03-21 0.536455 0.731701 0.848878 0.133867 1.000000 0.134471
2016-03-28 0.009716 0.880046 0.000000 0.299588 0.710215 0.310644
2017-03-06 0.085095 1.000000 0.810502 0.792946 0.481694 0.726653
2017-03-13 0.272674 0.890968 0.760774 0.227955 0.163028 0.352487
2017-03-20 0.000000 0.769808 0.589088 1.000000 0.000000 1.000000
2017-03-27 0.170325 0.656550 0.785720 0.247674 0.387465 0.547248
2018-03-05 0.663452 0.792394 0.715791 0.004552 0.321927 0.000000
2018-03-12 0.489003 0.838095 0.569241 0.269696 0.703545 0.079207
2018-03-19 0.411556 0.833784 0.616880 0.124014 0.830961 0.281638
2018-03-26 0.342121 0.851702 0.653559 0.554556 0.934628 0.426153
x6 year week
Date
2015-03-02 0.925160 2015 10
2015-03-09 0.631814 2015 11
2015-03-16 0.757044 2015 12
2015-03-23 0.617873 2015 13
2015-03-30 0.660571 2015 14
2016-03-07 1.000000 2016 10
2016-03-14 0.833336 2016 11
2016-03-21 0.884074 2016 12
2016-03-28 0.000000 2016 13
2017-03-06 0.796808 2017 10
2017-03-13 0.737460 2017 11
2017-03-20 0.567961 2017 12
2017-03-27 0.783137 2017 13
2018-03-05 0.739046 2018 10
2018-03-12 0.577926 2018 11
2018-03-19 0.620370 2018 12
2018-03-26 0.699337 2018 13
我的代码是
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pandas.io.sql as sql
from datetime import date, datetime, time, timedelta
import holidays
from db import DB
import torch
from torch import nn, optim
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, StandardScaler
## load dataframe
## inputs
cols0 = [i for i in ['x1','x2','x3','x4','x5','x6','year','week'] if i != 'y']
X = mydata[cols0]
## output
y0 = mydata[['y']]
X_train, X_test, y_train, y_test = train_test_split(X, y0, test_size=0.3, random_state=50)
## convert everything to tensors
X_train = torch.from_numpy(X_train.values).float()
y_train = torch.squeeze(torch.from_numpy(y_train.values).float())
X_test = torch.from_numpy(X_test.values).float()
y_test = torch.squeeze(torch.from_numpy(y_test.values).float())
## build neural network
class Net(nn.Module):
def __init__(self, n_features):
super(Net, self).__init__()
# n_features = no. inputs
n1 = 8 # no. nodes in layer 1
n2 = 5 # no. nodes in layer 2
n3 = 4 # no. nodes in layer 3
n4 = 5 # no. nodes in layer 4
n5 = 2 # no. nodes in layer 5
self.fc1 = nn.Linear(n_features,n1)
self.fc2 = nn.Linear(n1,n2)
self.fc3 = nn.Linear(n2,n3)
self.fc4 = nn.Linear(n3,n4)
self.fc5 = nn.Linear(n4,n5)
self.fc6 = nn.Linear(n5,1)
def forward(self, x):
#x = F.relu(self.fc1(x))
x = torch.tanh(self.fc1(x)) # activation function in layer 1
x = torch.sigmoid(self.fc2(x))
x = torch.sigmoid(self.fc3(x))
x = torch.tanh(self.fc4(x))
x = torch.tanh(self.fc5(x))
return torch.sigmoid(self.fc6(x))
net = Net(X_train.shape[1])
criterion = nn.MSELoss() # loss function
optimizer = optim.Adam(net.parameters(), lr=0.0001)
## training
for epoch in range(2001):
y_pred = net(X_train)
y_pred = torch.squeeze(y_pred)
train_loss = criterion(y_pred, y_train)
# forward feed
y_test_pred = net(X_test)
y_test_pred = torch.squeeze(y_test_pred)
test_loss = criterion(y_test_pred, y_test) # calculate the loss
optimizer.zero_grad() # clear out gradients from loss.backward()
train_loss.backward() # back propagation
optimizer.step() # update weights
## reverse scaling of test data and model predictions
scaler = MinMaxScaler()
scaler0 = scaler.fit(np.expand_dims(y_train, axis=1))
ytrue = scaler0.inverse_transform(np.expand_dims(y_test.detach().numpy().flatten(),axis=0)).flatten()
ypred = scaler0.inverse_transform(np.expand_dims(y_test_pred.detach().numpy(),axis=0)).flatten()
plt.figure()
plt.plot(ypred, label='predicted')
plt.plot(ytrue, label='actual')
plt.ylabel('output y')
plt.legend()
plt.show()
以及显示
predicted
值与实际/预期值的比值如下。我以为
预测
不会只是一条直线。