In [13]:
import os

print("Current working directory:")
print(os.getcwd())

print("\nFiles in this folder:")
print(os.listdir())
Current working directory:
C:\Users\User\AI_MachineLearningAssignment(CodeV2)

Files in this folder:
['.ipynb_checkpoints', 'AI_MachineLearningAssignment.ipynb', 'online_gaming_behavior_dataset.csv']
In [14]:
import pandas as pd

df = pd.read_csv("online_gaming_behavior_dataset.csv")
df.head()
Out[14]:
PlayerID Age Gender Location GameGenre PlayTimeHours InGamePurchases GameDifficulty SessionsPerWeek AvgSessionDurationMinutes PlayerLevel AchievementsUnlocked EngagementLevel
0 9000 43 Male Other Strategy 16.271119 0 Medium 6 108 79 25 Medium
1 9001 29 Female USA Strategy 5.525961 0 Medium 5 144 11 10 Medium
2 9002 22 Female USA Sports 8.223755 0 Easy 16 142 35 41 High
3 9003 35 Male USA Action 5.265351 1 Easy 9 85 57 47 Medium
4 9004 33 Male Europe Action 15.531945 0 Medium 2 131 95 37 Medium
In [15]:
# ===========================
# 1. IMPORT LIBRARIES
# ===========================

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, GridSearchCV
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
In [16]:
# ===========================
# 2. LOAD DATA
# ===========================

df = pd.read_csv("online_gaming_behavior_dataset.csv")

df.head()
Out[16]:
PlayerID Age Gender Location GameGenre PlayTimeHours InGamePurchases GameDifficulty SessionsPerWeek AvgSessionDurationMinutes PlayerLevel AchievementsUnlocked EngagementLevel
0 9000 43 Male Other Strategy 16.271119 0 Medium 6 108 79 25 Medium
1 9001 29 Female USA Strategy 5.525961 0 Medium 5 144 11 10 Medium
2 9002 22 Female USA Sports 8.223755 0 Easy 16 142 35 41 High
3 9003 35 Male USA Action 5.265351 1 Easy 9 85 57 47 Medium
4 9004 33 Male Europe Action 15.531945 0 Medium 2 131 95 37 Medium
In [17]:
# ===========================
# 3. EXPLORATORY DATA ANALYSIS (EDA)
# ===========================

# Dataset shape and info
print("Dataset shape:", df.shape)
print("\nDataset info:")
print(df.info())

# Check missing values
print("\nMissing values per column:")
print(df.isnull().sum())

# Summary statistics
print("\nSummary statistics of numerical features:")
print(df.describe())
Dataset shape: (40034, 13)

Dataset info:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 40034 entries, 0 to 40033
Data columns (total 13 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   PlayerID                   40034 non-null  int64  
 1   Age                        40034 non-null  int64  
 2   Gender                     40034 non-null  object 
 3   Location                   40034 non-null  object 
 4   GameGenre                  40034 non-null  object 
 5   PlayTimeHours              40034 non-null  float64
 6   InGamePurchases            40034 non-null  int64  
 7   GameDifficulty             40034 non-null  object 
 8   SessionsPerWeek            40034 non-null  int64  
 9   AvgSessionDurationMinutes  40034 non-null  int64  
 10  PlayerLevel                40034 non-null  int64  
 11  AchievementsUnlocked       40034 non-null  int64  
 12  EngagementLevel            40034 non-null  object 
dtypes: float64(1), int64(7), object(5)
memory usage: 4.0+ MB
None

Missing values per column:
PlayerID                     0
Age                          0
Gender                       0
Location                     0
GameGenre                    0
PlayTimeHours                0
InGamePurchases              0
GameDifficulty               0
SessionsPerWeek              0
AvgSessionDurationMinutes    0
PlayerLevel                  0
AchievementsUnlocked         0
EngagementLevel              0
dtype: int64

Summary statistics of numerical features:
           PlayerID           Age  PlayTimeHours  InGamePurchases  \
count  40034.000000  40034.000000   40034.000000     40034.000000   
mean   29016.500000     31.992531      12.024365         0.200854   
std    11556.964675     10.043227       6.914638         0.400644   
min     9000.000000     15.000000       0.000115         0.000000   
25%    19008.250000     23.000000       6.067501         0.000000   
50%    29016.500000     32.000000      12.008002         0.000000   
75%    39024.750000     41.000000      17.963831         0.000000   
max    49033.000000     49.000000      23.999592         1.000000   

       SessionsPerWeek  AvgSessionDurationMinutes   PlayerLevel  \
count     40034.000000               40034.000000  40034.000000   
mean          9.471774                  94.792252     49.655568   
std           5.763667                  49.011375     28.588379   
min           0.000000                  10.000000      1.000000   
25%           4.000000                  52.000000     25.000000   
50%           9.000000                  95.000000     49.000000   
75%          14.000000                 137.000000     74.000000   
max          19.000000                 179.000000     99.000000   

       AchievementsUnlocked  
count          40034.000000  
mean              24.526477  
std               14.430726  
min                0.000000  
25%               12.000000  
50%               25.000000  
75%               37.000000  
max               49.000000  
In [18]:
# ===========================
# 4. DATA PREPROCESSING
# ===========================

# Separate features (X) and target (y)
X = df.drop('EngagementLevel', axis=1)
y = df['EngagementLevel']

# Encode target variable
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
y = encoder.fit_transform(y)

# Encode categorical features using one-hot encoding
cat_cols = X.select_dtypes(include=['object']).columns
X = pd.get_dummies(X, columns=cat_cols, drop_first=True)

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

# Scale features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
In [19]:
# ===========================
# 5. DECISION TREE MODEL
# ===========================

# Train Decision Tree
dt_model = DecisionTreeClassifier(random_state=42)
dt_model.fit(X_train, y_train)

# Predict on test data
y_pred_dt = dt_model.predict(X_test)

# Evaluate performance
print("Decision Tree Performance:")
print("Accuracy:", accuracy_score(y_test, y_pred_dt))
print(classification_report(y_test, y_pred_dt))

# Confusion matrix
sns.heatmap(confusion_matrix(y_test, y_pred_dt), annot=True, fmt='d', cmap='Blues')
plt.title("Decision Tree Confusion Matrix")
plt.show()
Decision Tree Performance:
Accuracy: 0.8292743849132009
              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.82      0.82      8007
weighted avg       0.83      0.83      0.83      8007

No description has been provided for this image
In [20]:
# ===========================
# 6. SAFE SVM MODEL
# ===========================

from sklearn.svm import SVC

# --- Safety checks ---
required_vars = ["X_train", "X_test", "y_train", "y_test"]
for v in required_vars:
    if v not in globals():
        raise ValueError(f"❌ ERROR: '{v}' is not defined. Run preprocessing first.")

# --- Train SVM  ---
print("Training SVM...")

svm_model = SVC(kernel="linear", probability=True, random_state=42)

svm_model.fit(X_train, y_train)

# --- Predict ---
y_pred_svm = svm_model.predict(X_test)

# --- Evaluate ---
print("\nSVM Performance:")
print("Accuracy:", accuracy_score(y_test, y_pred_svm))
print(classification_report(y_test, y_pred_svm))

# --- Confusion matrix ---
plt.figure(figsize=(6,4))
sns.heatmap(confusion_matrix(y_test, y_pred_svm), annot=True, fmt='d', cmap='YlOrBr')
plt.title("SVM Confusion Matrix (Linear Kernel)")
plt.show()

print("\n✔️ SVM Completed Successfully")
Training SVM...

SVM Performance:
Accuracy: 0.8239040839265642
              precision    recall  f1-score   support

           0       0.88      0.84      0.86      2035
           1       0.80      0.71      0.75      2093
           2       0.81      0.87      0.84      3879

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

No description has been provided for this image
✔️ SVM Completed Successfully
In [21]:
# ===========================
# 7. HYPERPARAMETER TUNING
# ===========================

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC, LinearSVC

print("Tuning Decision Tree (fast mode)...")

# ----- Decision Tree -----
dt_params = {
    'max_depth': [5, 10, None],
    'min_samples_split': [2, 5],
    'min_samples_leaf': [1, 2]
}

grid_dt = GridSearchCV(
    DecisionTreeClassifier(random_state=42),
    dt_params,
    cv=3,
    n_jobs=-1
)

grid_dt.fit(X_train, y_train)
print("Best Decision Tree Parameters:", grid_dt.best_params_)


print("\nTuning SVM (ultra-fast mode)...")

# ----- SVM -----

svm_params = {
    'C': [1, 10],          # two key values
    'kernel': ['linear', 'rbf'],
    'gamma': ['scale']     # keep simple
}

# Remove probability=True
svm_tuner = GridSearchCV(
    SVC(random_state=42),
    svm_params,
    cv=3,
    n_jobs=-1
)

grid_svm = svm_tuner.fit(X_train, y_train)

print("Best SVM Parameters:", grid_svm.best_params_)
Tuning Decision Tree (fast mode)...
Best Decision Tree Parameters: {'max_depth': 10, 'min_samples_leaf': 2, 'min_samples_split': 5}

Tuning SVM (ultra-fast mode)...
Best SVM Parameters: {'C': 1, 'gamma': 'scale', 'kernel': 'rbf'}
In [22]:
# ===========================
# 8. K-MEANS CLUSTERING
# ===========================

# Use numeric features for clustering
X_cluster = X.copy()

# Scale features
scaler_cluster = StandardScaler()
X_cluster_scaled = scaler_cluster.fit_transform(X_cluster)

# Fit KMeans with 3 clusters
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(X_cluster_scaled)

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

# Evaluate clustering
from sklearn.metrics import silhouette_score
sil_score = silhouette_score(X_cluster_scaled, clusters)
print("Silhouette Score:", sil_score)
print("Inertia (sum of squared distances):", kmeans.inertia_)
Silhouette Score: 0.09307777405003374
Inertia (sum of squared distances): 630355.4553414898
In [23]:
# ===========================
# 9. CLUSTER ANALYSIS
# ===========================

# Imports
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import seaborn as sns
import matplotlib.pyplot as plt

# ---------------------------
# Step 1: Select features for clustering
# ---------------------------
numerical_cols = [
    'Age', 'PlayTimeHours', 'InGamePurchases', 
    'SessionsPerWeek', 'AvgSessionDurationMinutes', 
    'PlayerLevel', 'AchievementsUnlocked'
]

X_cluster = df[numerical_cols]

# ---------------------------
# Step 2: Scale features
# ---------------------------
scaler = StandardScaler()
X_cluster_scaled = scaler.fit_transform(X_cluster)

# ---------------------------
# Step 3: Run KMeans clustering
# ---------------------------
kmeans = KMeans(n_clusters=3, random_state=42)
df['Cluster'] = kmeans.fit_predict(X_cluster_scaled)

# ---------------------------
# Step 4: Inspect cluster centers
# ---------------------------
centers = kmeans.cluster_centers_
print("Cluster Centers (scaled features):\n", centers)

# ---------------------------
# Step 5: Visualize clusters using PCA
# ---------------------------
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_cluster_scaled)

plt.figure(figsize=(8,6))
sns.scatterplot(
    x=X_pca[:,0], y=X_pca[:,1], 
    hue=df['Cluster'], palette="Set1", s=60
)
plt.title("Clusters visualized with PCA")
plt.xlabel("PCA Component 1")
plt.ylabel("PCA Component 2")
plt.legend(title="Cluster")
plt.show()

# ---------------------------
# Step 6: Feature distribution per cluster
# ---------------------------
for col in numerical_cols:
    plt.figure(figsize=(6,4))
    sns.boxplot(x='Cluster', y=col, data=df)
    plt.title(f"{col} by Cluster")
    plt.show()
Cluster Centers (scaled features):
 [[-3.45407674e-02 -1.38549197e-02  2.24316396e-02 -2.10868206e-02
   6.02720922e-01 -1.02833440e-02 -9.47706482e-01]
 [-1.25802647e-02  1.43480370e-02 -2.13227685e-03  1.17360385e-02
   6.52602358e-01  1.24960500e-02  9.12367386e-01]
 [ 3.96548682e-02 -3.15063522e-04 -1.71360773e-02  7.96921744e-03
  -1.05419038e+00 -1.77843301e-03  3.62187023e-02]]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [24]:
# ===========================
# 10. MODEL COMPARISON
# ===========================

# Compare Decision Tree vs SVM
comparison = pd.DataFrame({
    'Model': ['Decision Tree', 'SVM'],
    'Accuracy': [accuracy_score(y_test, y_pred_dt), accuracy_score(y_test, y_pred_svm)],
    'Precision': [precision_score(y_test, y_pred_dt, average='weighted'), precision_score(y_test, y_pred_svm, average='weighted')],
    'Recall': [recall_score(y_test, y_pred_dt, average='weighted'), recall_score(y_test, y_pred_svm, average='weighted')],
    'F1 Score': [f1_score(y_test, y_pred_dt, average='weighted'), f1_score(y_test, y_pred_svm, average='weighted')]
})
print(comparison)
           Model  Accuracy  Precision    Recall  F1 Score
0  Decision Tree  0.829274   0.829885  0.829274  0.829511
1            SVM  0.823904   0.824399  0.823904  0.822742
In [ ]: