# survey <- read.csv("survey_data.csv")
set.seed(123)
survey <- data.frame(
taste = c(rnorm(100, 6.2, 0.7), rnorm(100, 3.5, 0.8), rnorm(100, 4.8, 0.9)),
price = c(rnorm(100, 3.2, 0.8), rnorm(100, 6.0, 0.7), rnorm(100, 4.5, 0.9)),
brand = c(rnorm(100, 4.0, 0.9), rnorm(100, 3.0, 0.8), rnorm(100, 6.1, 0.7)),
variety = c(rnorm(100, 6.0, 0.8), rnorm(100, 3.8, 0.9), rnorm(100, 4.2, 0.8))
)
head(survey)
## taste price brand variety
## 1 5.807667 2.627806 4.966611 5.188709
## 2 6.038876 2.597849 3.975388 5.366949
## 3 7.291096 2.449169 3.970003 6.239675
## 4 6.249356 2.357989 2.635539 7.311242
## 5 6.290501 2.850272 4.711347 6.867694
## 6 7.400545 3.464943 3.810339 5.500346
scaled <- scale(survey)
wss <- sapply(1:8, function(k) kmeans(scaled, k, nstart = 25)$tot.withinss)
plot(1:8, wss, type = "b", xlab = "Number of clusters", ylab = "Within-cluster error")
km <- kmeans(scaled, centers = 3, nstart = 25)
survey$cluster <- km$cluster
table(survey$cluster) # cluster sizes
##
## 1 2 3
## 103 99 98
aggregate(. ~ cluster, data = survey, mean) # cluster profiles
## cluster taste price brand variety
## 1 1 4.923456 4.463071 6.134029 4.217688
## 2 2 3.396123 6.089356 3.066365 3.893112
## 3 3 6.277902 3.144512 3.838553 5.998830
plot(scaled[, 1:2], col = km$cluster, pch = 19, xlab = "Taste", ylab = "Price")
The elbow plot levels off at three clusters, and the cluster plot shows three distinct groups. The profile table shows one segment that scores high on taste and variety, one that scores high on price, and one that scores highest on brand. These can be named Variety Seekers, Price Sensitive customers, and Brand Loyalists, and each would respond to different marketing, such as new flavors, discounts, or loyalty programs. This shows that customers do not all want the same thing, which is the same lesson from the yogurt beverage case.