data = np.genfromtxt("data/ionosphere.data")

data = pd.read_csv('data/ionosphere.data', sep=",", header=None)
data.describe()

data.head()

data.drop(data.columns[1], inplace=True, axis=1)
data[34] = [1 if e is "g" else 0 for e in data[34]]
data.head()

# sample the dataframe
data_train = data.sample(frac=0.9, random_state=42)
data_valid = data.drop(data_train.index)

df_x_train = data_train.iloc[:,:-1]
df_y_train = data_train.iloc[:,-1]

df_x_valid = data_valid.iloc[:,:-1]
df_y_valid = data_valid.iloc[:,-1]

df_y_train.sum()

df_y_train.sum()/len(df_y_train)

"""
Explanation: Data Set Information
This radar data was collected by a system in Goose Bay, Labrador. This system consists of a phased array of 16 high-frequency antennas with a total transmitted power on the order of 6.4 kilowatts. See the paper for more details. The targets were free electrons in the ionosphere. "Good" radar returns are those showing evidence of some type of structure in the ionosphere. "Bad" returns are those that do not; their signals pass through the ionosphere. 
Received signals were processed using an autocorrelation function whose arguments are the time of a pulse and the pulse number. There were 17 pulse numbers for the Goose Bay system. Instances in this databse are described by 2 attributes per pulse number, corresponding to the complex values returned by the function resulting from the complex electromagnetic signal.
Attribute Information

All 34 are continuous 
The 35th attribute is either "good" or "bad" according to the definition summarized above. This is a binary classification task. 
https://archive.ics.uci.edu/ml/machine-learning-databases/ionosphere/ionosphere.names

Data Import and preprocessing
End of explanation
"""


x_train = np.array(df_x_train.as_matrix())
y_train = np.array(pd.DataFrame(df_y_train).as_matrix())

x_val = np.array(df_x_valid.as_matrix())
y_val = np.array(pd.DataFrame(df_y_valid).as_matrix())

input_dim = x_train.shape[1]

"""
Explanation: preprocessing
End of explanation
"""


result = []
for i in range(1,5):
    model = Sequential()
    model.add(Dense(15, input_dim=input_dim, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(15, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(15, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(1, activation='sigmoid'))

    model.compile(loss='binary_crossentropy',
                  optimizer='adadelta',
                  metrics=['accuracy'])

    model.fit(x_train, y_train, 
              epochs=150,
              shuffle=True,
              batch_size=4,
              verbose=0,
              validation_split=0.1
             )
    score = model.evaluate(x_val, y_val)[1]
    result.append(score)
print(np.mean(result))

"""
Explanation: Train Classifier
The goal is to get a very accurate classifier.
End of explanation
"""


result = []
for i in range(1,5):
    single_auto = Sequential()
    single_auto.add(Dense(8, input_dim=input_dim, activation='relu'))
    # model.add(Dropout(0.1))
    single_auto.add(Dense(input_dim, activation='sigmoid'))

    single_auto.compile(loss='mean_squared_error',
                  optimizer='adadelta')

    single_auto.fit(x_train, x_train, 
                      epochs=150,
                      shuffle=True,
                      batch_size=4,
                      verbose=0,
                      validation_split=0.1
                     )
    score = single_auto.evaluate(x_val, x_val)
    result.append(score)
print(np.mean(result))

"""
Explanation: Single Hidden Layer Autoencoder
End of explanation
"""


model.evaluate(single_auto.predict(x_val), y_val)

"""
Explanation: How well does a classifier after the vanilla autoencoder perform?
End of explanation
"""


######## constants for stacked autoencoder ############
encoding_dim1 = 16
encoding_dim2 = 8
decoding_dim1 = 16
decoding_dim2 = input_dim

result = []
for i in range(1,5):
    stacked_auto = Sequential()
    stacked_auto.add(Dense(encoding_dim1, input_dim=input_dim, activation='relu'))
    # model.add(Dropout(0.1))
    stacked_auto.add(Dense(encoding_dim2, activation='relu'))
    # model.add(Dropout(0.05))
    stacked_auto.add(Dense(decoding_dim1, activation='relu'))
    # model.add(Dropout(0.05))
    stacked_auto.add(Dense(decoding_dim2, activation='sigmoid'))

    stacked_auto.compile(loss='mean_squared_error',
                  optimizer='adadelta')

    stacked_auto.fit(x_train, x_train, 
                      epochs=150,
                      shuffle=True,
                      batch_size=4,
                      verbose=0,
                      validation_split=0.1
                     )
    score = stacked_auto.evaluate(x_val, x_val)
    result.append(score)
print(np.mean(score))

"""
Explanation: So we lose about 12% by decoding
Stacked Autoencoder
End of explanation
"""


