In diesem Blog werden wir Deep Learning verwenden, um den Verkauf von Snacks in persönlichem Besitz durch Mütter vorherzusagen. Meine Mutter, die Managerin ist, ist immer besorgt über Ausgabenentscheidungen wie "Bestandsverwaltung, Anzahl der Mitarbeiter, Kapitalinvestitionen, Geschäftsausweitung". .. .. Daher dachte ich, wenn ich eine hochpräzise Umsatzprognose erstellen könnte, könnte ich diese Schwierigkeit so weit wie möglich reduzieren. Es ist einen Monat her, seit ich angefangen habe, maschinelles Lernen zu studieren, und ich habe mich nur daran erinnert, dass ich ein Modell mit tatsächlichen Daten erstellen wollte. Ich mache mir ein wenig Sorgen, ob ich es schaffen kann, aber ** Ich möchte die Herausforderung annehmen und gleichzeitig die Vergangenheit überprüfen! !! !! ** Ich hoffe auch, dass es ein Referenzartikel für diejenigen ist, die von nun an maschinelles Lernen studieren.
Es gibt viele Arten von Algorithmen für maschinelles Lernen, aber der zugrunde liegende Modellbildungsprozess war für alle gleich. Der einfache Ablauf des maschinellen Lernens ist wie folgt. Auch in diesem Blog werden wir ein Modell erstellen, wobei wir diesen Fluss berücksichtigen.
** 1. Datenerfassung 2. Datenvorverarbeitung (entfernen Sie Duplikate und fehlende Daten, um die Datengenauigkeit zu verbessern) 3. Lernen Sie Daten mithilfe von Techniken des maschinellen Lernens 4. Testleistung mit Testdaten **
Diese "Modellkonstruktion der Snack-Verkaufsprognose" entspricht einer Zeitreihendatenanalyse. Zeitreihendaten beziehen sich auf Daten, die sich im Laufe der Zeit ändern. Die Zeitreihendatenanalyse kann auch zur Prognose von Unternehmensverkäufen und Produktverkäufen verwendet werden. Daher wird sie als eine sehr wichtige Analysetechnologie in der Geschäftsszene angesehen. In diesem Blog werden wir die Verwendung der Algorithmen ** RNN (Recurrent Neural Network) ** und ** LSTM (Long-Short-Term-Memory) ** in Betracht ziehen, die die Deep-Learning-Methode anwenden. RNN(Recurrent Neural Network) RNN ist einer der Algorithmen für maschinelles Lernen, die Zeitreihendaten durch tiefes Lernen analysieren. In der mittleren Schicht ist RNN dadurch gekennzeichnet, dass die Daten zum vorherigen Zeitpunkt als aktuelle Eingabe selbst wiederholt werden. Dadurch können RNNs Informationen kommunizieren und gleichzeitig den Kontext der Daten in der mittleren Schicht beibehalten. Und diese Eigenschaft ermöglichte es, Daten mit dem Konzept der Zeit zu trainieren. (Zitiert von https://qiita.com/KojiOhki/items/89cd7b69a8a6239d67ca)
RNN hat es möglich gemacht, Zeitreihendaten durch tiefes Lernen zu analysieren, aber die Leistung ist nicht so hoch. Die Ursache ist, dass die Aktivierungsfunktion um ein Vielfaches mit der Schleifenstruktur von RNN multipliziert wird. Mit der Zeit wird die iterative Aktivierungsfunktion multipliziert, was zu einem ** Verschwinden des Gradienten ** oder einer ** Gradientenexplosion ** führt, bei der der Gradientenwert konvergiert und der Rechenaufwand exponentiell zunimmt. Infolgedessen wird eine ordnungsgemäße Datenverarbeitung schwierig. Aus diesen Gründen können wir auch feststellen, dass RNN nicht zum Trainieren von Langzeitzeitreihendaten geeignet ist. Das Deep-Learning-Modell, das diesen Nachteil löst, ist LSTM (Long-Short-Term-Momory), das als nächstes eingeführt wird.
LSTM(Long-short-term-memory) Im LSTM-Modell wird durch Ersetzen der Zellen in der mittleren Schicht durch LSTM-Blöcke der Nachteil von RNN "kann nicht lernen, während das Langzeitgedächtnis erhalten bleibt" überwunden. Die Grundkonfiguration des LETM-Blocks ist wie folgt.
・ CEC: Eine Einheit, die vergangene Daten speichert -Eingangsgatter: Ein Gatter, das das Eingangsgewicht der vorherigen Einheit anpasst -Ausgangsgatter: Ein Gatter, das das Ausgangsgewicht der vorherigen Einheit anpasst ・ Oblivion Gate: Ein Gate, mit dem angepasst wird, wie viel Inhalt der CEC mit früheren Informationen noch vorhanden ist.
(Zitiert von https://sagantaf.hatenablog.com/entry/2019/06/04/225239)
In LSTM können Sie mit der oben genannten Gate-Funktion Informationen entsprechend dem Zellenstatus löschen oder hinzufügen. Durch Anpassen der Eingabe- / Ausgabegewichte und Anpassen der Daten in der Zelle wurden die Probleme des Verschwindens des Gradienten und der Explosion des Gradienten, die die Nachteile von RNN waren, gelöst. Daher kann es auf die Analyse von Langzeitzeitreihendaten angewendet werden.
Die obige Erklärung ist die theoretische Geschichte von RNN und LSTM. Es gibt insgesamt 82 Daten zum Verkauf dieses Snacks für 7 Jahre. Da es sich bei der Länge um mittel- bis langfristige Daten handelt, möchte ich Vorhersagen sowohl mit RNN- als auch mit LSTM-Modellen treffen und ein Modell mit guten Ergebnissen übernehmen. Lassen Sie uns nun das Modell erstellen.
OS: Windows10
Python-Umgebung: Jupyter Notebook
Forecast-
|-Forecast.py(Python-Datei)
|-sales_data-
|-Verschiedene CSV-Dateien
Der Fluss der Modellkonstruktion ist der folgende Fluss, der zuvor eingeführt wurde. ** 1. Datenerfassung 2. Datenvorverarbeitung (entfernen Sie Duplikate und fehlende Daten, um die Datengenauigkeit zu verbessern) 3. Lernen Sie Daten mithilfe von Techniken des maschinellen Lernens 4. Testleistung mit Testdaten **
Importieren Sie zunächst die erforderlichen Module. Schreiben Sie den folgenden Code in die Ausführungsumgebung.
Forecast.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import SimpleRNN
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
Erstens ist die Datenerfassung. Nach einer verzweifelten Anfrage erhielt ich Verkaufsdaten für Snacks, die von meiner Mutter betrieben wurden. Das Format der Excel-Daten 2013-2019, in dem die monatlichen Verkäufe zusammengefasst sind, wird angepasst und im CSV-Format ausgegeben.
Monatlicher Verkaufsrekord für Snacks von 2013 bis 2019.
sales
Anzahl der Daten 8.400000e+01
Durchschnitt 7.692972e+05
Standardabweichung 1.001658e+05
Mindestwert 5.382170e+05
1/4 Minuten 7.006952e+05
Medianwert 7.594070e+05
3/4 Minuten 8.311492e+05
Maximalwert 1.035008e+06
Es scheint, dass der Umsatz im Laufe der Jahre tendenziell steigt.
2019 :801197 Yen
2018 :822819 Yen
2017 :732294 Yen
2016 :755799 Yen
2015 :771255 Yen
2014 :761587 Yen
2013 :740128 Yen
Die höchsten Umsätze wurden im Dezember erzielt, gefolgt von April. Es scheint in engem Zusammenhang mit der Tatsache zu stehen, dass am Ende des Jahres viele Trinkpartys und zu Jahresbeginn Trinkpartys stattfinden. Ich hoffe, ich kann diese Trends vorhersagen.
Januar:758305 Yen
Februar:701562 Yen
März:750777 Yen
April:805094 Yen
Kann:785633 Yen
Juni:778146 Yen
Juli:752226 Yen
August:763773 Yen
September:689561 Yen
Oktober:765723 Yen
November:779661 Yen
Dezember:901100 Yen
Dies bedeutet einen langfristigen Datentrend. In diesem Thema zeigen wir, ob die Snackverkäufe langfristig steigen oder fallen.
Bei Daten mit periodischen Schwankungen wiederholt sich der Wert der Daten im Laufe der Zeit. Insbesondere periodische Schwankungen über ein Jahr werden als saisonale Schwankungen bezeichnet. In Bezug auf dieses Thema stellten wir fest, dass die durchschnittlichen Verkäufe im Dezember und April, wenn es viele Trinkpartys gibt, hoch sind. Möglicherweise gibt es saisonale periodische Schwankungen.
trend_seasonal.py
#Berücksichtigung der ganzjährigen Umsatztrends und der Saisonalität
fig = sm.tsa.seasonal_decompose(df_sales_concat, freq=12).plot()
plt.show()
Der Umsatz verzeichnete erwartungsgemäß einen Aufwärtstrend. Im April und Dezember gab es auch periodische Umsatzschwankungen. Es wäre schön, wenn wir solche Inhalte mit einem maschinellen Lernmodell vorhersagen könnten.
Die Selbstverteilung von Zeitreihen bezieht sich auf die *** gemeinsame Verteilung derselben Zeitreihendaten zwischen verschiedenen Zeitpunkten. Die Selbstverteilung k-ter Ordnung bezieht sich auf die gemeinsame Verteilung mit Daten, die durch k Punkte getrennt sind. Die Ansicht dieser Selbstkovarianz als Funktion von *** k wird als Autokorrelationsfunktion *** bezeichnet. Die *** graphische Darstellung dieser Funktion wird als *** Cholerogramm bezeichnet.
corr.py
#Berechnung des Autokorrelationskoeffizienten-Cholerogramms
df_sales_concat_acf = sm.tsa.stattools.acf(df_sales_concat, nlags=12)
print(df_sales_concat_acf)
sm.graphics.tsa.plot_acf(df_sales_concat, lags=12)
fig = sm.graphics.tsa.plot_acf(df_sales_concat, lags=12)
Aus dem Cholerogramm können wir sehen, dass der Autokorrelationskoeffizient zunimmt, wenn k = 12 ist. Da es sich um Daten handelt, die monatliche Verkäufe erfassen, können Sie feststellen, dass zwischen einigen Daten und den Daten vor einem Jahr eine Korrelation besteht.
Die tatsächlich verwendeten Daten werden im unten stehenden Link "Google Sheets" veröffentlicht. https://docs.google.com/spreadsheets/d/1-eOPORhaGfSCdXCScSsBsM586yXkt3e_xbOlG2K6zN8/edit?usp=sharing
Forecast.py
#Lesen Sie die CSV-Datei im DataFrame-Format.
df_2019 = pd.read_csv('./sales_data/2019_sales.csv')
df_2018 = pd.read_csv('./sales_data/2018_sales.csv')
df_2017 = pd.read_csv('./sales_data/2017_sales.csv')
df_2016 = pd.read_csv('./sales_data/2016_sales.csv')
df_2015 = pd.read_csv('./sales_data/2015_sales.csv')
df_2014 = pd.read_csv('./sales_data/2014_sales.csv')
df_2013 = pd.read_csv('./sales_data/2013_sales.csv')
#Kombinieren Sie die geladenen DataFrames zu einem einzigen DataFrame.
df_sales_concat = pd.concat([df_2013, df_2014, df_2015,df_2016,df_2017,df_2018,df_2019], axis=0)
#Erstellen Sie einen Index für die FrameData, die Sie verwenden möchten.
index = pd.date_range("2013-01", "2019-12-31", freq='M')
df_sales_concat.index = index
#Löschen Sie nicht benötigte DataFrame-Spalten.
del df_sales_concat['month']
#Speichern Sie nur die tatsächlichen Verkaufsdaten, die beim Modellieren verwendet wurden, in der Datensatzvariablen.
dataset = df_sales_concat.values
dataset = dataset.astype('float32')
Als nächstes folgt die Datenvorverarbeitung. Insbesondere erstellen wir einen Datensatz, der für die Modellkonstruktion verwendet wird.
Forecast.py
#Teilen Sie in Trainingsdaten und Testdaten. Das Verhältnis beträgt 2:1=Ausbildung:Es ist ein Test.
train_size = int(len(dataset) * 0.67)
train, test = dataset[0:train_size, :], dataset[train_size:len(dataset), :]
#Datenskalierung.
#Ich erstelle eine Instanz für die Datenstandardisierung basierend auf Trainingsdaten.
scaler = MinMaxScaler(feature_range=(0, 1))
scaler_train = scaler.fit(train)
train_scale = scaler_train.transform(train)
test_scale = scaler_train.transform(test)
#Erstellen eines Datensatzes
look_back =1
train_X, train_Y = create_dataset(train_scale, look_back)
test_X, test_Y = create_dataset(test_scale, look_back)
#Erstellen eines Originaldatensatzes zur Auswertung
train_X_original, train_Y_original = create_dataset(train, look_back)
test_X_original, test_Y_original = create_dataset(test, look_back)
#Datenformung
train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1)
test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1)
Forecast.py
lstm_model = Sequential()
lstm_model.add(LSTM(64, return_sequences=True, input_shape=(look_back, 1)))
lstm_model.add(LSTM(32))
lstm_model.add(Dense(1))
lstm_model.compile(loss='mean_squared_error', optimizer='adam')
###Lernen
lstm_model.fit(train_X, train_Y, epochs=100, batch_size=64, verbose=2)
Forecast.py
rnn_model = Sequential()
rnn_model.add(SimpleRNN(64, return_sequences=True, input_shape=(look_back, 1)))
rnn_model.add(SimpleRNN(32))
rnn_model.add(Dense(1))
rnn_model.compile(loss='mean_squared_error', optimizer='adam')
###Lernen
rnn_model.fit(train_X, train_Y, epochs=100, batch_size=64, verbose=2)
Damit ist das maschinelle Lernen mit LSTM und RNN aus dem Datensatz abgeschlossen. Die Grundoperationen sind für beide gleich, nur die verwendeten Klassen sind unterschiedlich. Als nächstes folgt der Vorgang zum Zeichnen der Ergebnisse in einem Diagramm. Von nun an wird das Modell als Modell angezeigt, bezieht sich jedoch sowohl auf lstm_model als auch auf rnn_model.
Forecast.py
#Prognosedaten erstellen
train_predict = model.predict(train_X)
test_predict = model.predict(test_X)
#Setzen Sie die skalierten Daten zurück. Konvertiert den standardisierten Wert in den tatsächlich vorhergesagten Wert.
train_predict = scaler_train.inverse_transform(train_predict)
train_Y = scaler_train.inverse_transform([train_Y])
test_predict = scaler_train.inverse_transform(test_predict)
test_Y = scaler_train.inverse_transform([test_Y])
#Berechnung der Vorhersagegenauigkeit
train_score = math.sqrt(mean_squared_error(train_Y_original, train_predict[:, 0]))
print(train_score)
print('Train Score: %.2f RMSE' % (train_score))
test_score = math.sqrt(mean_squared_error(test_Y_original, test_predict[:, 0]))
print('Test Score: %.2f RMSE' % (test_score))
#Datenformung für Diagramme
train_predict_plot = np.empty_like(dataset)
train_predict_plot[:, :] = np.nan
train_predict_plot[look_back:len(train_predict)+look_back, :] = train_predict
train_predict_plot = pd.DataFrame({'sales':list(train_predict_plot.reshape(train_predict_plot.shape[0],))})
train_predict_plot.index = index
test_predict_plot = np.empty_like(dataset)
test_predict_plot[:, :] = np.nan
test_predict_plot[len(train_predict)+(look_back*2):len(dataset), :] = test_predict
test_predict_plot = pd.DataFrame({'sales':list(test_predict_plot.reshape(test_predict_plot.shape[0],))})
test_predict_plot.index = index
Als nächstes werden wir die tatsächlichen Daten in der Grafik darstellen.
Forecast.py
#Geben Sie die Metainformationen des Diagramms aus
plt.title("monthly-sales")
plt.xlabel("time(month)")
plt.ylabel("sales")
#Zeichnen Sie die Daten
plt.plot(dataset, label='sales_dataset', c='green')
plt.plot(train_predict_plot, label='train_data', c='red')
plt.plot(test_predict_plot, label='test_data', c='blue')
#Passen Sie die y-Achsenskala an
plt.yticks([500000, 600000, 700000, 800000, 900000, 1000000, 1100000])
#Zeichnen Sie das Diagramm
plt.legend()
plt.show()
Die Diagramme der RNN- und LSTM-Ausgabe als Ergebnis werden jeweils veröffentlicht.
Der Wert der Ausgabe geht vollständig verloren. .. .. Ich habe die Parameter stark geändert, aber die Ergebnisse haben sich nicht wesentlich geändert. Es ist ersichtlich, dass das Verfahren unter Verwendung von RNN selbst für die Zeitdauer von 84 Daten dieses Mal nicht geeignet ist.
Im Vergleich zur RNN-Prognose können wir den Umsatztrend irgendwie vorhersagen. Insbesondere konnten wir die Tendenz zur Umsatzsteigerung im April und Dezember kontrollieren. Insgesamt gibt es jedoch viele Punkte, die erheblich von den gemessenen Werten abweichen. Der *** RMSE ***, der der Standard für die Güte des Modells ist, ist auch *** Train Score: 94750,73 RMSE, Test Score: 115472,92 RMSE ***, was ziemlich große Werte sind. Es scheint, dass das Ergebnis nicht so gut ist.
Es wurde festgestellt, dass LSTM eine detaillierte Zeitreihenanalyse auch für Datensätze durchführen kann, die ein Verschwinden des Gradienten in RNN verursachen. Die Prognose von LSTM zeigt jedoch nur die Umsatzentwicklung, und es gibt viele Werte, die erheblich von den tatsächlichen Werten abweichen. Dies kann nicht als hochpräzise Umsatzprognose bezeichnet werden, und es kann keine Prognose von Einkommensdaten sein, die eine Managemententscheidung sein können.
Sowohl für RNN als auch für LSTM habe ich verschiedene Muster der Parameter loop_back, epochs, batch_size ausprobiert, aber die Leistung hat sich insbesondere nicht verbessert. Es kann davon ausgegangen werden, dass die Ursache ** eine geringe Datenmenge und Abweichung ist. ** Als ich später nachforschte, schien die Anzahl der Daten 84 in der Zeitreihenanalyse recht gering zu sein. Ich erkannte, dass ** Daten das Leben ** beim Aufbau eines maschinellen Lernmodells sind.
Ich denke jedoch, dass es ein gutes Unterrichtsmaterial für einen Monat Rückblick auf maschinelles Lernen und Anfänger war. Von nun an werde ich mich weiter widmen, um mein Niveau als Ingenieur für maschinelles Lernen zu verbessern! *** ***
Forecast.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import SimpleRNN
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
#Erstellen eines Datensatzes
def create_dataset(dataset, look_back):
data_X, data_Y = [], []
for i in range(look_back, len(dataset)):
data_X.append(dataset[i-look_back:i, 0])
data_Y.append(dataset[i, 0])
return np.array(data_X), np.array(data_Y)
df_2019 = pd.read_csv('./sales_data/2019_sales.csv')
df_2018 = pd.read_csv('./sales_data/2018_sales.csv')
df_2017 = pd.read_csv('./sales_data/2017_sales.csv')
df_2016 = pd.read_csv('./sales_data/2016_sales.csv')
df_2015 = pd.read_csv('./sales_data/2015_sales.csv')
df_2014 = pd.read_csv('./sales_data/2014_sales.csv')
df_2013 = pd.read_csv('./sales_data/2013_sales.csv')
df_sales_concat = pd.concat([df_2013, df_2014, df_2015,df_2016,df_2017,df_2018,df_2019], axis=0)
index = pd.date_range("2013-01", "2019-12-31", freq='M')
df_sales_concat.index = index
del df_sales_concat['month']
dataset = df_sales_concat.values
dataset = dataset.astype('float32')
#Teilen Sie in Trainingsdaten und Testdaten
train_size = int(len(dataset) * 0.67)
train, test = dataset[0:train_size, :], dataset[train_size:len(dataset), :]
#Datenskalierung
scaler = MinMaxScaler(feature_range=(0, 1))
scaler_train = scaler.fit(train)
train_scale = scaler_train.transform(train)
test_scale = scaler_train.transform(test)
#Daten erstellen
look_back =1
train_X, train_Y = create_dataset(train_scale, look_back)
test_X, test_Y = create_dataset(test_scale, look_back)
#Erstellen eines Datensatzes zur Auswertung
train_X_original, train_Y_original = create_dataset(train, look_back)
test_X_original, test_Y_original = create_dataset(test, look_back)
#Datenformung
train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1)
test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1)
#Erstellen und Trainieren von LSTM-Modellen
model = Sequential()
model.add(LSTM(64, return_sequences=True, input_shape=(look_back, 1)))
model.add(LSTM(32))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(train_X, train_Y, epochs=100, batch_size=64, verbose=2)
#Prognosedaten erstellen
train_predict = model.predict(train_X)
test_predict = model.predict(test_X)
#Setzen Sie die skalierten Daten zurück.
train_predict = scaler_train.inverse_transform(train_predict)
train_Y = scaler_train.inverse_transform([train_Y])
test_predict = scaler_train.inverse_transform(test_predict)
test_Y = scaler_train.inverse_transform([test_Y])
#Berechnung der Vorhersagegenauigkeit
train_score = math.sqrt(mean_squared_error(train_Y_original, train_predict[:, 0]))
print(train_score)
print('Train Score: %.2f RMSE' % (train_score))
test_score = math.sqrt(mean_squared_error(test_Y_original, test_predict[:, 0]))
print('Test Score: %.2f RMSE' % (test_score))
#Datenformung für Diagramme
train_predict_plot = np.empty_like(dataset)
train_predict_plot[:, :] = np.nan
train_predict_plot[look_back:len(train_predict)+look_back, :] = train_predict
train_predict_plot = pd.DataFrame({'sales':list(train_predict_plot.reshape(train_predict_plot.shape[0],))})
train_predict_plot.index = index
test_predict_plot = np.empty_like(dataset)
test_predict_plot[:, :] = np.nan
test_predict_plot[len(train_predict)+(look_back*2):len(dataset), :] = test_predict
test_predict_plot = pd.DataFrame({'sales':list(test_predict_plot.reshape(test_predict_plot.shape[0],))})
test_predict_plot.index = index
#Datenplot
plt.title("monthly-sales")
plt.xlabel("time(month)")
plt.ylabel("sales")
plt.plot(dataset, label='sales_dataset', c='green')
plt.plot(train_predict_plot, label='train_data', c='red')
plt.plot(test_predict_plot, label='test_data', c='blue')
plt.yticks([500000, 600000, 700000, 800000, 900000, 1000000, 1100000])
plt.legend()
plt.show()
Recommended Posts