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
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
✔️ 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]]
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 [ ]: