---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-1dcaf17b6567> in <cell line: 85>()
     83 # Convert sparse matrices to dense, if necessary.
     84 # Note: Be careful with large datasets; this can consume a lot of memory.
---> 85 X_train = X_train.toarray() if sparse.issparse(X_train) else X_train
     86 X_val = X_val.toarray() if sparse.issparse(X_val) else X_val
     87 X_test = X_test.toarray() if sparse.issparse(X_test) else X_test

NameError: name 'X_train' is not defined


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.metrics import confusion_matrix, roc_curve, auc
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from scipy import sparse
from tensorflow.keras.models import load_model
import joblib

# Loading the dataset
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
column_names = [
    "age", "workclass", "fnlwgt", "education", "education-num", "marital-status",
    "occupation", "relationship", "race", "sex", "capital-gain", "capital-loss",
    "hours-per-week", "native-country", "income"
]

df = pd.read_csv(url, names=column_names, na_values=" ?", skipinitialspace=True)
df['income'] = df['income'].str.strip().map({'>50K': 1, '<=50K': 0})

X = df.drop('income', axis=1)
y = df['income']

categorical_cols = X.select_dtypes(include=['object']).columns.tolist()
numerical_cols = X.select_dtypes(include=['int64', 'float64']).columns.tolist()

OneHotEncoder(handle_unknown='ignore')

# Preprocess the data function
def preprocess_data(X, categorical_cols, numerical_cols):
    # Define preprocessing for numerical columns (scale them)
    numerical_transformer = Pipeline(steps=[
        ('imputer', SimpleImputer(strategy='mean')),
        ('scaler', StandardScaler())
    ])
    
    # Define preprocessing for categorical columns (encode them)
    categorical_transformer = Pipeline(steps=[
        ('imputer', SimpleImputer(strategy='most_frequent')),
        ('onehot', OneHotEncoder(handle_unknown='ignore'))  # handle_unknown='ignore' is crucial
    ])
    
    # Bundle preprocessing for numerical and categorical data
    preprocessor = ColumnTransformer(
        transformers=[
            ('num', numerical_transformer, numerical_cols),
            ('cat', categorical_transformer, categorical_cols),
        ], remainder='passthrough'
    )
    
    X_processed = preprocessor.fit_transform(X)

    
    return X_processed, preprocessor

# Define the model
def build_model(input_shape):
    """Builds a neural network model suited for binary classification."""
    model = Sequential([
        Dense(64, activation='relu', input_shape=(input_shape,)),
        Dense(32, activation='relu'),
        Dense(1, activation='sigmoid')
    ])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

    # Save the trained model
    model.save('guacamole.h5')

    # Save the preprocessor
    joblib.dump(preprocessor, 'Pre-Processed.pkl')

    return model

# Continue from preprocessing…
# Convert sparse matrices to dense, if necessary.
# Note: Be careful with large datasets; this can consume a lot of memory.
X_train = X_train.toarray() if sparse.issparse(X_train) else X_train
X_val = X_val.toarray() if sparse.issparse(X_val) else X_val
X_test = X_test.toarray() if sparse.issparse(X_test) else X_test

# Define and compile your model correctly prior to this. Assume it's done.
model = build_model(X_train.shape[1])

# Train the model using manual validation set
history = model.fit(
    X_train, y_train,
    epochs=10,
    batch_size=32,
    validation_data=(X_val, y_val),  # Correct: Do NOT use validation_split here due to sparse array issue
    verbose=1
)

# model = build_model(X_train.shape[1])

# Train the model
# history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_split=0.2, verbose=1)

# Evaluate the model
train_acc = model.evaluate(X_train, y_train, verbose=0)[1]
test_acc = model.evaluate(X_test, y_test, verbose=0)[1]
print(f'Train: {train_acc:.3f}, Test: {test_acc:.3f}')

# Generate predictions and evaluate the model
y_pred_prob = model.predict(X_test).ravel()
y_pred = np.where(y_pred_prob > 0.5, 1, 0)

# Confusion Matrix
conf_matrix = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(6, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', cbar=False)
plt.title("Confusion Matrix")
plt.ylabel('Actual label')
plt.xlabel('Predicted label')
plt.show()

# ROC Curve & AUC
fpr, tpr, _ = roc_curve(y_test, y_pred_prob)
roc_auc = auc(fpr, tpr)

plt.figure(figsize=(6, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle=':')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()

# Training & Validation Loss and Accuracy Over Epochs
fig, ax = plt.subplots(1, 2, figsize=(14, 5))
ax[0].plot(history.history['loss'], label='Training Loss')
ax[0].plot(history.history['val_loss'], label='Validation Loss')
ax[0].set_title('Loss Over Epochs')
ax[0].set_xlabel('Epoch')
ax[0].set_ylabel('Loss')
ax[0].legend()

ax[1].plot(history.history['accuracy'], label='Training Accuracy')
ax[1].plot(history.history['val_accuracy'], label='Validation Accuracy')
ax[1].set_title('Accuracy Over Epochs')
ax[1].set_xlabel('Epoch')
ax[1].set_ylabel('Accuracy')
ax[1].legend()

plt.tight_layout()
plt.show()

# Load your pre-trained model and preprocessor
# This assumes you have saved your pre-trained model and preprocessor to file
model = load_model('guacamole.h5')
preprocessor = joblib.load('Pre-Processed.pkl')

def predict_income(user_input, preprocessor, model, column_names):
    # Split user input and strip spaces from each item
    input_values = [item.strip() for item in user_input.split(',')]
    
    # Create a DataFrame from the input_values, ensuring it matches the training data structure
    input_df = pd.DataFrame([input_values], columns=column_names[:-1])
    
    # Preprocess the input using the existing preprocessor
    X_processed = preprocessor.transform(input_df)
    
    # Convert to a dense array if the result is a sparse matrix
    if sparse.issparse(X_processed):
        X_processed = X_processed.toarray()

    # Make prediction
    prediction = model.predict(X_processed)
    predicted_class = ">50K" if prediction[0] > 0.5 else "<=50K"
    
    return predicted_class


# Assuming that all preprocess steps and model training happened above and using existing objects
sample_data = """
    Sample data format default input (dont change input format):
    Age, Workclass, Fnlwgt, Education, Education-num, Marital-status, Occupation, Relationship, Race, Sex, Capital-gain, Capital-loss, Hours-per-week, Native-country
    Example (input according to your needs but with above format):
    39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States
    (or)
    50, Self-emp-not-inc, 83311, Bachelors, 13, Married-civ-spouse, Exec-managerial, Husband, White, Male, 0, 0, 13, United-States
    (or)
    38, Private, 215646, HS-grad, 9, Divorced, Handlers-cleaners, Not-in-family, White, Male, 0, 0, 40, United-States
    (or)
    53, Private, 234721, 11th, 7, Married-civ-spouse, Handlers-cleaners, Husband, Black, Male, 0, 0, 40, United-States
"""

print(sample_data)
user_input = input("Please enter your data as shown in the example (comma-separated, no spaces after commas): ")
predicted_class = predict_income(user_input, preprocessor, model, column_names)
print(f"The predicted income class for the input data is: {predicted_class}")