In [2]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.metrics import accuracy_score, classification_report
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.cluster import KMeans

# ------------------------------------
# LOAD DATA
# ------------------------------------
df = pd.read_csv("online_gaming_behavior_dataset.csv")
print("\nDataset loaded:", df.shape)
print(df.head())

# ------------------------------------
# ENCODE TARGET
# ------------------------------------
le = LabelEncoder()
df["EngagementLevelEncoded"] = le.fit_transform(df["EngagementLevel"])

# ------------------------------------
# ONE-HOT ENCODE CATEGORICAL FEATURES
# ------------------------------------
categorical_cols = ["Gender", "Location", "GameGenre", "GameDifficulty"]
df = pd.get_dummies(df, columns=categorical_cols, drop_first=True)

# ------------------------------------
# SELECT FEATURES (ALL EXCEPT ID + TARGET)
# ------------------------------------
feature_cols = [col for col in df.columns if col not in ["PlayerID", "EngagementLevel", "EngagementLevelEncoded"]]
X = df[feature_cols]
y = df["EngagementLevelEncoded"]

# ------------------------------------
# TRAIN / TEST SPLIT
# ------------------------------------
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# ------------------------------------
# SCALING
# ------------------------------------
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# ------------------------------------
# DECISION TREE RESULTS
# ------------------------------------
print("\n========== DECISION TREE ==========")
try:
    dt = DecisionTreeClassifier(random_state=42)
    dt.fit(X_train_scaled, y_train)
    dt_pred = dt.predict(X_test_scaled)

    print("Accuracy:", accuracy_score(y_test, dt_pred))
    print(classification_report(y_test, dt_pred))
except Exception as e:
    print("Decision Tree error:", e)

# -----------------------------
# SVM RESULTS
# -------------------------------
print("\n========== SVM RESULTS (Linear SVM – fast + reliable) ==========")
try:
    from sklearn.svm import LinearSVC

    svm = LinearSVC(random_state=42, max_iter=5000)
    svm.fit(X_train_scaled, y_train)
    svm_pred = svm.predict(X_test_scaled)

    print("Accuracy:", accuracy_score(y_test, svm_pred))
    print(classification_report(y_test, svm_pred))

except Exception as e:
    print("SVM error:", e)


# ============================================
# K-MEANS CLUSTERING + PCA 2D VISUALISATION
# ============================================

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

# --------------------------------------------
# Select numeric features for clustering
# (Use whatever features you want here; these work well)
# --------------------------------------------
cluster_features = [
    'PlayTimeHours',
    'InGamePurchases',
    'SessionsPerWeek',
    'AvgSessionDurationMinutes',
    'PlayerLevel',
    'AchievementsUnlocked'
]

X_cluster = df[cluster_features]

# --------------------------------------------
# Scale data
# --------------------------------------------
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_cluster)

# --------------------------------------------
# Run K-Means
# --------------------------------------------
kmeans = KMeans(n_clusters=3, random_state=42, n_init='auto')
clusters = kmeans.fit_predict(X_scaled)

# Add cluster labels to dataset
df['Cluster'] = clusters

# --------------------------------------------
# Evaluate clustering
# --------------------------------------------
sil = silhouette_score(X_scaled, clusters)
print("\n--- K-Means Clustering Results ---")
print("Silhouette Score:", sil)
print("Inertia:", kmeans.inertia_)

# --------------------------------------------
# PCA FOR 2D VISUALISATION
# --------------------------------------------
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# --------------------------------------------
# Plot PCA clusters
# --------------------------------------------
plt.figure(figsize=(8,6))
plt.scatter(X_pca[:,0], X_pca[:,1], c=clusters, cmap='viridis', s=40)
plt.title("PCA 2D Cluster Visualisation")
plt.xlabel("PCA Component 1")
plt.ylabel("PCA Component 2")
plt.grid(True)
plt.show()

# --------------------------------------------
# Print cluster centroids (REAL interpretation)
# --------------------------------------------
centroids = scaler.inverse_transform(kmeans.cluster_centers_)
centroids_df = pd.DataFrame(centroids, columns=cluster_features)

print("\n--- Cluster Centroids (Original Scale) ---")
print(centroids_df)


# ------------------------------------
# CLUSTER VISUALISATION
# ------------------------------------
try:
    plt.figure(figsize=(8,6))
    plt.scatter(df["PlayTimeHours"], df["SessionsPerWeek"], c=df["Cluster"], s=40)
    plt.xlabel("PlayTimeHours")
    plt.ylabel("SessionsPerWeek")
    plt.title("K-Means Clustering")
    plt.show()
except Exception as e:
    print("Plot error:", e)

print("\n========== SVM DECISION BOUNDARY (FAST VERSION) ==========")
try:
    from sklearn.svm import LinearSVC
    
    # Train fast linear SVM on first 2 features
    X2 = X_train_scaled[:, :2]
    svm2 = LinearSVC(random_state=42, max_iter=5000)
    svm2.fit(X2, y_train)

    # Small grid for very fast plotting
    x_min, x_max = X2[:,0].min() - 1, X2[:,0].max() + 1
    y_min, y_max = X2[:,1].min() - 1, X2[:,1].max() + 1

    xx, yy = np.meshgrid(
        np.linspace(x_min, x_max, 50),   # drastically reduced
        np.linspace(y_min, y_max, 50)
    )

    Z = svm2.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

    plt.figure(figsize=(8,6))
    plt.contourf(xx, yy, Z, alpha=0.3)
    plt.scatter(X2[:,0], X2[:,1], c=y_train, edgecolor='k', s=40)
    plt.title("Linear SVM Decision Boundary (Fast Plot)")
    plt.xlabel("Feature 1 (scaled)")
    plt.ylabel("Feature 2 (scaled)")
    plt.show()

except Exception as e:
    print("Decision boundary error:", e)

print("\n\n===== SCRIPT FINISHED WITH NO INTERRUPTIONS =====\n")
Dataset loaded: (40034, 13)
   PlayerID  Age  Gender Location GameGenre  PlayTimeHours  InGamePurchases  \
0      9000   43    Male    Other  Strategy      16.271119                0   
1      9001   29  Female      USA  Strategy       5.525961                0   
2      9002   22  Female      USA    Sports       8.223755                0   
3      9003   35    Male      USA    Action       5.265351                1   
4      9004   33    Male   Europe    Action      15.531945                0   

  GameDifficulty  SessionsPerWeek  AvgSessionDurationMinutes  PlayerLevel  \
0         Medium                6                        108           79   
1         Medium                5                        144           11   
2           Easy               16                        142           35   
3           Easy                9                         85           57   
4         Medium                2                        131           95   

   AchievementsUnlocked EngagementLevel  
0                    25          Medium  
1                    10          Medium  
2                    41            High  
3                    47          Medium  
4                    37          Medium  

========== DECISION TREE ==========
Accuracy: 0.8317721993255901
              precision    recall  f1-score   support

           0       0.80      0.82      0.81      2035
           1       0.79      0.80      0.80      2093
           2       0.87      0.85      0.86      3879

    accuracy                           0.83      8007
   macro avg       0.82      0.83      0.82      8007
weighted avg       0.83      0.83      0.83      8007


========== SVM RESULTS (Linear SVM – fast + reliable) ==========
Accuracy: 0.8211564880729362
              precision    recall  f1-score   support

           0       0.85      0.85      0.85      2035
           1       0.81      0.72      0.76      2093
           2       0.81      0.86      0.84      3879

    accuracy                           0.82      8007
   macro avg       0.82      0.81      0.82      8007
weighted avg       0.82      0.82      0.82      8007


--- K-Means Clustering Results ---
Silhouette Score: 0.11325609761258085
Inertia: 191888.45986228046
No description has been provided for this image
--- Cluster Centroids (Original Scale) ---
   PlayTimeHours  InGamePurchases  SessionsPerWeek  AvgSessionDurationMinutes  \
0      12.008540         0.200854         9.360393                 127.029556   
1      11.994308         0.197475         9.481528                  43.065201   
2      12.075474         0.204855         9.569576                 124.363061   

   PlayerLevel  AchievementsUnlocked  
0    49.244342             11.228638  
1    49.613668             24.139087  
2    50.108871             38.039927  
No description has been provided for this image
========== SVM DECISION BOUNDARY (FAST VERSION) ==========
No description has been provided for this image

===== SCRIPT FINISHED WITH NO INTERRUPTIONS =====

In [ ]: