欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python使用LSTM實(shí)現(xiàn)銷售額預(yù)測詳解

 更新時(shí)間:2022年07月01日 15:42:14   作者:可以叫我才哥  
大家經(jīng)常會遇到一些需要預(yù)測的場景,比如預(yù)測品牌銷售額,預(yù)測產(chǎn)品銷量。本文給大家分享一波使用?LSTM?進(jìn)行端到端時(shí)間序列預(yù)測的完整代碼和詳細(xì)解釋,需要的可以參考一下

大家經(jīng)常會遇到一些需要預(yù)測的場景,比如預(yù)測品牌銷售額,預(yù)測產(chǎn)品銷量。

今天給大家分享一波使用 LSTM 進(jìn)行端到端時(shí)間序列預(yù)測的完整代碼和詳細(xì)解釋。

我們先來了解兩個主題:

  • 什么是時(shí)間序列分析?
  • 什么是 LSTM?

時(shí)間序列分析:時(shí)間序列表示基于時(shí)間順序的一系列數(shù)據(jù)。它可以是秒、分鐘、小時(shí)、天、周、月、年。未來的數(shù)據(jù)將取決于它以前的值。

在現(xiàn)實(shí)世界的案例中,我們主要有兩種類型的時(shí)間序列分析:

  • 單變量時(shí)間序列
  • 多元時(shí)間序列

對于單變量時(shí)間序列數(shù)據(jù),我們將使用單列進(jìn)行預(yù)測。

正如我們所見,只有一列,因此即將到來的未來值將僅取決于它之前的值。

但是在多元時(shí)間序列數(shù)據(jù)的情況下,將有不同類型的特征值并且目標(biāo)數(shù)據(jù)將依賴于這些特征。

正如在圖片中看到的,在多元變量中將有多個列來對目標(biāo)值進(jìn)行預(yù)測。(上圖中“count”為目標(biāo)值)

在上面的數(shù)據(jù)中,count不僅取決于它以前的值,還取決于其他特征。因此,要預(yù)測即將到來的count值,我們必須考慮包括目標(biāo)列在內(nèi)的所有列來對目標(biāo)值進(jìn)行預(yù)測。

在執(zhí)行多元時(shí)間序列分析時(shí)必須記住一件事,我們需要使用多個特征預(yù)測當(dāng)前的目標(biāo),讓我們通過一個例子來理解:

在訓(xùn)練時(shí),如果我們使用 5 列 [feature1, feature2, feature3, feature4, target] 來訓(xùn)練模型,我們需要為即將到來的預(yù)測日提供 4 列 [feature1, feature2, feature3, feature4]。

LSTM

本文中不打算詳細(xì)討論LSTM。所以只提供一些簡單的描述,如果你對LSTM沒有太多的了解,可以參考我們以前發(fā)布的文章。

LSTM基本上是一個循環(huán)神經(jīng)網(wǎng)絡(luò),能夠處理長期依賴關(guān)系。

假設(shè)你在看一部電影。所以當(dāng)電影中發(fā)生任何情況時(shí),你都已經(jīng)知道之前發(fā)生了什么,并且可以理解因?yàn)檫^去發(fā)生的事情所以才會有新的情況發(fā)生。RNN也是以同樣的方式工作,它們記住過去的信息并使用它來處理當(dāng)前的輸入。RNN的問題是,由于漸變消失,它們不能記住長期依賴關(guān)系。因此為了避免長期依賴問題設(shè)計(jì)了lstm。

現(xiàn)在我們討論了時(shí)間序列預(yù)測和LSTM理論部分。讓我們開始編碼。

讓我們首先導(dǎo)入進(jìn)行預(yù)測所需的庫:

import?numpy?as?np
import?pandas?as?pd
from?matplotlib?import?pyplot?as?plt
from?tensorflow.keras.models?import?Sequential
from?tensorflow.keras.layers?import?LSTM
from?tensorflow.keras.layers?import?Dense,?Dropout
from?sklearn.preprocessing?import?MinMaxScaler
from?keras.wrappers.scikit_learn?import?KerasRegressor
from?sklearn.model_selection?import?GridSearchCV

加載數(shù)據(jù),并檢查輸出:

df=pd.read_csv("train.csv",parse_dates=["Date"],index_col=[0])
df.head()

df.tail()

現(xiàn)在讓我們花點(diǎn)時(shí)間看看數(shù)據(jù):csv文件中包含了谷歌從2001-01-25到2021-09-29的股票數(shù)據(jù),數(shù)據(jù)是按照天數(shù)頻率的。

[如果您愿意,您可以將頻率轉(zhuǎn)換為“B”[工作日]或“D”,因?yàn)槲覀儾粫褂萌掌?,我只是保持它的現(xiàn)狀。]

這里我們試圖預(yù)測“Open”列的未來值,因此“Open”是這里的目標(biāo)列。

讓我們看一下數(shù)據(jù)的形狀:

df.shape
(5203,5)

現(xiàn)在讓我們進(jìn)行訓(xùn)練測試拆分。這里我們不能打亂數(shù)據(jù),因?yàn)樵跁r(shí)間序列中必須是順序的。

test_split=round(len(df)*0.20)
df_for_training=df[:-1041]
df_for_testing=df[-1041:]
print(df_for_training.shape)
print(df_for_testing.shape)

(4162,?5)
(1041,?5)

可以注意到數(shù)據(jù)范圍非常大,并且它們沒有在相同的范圍內(nèi)縮放,因此為了避免預(yù)測錯誤,讓我們先使用MinMaxScaler縮放數(shù)據(jù)。(也可以使用StandardScaler)

scaler?=?MinMaxScaler(feature_range=(0,1))
df_for_training_scaled?=?scaler.fit_transform(df_for_training)
df_for_testing_scaled=scaler.transform(df_for_testing)
df_for_training_scaled

將數(shù)據(jù)拆分為X和Y,這是最重要的部分,正確閱讀每一個步驟。

def?createXY(dataset,n_past):
??dataX?=?[]
??dataY?=?[]
??for?i?in?range(n_past,?len(dataset)):
??????????dataX.append(dataset[i?-?n_past:i,?0:dataset.shape[1]])
??????????dataY.append(dataset[i,0])
??return?np.array(dataX),np.array(dataY)

trainX,trainY=createXY(df_for_training_scaled,30)
testX,testY=createXY(df_for_testing_scaled,30)

讓我們看看上面的代碼中做了什么:

N_past是我們在預(yù)測下一個目標(biāo)值時(shí)將在過去查看的步驟數(shù)。

這里使用30,意味著將使用過去的30個值(包括目標(biāo)列在內(nèi)的所有特性)來預(yù)測第31個目標(biāo)值。

因此,在trainX中我們會有所有的特征值,而在trainY中我們只有目標(biāo)值。

讓我們分解for循環(huán)的每一部分:

對于訓(xùn)練,dataset = df_for_training_scaled, n_past=30

當(dāng)i= 30:

data_X.addend?(df_for_training_scaled[i?-?n_past:i,?0:df_for_training.shape[1]])

從n_past開始的范圍是30,所以第一次數(shù)據(jù)范圍將是-[30 - 30,30,0:5] 相當(dāng)于 [0:30,0:5]

因此在dataX列表中,df_for_training_scaled[0:30,0:5]數(shù)組將第一次出現(xiàn)。

現(xiàn)在, dataY.append(df_for_training_scaled[i,0])

i = 30,所以它將只取第30行開始的open(因?yàn)樵陬A(yù)測中,我們只需要open列,所以列范圍僅為0,表示open列)。

第一次在dataY列表中存儲df_for_training_scaled[30,0]值。

所以包含5列的前30行存儲在dataX中,只有open列的第31行存儲在dataY中。然后我們將dataX和dataY列表轉(zhuǎn)換為數(shù)組,它們以數(shù)組格式在LSTM中進(jìn)行訓(xùn)練。

我們來看看形狀。

print("trainX?Shape--?",trainX.shape)
print("trainY?Shape--?",trainY.shape)

(4132,?30,?5)
(4132,)

print("testX?Shape--?",testX.shape)
print("testY?Shape--?",testY.shape)

(1011,?30,?5)
(1011,)

4132 是 trainX 中可用的數(shù)組總數(shù),每個數(shù)組共有 30 行和 5 列, 在每個數(shù)組的 trainY 中,我們都有下一個目標(biāo)值來訓(xùn)練模型。

讓我們看一下包含來自 trainX 的 (30,5) 數(shù)據(jù)的數(shù)組之一 和 trainX 數(shù)組的 trainY 值:

print("trainX[0]--?\n",trainX[0])
print("trainY[0]--?",trainY[0])

如果查看 trainX[1] 值,會發(fā)現(xiàn)到它與 trainX[0] 中的數(shù)據(jù)相同(第一列除外),因?yàn)槲覀儗⒖吹角?30 個來預(yù)測第 31 列,在第一次預(yù)測之后它會自動移動 到第 2 列并取下一個 30 值來預(yù)測下一個目標(biāo)值。

讓我們用一種簡單的格式來解釋這一切:

trainX?—?—?→trainY

[0?:?30,0:5]?→?[30,0]

[1:31,?0:5]?→?[31,0]

[2:32,0:5]?→[32,0]

像這樣,每個數(shù)據(jù)都將保存在 trainX 和 trainY 中。

現(xiàn)在讓我們訓(xùn)練模型,我使用 girdsearchCV 進(jìn)行一些超參數(shù)調(diào)整以找到基礎(chǔ)模型。

def?build_model(optimizer):
??grid_model?=?Sequential()
??grid_model.add(LSTM(50,return_sequences=True,input_shape=(30,5)))
??grid_model.add(LSTM(50))
??grid_model.add(Dropout(0.2))
??grid_model.add(Dense(1))

grid_model.compile(loss?=?'mse',optimizer?=?optimizer)
??return?grid_modelgrid_model?=?KerasRegressor(build_fn=build_model,verbose=1,validation_data=(testX,testY))

parameters?=?{'batch_size'?:?[16,20],
????????????'epochs'?:?[8,10],
????????????'optimizer'?:?['adam','Adadelta']?}

grid_search?=?GridSearchCV(estimator?=?grid_model,
??????????????????????????param_grid?=?parameters,
??????????????????????????cv?=?2)

如果你想為你的模型做更多的超參數(shù)調(diào)整,也可以添加更多的層。但是如果數(shù)據(jù)集非常大建議增加 LSTM 模型中的時(shí)期和單位。

在第一個 LSTM 層中看到輸入形狀為 (30,5)。它來自 trainX 形狀。

(trainX.shape[1],trainX.shape[2])?→?(30,5)

現(xiàn)在讓我們將模型擬合到 trainX 和 trainY 數(shù)據(jù)中。

grid_search?=?grid_search.fit(trainX,trainY)

由于進(jìn)行了超參數(shù)搜索,所以這將需要一些時(shí)間來運(yùn)行。

你可以看到損失會像這樣減少:

現(xiàn)在讓我們檢查模型的最佳參數(shù)。

grid_search.best_params_

{‘batch_size':?20,?‘epochs':?10,?‘optimizer':?‘a(chǎn)dam'}

將最佳模型保存在 my_model 變量中。

my_model=grid_search.best_estimator_.model

現(xiàn)在可以用測試數(shù)據(jù)集測試模型。

prediction=my_model.predict(testX)
print("prediction\n",?prediction)
print("\nPrediction?Shape-",prediction.shape)

testY 和 prediction 的長度是一樣的?,F(xiàn)在可以將 testY 與預(yù)測進(jìn)行比較。

但是我們一開始就對數(shù)據(jù)進(jìn)行了縮放,所以首先我們必須做一些逆縮放過程。

scaler.inverse_transform(prediction)

報(bào)錯了,這是因?yàn)樵诳s放數(shù)據(jù)時(shí),我們每行有 5 列,現(xiàn)在我們只有 1 列是目標(biāo)列。

所以我們必須改變形狀來使用 inverse_transform:

prediction_copies_array?=?np.repeat(prediction,5,?axis=-1)

5 列值是相似的,它只是將單個預(yù)測列復(fù)制了 4 次。所以現(xiàn)在我們有 5 列相同的值 。

prediction_copies_array.shape
(1011,5)

這樣就可以使用 inverse_transform 函數(shù)。

pred=scaler.inverse_transform(np.reshape(prediction_copies_array,(len(prediction),5)))[:,0]

但是逆變換后的第一列是我們需要的,所以我們在最后使用了 → [:,0]。

現(xiàn)在將這個 pred 值與 testY 進(jìn)行比較,但是 testY 也是按比例縮放的,也需要使用與上述相同的代碼進(jìn)行逆變換。

original_copies_array?=?np.repeat(testY,5,?axis=-1)
original=scaler.inverse_transform(np.reshape(original_copies_array,(len(testY),5)))[:,0]

現(xiàn)在讓我們看一下預(yù)測值和原始值:

print("Pred?Values--?"?,pred)
print("\nOriginal?Values--?"?,original)

最后繪制一個圖來對比我們的 pred 和原始數(shù)據(jù)。

plt.plot(original,?color?=?'red',?label?=?'Real?Stock?Price')
plt.plot(pred,?color?=?'blue',?label?=?'Predicted?Stock?Price')
plt.title('Stock?Price?Prediction')
plt.xlabel('Time')
plt.ylabel('Google?Stock?Price')
plt.legend()
plt.show()

看樣子還不錯,到目前為止,我們訓(xùn)練了模型并用測試值檢查了該模型。現(xiàn)在讓我們預(yù)測一些未來值。

從主 df 數(shù)據(jù)集中獲取我們在開始時(shí)加載的最后 30 個值[為什么是 30?因?yàn)檫@是我們想要的過去值的數(shù)量,來預(yù)測第 31 個值]

df_30_days_past=df.iloc[-30:,:]
df_30_days_past.tail()

可以看到有包括目標(biāo)列(“Open”)在內(nèi)的所有列?,F(xiàn)在讓我們預(yù)測未來的 30 個值。

在多元時(shí)間序列預(yù)測中,需要通過使用不同的特征來預(yù)測單列,所以在進(jìn)行預(yù)測時(shí)我們需要使用特征值(目標(biāo)列除外)來進(jìn)行即將到來的預(yù)測。

這里我們需要“High”、“Low”、“Close”、“Adj Close”列的即將到來的 30 個值來對“Open”列進(jìn)行預(yù)測。

df_30_days_future=pd.read_csv("test.csv",parse_dates=["Date"],index_col=[0])
df_30_days_future

剔除“Open”列后,使用模型進(jìn)行預(yù)測之前還需要做以下的操作:

縮放數(shù)據(jù),因?yàn)閯h除了‘Open’列,在縮放它之前,添加一個所有值都為“0”的Open列。

縮放后,將未來數(shù)據(jù)中的“Open”列值替換為“nan”

現(xiàn)在附加 30 天舊值和 30 天新值(其中最后 30 個“打開”值是 nan)

df_30_days_future["Open"]=0
df_30_days_future=df_30_days_future[["Open","High","Low","Close","Adj?Close"]]
old_scaled_array=scaler.transform(df_30_days_past)
new_scaled_array=scaler.transform(df_30_days_future)
new_scaled_df=pd.DataFrame(new_scaled_array)
new_scaled_df.iloc[:,0]=np.nan
full_df=pd.concat([pd.DataFrame(old_scaled_array),new_scaled_df]).reset_index().drop(["index"],axis=1)

full_df  形狀是 (60,5),最后第一列有 30 個 nan 值。

要進(jìn)行預(yù)測必須再次使用 for 循環(huán),我們在拆分 trainX 和 trainY 中的數(shù)據(jù)時(shí)所做的。但是這次我們只有 X,沒有 Y 值。

full_df_scaled_array=full_df.values
all_data=[]
time_step=30
for?i?in?range(time_step,len(full_df_scaled_array)):
??data_x=[]
??data_x.append(
????full_df_scaled_array[i-time_step?:i?,?0:full_df_scaled_array.shape[1]])
??data_x=np.array(data_x)
??prediction=my_model.predict(data_x)
??all_data.append(prediction)
??full_df.iloc[i,0]=prediction

對于第一個預(yù)測,有之前的 30 個值,當(dāng) for 循環(huán)第一次運(yùn)行時(shí)它會檢查前 30 個值并預(yù)測第 31 個“Open”數(shù)據(jù)。

當(dāng)?shù)诙€ for 循環(huán)將嘗試運(yùn)行時(shí),它將跳過第一行并嘗試獲取下 30 個值 [1:31] 。這里會報(bào)錯錯誤因?yàn)镺pen列最后一行是 “nan”,所以需要每次都用預(yù)測替換“nan”。

最后還需要對預(yù)測進(jìn)行逆變換:

new_array=np.array(all_data)
new_array=new_array.reshape(-1,1)
prediction_copies_array?=?np.repeat(new_array,5,?axis=-1)
y_pred_future_30_days?=?scaler.inverse_transform(np.reshape(prediction_copies_array,(len(new_array),5)))[:,0]
print(y_pred_future_30_days)

這樣一個完整的流程就已經(jīng)跑通了。

到此這篇關(guān)于Python使用LSTM實(shí)現(xiàn)銷售額預(yù)測詳解的文章就介紹到這了,更多相關(guān)Python LSTM銷售額預(yù)測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Pytorch之parameters的使用

    Pytorch之parameters的使用

    今天小編就為大家分享一篇Pytorch之parameters的使用,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python 中星號(*)的用法小結(jié)

    Python 中星號(*)的用法小結(jié)

    星號??*?? 往往被稱為乘法運(yùn)算符,是所有程序中最為常用的運(yùn)算符號之一,在Python 中,星號還有很多隱藏的強(qiáng)大功能, 本文將用最容易理解的例子來解釋星號*的 五個使用場景,從初級用法到高階用法,感興趣的朋友可以參考下
    2023-08-08
  • 分析經(jīng)典Python開發(fā)工程師面試題

    分析經(jīng)典Python開發(fā)工程師面試題

    在本篇內(nèi)容中小編給大家分享了一篇關(guān)于Python開發(fā)工程師面試題的相關(guān)總結(jié)內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2019-04-04
  • Pytorch實(shí)現(xiàn)網(wǎng)絡(luò)部分層的固定不進(jìn)行回傳更新問題及思路詳解

    Pytorch實(shí)現(xiàn)網(wǎng)絡(luò)部分層的固定不進(jìn)行回傳更新問題及思路詳解

    這篇文章主要介紹了Pytorch實(shí)現(xiàn)網(wǎng)絡(luò)部分層的固定不進(jìn)行回傳更新,實(shí)現(xiàn)思路就是利用tensor的requires_grad,每一個tensor都有自己的requires_grad成員,值只能為True和False,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-08-08
  • PyQt5中多線程模塊QThread使用方法的實(shí)現(xiàn)

    PyQt5中多線程模塊QThread使用方法的實(shí)現(xiàn)

    這篇文章主要介紹了PyQt5中多線程模塊QThread使用方法的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • python中的selenium入門超詳細(xì)教程

    python中的selenium入門超詳細(xì)教程

    這篇文章主要介紹了python中的selenium入門超詳細(xì)教程,本文是在python環(huán)境下使用selenium,使用瀏覽器是Chrome,系統(tǒng)是win10系統(tǒng),需要的朋友可以參考下
    2023-11-11
  • 基于Python+Matplotlib繪制漸變色扇形圖與等高線圖

    基于Python+Matplotlib繪制漸變色扇形圖與等高線圖

    這篇文章主要為大家介紹了如何利用Python中的Matplotlib繪制漸變色扇形圖與等高線圖,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下方法
    2022-04-04
  • keras 多gpu并行運(yùn)行案例

    keras 多gpu并行運(yùn)行案例

    這篇文章主要介紹了keras 多gpu并行運(yùn)行案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python游戲推箱子的實(shí)現(xiàn)

    Python游戲推箱子的實(shí)現(xiàn)

    這篇文章主要介紹了Python游戲推箱子的實(shí)現(xiàn),推箱子游戲是一款可玩性極高的策略解謎手游,游戲中玩家將扮演一名可愛Q萌的角色,下面我們就看看看具體的實(shí)現(xiàn)過程吧,需要的小伙伴可以參考一下
    2021-12-12
  • python使用timeit時(shí)間模塊

    python使用timeit時(shí)間模塊

    這篇文章主要介紹了python之timeit統(tǒng)計(jì)運(yùn)行時(shí)間模塊,這個技巧非常的實(shí)用,感興趣的小伙伴可以試試
    2021-04-04

最新評論