In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

#data analysis and preprocessing
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

#Model Evaluation
from sklearn import metrics
from sklearn.metrics import confusion_matrix, classification_report, precision_recall_curve,recall_score

#decision tree
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt

#svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.ensemble import VotingClassifier
from sklearn.svm import SVC

#kmeans clustering
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

#ignore warnings
import warnings
warnings.filterwarnings("ignore")

#Loading dataset
df = pd.read_csv('online_gaming_behavior_dataset.csv')
df.head()
Out[1]:
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 [2]:
#Information about the dataset
df.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
In [3]:
#Checking Frequency of unique values in collums
df.nunique()
Out[3]:
PlayerID                     40034
Age                             35
Gender                           2
Location                         4
GameGenre                        5
PlayTimeHours                40034
InGamePurchases                  2
GameDifficulty                   3
SessionsPerWeek                 20
AvgSessionDurationMinutes      170
PlayerLevel                     99
AchievementsUnlocked            50
EngagementLevel                  3
dtype: int64
In [4]:
#Dropping collums irrelevent for prediction model
df=df.drop(['PlayerID'], axis=1)  # axis 1 means column

#Sorting data into numerical and catagorical collums
num_cols=['Age', 'PlayTimeHours','SessionsPerWeek','InGamePurchases','AvgSessionDurationMinutes','PlayerLevel','AchievementsUnlocked']

cat_cols= ['Gender','Location','GameGenre','GameDifficulty','EngagementLevel']
In [5]:
#Checking summary statistics
df[num_cols].describe().T
Out[5]:
count mean std min 25% 50% 75% max
Age 40034.0 31.992531 10.043227 15.000000 23.000000 32.000000 41.000000 49.000000
PlayTimeHours 40034.0 12.024365 6.914638 0.000115 6.067501 12.008002 17.963831 23.999592
SessionsPerWeek 40034.0 9.471774 5.763667 0.000000 4.000000 9.000000 14.000000 19.000000
InGamePurchases 40034.0 0.200854 0.400644 0.000000 0.000000 0.000000 0.000000 1.000000
AvgSessionDurationMinutes 40034.0 94.792252 49.011375 10.000000 52.000000 95.000000 137.000000 179.000000
PlayerLevel 40034.0 49.655568 28.588379 1.000000 25.000000 49.000000 74.000000 99.000000
AchievementsUnlocked 40034.0 24.526477 14.430726 0.000000 12.000000 25.000000 37.000000 49.000000
In [6]:
# Creation of histograms of data frequency
df[num_cols].hist(figsize=(14,14))
plt.show()
No description has been provided for this image
In [7]:
#printing the % of data in catagory collums
for i in cat_cols:
    print(df[i].value_counts (normalize=True))
    print('*'*40)
Gender
Male      0.598466
Female    0.401534
Name: proportion, dtype: float64
****************************************
Location
USA       0.399660
Europe    0.299845
Asia      0.202203
Other     0.098291
Name: proportion, dtype: float64
****************************************
GameGenre
Sports        0.201029
Action        0.200804
Strategy      0.200130
Simulation    0.199406
RPG           0.198631
Name: proportion, dtype: float64
****************************************
GameDifficulty
Easy      0.49995
Medium    0.30002
Hard      0.20003
Name: proportion, dtype: float64
****************************************
EngagementLevel
Medium    0.483939
High      0.258181
Low       0.257881
Name: proportion, dtype: float64
****************************************
In [8]:
#prepping data for decision tree
d={'Male':1,'Female':2}
df['Gender'] = df['Gender'].map(d)

d={'USA':1,'Europe':2,'Aisa':3,'Other':4}
df['Location'] = df['Location'].map(d)

d={'Sports':1,'Action':2,'Strategy':3, 'Simulation':4,'RPG':5}
df['GameGenre'] = df['GameGenre'].map(d)

d={'Easy':1,'Medium':2,'Hard':3}
df['GameDifficulty'] = df['GameDifficulty'].map(d)

d={'Low':1,'Medium':2,'High':3}
df['EngagementLevel'] = df['EngagementLevel'].map(d)

#assigning updated catagory information to dataset
df = df.fillna(0)
print(df)
       Age  Gender  Location  GameGenre  PlayTimeHours  InGamePurchases  \
0       43       1       4.0          3      16.271119                0   
1       29       2       1.0          3       5.525961                0   
2       22       2       1.0          1       8.223755                0   
3       35       1       1.0          2       5.265351                1   
4       33       1       2.0          2      15.531945                0   
...    ...     ...       ...        ...            ...              ...   
40029   32       1       1.0          3      20.619662                0   
40030   44       2       4.0          4      13.539280                0   
40031   15       2       1.0          5       0.240057                1   
40032   34       1       1.0          1      14.017818                1   
40033   19       1       1.0          1      10.083804                0   

       GameDifficulty  SessionsPerWeek  AvgSessionDurationMinutes  \
0                   2                6                        108   
1                   2                5                        144   
2                   1               16                        142   
3                   1                9                         85   
4                   2                2                        131   
...               ...              ...                        ...   
40029               1                4                         75   
40030               3               19                        114   
40031               1               10                        176   
40032               2                3                        128   
40033               1               13                         84   

       PlayerLevel  AchievementsUnlocked  EngagementLevel  
0               79                    25                2  
1               11                    10                2  
2               35                    41                3  
3               57                    47                2  
4               95                    37                2  
...            ...                   ...              ...  
40029           85                    14                2  
40030           71                    27                3  
40031           29                     1                3  
40032           70                    10                2  
40033           72                    39                2  

[40034 rows x 12 columns]
In [9]:
#defineing Features k means
features = ['Age', 'PlayTimeHours','SessionsPerWeek','InGamePurchases','AvgSessionDurationMinutes','PlayerLevel','AchievementsUnlocked','Gender','Location','GameGenre','GameDifficulty']
x = df[features]
y = df.EngagementLevel
In [10]:
#k-means Clustering algorythm here, update svm. - keep svc to compair supervised and unsupervised

#samplle of data - reuseing data split function to create a smaller sample to identify clusters
a,Splot,B, C  = train_test_split(df[features], y, test_size=0.02, random_state=42)
plt.figure(figsize = (8,4))
plt.scatter(Splot["PlayTimeHours"],Splot["AvgSessionDurationMinutes"])

plt.show()
No description has been provided for this image
In [11]:
#standerdiseing the data we are applying k means to
df[["PlayTimeHoursstan", "AvgSessionDurationMinutesstan"]]  = StandardScaler().fit_transform(df[["PlayTimeHours", "AvgSessionDurationMinutes"]])
df.head()
Out[11]:
Age Gender Location GameGenre PlayTimeHours InGamePurchases GameDifficulty SessionsPerWeek AvgSessionDurationMinutes PlayerLevel AchievementsUnlocked EngagementLevel PlayTimeHoursstan AvgSessionDurationMinutesstan
0 43 1 4.0 3 16.271119 0 2 6 108 79 25 2 0.614176 0.269487
1 29 2 1.0 3 5.525961 0 2 5 144 11 10 2 -0.939816 1.004019
2 22 2 1.0 1 8.223755 0 1 16 142 35 41 3 -0.549654 0.963212
3 35 1 1.0 2 5.265351 1 1 9 85 57 47 2 -0.977506 -0.199798
4 33 1 2.0 2 15.531945 0 2 2 131 95 37 2 0.507275 0.738771
In [12]:
#scalculates shilloette score and variance for multiple k values
import warnings
warnings.filterwarnings("ignore")

totalVariance = []
Silhouette = []

#start and end points of k values
StartK = 2
EndK = 12 #based on visual data graph starting with 12 points of kvalues

#loops to calculate the variance and silloette values for each k value
for K in range(StartK,EndK):
    kmeans = KMeans(n_clusters=K, init="k-means++", n_init="auto", random_state=0)
    kmeans.fit(df[["PlayTimeHours", "AvgSessionDurationMinutes"]])
    labels = kmeans.labels_
    Silhouette.append(silhouette_score(df[["PlayTimeHours", "AvgSessionDurationMinutes"]], labels))
    totalVariance.append(kmeans.inertia_)
In [13]:
#plotting outputs as elbow plot.
plt.figure(figsize=(8,4))

plt.plot(range(StartK,EndK), totalVariance, color="red",marker = "8")
plt.xlabel("K Value")
plt.xticks(np.arange(StartK,EndK,1))
plt.ylabel("Total Variation")
plt.title("K-meanselbow plot by total variation ")
plt.show()
No description has been provided for this image
In [14]:
#plotting outputs as elbow plot.
plt.figure(figsize=(8,4))

plt.plot(range(StartK,EndK), Silhouette, color="blue",marker = "8")
plt.xlabel("K Value")
plt.xticks(np.arange(StartK,EndK,1))
plt.ylabel("Silhouette Score")
plt.title("K-means and clusters by silhouette score ")
plt.show()
No description has been provided for this image
In [15]:
#plotting outputs as table
LoopResults = pd.DataFrame(np.arange(StartK, EndK,1), columns = ["K Value"])
LoopResults["Total Variation"] = totalVariance
LoopResults["Silhouette Score"] = Silhouette
print(LoopResults)
   K Value  Total Variation  Silhouette Score
0        2     2.596334e+07          0.601234
1        3     1.261583e+07          0.542766
2        4     7.999306e+06          0.498032
3        5     5.747856e+06          0.467678
4        6     4.633251e+06          0.434855
5        7     3.898242e+06          0.407638
6        8     3.460678e+06          0.381414
7        9     3.188328e+06          0.358483
8       10     2.887951e+06          0.337292
9       11     2.723388e+06          0.338052
In [16]:
#Final Kmeans Useing k=6
kmeans = KMeans(n_clusters=6,init = "k-means++",n_init = "auto",random_state = 0)

kmeans.fit(df[["PlayTimeHoursstan", "AvgSessionDurationMinutesstan"]])
Out[16]:
KMeans(n_clusters=6, random_state=0)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
KMeans(n_clusters=6, random_state=0)
In [17]:
#apply Clusters to Dataset
df["clusters"] = kmeans.fit_predict(df[["PlayTimeHoursstan", "AvgSessionDurationMinutesstan"]])

df.head()
Out[17]:
Age Gender Location GameGenre PlayTimeHours InGamePurchases GameDifficulty SessionsPerWeek AvgSessionDurationMinutes PlayerLevel AchievementsUnlocked EngagementLevel PlayTimeHoursstan AvgSessionDurationMinutesstan clusters
0 43 1 4.0 3 16.271119 0 2 6 108 79 25 2 0.614176 0.269487 4
1 29 2 1.0 3 5.525961 0 2 5 144 11 10 2 -0.939816 1.004019 2
2 22 2 1.0 1 8.223755 0 1 16 142 35 41 3 -0.549654 0.963212 0
3 35 1 1.0 2 5.265351 1 1 9 85 57 47 2 -0.977506 -0.199798 5
4 33 1 2.0 2 15.531945 0 2 2 131 95 37 2 0.507275 0.738771 0
In [18]:
#visualise of clusters
plt.figure(figsize=(8,4))

plt.scatter(df["PlayTimeHours"], df["AvgSessionDurationMinutes"], c=df["clusters"]) 
plt.title("Playtime Hours and avg session duration (mins) by cluster")
plt.xlabel("PlaytimeHours")
plt.ylabel("AvgSessionDurationMinutes")
plt.show()
No description has been provided for this image
In [19]:
#defineing Features for prediction model
features = ['Age', 'PlayTimeHours','SessionsPerWeek','InGamePurchases','AvgSessionDurationMinutes',
            'PlayerLevel','AchievementsUnlocked','Gender','Location','GameGenre','GameDifficulty',"clusters"]
#dataset for model training (x) and target (y)
x = df[features]
print(x)
y = df.EngagementLevel  #['EngagementLevel']

#Splitting the dataset into training and test sets
xtrain, xtest, ytrain, ytest = train_test_split(df[features], y, test_size=0.2, random_state=42)

#svm classifyer and creation of decision tree
svm_bc = SVC(probability=True)
dtree = DecisionTreeClassifier()

#createing tree for model
dtree = dtree.fit(xtest, ytest)
       Age  PlayTimeHours  SessionsPerWeek  InGamePurchases  \
0       43      16.271119                6                0   
1       29       5.525961                5                0   
2       22       8.223755               16                0   
3       35       5.265351                9                1   
4       33      15.531945                2                0   
...    ...            ...              ...              ...   
40029   32      20.619662                4                0   
40030   44      13.539280               19                0   
40031   15       0.240057               10                1   
40032   34      14.017818                3                1   
40033   19      10.083804               13                0   

       AvgSessionDurationMinutes  PlayerLevel  AchievementsUnlocked  Gender  \
0                            108           79                    25       1   
1                            144           11                    10       2   
2                            142           35                    41       2   
3                             85           57                    47       1   
4                            131           95                    37       1   
...                          ...          ...                   ...     ...   
40029                         75           85                    14       1   
40030                        114           71                    27       2   
40031                        176           29                     1       2   
40032                        128           70                    10       1   
40033                         84           72                    39       1   

       Location  GameGenre  GameDifficulty  clusters  
0           4.0          3               2         4  
1           1.0          3               2         2  
2           1.0          1               1         0  
3           1.0          2               1         5  
4           2.0          2               2         0  
...         ...        ...             ...       ...  
40029       1.0          3               1         1  
40030       4.0          4               3         3  
40031       1.0          5               1         2  
40032       1.0          1               2         0  
40033       1.0          1               1         3  

[40034 rows x 12 columns]
In [20]:
#Createion of the voting classifier
#needs to be a svm classifyer not an svm classifyter before this code is ran needs to run a Clustering algorythm
voting_clf_bc = VotingClassifier(estimators=[('svm', svm_bc), ('dt', dtree)], voting='soft')

#Training the voting classifier
voting_clf_bc.fit(xtrain, ytrain)
Out[20]:
VotingClassifier(estimators=[('svm', SVC(probability=True)),
                             ('dt', DecisionTreeClassifier())],
                 voting='soft')
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
VotingClassifier(estimators=[('svm', SVC(probability=True)),
                             ('dt', DecisionTreeClassifier())],
                 voting='soft')
SVC(probability=True)
DecisionTreeClassifier()
In [21]:
#Make predictions of dataset
y_pred_bc = voting_clf_bc.predict(xtest)
 
#Calculate accuracy of model
accuracy_bc = accuracy_score(ytest, y_pred_bc)
print(f'Accuracy on User Engagement: {accuracy_bc}')
Accuracy on User Engagement: 0.8311477457224928
In [ ]: