# -*- coding: utf-8 -*-
"""Example of using Adversarially Learned Anomaly Detection (ALAD) for outlier
detection
"""
from __future__ import division
from __future__ import print_function

import os
import sys

# temporary solution for relative imports in case pyod is not installed
# if pyod is installed, no need to use the following line
sys.path.append(
    os.path.abspath(os.path.join(os.path.dirname("__file__"), '..')))

from pyod.models.alad import ALAD
from pyod.utils.data import generate_data

from pyod.utils.data import evaluate_print
from pyod.utils.example import visualize

if __name__ == "__main__":
    contamination = 0.1  # percentage of outliers
    n_train = 500  # number of training points
    n_test = 200  # number of testing points

    # Generate sample data
    X_train, X_test, y_train, y_test = \
        generate_data(n_train=n_train,
                      n_test=n_test,
                      n_features=2,
                      contamination=contamination,
                      random_state=42)

    # train ALAD detector
    clf_name = 'ALAD'
    clf = ALAD(epochs=100, latent_dim=2,
               learning_rate_disc=0.0001,
               learning_rate_gen=0.0001,
               dropout_rate=0.2,
               add_recon_loss=False,
               lambda_recon_loss=0.05,
               add_disc_zz_loss=True,
               dec_layers=[75, 100],
               enc_layers=[100, 75],
               disc_xx_layers=[100, 75],
               disc_zz_layers=[25, 25],
               disc_xz_layers=[100, 75],
               spectral_normalization=False,
               activation_hidden_disc='tanh', activation_hidden_gen='tanh',
               preprocessing=True, batch_size=200, contamination=contamination)

    clf.fit(X_train)

    # get the prediction labels and outlier scores of the training data
    y_train_pred = clf.labels_  # binary labels (0: inliers, 1: outliers)
    y_train_scores = clf.decision_scores_  # raw outlier scores

    # get the prediction on the test data
    y_test_pred = clf.predict(X_test)  # outlier labels (0 or 1)
    y_test_scores = clf.decision_function(X_test)  # outlier scores

    # evaluate and print the results
    print("\nOn Training Data:")
    evaluate_print(clf_name, y_train, y_train_scores)
    print("\nOn Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)

    # visualize the results
    visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
              y_test_pred, show_figure=True, save_figure=False)
