Skip to forum
Benachrichtigungen
Alles löschen

Tensorflow Frage [BTC Trading inside]

8 Beiträge
3 Benutzer
1 Reactions
827 Ansichten
pg89
Joined: 05.04.2008

Hi,
ich bin zufällig über diesen Artikel gestolpert: https://towardsdatascience.com/cryptocurrency-price-prediction-using-deep-learning-70cfca50dd3a

Es geht darum, dass angeblich jemand mit Hilfe von einer KI den Bitcoinkurs vorhersagen will. So wie es dort aussieht, müsste er den Heiligen Gral gefunden haben und könnte eigentlich infinite money drucken. Irgendwie ist also klar, dass das so nicht ganz stimmen kann.
Ich habe trotzdem mal ein bisschen damit rumgespielt und dachte mir eigentlich, ich mache mal eine vorhersage für die nächsten Wochen, speichere mir den Graphen und gucke wie er zu der Kursentwicklung passt.
Da ich irgendwie zu blöd war, die vorhersage über die Testdaten hinaus ausgeben zu lassen, habe ich halt die Testdaten so manipuliert, dass sie noch ein paar Wochen den aktuellen Preis halten :coolface: Nach meinem Verständnis dürfen die Testdaten ja keinen Einfluss auf die Vorhersage haben. Dass dann die Statistiken über Genauigkeit nicht mehr passen, ist klar, war mir in dem Fall aber egal.
Nun ist es aber so, dass die predict-Funktion kurz nachdem sie bei meinen Pseudodaten angekommen ist abbricht und sich am Ende generell komisch verhält.

Wie gesagt, mir ist klar dass niemand so einfach den Kurs so exakt vorhersagen kann, wie es in dem Beispiel funktioniert. Aber ich verstehe trotzdem nicht, wieso am Ende keine Berechnung mehr erfolgt. Kann mir das jemand vllt genauer erklären? Wie würde man denn mit dem Algorithmus eine "richtige" Vorhersage über die nächsten Tage/Wochen treffen können?
Hier mein angepasster code (ja, quick&dirty):

import tensorflow
import json
import requests
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, LSTM
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.metrics import mean_absolute_error
from datetime import datetime
from datetime import timedelta
%matplotlib inline

endpoint = ' https://min-api.cryptocompare.com/data/histoday' 
res = requests.get(endpoint + '?fsym=BTC&tsym=USD&limit=2000')
hist = pd.DataFrame(json.loads(res.content)['Data'])

t_today = hist["time"].iloc[-1]
last_close = hist["close"].iloc[-1]
for i in range(1, 60):
    t_next = datetime.fromtimestamp(t_today) + timedelta(days = i)
    t_next = int(datetime.timestamp(t_next))
    l = {"time": t_next, "close": last_close, "high": 0, "low": 0, "open": 0, "volumefrom": 0, "volumeto": 0}
    hist = hist.append(l, ignore_index = True)

hist = hist.set_index('time')
hist.index = pd.to_datetime(hist.index, unit='s')
target_col = 'close'

def train_test_split(df, test_size=0.1):
    split_row = len(df) - int(test_size * len(df))
    train_data = df.iloc[:split_row]
    test_data = df.iloc[split_row:]
    return train_data, test_data

train, test = train_test_split(hist, test_size=0.1)

def line_plot(line1, line2, label1=None, label2=None, title='', lw=2):
    fig, ax = plt.subplots(1, figsize=(13, 7))
    ax.plot(line1, label=label1, linewidth=lw)
    ax.plot(line2, label=label2, linewidth=lw)
    ax.set_ylabel('price [USD]', fontsize=14)
    ax.set_title(title, fontsize=16)
    ax.legend(loc='best', fontsize=16);

line_plot(train[target_col], test[target_col], 'training', 'test', title='')

def normalise_zero_base(df):
    return df / df.iloc[0] - 1

def normalise_min_max(df):
    return (df - df.min()) / (data.max() - df.min())

def extract_window_data(df, window_len=5, zero_base=True):
    window_data = []
    for idx in range(len(df) - window_len):
        tmp = df[idx: (idx + window_len)].copy()
        if zero_base:
            tmp = normalise_zero_base(tmp)
        window_data.append(tmp.values)
    return np.array(window_data)

def prepare_data(df, target_col, window_len=10, zero_base=True, test_size=0.2):
    train_data, test_data = train_test_split(df, test_size=test_size)
    X_train = extract_window_data(train_data, window_len, zero_base)
    X_test = extract_window_data(test_data, window_len, zero_base)
    y_train = train_data[target_col][window_len:].values
    y_test = test_data[target_col][window_len:].values
    if zero_base:
        y_train = y_train / train_data[target_col][:-window_len].values - 1
        y_test = y_test / test_data[target_col][:-window_len].values - 1

    return train_data, test_data, X_train, X_test, y_train, y_test

def build_lstm_model(input_data, output_size, neurons=100, activ_func='linear',
                     dropout=0.1, loss='mse', optimizer='adam'):
    model = Sequential()
    model.add(LSTM(neurons, input_shape=(input_data.shape[1], input_data.shape[2])))
    model.add(Dropout(dropout))
    model.add(Dense(units=output_size))
    model.add(Activation(activ_func))

    model.compile(loss=loss, optimizer=optimizer)
    return model

np.random.seed(42)
window_len = 5
test_size = 0.1
zero_base = True
lstm_neurons = 100
epochs = 20
batch_size = 32
loss = 'mse'
dropout = 0.1
optimizer = 'adam'

train, test, X_train, X_test, y_train, y_test = prepare_data(
    hist, target_col, window_len=window_len, zero_base=zero_base, test_size=test_size)

model = build_lstm_model(
    X_train, output_size=1, neurons=lstm_neurons, dropout=dropout, loss=loss,
    optimizer=optimizer)
history = model.fit(
    X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=1, shuffle=True)

targets = test[target_col][window_len:]
preds = model.predict(X_test).squeeze()

preds = test[target_col].values[:-window_len] * (preds + 1)
preds = pd.Series(index=targets.index, data=preds)
line_plot(targets, preds, 'actual', 'prediction', lw=3)

Original: https://github.com/abhinavsagar/Cryptocurrency-Price-Prediction/blob/master/price_prediction.ipynb

Danke schon mal für jede Hilfe!


Antwort
Zitat
7 replies
Moderator
cjheigl
Joined: 10.04.2006

Ich kann dir mit dem Code nicht helfen, aber der abgedruckte Graph sieht so aus, als würde das Modell das "vorhersagen", was einen Tag vorher schon passiert ist. Das ist also gar keine Vorhersage, sondern nur das Nachverfolgen vergangener Ereignisse.


Antwort
Zitat
pg89
Joined: 05.04.2008

Den Verdacht habe ich irgendwie auch, dass die Testdaten mit ins Training eingehen... Würde auf jeden Fall einiges erklären.


Antwort
Zitat
Rho0
Joined: 20.10.2008

du sagst mehrere wochen vorher, indem du die aktuelle vorhersage an deinen x-vektor anhängst.

es sei dein x-vektor

x_1, x_2, x_3, x_4, x_5.

deine vorhersage ist

x_6

der neue x-vektor ist

x_2, x_3, x_4, x_5, x_6

und damit sagst du x_7 vorher.

deinen code will ich ehrlich gesagt nicht weiter anschauen, weil er scheiße ist. train_test_split hast du zb doppelt definiert, keine kommentare.... sorry, aber das ist bullshit-code.

meine tipps für sauberen code:
1) benenne variablen so, dass jederzeit für jeden leser, egal ob er coden kann oder nicht, klar ist, was passiert
2) zerlege funktionen in unterfunktionen, so dass jede funktion nur eine einzige aufgabe erfüllt
3) schreibe mit docstrings am anfang jeder funktion, was sie machen soll, was sie für parameter hat, welche variablen vorkommen, und wozu die variablen gut sind, und was zurückgegeben wird.


Antwort
Zitat
pg89
Joined: 05.04.2008

Stimme ich dir voll und ganz zu mit dem code, vielleicht steige ich da auch genau aus dem Grund nicht ganz durch.
Der ist aber auch nicht von mir, abgesehen von den 5 Zeilen mit der for-schleife und dass ich den Trainingsdatensatz etwas vergrößert habe.
train_test_split() hab ich wohl echt doppelt kopiert, habs direkt mal raus genommen. Da ich es mit jupyter ausgeführt habe, war nichts mit einem mal copy&paste sondern ich hab abschnitt für abschnitt übernommen.

edit: Den rest verstehe ich nicht ganz...im originalen code geht die vorhersage nur soweit wie es auch Daten zum Vergleich gibt (Testdaten). Deshalb habe ich diese einfach erweitert, nur genau das funktioniert ja nicht.


Antwort
Zitat
Rho0
Joined: 20.10.2008

in prepare_data werden die daten so manipuliert, dass x_1 immer 0 ist, hast du daran gedacht, als du deine eigene erweiterung der daten programmiert hast?

edit: übrigens, diese normalisierung ist übelster mist, normalerweise normalisiert man den kompletten datensatz.
weiterhin kommt mir fishy vor, dass der train-test-split 80:20 ist. das ist per se nicht schlimm, aber laut dem github-code schaut er sich im original nur 16 monate an, d.h. im testset sind vielleicht 80 tage. da ist auch viel zufall dabei. und eine dropout-rate von 0.2 kann man sich eigentlich auch sparen.

ne, insgesamt halte ich den code für müll.


Antwort
Zitat
pg89
Joined: 05.04.2008

Ich erweitere ja die Daten ganz am Anfang, das heißt meine Erweiterung geht ja in die prepare_data Funktion mit rein.

Ja, der Zeitraum ist winzig...deshalb habe ich ihn direkt mal auf die 2000 Tage erweitert. Da passt es dann aber immernoch ziemlich genau. Und irgendwie würde mich interessieren, was genau da Faul ist.
Danke dir auf jeden Fall für deine Antworten bisher :)


Antwort
Zitat
pg89
Joined: 05.04.2008

Für alle die es interessiert: auf github wurde inzwischen auch angemerkt, dass sein code unsinn ist:
https://github.com/abhinavsagar/Cryptocurrency-Price-Prediction/issues/1
https://github.com/abhinavsagar/Cryptocurrency-Price-Prediction/issues/2


Antwort
Zitat