# -*- coding: utf-8 -*-
"""
Created on Wed May 10 17:39:12 2023

@author: user
"""

# Load libraries
import numpy as np
from keras.datasets import reuters
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.text import Tokenizer
from keras import models
from keras import layers
import tensorflow as tf
# Set random seed
import random
random.seed(0)
np.random.seed(0)
tf.random.set_seed(0)
# Set the number of features we want
number_of_features = 5000
# Load feature and target data
data = reuters.load_data(num_words=number_of_features)
(data_train, target_vector_train), (data_test, target_vector_test) = data
# Convert feature data to a one-hot encoded feature matrix
tokenizer = Tokenizer(num_words=number_of_features)
features_train = tokenizer.sequences_to_matrix(data_train, mode="binary")
features_test = tokenizer.sequences_to_matrix(data_test, mode="binary")
# One-hot encode target vector to create a target matrix
target_train = to_categorical(target_vector_train)
target_test = to_categorical(target_vector_test)
# Start neural network
network = models.Sequential()
# Add fully connected layer with a ReLU activation function
network.add(layers.Dense(units=100,activation="relu",input_shape=(number_of_features,)))
# Add fully connected layer with a ReLU activation function
network.add(layers.Dense(units=100, activation="relu"))
# Add fully connected layer with a ReLU activation function
network.add(layers.Dense(units=50, activation="relu"))
# Add fully connected layer with a softmax activation function
network.add(layers.Dense(units=46, activation="softmax"))
# Compile neural network
network.compile(loss="categorical_crossentropy", # Cross-entropy
optimizer="rmsprop", # Root Mean Square Propagation
metrics=["accuracy"]) # Accuracy performance metric
# Train neural network
history = network.fit(features_train, # Features
target_train, # Target
epochs=3, # Three epochs
verbose=1,  
batch_size=100, # Number of observations per batch
validation_data=(features_test, target_test)) # Test data



from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, confusion_matrix
import numpy as np

# Predict probabilities for test data
predicted_probabilities = network.predict(features_test)

# Convert probabilities to class labels (argmax gives the class with the highest probability)
predicted_labels = np.argmax(predicted_probabilities, axis=1)

# Convert one-hot encoded targets to class labels
true_labels = np.argmax(target_test, axis=1)

# Calculate Accuracy
accuracy = accuracy_score(true_labels, predicted_labels)

# Calculate Precision, Recall, and F1-Score (macro and weighted averages are useful for multi-class)
precision = precision_score(true_labels, predicted_labels, average='weighted')  # Use 'weighted' for imbalance handling
recall = recall_score(true_labels, predicted_labels, average='weighted')       # Use 'weighted' for imbalance handling
f1 = f1_score(true_labels, predicted_labels, average='weighted')               # Use 'weighted' for imbalance handling

# Print metrics
print(f"Accuracy: {accuracy}")
print(f"Precision (Weighted): {precision}")
print(f"Recall (Weighted): {recall}")
print(f"F1-Score (Weighted): {f1}")

# Detailed Classification Report
print("\nClassification Report:")
print(classification_report(true_labels, predicted_labels))

# Confusion Matrix
conf_matrix = confusion_matrix(true_labels, predicted_labels)
print("\nConfusion Matrix:")
print(conf_matrix)

# Visualize Confusion Matrix
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(12, 10))
sns.heatmap(conf_matrix, annot=True, fmt="d", cmap="Blues", xticklabels=range(46), yticklabels=range(46))
plt.xlabel("Predicted Label")
plt.ylabel("True Label")
plt.title("Confusion Matrix")
plt.show()