Introduction

In this assignment, I used cluster analysis to examine customer survey data and identify groups of customers with similar responses. Market segmentation helps businesses understand their customers and develop better marketing strategies.

Step 1: Importing the Dataset

First, I imported the customer segmentation dataset into RStudio.

mydata <- read.csv("customer_segmentation.csv")

names(mydata) <- trimws(names(mydata))

head(mydata)
##   ID CS_helpful Recommend Come_again All_Products Profesionalism Limitation
## 1  1          2         2          2            2              2          2
## 2  2          1         2          1            1              1          1
## 3  3          2         1          1            1              1          2
## 4  4          3         3          2            4              1          2
## 5  5          2         1          3            5              2          1
## 6  6          1         1          3            2              1          1
##   Online_grocery delivery Pick_up Find_items other_shops Gender Age Education
## 1              2        3       4          1           2      1   2         2
## 2              2        3       3          1           2      1   2         2
## 3              3        3       2          1           3      1   2         2
## 4              3        3       2          2           2      1   3         5
## 5              2        3       1          2           3      2   4         2
## 6              1        2       1          1           4      1   2         5
dim(mydata)
## [1] 22 15
str(mydata)
## 'data.frame':    22 obs. of  15 variables:
##  $ ID            : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ CS_helpful    : int  2 1 2 3 2 1 2 1 1 1 ...
##  $ Recommend     : int  2 2 1 3 1 1 1 1 1 1 ...
##  $ Come_again    : int  2 1 1 2 3 3 1 1 1 1 ...
##  $ All_Products  : int  2 1 1 4 5 2 2 2 2 1 ...
##  $ Profesionalism: int  2 1 1 1 2 1 2 1 2 1 ...
##  $ Limitation    : int  2 1 2 2 1 1 1 2 1 1 ...
##  $ Online_grocery: int  2 2 3 3 2 1 2 1 2 3 ...
##  $ delivery      : int  3 3 3 3 3 2 2 1 1 2 ...
##  $ Pick_up       : int  4 3 2 2 1 1 2 2 3 2 ...
##  $ Find_items    : int  1 1 1 2 2 1 1 2 1 1 ...
##  $ other_shops   : int  2 2 3 2 3 4 1 4 1 1 ...
##  $ Gender        : int  1 1 1 1 2 1 1 1 2 2 ...
##  $ Age           : int  2 2 2 3 4 2 2 2 2 2 ...
##  $ Education     : int  2 2 2 5 2 5 3 2 1 2 ...
summary(mydata)
##        ID          CS_helpful      Recommend       Come_again   
##  Min.   : 1.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.: 6.25   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:1.000  
##  Median :11.50   Median :1.000   Median :1.000   Median :1.000  
##  Mean   :11.50   Mean   :1.591   Mean   :1.318   Mean   :1.455  
##  3rd Qu.:16.75   3rd Qu.:2.000   3rd Qu.:1.000   3rd Qu.:2.000  
##  Max.   :22.00   Max.   :3.000   Max.   :3.000   Max.   :3.000  
##   All_Products   Profesionalism    Limitation  Online_grocery     delivery    
##  Min.   :1.000   Min.   :1.000   Min.   :1.0   Min.   :1.000   Min.   :1.000  
##  1st Qu.:1.250   1st Qu.:1.000   1st Qu.:1.0   1st Qu.:2.000   1st Qu.:2.000  
##  Median :2.000   Median :1.000   Median :1.0   Median :2.000   Median :3.000  
##  Mean   :2.091   Mean   :1.409   Mean   :1.5   Mean   :2.273   Mean   :2.409  
##  3rd Qu.:2.000   3rd Qu.:2.000   3rd Qu.:2.0   3rd Qu.:3.000   3rd Qu.:3.000  
##  Max.   :5.000   Max.   :3.000   Max.   :4.0   Max.   :3.000   Max.   :3.000  
##     Pick_up        Find_items     other_shops        Gender     
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:1.000   1st Qu.:1.250   1st Qu.:1.000  
##  Median :2.000   Median :1.000   Median :2.000   Median :1.000  
##  Mean   :2.455   Mean   :1.455   Mean   :2.591   Mean   :1.273  
##  3rd Qu.:3.000   3rd Qu.:2.000   3rd Qu.:3.750   3rd Qu.:1.750  
##  Max.   :5.000   Max.   :3.000   Max.   :5.000   Max.   :2.000  
##       Age          Education    
##  Min.   :2.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:2.000  
##  Median :2.000   Median :2.500  
##  Mean   :2.455   Mean   :3.182  
##  3rd Qu.:3.000   3rd Qu.:5.000  
##  Max.   :4.000   Max.   :5.000

The dataset contains 22 customer responses and 15 columns. These columns include customer service, product availability, shopping behavior, and demographic information.

Step 2: Standardizing the Data

Before performing cluster analysis, I standardized the data so that variables with different numerical ranges would not dominate the analysis.

# Remove customer ID
mydata2 <- mydata[, -1]

# Standardize the variables
mydata.scaled <- scale(mydata2)

# View standardized data
head(mydata.scaled)
##      CS_helpful  Recommend Come_again All_Products Profesionalism Limitation
## [1,]  0.5572385  1.0548991  0.7385489  -0.08536162      1.0009877  0.6236096
## [2,] -0.8049001  1.0548991 -0.6154575  -1.02433946     -0.6929915 -0.6236096
## [3,]  0.5572385 -0.4922862 -0.6154575  -1.02433946     -0.6929915  0.6236096
## [4,]  1.9193772  2.6020844  0.7385489   1.79259406     -0.6929915  0.6236096
## [5,]  0.5572385 -0.4922862  2.0925553   2.73157191      1.0009877 -0.6236096
## [6,] -0.8049001 -0.4922862  2.0925553  -0.08536162     -0.6929915 -0.6236096
##      Online_grocery   delivery    Pick_up Find_items other_shops    Gender
## [1,]     -0.3554390  0.8049001  1.4623535 -0.6774335  -0.4212692 -0.598293
## [2,]     -0.3554390  0.8049001  0.5161248 -0.6774335  -0.4212692 -0.598293
## [3,]      0.9478374  0.8049001 -0.4301040 -0.6774335   0.2916479 -0.598293
## [4,]      0.9478374  0.8049001 -0.4301040  0.8129201  -0.4212692 -0.598293
## [5,]     -0.3554390  0.8049001 -1.3763327  0.8129201   0.2916479  1.595448
## [6,]     -1.6587154 -0.5572385 -1.3763327 -0.6774335   1.0045650 -0.598293
##             Age  Education
## [1,] -0.6154575 -0.7284586
## [2,] -0.6154575 -0.7284586
## [3,] -0.6154575 -0.7284586
## [4,]  0.7385489  1.1207055
## [5,]  2.0925553 -0.7284586
## [6,] -0.6154575  1.1207055

Standardization makes it easier to compare the survey variables during clustering.

Step 3: Hierarchical Cluster Analysis

Hierarchical clustering helps identify groups of customers with similar characteristics.

For this analysis, I used complete linkage and Euclidean distances. I followed the classroom examples’ distance calculation.

# Calculate distances
d <- dist(mydata.scaled)

# Match the classroom example procedure
d2 <- dist(as.matrix(d))

# Perform hierarchical clustering
seg.hclust <- hclust(
  d2,
  method = "complete"
)

# Display dendrogram
plot(
  seg.hclust,
  labels = mydata$ID,
  main = "Hierarchical Cluster Analysis",
  xlab = "Customer ID",
  ylab = "Distance",
  sub = "",
  hang = -1
)

# Highlight three clusters
rect.hclust(
  seg.hclust,
  k = 3,
  border = c("red", "blue", "green")
)

The dendrogram shows how customers are grouped based on similarities in their survey responses.

Note: The additional distance calculation matches the classroom examples. A more conventional approach would be hclust(dist(mydata.scaled), method = "complete"), which can produce different clusters.

Step 4: Creating Three Clusters

I divided the respondents into three clusters to understand the differences between customer groups.

# Create three clusters
groups.3 <- cutree(
  seg.hclust,
  k = 3
)

# Display cluster membership
groups.3
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 
##  1  1  1  2  3  1  1  1  1  1  1  1  1  1  1  1  1  1  3  3  1  2
# Count respondents in each cluster
table(groups.3)
## groups.3
##  1  2  3 
## 17  2  3
# Cluster percentages
round(prop.table(table(groups.3)) * 100, 2)
## groups.3
##     1     2     3 
## 77.27  9.09 13.64

Cluster Results

The analysis identified three customer groups:

  • Cluster 1: 17 customers (77.3%)
  • Cluster 2: 2 customers (9.1%)
  • Cluster 3: 3 customers (13.6%)

Cluster 1 contains most of the respondents, while Clusters 2 and 3 represent smaller groups with different response patterns.

Step 5: Comparing Cluster Means

The next step is to compare the average responses of each cluster.

# Calculate mean values
cluster.mean <- aggregate(
  mydata2,
  by = list(Cluster = groups.3),
  FUN = mean
)

# Display cluster means
cluster.mean
##   Cluster CS_helpful Recommend Come_again All_Products Profesionalism
## 1       1   1.294118  1.117647   1.235294     1.823529       1.235294
## 2       2   3.000000  2.500000   1.500000     3.000000       1.500000
## 3       3   2.333333  1.666667   2.666667     3.000000       2.333333
##   Limitation Online_grocery delivery  Pick_up Find_items other_shops   Gender
## 1   1.352941       2.235294 2.235294 2.705882   1.294118    2.647059 1.176471
## 2   2.000000       3.000000 3.000000 2.500000   2.000000    1.500000 1.000000
## 3   2.000000       2.000000 3.000000 1.000000   2.000000    3.000000 2.000000
##        Age Education
## 1 2.411765  3.117647
## 2 2.500000  5.000000
## 3 2.666667  2.333333
# Display formatted table
knitr::kable(
  round(cluster.mean, 2),
  caption = "Mean Values for Each Cluster"
)
Mean Values for Each Cluster
Cluster CS_helpful Recommend Come_again All_Products Profesionalism Limitation Online_grocery delivery Pick_up Find_items other_shops Gender Age Education
1 1.29 1.12 1.24 1.82 1.24 1.35 2.24 2.24 2.71 1.29 2.65 1.18 2.41 3.12
2 3.00 2.50 1.50 3.00 1.50 2.00 3.00 3.00 2.50 2.00 1.50 1.00 2.50 5.00
3 2.33 1.67 2.67 3.00 2.33 2.00 2.00 3.00 1.00 2.00 3.00 2.00 2.67 2.33

Interpretation of Mean Values

The mean values help explain how each customer group responded to the survey.

Cluster 1 generally has lower numerical responses for customer service helpfulness, recommendations, and returning to the store.

Cluster 2 has higher numerical responses for customer service helpfulness and recommendation questions.

Cluster 3 shows a different response pattern for returning to the store and pickup services.

These differences can help businesses identify potential customer segments and evaluate areas for improvement.

Step 6: Comparing Cluster Medians

I also calculated the median responses to identify typical values within each cluster.

# Calculate median values
cluster.median <- aggregate(
  mydata2,
  by = list(Cluster = groups.3),
  FUN = median
)

# Display median values
cluster.median
##   Cluster CS_helpful Recommend Come_again All_Products Profesionalism
## 1       1          1       1.0        1.0            2            1.0
## 2       2          3       2.5        1.5            3            1.5
## 3       3          2       1.0        3.0            3            2.0
##   Limitation Online_grocery delivery Pick_up Find_items other_shops Gender Age
## 1          1              2        2     3.0          1         2.0      1 2.0
## 2          2              3        3     2.5          2         1.5      1 2.5
## 3          1              2        3     1.0          2         3.0      2 2.0
##   Education
## 1         2
## 2         5
## 3         2
# Format median table
knitr::kable(
  cluster.median,
  caption = "Median Values for Each Cluster"
)
Median Values for Each Cluster
Cluster CS_helpful Recommend Come_again All_Products Profesionalism Limitation Online_grocery delivery Pick_up Find_items other_shops Gender Age Education
1 1 1.0 1.0 2 1.0 1 2 2 3.0 1 2.0 1 2.0 2
2 3 2.5 1.5 3 1.5 2 3 3 2.5 2 1.5 1 2.5 5
3 2 1.0 3.0 3 2.0 1 2 3 1.0 2 3.0 2 2.0 2

Interpretation of Median Values

Median values are useful because they represent the middle response in each cluster.

Since the survey uses coded responses, the median can help identify common response patterns without relying entirely on averages.

Comparing both the mean and median gives businesses a better understanding of differences among customer groups.

Step 7: Principal Component Analysis

I also used Principal Component Analysis (PCA) to visualize the customer segments.

# Perform PCA
pca <- prcomp(
  mydata.scaled,
  center = FALSE,
  scale. = FALSE
)

# PCA summary
summary(pca)
## Importance of components:
##                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
## Standard deviation     1.7763 1.5393 1.3418 1.2575 1.12172 1.00800 0.78243
## Proportion of Variance 0.2254 0.1692 0.1286 0.1129 0.08988 0.07258 0.04373
## Cumulative Proportion  0.2254 0.3946 0.5232 0.6361 0.72602 0.79860 0.84233
##                            PC8     PC9    PC10   PC11    PC12    PC13    PC14
## Standard deviation     0.76198 0.67310 0.62577 0.5999 0.45093 0.43527 0.17180
## Proportion of Variance 0.04147 0.03236 0.02797 0.0257 0.01452 0.01353 0.00211
## Cumulative Proportion  0.88380 0.91616 0.94413 0.9698 0.98436 0.99789 1.00000
# Create colors for clusters
colors <- c("red", "blue", "green")

# Plot PCA
plot(
  pca$x[,1],
  pca$x[,2],
  col = colors[groups.3],
  pch = 19,
  xlab = "Principal Component 1",
  ylab = "Principal Component 2",
  main = "PCA Customer Segmentation"
)

# Add customer ID labels
text(
  pca$x[,1],
  pca$x[,2],
  labels = mydata$ID,
  pos = 3,
  cex = 0.7
)

# Add legend
legend(
  "topright",
  legend = c("Cluster 1", "Cluster 2", "Cluster 3"),
  col = colors,
  pch = 19
)

The PCA visualization helps show differences between customer responses in two dimensions.

Step 8: Marketing Interpretation

The cluster analysis identified three different customer groups.

Cluster 1: This is the largest group, containing 17 customers. The group generally has lower numerical response codes for several customer service and shopping-related questions.

Cluster 2: This group contains two customers. Their responses differ from the majority, particularly regarding customer service helpfulness and recommendations.

Cluster 3: This group contains three customers. Their responses show noticeable differences in return visits and pickup-related questions.

These findings demonstrate how cluster analysis can help businesses identify customer groups and develop more focused marketing strategies.

However, the original survey does not provide the meaning of each numerical response code. Therefore, I cannot determine which cluster is more satisfied without reviewing the original survey questions and response options.

Discussion Questions

1. How many observations are in each cluster?

Cluster 1 contains 17 customers, Cluster 2 contains 2 customers, and Cluster 3 contains 3 customers. There are 22 respondents in total. Cluster 1 represents the largest segment, with approximately 77.3% of all respondents.

2. Why is it important to compare the mean and median of each cluster?

Comparing the mean and median helps identify differences between customer groups. These values show how respondents answered questions about customer service, product availability, and shopping preferences. Businesses can use these differences to better understand customer behavior.

3. Should we use the mean or median?

I would focus more on the median because the survey uses numerical codes to represent customer responses. The median provides a useful way to identify typical responses. However, I would still use the mean to compare general numerical patterns between clusters.

4. How can cluster analysis help businesses?

Cluster analysis can help businesses understand different groups of customers. Instead of treating every customer the same, companies can identify differences in preferences and behaviors. This information can help improve customer service, develop targeted marketing strategies, and improve customer experiences.

5. What is the difference between K-means and hierarchical clustering?

K-means clustering divides observations into a selected number of groups based on similarities. Hierarchical clustering creates a tree diagram called a dendrogram that shows how observations are grouped. Both methods can help businesses identify customer segments and understand consumer behavior.

6. How does this analysis connect to marketing analytics careers?

This analysis helped me understand how marketing analysts use data to make business decisions. Through my Marketing Analytics coursework at CSUB, I have gained experience using RStudio, Excel, and data visualization. These skills can help prepare me for positions such as Marketing Analyst, Market Research Analyst, or Data Analyst.

I still want to improve my skills in SQL, Power BI, and advanced statistical analysis to become more competitive in the marketing analytics field.

Conclusion

Overall, this assignment helped me understand how hierarchical clustering can be used for market segmentation. By analyzing 22 customer responses, I identified three clusters with different response patterns. I also learned how to use RStudio to create a dendrogram, calculate mean and median values, and visualize customer groups using PCA.

This experience showed me how businesses can use data analytics to better understand customers and improve marketing decisions.

Exporting the Results

# Save cluster assignments
cluster.results <- data.frame(
  ID = mydata$ID,
  Cluster = groups.3
)

write.csv(
  cluster.results,
  "customer_cluster_results.csv",
  row.names = FALSE
)

# Save means
write.csv(
  cluster.mean,
  "customer_cluster_means.csv",
  row.names = FALSE
)

# Save medians
write.csv(
  cluster.median,
  "customer_cluster_medians.csv",
  row.names = FALSE
)

References