1
2
3
4
5
6
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import datetime
%matplotlib inline
1
data = pd.read_csv("./all_sales_details.csv")
C:\Users\X\AppData\Local\Temp\ipykernel_7016\2215346632.py:1: DtypeWarning: Columns (15) have mixed types. Specify dtype option on import or set low_memory=False.
  data = pd.read_csv("./all_sales_details.csv")
1
2
data.columns = ['创建日期', '物料编号', '物料描述', 'K3编号', '产品组', '客户物料号', '销售组织',
'交货单号', ' 是否拣配','交货单创建者', '交货单修改者', '交货单行项目', '销售大区', '销售小区', '发运渠道', '客户代码', '应发库','采购订单编号', '销售订单号', '销售订单创建者', '订单类型', '销售订单行项目', '销售订单数量', '交货数量','单位', '币别']
1
data.sample(3)

创建日期 物料编号 物料描述 K3编号 产品组 客户物料号 销售组织 交货单号 是否拣配 交货单创建者 ... 应发库 采购订单编号 销售订单号 销售订单创建者 订单类型 销售订单行项目 销售订单数量 交货数量 单位 币别
82268 2014.05.07 10635292-00 S6-3106010C_子午线轮胎_M00000 27.03.0500S6007S 公共产品线 S603 X990 82512190 完全拣配 QCXSSD011 ... 深圳 PJFH-20140507397226 11636874.0 QCXSSD011 ZPJ1 6.0 1.0 1.0 PCS RMB
141046 2014.11.12 10278322-00 发动机油_SG_10W-30_3.0L/桶 20.07.0100F0001 公共产品线 F007 X990 82755455 完全拣配 QCXSSD011 ... 上海 PJFH-20141112711166 11811363.0 QCXSSD011 ZPJ1 26.0 60.0 60.0 桶 RMB
120586 2014.09.15 10933037-00 6DT25-1723010C_电液控制模块总成-速锐车型 30.04.01005A002S 公共产品线 5A04 X990 82679316 完全拣配 QCXSMM022 ... 西安 PJFH-20140915273315 11755155.0 QCXSSD011 ZPJ1 1.0 1.0 1.0 PCS RMB

3 rows × 26 columns

1
len(data),data.describe(),data.info(),data.isnull().sum(),np.unique(data["应发库"].map(str)),np.unique(data["物料描述"].map(str)),np.unique(data["销售订单数量"].map(str)),np.unique(data["交货数量"].map(str))
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 423214 entries, 0 to 423213
Data columns (total 26 columns):
 #   Column   Non-Null Count   Dtype  
---  ------   --------------   -----  
 0   创建日期     423213 non-null  object 
 1   物料编号     423213 non-null  object 
 2   物料描述     423213 non-null  object 
 3   K3编号     423213 non-null  object 
 4   产品组      421754 non-null  object 
 5   客户物料号    422143 non-null  object 
 6   销售组织     423213 non-null  object 
 7   交货单号     423213 non-null  object 
 8    是否拣配    423037 non-null  object 
 9   交货单创建者   423041 non-null  object 
 10  交货单修改者   422965 non-null  object 
 11  交货单行项目   423213 non-null  object 
 12  销售大区     422870 non-null  object 
 13  销售小区     422870 non-null  object 
 14  发运渠道     423041 non-null  object 
 15  客户代码     423213 non-null  object 
 16  应发库      423213 non-null  object 
 17  采购订单编号   423213 non-null  object 
 18  销售订单号    423213 non-null  float64
 19  销售订单创建者  423213 non-null  object 
 20  订单类型     423213 non-null  object 
 21  销售订单行项目  423213 non-null  float64
 22  销售订单数量   423213 non-null  float64
 23  交货数量     423213 non-null  float64
 24  单位       423213 non-null  object 
 25  币别       423213 non-null  object 
dtypes: float64(4), object(22)
memory usage: 84.0+ MB





(423214,
               销售订单号        销售订单行项目         销售订单数量           交货数量
 count  4.232130e+05  423213.000000  423213.000000  423213.000000
 mean   1.197899e+07      83.072855      15.328537      15.044727
 std    3.379266e+05     201.739849      24.883478      24.769943
 min    1.132657e+07       1.000000       1.000000       0.000000
 25%    1.171263e+07       6.000000       2.000000       2.000000
 50%    1.199496e+07      18.000000       6.000000       6.000000
 75%    1.225793e+07      69.000000      20.000000      20.000000
 max    2.006676e+07    4680.000000    1500.000000    1500.000000,
 None,
 创建日期          1
 物料编号          1
 物料描述          1
 K3编号          1
 产品组        1460
 客户物料号      1071
 销售组织          1
 交货单号          1
  是否拣配       177
 交货单创建者      173
 交货单修改者      249
 交货单行项目        1
 销售大区        344
 销售小区        344
 发运渠道        173
 客户代码          1
 应发库           1
 采购订单编号        1
 销售订单号         1
 销售订单创建者       1
 订单类型          1
 销售订单行项目       1
 销售订单数量        1
 交货数量          1
 单位            1
 币别            1
 dtype: int64,
 array(['nan', '上海', '北京', '成都', '昆明', '沈阳', '济南', '深圳', '西安', '长沙', '零售'],
       dtype=object),
 array(['476ZQA-1017100_机油滤清器_M00000', '476ZQA-3707100_火花塞_M00000',
        '483QA-1017010_机油滤清器_M00000', '483QA-1306200_调温器组件_M00666',
        '483QA-3707100_火花塞_M00000', '487ZQA-1017100_机油滤清器_M00000',
        '5A-3722400A_仪表板配电盒壳体总成_M00666', '5B-3791200_电子智能钥匙_M00666',
        '5T19-4113010_倒车灯开关组件_M00000', '6A-3746500_左前门玻璃升降器开关_M00666',
        '6A-3791211/92_电子钥匙上盖-带锁扣_M00666',
        '6A-3791212/70_电子钥匙下盖-5分光UV处理_M', '6A-3791217_电池座_M00000',
        '6AK-3722020_前舱配电盒总成_M00666', '6B-3722020_前舱配电盒总成_M00666',
        '6DT25-1600010_干式双离合器总成_M00666', '6DT25-1723010C_电液控制模块总成-速锐车型',
        '6DT25-1723010D_电液控制模块总成-思锐3B_M',
        '6DT25-1723010F_电液控制模块总成-F3-L3-G3',
        '6DT35-1723010_电液控制模块总成_M00666', '6DT35-4B-1700010_变速器总成_M00666',
        '6HDT35-3-1702010_变速器分总成_M00666', 'BYDQ304A12T13F13_车轮螺母',
        'BYDQ831A1106_子母扣_M00000', 'BYDQ837B4802_塑料卡座_M00666',
        'CQ02_气门嘴总成_含帽盖', 'EG-3703010_蓄电池_M00000',
        'EG-3703010_蓄电池总成_M00000', 'EG-4134200_制动灯开关总成_M00000',
        'EG-6109100_左前门限位器_M00000', 'F3-3791201/92_钥匙上盖-带锁扣_M00666',
        'F3-3791207-B2_电池座_M00000', 'F3-4116113B_灯泡-H3-12v-55w_M00000',
        'F3-8106100_膨胀阀_M00000', 'F3M-1117100_燃油滤清器总成_M00000',
        'G3-3791400_卡式智能钥匙_M00666', 'LK-1104116-C2_加油软管_M00666',
        'LK-1104118-C2_加油通气软管_M00666', 'LK-4116200A_右前雾灯_M00666',
        'M6-1109302_空滤器滤芯_M00666', 'M6-3722020A_前舱配电盒总成_M00666',
        'M6-3722020B_前舱配电盒总成_M00666', 'S6-2803711_前保险杠_M00666',
        'S6-2803711_前保险杠本体_M00666', 'S6-2803715A_牌照座板_M00666',
        'S6-2803715_牌照座板_M00666', 'S6-2905600_右前减阻尼器总成_M00666',
        'S6-2906314_前横向稳定杆压板衬套_M00000', 'S6-2906314_前稳定杆衬套_M00000',
        'S6-2916314_后横向稳定杆压板衬套_M00000', 'S6-2916314_后稳定杆衬套_M00000',
        'S6-3106010C_子午线轮胎_M00000', 'S6-3642200_高频接收模块_M00666',
        'S6-3746500_左前门玻璃升降器开关_M00666', 'S6-4121020B_右组合前灯总成_M00666',
        'S6-5206010B_前风挡玻璃总成_M00000', 'S6-5206010_前风挡玻璃总成_M00000',
        'S6-5206010_前风窗玻璃总成_M00000', 'S6-5401010/70_左侧围总成-电泳_M00666',
        'S6-5401010/77_左侧围总成_M00666', 'S6-7911200E_前门扬声器总成_M00666',
        'S6DM-2203020A_右前传动半轴总成_M00666', 'S6DM-2803111B/00_前保险杠本体_M00666',
        'S6DM-2803114/71_前保险杠右装饰条_M00000', 'S6DM-2803151_前保险杠下进气网格_M00666',
        'S6DM-2803215_安装卡扣_M00000', 'S6DM-3102120_右前轮挡泥板总成_M00666',
        'SA-3774100_支架分总成_M00666', 'SA-3776500_全景影像控制器_M00666',
        'SE-1303530_中冷器进气软管Ⅱ总成_M00000', 'SE-2803111A_前保险杠本体-高配_M00666',
        'SE-2804181_后保险杠下护板_M00666', 'SE-3722010_仪表板配电盒总成_M00666',
        'SE-3722020_前舱配电盒总成_M00666', 'SE-4011200_前横梁线束_M00666',
        'SE-4121010-C1_左组合前灯总成_M00666', 'SE-4121020-C1_右组合前灯总成_M00666',
        'SE-5302320_散热器右导流板总成_M00666', 'SMD136466V_机油滤清器组件',
        'SMD198128G_油封', 'SMN158596_火花塞组件', 'SMW250976_发电机组件', 'nan',
        '专机配件_胎压监测模块传感器配件包_T451B-', '冷媒_R134A_250g/瓶',
        '发动机油_A3/B4-SN-5W-40-BJ_1L/桶', '发动机油_A3/B4-SN-5W-40-BJ_4L/桶',
        '发动机油_SG_10W-30_3.0L/桶', '发动机油_SJ-10W-30-BJ_1L/桶',
        '发动机油_SJ_10W-30_3.3L/桶', '发动机油_SJ_5W-30_3.8L/桶',
        '发动机油_SN-5W-40-BJ_1L/桶', '发动机油_SN-5W-40-BJ_4L/桶',
        '汽油清净剂_G17_180ml/瓶', '索赔件包装箱贴_13×10cm_红色', '纽扣电池_CR1632',
        '纽扣电池_CR2025', '自动变速箱油_ATF DiaQueen _SPⅢ_4L/桶',
        '铁电池组_HA-135A_FV20×18S', '铁电池组_HA-24A_FV20×16S',
        '铁电池组_HA-79A_FV20×14S', '铁电池组_HA79_C20×14S',
        '防冻液_冰点-25℃_3.5L/桶_BYD', '防冻液_冰点-25℃_有机酸_1.5L/桶',
        '防冻液_冰点-25℃_有机酸_3.5L/桶', '防冻液_冰点-40℃_1.5L/桶',
        '防冻液_冰点-40℃_3.5L/桶_BYD', '防冻液_冰点-40℃_有机酸_1.5L/桶', '齿轮油_FFL-2_1L/桶'],
       dtype=object),
 array(['1.0', '10.0', '100.0', '1000.0', '102.0', '108.0', '109.0',
        '11.0', '110.0', '112.0', '114.0', '12.0', '120.0', '124.0',
        '125.0', '126.0', '13.0', '130.0', '132.0', '138.0', '14.0',
        '140.0', '141.0', '144.0', '145.0', '15.0', '150.0', '1500.0',
        '151.0', '156.0', '16.0', '160.0', '162.0', '168.0', '17.0',
        '170.0', '174.0', '175.0', '18.0', '180.0', '186.0', '19.0',
        '190.0', '192.0', '194.0', '195.0', '198.0', '2.0', '20.0',
        '200.0', '204.0', '205.0', '206.0', '21.0', '210.0', '214.0',
        '216.0', '22.0', '220.0', '228.0', '23.0', '230.0', '234.0',
        '24.0', '240.0', '25.0', '250.0', '252.0', '258.0', '26.0',
        '264.0', '27.0', '270.0', '276.0', '28.0', '280.0', '288.0',
        '29.0', '290.0', '3.0', '30.0', '300.0', '305.0', '31.0', '32.0',
        '324.0', '33.0', '330.0', '336.0', '34.0', '348.0', '35.0',
        '350.0', '36.0', '360.0', '37.0', '370.0', '38.0', '39.0', '390.0',
        '4.0', '40.0', '400.0', '41.0', '42.0', '420.0', '43.0', '432.0',
        '44.0', '440.0', '45.0', '450.0', '46.0', '47.0', '474.0', '48.0',
        '480.0', '49.0', '494.0', '5.0', '50.0', '500.0', '51.0', '52.0',
        '53.0', '534.0', '54.0', '55.0', '56.0', '570.0', '58.0', '6.0',
        '60.0', '600.0', '62.0', '624.0', '64.0', '65.0', '650.0', '66.0',
        '660.0', '68.0', '69.0', '7.0', '70.0', '700.0', '71.0', '72.0',
        '720.0', '75.0', '750.0', '76.0', '78.0', '79.0', '8.0', '80.0',
        '800.0', '81.0', '82.0', '84.0', '85.0', '86.0', '88.0', '9.0',
        '90.0', '900.0', '91.0', '92.0', '93.0', '94.0', '95.0', '96.0',
        '97.0', '98.0', '99.0', 'nan'], dtype=object),
 array(['0.0', '1.0', '10.0', '100.0', '1000.0', '102.0', '108.0', '109.0',
        '11.0', '110.0', '112.0', '114.0', '12.0', '120.0', '124.0',
        '125.0', '126.0', '13.0', '130.0', '132.0', '138.0', '14.0',
        '140.0', '141.0', '144.0', '145.0', '15.0', '150.0', '1500.0',
        '151.0', '156.0', '16.0', '160.0', '162.0', '168.0', '17.0',
        '170.0', '174.0', '175.0', '18.0', '180.0', '186.0', '19.0',
        '190.0', '192.0', '194.0', '195.0', '198.0', '2.0', '20.0',
        '200.0', '204.0', '205.0', '206.0', '21.0', '210.0', '214.0',
        '216.0', '22.0', '220.0', '228.0', '23.0', '230.0', '234.0',
        '24.0', '240.0', '25.0', '250.0', '252.0', '258.0', '26.0',
        '264.0', '27.0', '270.0', '276.0', '28.0', '280.0', '288.0',
        '29.0', '290.0', '3.0', '30.0', '300.0', '305.0', '31.0', '32.0',
        '324.0', '33.0', '330.0', '336.0', '34.0', '348.0', '35.0',
        '350.0', '36.0', '360.0', '37.0', '370.0', '38.0', '39.0', '390.0',
        '4.0', '40.0', '400.0', '41.0', '42.0', '420.0', '43.0', '432.0',
        '44.0', '440.0', '45.0', '450.0', '46.0', '47.0', '474.0', '48.0',
        '480.0', '49.0', '494.0', '5.0', '50.0', '500.0', '51.0', '52.0',
        '53.0', '534.0', '54.0', '55.0', '56.0', '57.0', '570.0', '58.0',
        '59.0', '6.0', '60.0', '600.0', '61.0', '62.0', '624.0', '63.0',
        '64.0', '65.0', '650.0', '66.0', '660.0', '68.0', '69.0', '7.0',
        '70.0', '700.0', '71.0', '72.0', '720.0', '75.0', '750.0', '76.0',
        '78.0', '79.0', '8.0', '80.0', '800.0', '81.0', '82.0', '84.0',
        '85.0', '86.0', '87.0', '88.0', '89.0', '9.0', '90.0', '900.0',
        '92.0', '93.0', '94.0', '95.0', '96.0', '97.0', '98.0', 'nan'],
       dtype=object))
1
2
3
4
5
6
7
8
9
10
data = data.loc[:,['创建日期','应发库','销售订单数量','交货数量']]
data['应发库']=data['应发库'].map({'深圳':'sz','济南':'jn','长沙':'cs','西安':'xa','昆明':'km','北京':'bj','成都':'cd','沈阳':'sy','上海':'sh'})
data['应发库']=pd.factorize(data['应发库'])[0]
data.columns = ['create_date', 'wraehouse', 'order_num', 'delivery_num']
# 数据清洗
data.dropna(how='any',inplace=True)
data['year']=data['create_date'].str.split('.').str[0]
data['month']=data['create_date'].str.split('.').str[1]
data['day']=data['create_date'].str.split('.').str[2]
data = data.groupby(by=['year','month','day','wraehouse'])[['order_num','delivery_num']].sum().reset_index()
1
data.head()

year month day wraehouse order_num delivery_num
0 2013 05 30 0 1898.0 1898.0
1 2013 05 30 1 1573.0 1573.0
2 2013 05 30 2 968.0 968.0
3 2013 05 30 3 1254.0 1254.0
4 2013 05 30 4 122.0 122.0

x=[f’{yyyy:4}-{mm:02}’for (yyyy,mm)in y.index]

y=data_df.groupby(by=[‘year’,’month’])[[‘order_num’,’delivery_num’]].sum()

df = df.groupby(by=[‘year’,’month’,’day’,’wraehouse’])[[‘order_num’,’delivery_num’]].sum().reset_index()

1
data['order_num'].plot(

​ output_10_1

​

1
data['delivery_num'].plot(color='r')

​ output_11_1

1
2
seq_length = 12     #定义观察前面多久的值
delay = 12 #预测时间
1
2
3
data_ = []
for i in range(len(data)-seq_length-delay):
data_.append(data.iloc[i:i+seq_length+delay]
1
data = np.array([df_.values for df_ in data_],dtype="float32")
1
2
3
np.random.shuffle(data)
y = data[:,0,4:]
y = data[:,0,4:]
1
2
data.shape
(8772, 24, 6)
1
y
1
2
3
4
5
6
7
array([[1898., 1898.],
[1573., 1573.],
[ 968., 968.],
...,
[ 497., 497.],
[ 792., 792.],
[ 985., 985.]], dtype=float32)
1
x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
array([[[2.013e+03, 5.000e+00, 3.000e+01, 0.000e+00, 1.898e+03,
1.898e+03],
[2.013e+03, 5.000e+00, 3.000e+01, 1.000e+00, 1.573e+03,
1.573e+03],
[2.013e+03, 5.000e+00, 3.000e+01, 2.000e+00, 9.680e+02,
9.680e+02],
...,
[[2.016e+03, 5.000e+00, 2.700e+01, 6.000e+00, 9.850e+02,
9.850e+02],
[2.016e+03, 5.000e+00, 2.700e+01, 7.000e+00, 4.590e+02,
4.590e+02],
[2.016e+03, 5.000e+00, 2.700e+01, 8.000e+00, 2.414e+03,
2.414e+03],
...,
[2.016e+03, 5.000e+00, 2.800e+01, 8.000e+00, 1.200e+01,
1.200e+01],
[2.016e+03, 5.000e+00, 2.900e+01, 1.000e+00, 1.000e+00,
1.000e+00],
[2.016e+03, 5.000e+00, 2.900e+01, 2.000e+00, 3.000e+00,
3.000e+00]]], dtype=float32)
x.shape,y.shape
((8772, 12, 6), (8772, 2))
1
2
3
4
5
6
split_b = int(data.shape[0]*0.8)

train_x = x[:split_b]
train_y = y[:split_b]
test_x = x[split_b:]
test_y = y[split_b:]
1
2
3
4
mean = train_x.mean(axis=0)#计算每一列的均值
std = train_x.std(axis=0)#计算方差
np.save(file='mean.npy',arr=mean)
np.save(file='std.npy',arr=std)
1
2
train_x = (train_x - mean)/std#标准化减均值除方差
test_x = (test_x - mean)/std#标准化减均值除方差
1
train_x.shape,train_y.shape
((7017, 12, 6), (7017, 2))
1
test_x.shape,test_y.shape
((1755, 12, 6), (1755, 2))
1
2
3
4
5
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from math import sqrt
1
device ='cuda' if torch.cuda.is_available() else 'cpu'
1
torch.cuda.is_available()
True
1
2
3
4
5
6
7
8
9
10
11
# 自定义数据集类
class MyDataset(Dataset):
def __init__(self, x, y):
self.x = torch.tensor(x, dtype=torch.float32).to(device)
self.y = torch.tensor(y, dtype=torch.float32).to(device)

def __len__(self):
return len(self.x)

def __getitem__(self, idx):
return self.x[idx], self.y[idx]
1
2
3
4
5
6
7
8
# 创建数据集实例
train_dataset = MyDataset(train_x, train_y)
test_dataset = MyDataset(test_x, test_y)

# 创建数据加载器
BATCH_SIZE = 32
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class LSTMModel(nn.Module):
def __init__(self):
super(LSTMModel, self).__init__()
self.lstm1 = nn.LSTM(6, 32, batch_first=True)
self.lstm2 = nn.LSTM(32, 32, batch_first=True)
self.lstm3 = nn.LSTM(32, 32, batch_first=True)
self.lstm4 = nn.LSTM(32, 32, batch_first=True)
self.dense = nn.Linear(32, 1)

def forward(self, x):
x, _ = self.lstm1(x)
x, _ = self.lstm2(x)
x, _ = self.lstm3(x)
x, _ = self.lstm4(x)
x = self.dense(x[:, -1, :])
return x

定义模型

class LSTMModel(nn.Module):
def init(self):
super(LSTMModel, self).init()
self.lstm1 = nn.LSTM(6, 32, batch_first=True, return_sequences=True)
self.lstm2 = nn.LSTM(32, 32, batch_first=True, return_sequences=True)
self.lstm3 = nn.LSTM(32, 32, batch_first=True, return_sequences=True)
self.lstm4 = nn.LSTM(32, 32, batch_first=True)
self.dense = nn.Linear(32, 1)

def forward(self, x):
    x, _ = self.lstm1(x)
    x, _ = self.lstm2(x)
    x, _ = self.lstm3(x)
    x, _ = self.lstm4(x[:, -1, :].unsqueeze(1))
    x = self.dense(x.squeeze(1))
    return x
1
2
3
4
5
6
7
# 定义计算R方的函数
def r_squared(y_true, y_pred):
y_mean = torch.mean(y_true)
ss_total = torch.sum((y_true - y_mean) ** 2)
ss_residual = torch.sum((y_true - y_pred) ** 2)
r2 = 1 - (ss_residual / ss_total)
return r2.item()
1
2
3
4
# 定义计算RMSE的函数
def rmse(y_true, y_pred):
mse = nn.MSELoss()
return sqrt(mse(y_true, y_pred).item())
1
2
3
4
5
6
7
8
9
# 创建模型实例
model = LSTMModel().to(device)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters())

# 定义学习率调度器
lr_scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=3, min_lr=0.000001)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
train_r2_values = []
train_rmse_values = []
test_r2_values = []
test_rmse_values = []
# 训练模型
for epoch in range(2000):
train_loss = 0.0
train_r2 = 0.0
train_rmse = 0.0
model.train() # 设置模型为训练模式
for inputs, targets in train_loader:
optimizer.zero_grad() # 梯度清零

# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)

# 反向传播和优化
loss.backward()
optimizer.step()

train_loss += loss.item() * inputs.size(0)
train_r2 += r_squared(targets, outputs) * inputs.size(0)
train_rmse += rmse(targets, outputs) * inputs.size(0)

train_loss /= len(train_dataset)
train_r2 /= len(train_dataset)
train_rmse /= len(train_dataset)

# 在验证集上评估模型
test_loss = 0.0
test_r2 = 0.0
test_rmse = 0.0
model.eval() # 设置模型为评估模式
with torch.no_grad():
for inputs, targets in test_loader:
outputs = model(inputs)
loss = criterion(outputs, targets)
test_loss += loss.item() * inputs.size(0)
test_r2 += r_squared(targets, outputs) * inputs.size(0)
test_rmse += rmse(targets, outputs) * inputs.size(0)

test_loss /= len(test_dataset)
test_r2 /= len(test_dataset)
test_rmse /= len(test_dataset)

# 更新学习率
lr_scheduler.step(test_loss)
# 记录R方和RMSE值
train_r2_values.append(train_r2)
train_rmse_values.append(train_rmse)
test_r2_values.append(test_r2)
test_rmse_values.append(test_rmse)
# 打印训练和验证集上的损失、R方和RMSE
print(f"Epoch {epoch+1}/{2000}, Train Loss: {train_loss:.4f}, Train R2: {train_r2:.4f}, Train RMSE: {train_rmse:.4f}, Test Loss: {test_loss:.4f}, Test R2: {test_r2:.4f}, Test RMSE: {test_rmse:.4f}")

Epoch 1/2000, Train Loss: 1173204.1329, Train R2: -0.7116, Train RMSE: 1048.4773, Test Loss: 2426936.2315, Test R2: -0.8798, Test RMSE: 1463.3235
Epoch 2/2000, Train Loss: 1162037.2223, Train R2: -0.6890, Train RMSE: 1042.3293, Test Loss: 2412321.1203, Test R2: -0.8649, Test RMSE: 1458.4004
Epoch 3/2000, Train Loss: 1152575.2023, Train R2: -0.6884, Train RMSE: 1036.6379, Test Loss: 2398310.5292, Test R2: -0.8507, Test RMSE: 1453.6733
Epoch 4/2000, Train Loss: 1143438.9900, Train R2: -0.6567, Train RMSE: 1038.5152, Test Loss: 2384640.7328, Test R2: -0.8371, Test RMSE: 1449.0545
..........
Epoch 1994/2000, Train Loss: 5958.8076, Train R2: 0.9960, Train RMSE: 37.4799, Test Loss: 31473.0775, Test R2: 0.9912, Test RMSE: 73.3626
Epoch 1995/2000, Train Loss: 5958.8074, Train R2: 0.9963, Train RMSE: 37.4431, Test Loss: 31473.1087, Test R2: 0.9912, Test RMSE: 73.3597
Epoch 1996/2000, Train Loss: 5958.8073, Train R2: 0.9963, Train RMSE: 36.7089, Test Loss: 31473.2759, Test R2: 0.9912, Test RMSE: 73.3661
Epoch 1997/2000, Train Loss: 5958.8070, Train R2: 0.9962, Train RMSE: 37.2948, Test Loss: 31473.4922, Test R2: 0.9912, Test RMSE: 73.3695
Epoch 1998/2000, Train Loss: 5958.8066, Train R2: 0.9963, Train RMSE: 37.1331, Test Loss: 31473.3315, Test R2: 0.9912, Test RMSE: 73.3651
Epoch 1999/2000, Train Loss: 5958.8067, Train R2: 0.9969, Train RMSE: 35.2002, Test Loss: 31473.6264, Test R2: 0.9912, Test RMSE: 73.3704
Epoch 2000/2000, Train Loss: 5958.8060, Train R2: 0.9961, Train RMSE: 37.3191, Test Loss: 31473.9803, Test R2: 0.9912, Test RMSE: 73.3778
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 绘制R方和RMSE的变化曲线
plt.figure(figsize=(10, 5))
epochs = range(1, 2001)

# 绘制训练集上的R方曲线
plt.subplot(1, 2, 1)
plt.plot(epochs, train_r2_values, label='Train R2')
plt.xlabel('Epochs')
plt.ylabel('R2')
plt.title('Train R2 over Epochs')
plt.legend()

# 绘制验证集上的R方曲线
plt.subplot(1, 2, 2)
plt.plot(epochs, test_r2_values, label='Test R2')
plt.xlabel('Epochs')
plt.ylabel('R2')
plt.title('Test R2 over Epochs')
plt.legend()

plt.tight_layout()
plt.show()

# 绘制训练集上的RMSE曲线
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(epochs, train_rmse_values, label='Train RMSE')
plt.xlabel('Epochs')
plt.ylabel('RMSE')
plt.title('Train RMSE over Epochs')
plt.legend()

# 绘制验证集上的RMSE曲线
plt.subplot(1, 2, 2)
plt.plot(epochs, test_rmse_values, label='Test RMSE')
plt.xlabel('Epochs')
plt.ylabel('RMSE')
plt.title('Test RMSE over Epochs')
plt.legend()

plt.tight_layout()
plt.show()

output_42_0
output_42_1

1
2
# 保存模型
torch.save(model.state_dict(), 'model.pth')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 加载模型
model = LSTMModel()
model.load_state_dict(torch.load('model.pth'))
model.eval()

# 准备输入数据
input_data = torch.tensor([[0.1, 0.2, 0.3]]) # 示例输入数据,需要根据实际情况进行调整

# 进行预测
with torch.no_grad():
output = model(input_data)

# 输出预测结果
print(output)