I am using CNN to do deep learning on phishing detection. Help me do 3 things:
1. Improve my current implementation
2. Improve current implementation by using hyperparameter tuning and other methods
3. Use character level CNN: only use url column to do CNN based on the url.

For each of the implementation, give me the entire code. Also, implement it such a way that it gives the results of the trained model, as well as save the best model. Also teach me how to predict future datas using the trained model for all 3.

Current implementation:
# Import packages
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.feature_selection import VarianceThreshold
import seaborn as sns
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LassoCV
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.metrics import (accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, classification_report, confusion_matrix)
# Read data
data = pd.read_csv('dataset_phishing.csv')
features = ['shortest_word_path',
 'ratio_intMedia',
 'links_in_tags',
 'nb_hyphens',
 'page_rank',
 'avg_word_path',
 'ratio_extHyperlinks',
 'longest_words_raw',
 'google_index',
 'length_hostname',
 'longest_word_host',
 'domain_registration_length',
 'nb_www',
 'nb_underscore',
 'nb_dots',
 'ratio_extMedia',
 'phish_hints',
 'domain_in_title',
 'web_traffic',
 'safe_anchor',
 'nb_space',
 'shortening_service',
 'ip',
 'domain_age',
 'nb_qm',
 'nb_hyperlinks',
 'nb_slash']

X = data[features]
y = data['status']  # Assuming you have a 'label' column for phishing (1) or legitimate (0) sites

# Check for any missing values and handle them if necessary
X.fillna(0, inplace=True)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_reshaped = np.expand_dims(X_scaled, axis=2)  # Adding a dimension to fit (samples, timesteps, features)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv1D, MaxPooling1D, Flatten, Dense, Dropout

# Define CNN model
model = Sequential()

# Add Conv1D layer
model.add(Conv1D(filters=32, kernel_size=3, activation='relu', input_shape=(X_reshaped.shape[1], 1)))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.25))

# Add more Conv1D layers (optional)
model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.25))

# Flatten the output before Dense layers
model.add(Flatten())

# Dense layers for classification
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))  # Use 'sigmoid' for binary classification

# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import numpy as np

# Convert labels to binary values (0/1)
label_encoder = LabelEncoder()
y_encoded = label_encoder.fit_transform(y)

# Ensure features and labels are numeric
X_reshaped = X_reshaped.astype(float)
y_encoded = y_encoded.astype(float)

# Split data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(X_reshaped, y_encoded, test_size=0.2, random_state=42)

# Train the model
model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test))
# Evaluate the model
loss, accuracy = model.evaluate(X_test, y_test)
print(f"Test Accuracy: {accuracy:.4f}")