K-means clustering is an unsupervised learning algorithm used for data clustering, which groups unlabeled data points into groups or clusters. https://www.ibm.com/think/topics/k-means-clustering
K-Means is one of the most popular clustering techniques in unsupervised learning. The k-means approach uses a mathematical distance metric to group data points into clusters. By switching between allocating data points to clusters based on the existing centroids and selecting centroids based on the current assignment of data points to clusters, K-Means determines the optimal centroids.
The data used for the research is about exercise routines, physical attributes, and fitness metrics. It contains key performance indicators such as heart rate, calories burned, and workout duration. Each entry also included demographic data and experience levels, allowing for a comprehensive analysis of fitness patterns, athlete progression, and health trends.
Data: https://www.kaggle.com/datasets/valakhorasani/gym-members-exercise-dataset
Libraries:
library(dplyr)
library(tidymodels)
library(tidyclust)
library(tidyverse)
library(tidyquant)
library(plotly)
library(stats)
library(ggplot2)
library(factoextra)
full_data <- read_csv("gym.csv")
data <- full_data[1:100, ]
data %>% glimpse()
## Rows: 100
## Columns: 15
## $ Age <dbl> 56, 46, 32, 25, 38, 56, 36, 40, 28, 28…
## $ Gender <chr> "Male", "Female", "Female", "Male", "M…
## $ `Weight (kg)` <dbl> 88.3, 74.9, 68.1, 53.2, 46.1, 58.0, 70…
## $ `Height (m)` <dbl> 1.71, 1.53, 1.66, 1.70, 1.79, 1.68, 1.…
## $ Max_BPM <dbl> 180, 179, 167, 190, 188, 168, 174, 189…
## $ Avg_BPM <dbl> 157, 151, 122, 164, 158, 156, 169, 141…
## $ Resting_BPM <dbl> 60, 66, 54, 56, 68, 74, 73, 64, 52, 64…
## $ `Session_Duration (hours)` <dbl> 1.69, 1.30, 1.11, 0.59, 0.64, 1.59, 1.…
## $ Calories_Burned <dbl> 1313, 883, 677, 532, 556, 1116, 1385, …
## $ Workout_Type <chr> "Yoga", "HIIT", "Cardio", "Strength", …
## $ Fat_Percentage <dbl> 12.6, 33.9, 33.4, 28.8, 29.2, 15.5, 21…
## $ `Water_Intake (liters)` <dbl> 3.5, 2.1, 2.3, 2.1, 2.8, 2.7, 2.3, 1.9…
## $ `Workout_Frequency (days/week)` <dbl> 4, 4, 4, 3, 3, 5, 3, 3, 4, 3, 2, 3, 3,…
## $ Experience_Level <dbl> 3, 2, 2, 1, 1, 3, 2, 2, 2, 1, 1, 2, 2,…
## $ BMI <dbl> 30.20, 32.00, 24.71, 18.41, 14.39, 20.…
data_prep <- data %>%
drop_na() %>%
select(-`Water_Intake (liters)`, -Fat_Percentage, -`Weight (kg)`, -`Height (m)`, -Experience_Level, -Max_BPM,
- Workout_Type)
cal_bpm = data_prep %>%
select(Calories_Burned, Avg_BPM)
cal_duration = data_prep %>%
select(Calories_Burned, `Session_Duration (hours)`)
fviz_nbclust(cal_bpm, kmeans, method = "wss") +
labs(subtitle = "Elbow method")
fviz_nbclust(cal_duration, kmeans, method = "wss") +
labs(subtitle = "Elbow method")
As can be seen from the tables for both data frames, 3 can be selected as the optimal number of clusters.
km <- kmeans(cal_bpm, centers = 3)
km.cluster <- km$cluster
rownames(cal_bpm) <- paste(data$Workout_Type, 1:dim(data)[1], sep = "-")
fviz_cluster(list(data = cal_bpm, cluster = km.cluster))
km <- kmeans(cal_duration, centers = 3)
km.cluster <- km$cluster
rownames(cal_duration) <- paste(data$Workout_Type, 1:dim(data)[1], sep = "-")
fviz_cluster(list(data = cal_duration, cluster = km.cluster))
The plot indicates that session duration exhibits a stronger
correlation with burnt calories, and it can be anlyzed more with
interactive data.
recipe <- recipe(~ ., data = cal_duration) %>%
step_scale(all_numeric_predictors())
recipe %>% prep() %>% juice() %>% glimpse()
## Rows: 100
## Columns: 2
## $ Calories_Burned <dbl> 4.893835, 3.291132, 2.523325, 1.982879, 2.0…
## $ `Session_Duration (hours)` <dbl> 5.246849, 4.036038, 3.446155, 1.831740, 1.9…
model_kmeans <- k_means(num_clusters = 3) %>%
set_engine("stats")
set.seed(123)
calories <- workflow() %>%
add_model(model_kmeans) %>%
add_recipe(recipe) %>%
fit(cal_duration)
calories %>% predict(cal_duration)
## # A tibble: 100 × 1
## .pred_cluster
## <fct>
## 1 Cluster_1
## 2 Cluster_2
## 3 Cluster_3
## 4 Cluster_3
## 5 Cluster_3
## 6 Cluster_1
## 7 Cluster_1
## 8 Cluster_2
## 9 Cluster_3
## 10 Cluster_3
## # ℹ 90 more rows
extract_cluster_assignment(calories)
## # A tibble: 100 × 1
## .cluster
## <fct>
## 1 Cluster_1
## 2 Cluster_2
## 3 Cluster_3
## 4 Cluster_3
## 5 Cluster_3
## 6 Cluster_1
## 7 Cluster_1
## 8 Cluster_2
## 9 Cluster_3
## 10 Cluster_3
## # ℹ 90 more rows
extract_centroids(calories)
## # A tibble: 3 × 3
## .cluster Calories_Burned `Session_Duration (hours)`
## <fct> <dbl> <dbl>
## 1 Cluster_1 4.84 5.37
## 2 Cluster_2 3.66 4.05
## 3 Cluster_3 2.43 2.91
g <- data_prep %>%
bind_cols(extract_cluster_assignment(calories), .) %>%
ggplot(aes(Calories_Burned, `Session_Duration (hours)`)) +
geom_point(
aes(fill = .cluster),
shape = 21, alpha = 0.4, size = 5) +
geom_smooth(color = "red", se = FALSE) +
scale_x_continuous(labels = scales::number_format(),
limits = c(0, 2000))+
scale_y_continuous(labels = scales::number_format(),
limits = c(0, 3)) +
labs(title = "Calories burned by Duration", x = "Calories Burnt", y = "Duration of Session")+
scale_fill_tq()+
theme_tq()
ggplotly(g)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
This study employed K-Means clustering on exercise routine data to identify patterns in calories burned, average BPM, and session duration. The Elbow Method was utilized to determine the optimal number of clusters, which was found to be three for calories burned versus BPM and session duration. Through the application of clustering techniques, correlations were also identified, and predictions were generated.