Search code examples
pythontensorflowmachine-learningkeraslstm

Keras LSTM index order (ascending or decending) and seeing string attached to 1 in binary classification


When doing an LSTM should the datetime index be ascending or decending? What I mean is should the head of the dataset be 2014 and the tail 2020 or the other way around? The reason I'm asking about this is because of the LSTM lookback period, I'm afraid that if it is not sorted correctly, then it will look into the wrong timeframe.

My current timeframe index when doing print(df) looks like this:

2014-21-3 XYZ
2014-22-3 XYZ
2014-23-3 XYZ

Should it be changed to this order instead for the LSTM to "work"?

2014-23-3 XYZ
2014-22-3 XYZ
2014-21-3 XYZ

Also when I am loading in a dataset which has a binary response variable that fluctuates between the two strings "Up" and "Down". When doing a keras model it will output probabilities for the 1 value, however how do I know which string is 1 and which is the 0?

Also if the answer is do predict_classification then I'm sorry, that's not what I'm looking for here (just a heads up, since I've seen similar questions with that answer).


Solution

  • you must use increasing order...

    2014-21-3 XYZ
    2014-22-3 XYZ
    2014-23-3 XYZ
    

    EDIT (how to interpret probabilities):

    you can encode Up as class 1 and Down as class 0

    label = ['up','down','up','up','down']
    
    map_label = {'up':1,'down':0}
    
    [map_label[l] for l in label]
    # ===> [1, 0, 1, 1, 0]
    

    you have two choices on how to interpret the output of a classification problem. it depends on the activation output you choose (sigmoid or softmax)

    the sigmoid activation function is used to generate probabilities in binary classification problems. in this case, the model output an array of probabilities with shape equal to the length of the sample to predict. we can retrieve the predicted class simply checking the probability score... if it's above 0.5 (this is a common practice but u can also change it according to your needs) the sample belongs to the class 1 else it belongs to the class 0. in case of sigmoid, your last output layer must be Dense(1, activation='sigmoid')

    n_sample = 10
    timestemp = 5
    n_features = 3
    X = np.random.uniform(0,1, (n_sample, timestemp, n_features))
    y = np.random.randint(0,2, n_sample)
    
    inp = Input((timestemp,n_features))
    x = LSTM(8, activation='relu')(inp)
    out = Dense(1, activation='sigmoid')(x)
    
    model = Model(inp, out)
    model.compile('adam', 'binary_crossentropy')
    model.fit(X,y, epochs=3)
    
    preds = model.predict(X) # (n_samples, 1)
    y_classes = ((preds > 0.5)+0).ravel() # Up == 1 and Down == 0
    

    in the case of softmax, the predicted class are retrieved using argmax and your last output layer must be Dense(n_classes, activation='softmax')

    n_sample = 10
    timestemp = 5
    n_features = 3
    X = np.random.uniform(0,1, (n_sample, timestemp, n_features))
    y = np.random.randint(0,2, n_sample)
    
    inp = Input((timestemp,n_features))
    x = LSTM(8, activation='relu')(inp)
    out = Dense(2, activation='softmax')(x)
    
    model = Model(inp, out)
    model.compile('adam', 'sparse_categorical_crossentropy')
    model.fit(X,y, epochs=3)
    
    preds = model.predict(X) # (n_samples, n_class)
    y_classes = np.argmax(preds , axis=1)  # Up == 1 and Down == 0
    

    I remain at disposal