# PART 1: DATA LOADING, EXPLORATION, PREPROCESSING & EDA
# Dissertation: GPS Spoofing Detection in UAV Communication



# 1. Import Libraries

import warnings
warnings.filterwarnings("ignore")

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.preprocessing import LabelEncoder, StandardScaler


# 2. Load Dataset

path = "/content/drone_communication_dataset.csv"
df = pd.read_csv(path)

print("="*60)
print("DATASET LOADED SUCCESSFULLY")
print("="*60)

print("\nFirst 5 Rows")
print(df.head())

print("\nLast 5 Rows")
print(df.tail())

print("\nDataset Shape:", df.shape)


# 3. Dataset Information

print("\nDataset Information")
print(df.info())

print("\nSummary Statistics")
print(df.describe())

print("\nMissing Values")
print(df.isnull().sum())

print("\nDuplicate Rows:", df.duplicated().sum())

print("\nData Types")
print(df.dtypes)


# 4. Feature Engineering


# Convert timestamp
df['timestamp'] = pd.to_datetime(df['timestamp'])

df['hour'] = df['timestamp'].dt.hour
df['day'] = df['timestamp'].dt.day
df['month'] = df['timestamp'].dt.month

# Split GPS Coordinates
gps = df['drone_gps_coordinates'].str.strip("()").str.split(",", expand=True)

df['latitude'] = gps[0].astype(float)
df['longitude'] = gps[1].astype(float)

# Drop Original Columns
df.drop(['timestamp','drone_gps_coordinates'], axis=1, inplace=True)

# Encode Categorical Columns
le = LabelEncoder()

for col in ['communication_protocol','encryption_type']:
    df[col] = le.fit_transform(df[col])

print("\nFeature Engineering Completed")


# 5. Feature Scaling


target = "label_gps_spoofing"

features = [c for c in df.columns if c != target]

scaler = StandardScaler()

df[features] = scaler.fit_transform(df[features])

print("Feature Scaling Completed")


# 6. Exploratory Data Analysis


# ---------- Graph 1 ----------
plt.figure(figsize=(6,4))
counts = df[target].value_counts()
counts.plot(kind="bar")

plt.title("GPS Spoofing Class Distribution")
plt.xlabel("Class")
plt.ylabel("Count")

for i,v in enumerate(counts):
    plt.text(i,v,str(v),ha='center')

plt.show()

print("\nClass Distribution")
print(counts)

# ---------- Graph 2 ----------
plt.figure(figsize=(8,6))
corr = df.corr(numeric_only=True)
plt.imshow(corr,cmap="coolwarm")
plt.colorbar()
plt.title("Correlation Heatmap")
plt.xticks([])
plt.yticks([])
plt.show()

print("\nHighest Correlation")
print(corr[target].sort_values(ascending=False).head(10))

# ---------- Graph 3 ----------
plt.figure(figsize=(6,4))
plt.hist(df["signal_strength"],bins=30)

plt.title("Signal Strength Distribution")
plt.xlabel("Signal Strength")
plt.ylabel("Frequency")

plt.show()

print("\nSignal Strength Statistics")
print(df["signal_strength"].describe())

# ---------- Graph 4 ----------
protocol_counts = pd.read_csv(path)["communication_protocol"].value_counts()

plt.figure(figsize=(6,4))
protocol_counts.plot(kind="bar")

plt.title("Communication Protocol")
plt.xlabel("Protocol")
plt.ylabel("Count")

for i,v in enumerate(protocol_counts):
    plt.text(i,v,str(v),ha='center')

plt.show()

print("\nProtocol Counts")
print(protocol_counts)

# ---------- Graph 5 ----------
plt.figure(figsize=(8,4))
plt.boxplot([
    df["signal_strength"],
    df["round_trip_time"],
    df["packet_loss_rate"]
],
labels=["Signal","RTT","Packet Loss"])

plt.title("Boxplot of Important Features")
plt.show()

print("\nMedian Values")
print(df[["signal_strength",
          "round_trip_time",
          "packet_loss_rate"]].median())


# 7. Save Cleaned Dataset


df.to_csv("/content/cleaned_drone_dataset.csv",index=False)

print("\nCleaned Dataset Saved Successfully")

print("\nFinal Dataset Shape:",df.shape)



# PART 2 : MACHINE LEARNING MODELS


import pandas as pd
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier


# Load Cleaned Dataset

df = pd.read_csv("/content/cleaned_drone_dataset.csv")

X = df.drop("label_gps_spoofing", axis=1)
y = df["label_gps_spoofing"]

X_train,X_test,y_train,y_test=train_test_split(
    X,y,test_size=0.2,random_state=42,stratify=y)


# Train Models

models={
    "Logistic Regression":LogisticRegression(max_iter=1000),
    "Decision Tree":DecisionTreeClassifier(random_state=42),
    "Random Forest":RandomForestClassifier(random_state=42),
    "XGBoost":XGBClassifier(eval_metric="logloss",random_state=42)
}

results={}

for name,model in models.items():
    model.fit(X_train,y_train)
    acc=cross_val_score(model,X,y,cv=5,scoring="accuracy").mean()
    results[name]=round(acc,4)

print("\nCross Validation Accuracy")
print(pd.DataFrame(results.items(),columns=["Model","Accuracy"]))


# Hyperparameter Tuning

params={
    "max_depth":[3,5],
    "n_estimators":[100,200]
}

grid=GridSearchCV(
    XGBClassifier(eval_metric="logloss"),
    params,
    cv=3,
    scoring="accuracy")

grid.fit(X_train,y_train)

best_model=grid.best_estimator_

print("\nBest Parameters")
print(grid.best_params_)

print("Best Accuracy:",round(grid.best_score_,4))


# Graph 1 : Decision Tree

plt.figure(figsize=(10,6))
plot_tree(
    models["Decision Tree"],
    max_depth=2,
    filled=True,
    feature_names=X.columns)

plt.title("Decision Tree")
plt.show()

print("Decision Tree Depth:",
      models["Decision Tree"].get_depth())


# Graph 2 : Feature Importance

importance=pd.Series(
    best_model.feature_importances_,
    index=X.columns).sort_values(ascending=False).head(10)

plt.figure(figsize=(8,5))
importance.plot(kind="bar")

plt.title("Top 10 Important Features")
plt.ylabel("Importance")
plt.show()

print("\nTop 10 Features")
print(importance)
