import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt
import torch

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

# Leemos los datos
cols=list(range(1,31))
D = np.genfromtxt( "creditcard.csv", delimiter=',', skip_header=1, usecols=cols, dtype=np.float32)
print( D.shape )

# De 0 a 27 son las características

A = StandardScaler().fit_transform( D[:,28].reshape(-1,1) )
print(A.shape)

D[:,28] = A[:,0]
print( D.shape )

Datos = torch.from_numpy( D )

# Leemos el modelo
class AE(torch.nn.Module):
    def __init__(self):
        super().__init__()
         
       
        self.encoder = torch.nn.Sequential(
            torch.nn.Linear(29, 20),
            torch.nn.Tanh(),
            torch.nn.Linear(20, 14),
            torch.nn.ReLU(),
        )
         
        self.decoder = torch.nn.Sequential(
            torch.nn.Linear(14, 20),
            torch.nn.Tanh(),
            torch.nn.Linear(20, 29),
            torch.nn.Tanh()
        )
 
    def forward(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return decoded


autoencoder = AE()

# autoencoder.load_state_dict(torch.load("Adam1270.pt", map_location=torch.device('cpu')))
autoencoder.load_state_dict(torch.load("adam00.pth", map_location=torch.device('cpu')))
autoencoder.to(device)

X_pred = autoencoder( Datos[:,0:29] )

ecm = np.mean(np.power( D[:,0:29]-X_pred.detach().numpy(),2), axis=1)

precision, recall, umbral = precision_recall_curve( D[:,29], ecm)
print( precision.shape )
print( recall.shape )
print( umbral.shape )

print( precision[1:10] )
print( recall[1:10] )
print( umbral[1:10] )

fig, ax = plt.subplots( )

ax.plot(umbral, precision[1:], label="Precisión",linewidth=5)
ax.plot(umbral, recall[1:], label="Sensitividad",linewidth=5)
plt.title('Precision y Recall para diferentes umbrales')
plt.xlabel('Umbral')
plt.ylabel('Precision/Sensitividad')
ax.set_xlim(0,50)
plt.legend()
plt.show()

