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()
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()
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()
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()
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()
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 [ ]: