Skip to content

Commit 1a3739f

Browse files
committed
完成神经网络模型预测股价程序,效果不好。程序到此为止了。
1 parent 0194041 commit 1a3739f

File tree

7 files changed

+302
-15
lines changed

7 files changed

+302
-15
lines changed

Diff for: dl.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# coding:utf-8
2+
# 神经网络预测股价
3+
# 没完成
4+
5+
6+
import run
7+
import tools
8+
import pandas as pd
9+
import numpy as np
10+
from sklearn.preprocessing import MinMaxScaler
11+
import torch
12+
import torch.nn as nn
13+
from torch.utils.data import DataLoader, Dataset
14+
15+
16+
# 训练神经网络
17+
def DL(code="sh000300", start="2018-01-01", end="2018-12-31", refresh = False):
18+
# 加载数据
19+
tools.initOutput()
20+
data = tools.loadData(code=code, start=start, end=end, refresh=refresh)
21+
# 筛选特征
22+
feature_cols = ["open", "close", "high", "low", "volume"]
23+
target_cols = ["close"]
24+
features_data = data.loc[:, feature_cols]
25+
# 特征归一化
26+
mm = MinMaxScaler(feature_range=(0, 1))
27+
for col in feature_cols:
28+
features_data[col] = mm.fit_transform(features_data[col].values.reshape(-1, 1))
29+
target_data = data.loc[:, target_cols].values
30+
print(features_data.shape)
31+
features_data = np.array(features_data)
32+
features_data = torch.tensor(features_data)
33+
stock_len = len(features_data)
34+
tr_val_slip = int(0.8*stock_len)
35+
print("数据天数:", stock_len)
36+
print("可预测天数:", tr_val_slip)
37+
sqe_len = 5
38+
x = torch.zeros(stock_len - sqe_len, sqe_len, 5)
39+
y = torch.zeros(stock_len - sqe_len, 1)
40+
for i in range(0, stock_len - sqe_len - 1):
41+
x[i] = features_data[i:i+sqe_len]
42+
y[i] = features_data[i+sqe_len, 1]
43+
print(x[i])
44+
45+
# 形成训练集和验证集
46+
train_x = x[0:tr_val_slip]
47+
train_y = y[0:tr_val_slip]
48+
vaild_x = x[tr_val_slip:]
49+
vaild_y = y[tr_val_slip:]
50+
print(train_x.shape, train_y.shape, vaild_x.shape, vaild_y.shape)
51+
52+
# 形成DataLoader
53+
class StockDataset(Dataset):
54+
def __init__(self, x, y):
55+
self.x = x
56+
self.y = y
57+
58+
def __len__(self):
59+
return len(self.x)
60+
61+
def __getitem__(self, index):
62+
X = self.x[index]
63+
Y = self.y[index]
64+
return X, Y
65+
66+
batch_size = 2
67+
train_set = StockDataset(train_x, train_y)
68+
vaild_set = StockDataset(vaild_x, vaild_y)
69+
train_loader = DataLoader(train_set, batch_size = batch_size, shuffle = False)
70+
vaild_loader = DataLoader(vaild_set, batch_size = batch_size, shuffle = False)
71+
72+
#for i in range(5, len(features_data)):
73+
# temp = []
74+
# for j in range(5):
75+
# temp.append(features_data[i][j])
76+
# x.append(temp)
77+
# y.append(target_data[i])
78+
# print(x, len(x), len(y))
79+
# train_x = x[:200]
80+
# train_y = y[:200]
81+
# test_x = x[200:]
82+
# test_y = y[200:]
83+
# 定义神经网络
84+
lr = 0.001
85+
epochs = 20
86+
class bp_net(nn.Module):
87+
def __init__(self, batch_size = batch_size):
88+
super(bp_net, self).__init__()
89+
self.layer_input = nn.Linear(5, 200)
90+
self.layer_hide = nn.Linear(200, 16)
91+
self.layer_output = nn.Linear(16, 1)
92+
self.batch_size = batch_size
93+
94+
def forward(self, x):
95+
x = self.layer_input(x)
96+
nn.ReLU()
97+
x = self.layer_hide(x)
98+
nn.ReLU()
99+
x = self.layer_output(x)
100+
return x
101+
102+
net = bp_net(batch_size)
103+
criterion = nn.MSELoss()
104+
optim = torch.optim.Adam(net.parameters(), lr = lr, weight_decay=0.0)
105+
# 训练过程
106+
for epoch in range(epochs):
107+
train_loss = []
108+
for x, y in train_loader:
109+
# x = x.view(batch_size, -1)
110+
y_pred = net.forward(x)
111+
print("测试", y.shape, y_pred.shape)
112+
print(y_pred)
113+
loss = criterion(y_pred, y)
114+
train_loss.append(loss.item())
115+
optim.zero_grad()
116+
loss.backward()
117+
optim.step()
118+
mean_train_loss = torch.mean(torch.tensor(train_loss))
119+
print("第%d次迭代,平均损失值:%f" % (i, mean_train_loss))
120+
121+
122+
if __name__ == "__main__":
123+
DL()

Diff for: lstm.py

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# coding:utf-8
2+
# lstm神经网络预测股价
3+
4+
5+
import run
6+
import tools
7+
import pandas as pd
8+
import numpy as np
9+
from sklearn.preprocessing import MinMaxScaler
10+
import torch
11+
import torch.nn as nn
12+
from torch.utils.data import DataLoader, Dataset
13+
import matplotlib.pyplot as plt
14+
15+
16+
# 读取数据
17+
def readData(code="sh000300", start="2018-01-01", end="2018-12-31", refresh = False):
18+
# 加载数据
19+
tools.initOutput()
20+
data = tools.loadData(code=code, start=start, end=end, refresh=refresh)
21+
print(data, type(data))
22+
return data
23+
24+
25+
# 数据归一化
26+
def data_pre(data):
27+
dataset = data.astype("double")
28+
max_value = np.max(dataset)
29+
min_value = np.min(dataset)
30+
scalar = max_value - min_value
31+
dataset = list(map(lambda x: x / scalar, dataset))
32+
return dataset
33+
34+
35+
# 创建数据集
36+
def create_dataset(dataset, look_back = 2):
37+
dataX, dataY = [], []
38+
for i in range(len(dataset) - look_back):
39+
a = dataset[i:i+look_back]
40+
dataX.append(a)
41+
dataY.append(dataset[i+look_back])
42+
return np.array(dataX), np.array(dataY)
43+
44+
45+
class LSTM(nn.Module):
46+
def __init__(self, input_size, hidden_size, output_size, num_layer):
47+
super(LSTM, self).__init__()
48+
self.layer1 = nn.LSTM(input_size, hidden_size, num_layer, bias = True, batch_first = False, dropout = 0.1)
49+
self.layer2 = nn.Linear(hidden_size, output_size)
50+
51+
def forward(self, x):
52+
x, _ = self.layer1(x)
53+
s, b1, n = x.size()
54+
x = x.view(s*b1, n)
55+
x = self.layer2(x)
56+
x = x.view(s*b1, -1)
57+
return x
58+
59+
60+
# lstm预测模型
61+
@run.change_dir
62+
def lstm():
63+
# 准备数据
64+
data = readData()
65+
open = data["open"].values
66+
open = open[::-1]
67+
open = data_pre(open)
68+
plt.figure()
69+
plt.plot(open)
70+
plt.savefig("./output/open.png")
71+
index = int(len(open)*0.8)
72+
train = open[:index]
73+
test = open[index:]
74+
# 生成数据集
75+
data_X2, data_Y2 = create_dataset(test)
76+
data_X1, data_Y1 = create_dataset(train)
77+
train_X = data_X1
78+
train_Y = data_Y1
79+
train_X = train_X.reshape(-1, 1, 2)
80+
train_Y = train_Y.reshape(-1, 1, 1)
81+
train_x = torch.from_numpy(train_X).float()
82+
train_y = torch.from_numpy(train_Y).float()
83+
# 模型搭建
84+
model = LSTM(2, 4, 2, 2)
85+
# 损失函数
86+
criterion = nn.MSELoss()
87+
# 优化器
88+
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
89+
# 模型训练
90+
epoches = 1500
91+
plt.figure()
92+
for epoch in range(epoches):
93+
# 前向传播
94+
out = model.forward(train_x)
95+
loss = criterion(out, train_y)
96+
# 反向传播
97+
optimizer.zero_grad()
98+
loss.backward()
99+
optimizer.step()
100+
if epoch % int(epoches/10) == 0:
101+
out1=loss.view(-1).data.numpy()
102+
plt.plot(out1,'r')
103+
plt.plot(train_x.view(-1).data.numpy(), 'b')
104+
print(epoch, loss)
105+
plt.savefig("./output/loss.png")
106+
plt.close()
107+
# 模型测试
108+
test_X = data_X2
109+
test_Y = data_Y2
110+
test_X = test_X.reshape(-1, 1, 2)
111+
test_Y = test_Y.reshape(-1, 1, 1)
112+
test_x = torch.from_numpy(test_X).float()
113+
test_y = torch.from_numpy(test_Y).float()
114+
pred_test = model(test_x)
115+
pred_test = pred_test.view(-1).data.numpy()
116+
plt.figure()
117+
plt.plot(pred_test, 'r', label='prediction')
118+
plt.plot(test_x.view(-1).data.numpy(), 'b', label='real')
119+
plt.legend(loc='best')
120+
plt.savefig("./output/predict.png")
121+
plt.close()
122+
123+
124+
if __name__ == "__main__":
125+
lstm()

Diff for: output/loss.png

10 KB
Loading

Diff for: output/open.png

27.6 KB
Loading

Diff for: output/predict.png

21.3 KB
Loading

Diff for: run.py

+35-15
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,72 @@
77

88

99
# 上传代码至服务器并运行
10-
def run(gpus, server):
10+
def run(gpus, user, server):
1111
# 上传本目录所有文件再执行指定文件
1212
if gpus == "all":
1313
# 清除服务器代码目录里所有源文件以及输出目录中的文件
14-
s = "ssh ubuntu@" + server + " \"sudo rm -rf ~/code/*.py\""
14+
s = "ssh " + user + "@" + server + " \"sudo rm -rf ~/code/*.py\""
15+
# print("测试1", s)
1516
os.system(s)
16-
s = "ssh ubuntu@" + server + " \"sudo rm -rf ~/code/output/*\""
17+
s = "ssh " + user + "@" + server + " \"sudo rm -rf ~/code/output/*\""
18+
# print("测试2", s)
1719
os.system(s)
1820
# 将本地目录所有文件上传至容器
19-
s = "scp -r ./*.py ubuntu@" + server + ":~/code"
21+
s = "scp -r ./*.py " + user + "@" + server + ":~/code"
22+
# print("测试3", s)
2023
os.system(s)
2124
# 运行指定代码
2225
s = "ssh root@" + server + " -p 2222 \"python /home/code/" + sys.argv[2] + "\""
26+
# print("测试4", s)
2327
print("正在运行代码……\n")
2428
os.system(s)
2529
# 将代码目录里所有输出文件传回
26-
s = "scp -r ubuntu@" + server + ":~/code/output/* ./output/"
30+
s = "scp -r " + user +"@" + server + ":~/code/output/* ./output/"
31+
# print("测试5", s)
2732
os.system(s)
2833
# 将所有结果文件传回
2934
elif gpus == "copy":
30-
s = "scp -r ubuntu@" + server + ":~/code/output/* ./output/"
35+
s = "scp -r " + user + "@" + server + ":~/code/output/* ./output/"
3136
os.system(s)
3237
# 上传指定文件并执行
3338
else:
3439
## 清除服务器代码目录里所有源文件以及输出目录中的文件
35-
s = "ssh ubuntu@" + server + " \"sudo rm -rf ~/code/*.py\""
40+
s = "ssh " + user + "@" + server + " \"sudo rm -rf ~/code/*.py\""
3641
os.system(s)
37-
s = "ssh ubuntu@" + server + " \"sudo rm -rf ~/code/output/*\""
42+
s = "ssh " + user + "@" + server + " \"sudo rm -rf ~/code/output/*\""
3843
os.system(s)
3944
# 将本地目录指定文件上传至容器
40-
s = "scp " + sys.argv[1] + " ubuntu@" + server + ":~/code"
45+
s = "scp " + sys.argv[1] + " " + user + "@" + server + ":~/code"
4146
os.system(s)
4247
# 运行指定代码
4348
s = "ssh root@" + server + " -p 2222 \"python /home/code/" + sys.argv[1] + "\""
4449
os.system(s)
4550
# 将代码目录里所有文件传回
46-
s = "scp -r ubuntu@" + server + ":~/code/output/* ./output/"
51+
s = "scp -r " + user +"@" + server + ":~/code/output/* ./output/"
4752
os.system(s)
48-
49-
50-
if __name__ == "__main__":
53+
54+
55+
# 主函数
56+
def main():
5157
gpus = sys.argv[1]
5258
# 读取服务器IP地址,自己编辑serverIP.txt去
5359
with open("serverIP.txt", "rt") as f:
54-
server = f.read()
55-
run(gpus, server)
60+
server_list = f.readlines()
61+
for s in server_list:
62+
s = s.replace('\n', '').replace('\r', '')
63+
# print(s)
64+
if s[0] != "#":
65+
res = s.split("@")
66+
username = res[0]
67+
server = res[1]
68+
# print("测试", username, server)
69+
# input("按任意键继续")
70+
run(gpus, username, server)
71+
return
72+
73+
74+
if __name__ == "__main__":
75+
main()
5676

5777

5878
# 工具函数,在上传到服务器上运行时改变当前目录

Diff for: testpypy.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# coding:utf-8
2+
# 测试pypy
3+
4+
5+
import run
6+
7+
8+
@run.timethis
9+
def testPypy():
10+
number = 0
11+
for i in range(100000000):
12+
number += i
13+
14+
print("完成")
15+
16+
17+
if __name__ == "__main__":
18+
testPypy()
19+

0 commit comments

Comments
 (0)