PyTorch搭建ANN實(shí)現(xiàn)時(shí)間序列風(fēng)速預(yù)測(cè)
數(shù)據(jù)集
數(shù)據(jù)集為Barcelona某段時(shí)間內(nèi)的氣象數(shù)據(jù),其中包括溫度、濕度以及風(fēng)速等。本文將簡單搭建來對(duì)風(fēng)速進(jìn)行預(yù)測(cè)。
特征構(gòu)造
對(duì)于風(fēng)速的預(yù)測(cè),除了考慮歷史風(fēng)速數(shù)據(jù)外,還應(yīng)該充分考慮其余氣象因素的影響。因此,我們根據(jù)前24個(gè)時(shí)刻的風(fēng)速+下一時(shí)刻的其余氣象數(shù)據(jù)來預(yù)測(cè)下一時(shí)刻的風(fēng)速。
數(shù)據(jù)處理
1.數(shù)據(jù)預(yù)處理
數(shù)據(jù)預(yù)處理階段,主要將某些列上的文本數(shù)據(jù)轉(zhuǎn)為數(shù)值型數(shù)據(jù),同時(shí)對(duì)原始數(shù)據(jù)進(jìn)行歸一化處理。文本數(shù)據(jù)如下所示:
經(jīng)過轉(zhuǎn)換后,上述各個(gè)類別分別被賦予不同的數(shù)值,比如"sky is clear"為0,"few clouds"為1。
def load_data(): global Max, Min df = pd.read_csv('Barcelona/Barcelona.csv') df.drop_duplicates(subset=[df.columns[0]], inplace=True) # weather_main listType = df['weather_main'].unique() df.fillna(method='ffill', inplace=True) dic = dict.fromkeys(listType) for i in range(len(listType)): dic[listType[i]] = i df['weather_main'] = df['weather_main'].map(dic) # weather_description listType = df['weather_description'].unique() dic = dict.fromkeys(listType) for i in range(len(listType)): dic[listType[i]] = i df['weather_description'] = df['weather_description'].map(dic) # weather_icon listType = df['weather_icon'].unique() dic = dict.fromkeys(listType) for i in range(len(listType)): dic[listType[i]] = i df['weather_icon'] = df['weather_icon'].map(dic) # print(df) columns = df.columns Max = np.max(df['wind_speed']) # 歸一化 Min = np.min(df['wind_speed']) for i in range(2, 17): column = columns[i] if column == 'wind_speed': continue df[column] = df[column].astype('float64') if len(df[df[column] == 0]) == len(df): # 全0 continue mx = np.max(df[column]) mn = np.min(df[column]) df[column] = (df[column] - mn) / (mx - mn) # print(df.isna().sum()) return df
2.數(shù)據(jù)集構(gòu)造
利用當(dāng)前時(shí)刻的氣象數(shù)據(jù)和前24個(gè)小時(shí)的風(fēng)速數(shù)據(jù)來預(yù)測(cè)當(dāng)前時(shí)刻的風(fēng)速:
def nn_seq(): """ :param flag: :param data: 待處理的數(shù)據(jù) :return: X和Y兩個(gè)數(shù)據(jù)集,X=[當(dāng)前時(shí)刻的year,month, hour, day, lowtemp, hightemp, 前一天當(dāng)前時(shí)刻的負(fù)荷以及前23小時(shí)負(fù)荷] Y=[當(dāng)前時(shí)刻負(fù)荷] """ print('處理數(shù)據(jù):') data = load_data() speed = data['wind_speed'] speed = speed.tolist() speed = torch.FloatTensor(speed).view(-1) data = data.values.tolist() seq = [] for i in range(len(data) - 30): train_seq = [] train_label = [] for j in range(i, i + 24): train_seq.append(speed[j]) # 添加溫度、濕度、氣壓等信息 for c in range(2, 7): train_seq.append(data[i + 24][c]) for c in range(8, 17): train_seq.append(data[i + 24][c]) train_label.append(speed[i + 24]) train_seq = torch.FloatTensor(train_seq).view(-1) train_label = torch.FloatTensor(train_label).view(-1) seq.append((train_seq, train_label)) # print(seq[:5]) Dtr = seq[0:int(len(seq) * 0.5)] Den = seq[int(len(seq) * 0.50):int(len(seq) * 0.75)] Dte = seq[int(len(seq) * 0.75):len(seq)] return Dtr, Den, Dte
任意輸出其中一條數(shù)據(jù):
(tensor([1.0000e+00, 1.0000e+00, 2.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 0.0000e+00, 1.0000e+00, 5.0000e+00, 0.0000e+00, 2.0000e+00, 0.0000e+00, 0.0000e+00, 5.0000e+00, 0.0000e+00, 2.0000e+00, 2.0000e+00, 5.0000e+00, 6.0000e+00, 5.0000e+00, 5.0000e+00, 5.0000e+00, 5.3102e-01, 5.5466e-01, 4.6885e-01, 1.0066e-03, 5.8000e-01, 6.6667e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 9.9338e-01, 0.0000e+00, 0.0000e+00, 0.0000e+00]), tensor([5.]))
數(shù)據(jù)被劃分為三部分:Dtr、Den以及Dte,Dtr用作訓(xùn)練集,Dte用作測(cè)試集。
ANN模型
1.模型訓(xùn)練
ANN模型搭建如下:
def ANN(): Dtr, Den, Dte = nn_seq() my_nn = torch.nn.Sequential( torch.nn.Linear(38, 64), torch.nn.ReLU(), torch.nn.Linear(64, 128), torch.nn.ReLU(), torch.nn.Linear(128, 1), ) model = my_nn.to(device) loss_function = nn.MSELoss().to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.001) train_inout_seq = Dtr # 訓(xùn)練 epochs = 50 for i in range(epochs): print('當(dāng)前', i) for seq, labels in train_inout_seq: seq = seq.to(device) labels = labels.to(device) y_pred = model(seq) single_loss = loss_function(y_pred, labels) optimizer.zero_grad() single_loss.backward() optimizer.step() # if i % 2 == 1: print(f'epoch: {i:3} loss: {single_loss.item():10.8f}') print(f'epoch: {i:3} loss: {single_loss.item():10.10f}') state = {'model': model.state_dict(), 'optimizer': optimizer.state_dict(), 'epoch': epochs} torch.save(state, 'Barcelona' + ANN_PATH)
可以看到,模型定義的代碼段為:
my_nn = torch.nn.Sequential( torch.nn.Linear(38, 64), torch.nn.ReLU(), torch.nn.Linear(64, 128), torch.nn.ReLU(), torch.nn.Linear(128, 1), )
第一層全連接層輸入維度為38(前24小時(shí)風(fēng)速+14種氣象數(shù)據(jù)),輸出維度為64;第二層輸入為64,輸出128;第三層輸入為128,輸出為1。
2.模型預(yù)測(cè)及表現(xiàn)
def ANN_predict(ann, test_seq): pred = [] for seq, labels in test_seq: seq = seq.to(device) with torch.no_grad(): pred.append(ann(seq).item()) pred = np.array([pred]) return pred
測(cè)試:
def test(): Dtr, Den, Dte = nn_seq() ann = torch.nn.Sequential( torch.nn.Linear(38, 64), torch.nn.ReLU(), torch.nn.Linear(64, 128), torch.nn.ReLU(), torch.nn.Linear(128, 1), ) ann = ann.to(device) ann.load_state_dict(torch.load('Barcelona' + ANN_PATH)['model']) ann.eval() pred = ANN_predict(ann, Dte) print(mean_absolute_error(te_y, pred2.T), np.sqrt(mean_squared_error(te_y, pred2.T)))
ANN在Dte上的表現(xiàn)如下表所示:
MAE | RMSE |
---|---|
1.04 | 1.46 |
以上就是PyTorch搭建ANN實(shí)現(xiàn)時(shí)間序列風(fēng)速預(yù)測(cè)的詳細(xì)內(nèi)容,更多關(guān)于ANN時(shí)序風(fēng)速預(yù)測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pytorch之Tensor和Numpy之間的轉(zhuǎn)換的實(shí)現(xiàn)方法
這篇文章主要介紹了Pytorch之Tensor和Numpy之間的轉(zhuǎn)換的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Python面向?qū)ο笕筇卣?封裝、繼承、多態(tài)
這篇文章主要介紹了Python面向?qū)ο笕筇卣?封裝、繼承、多態(tài),下面文章圍繞Python面向?qū)ο笕筇卣鞯南嚓P(guān)資料展開具體內(nèi)容,需要的朋友可以參考一下,希望對(duì)大家有所幫助2021-11-11Python+PyQt5實(shí)現(xiàn)自動(dòng)點(diǎn)擊神器
這篇文章主要為大家詳細(xì)介紹了如何利用Python和PyQt5實(shí)現(xiàn)自動(dòng)點(diǎn)擊神器,旨在解決重復(fù)性的點(diǎn)擊工作,解放雙手,具有及時(shí)性和準(zhǔn)確性,需要的可以參考下2024-01-01