1 Đọc và tổng quan về bộ dữ liệu

1.1 Đọc file dữ liệu Supermarket_Transactions.csv

Trong bước đầu tiên của quá trình phân tích, ta tiến hành đọc file dữ liệu Supermarket_Transactions.csv từ thư mục chỉ định. File này chứa thông tin về các giao dịch tại siêu thị, bao gồm các trường như ngày giao dịch, loại sản phẩm, khu vực, thu nhập khách hàng, tình trạng hôn nhân, v.v. Sau khi tải dữ liệu thành công, bảng dữ liệu được hiển thị bằng hàm datatable() để quan sát trực quan các dòng và cột dữ liệu.

data <- read.csv("D:/PTDLDT/Supermarket_Transactions.csv", header = T)
datatable(data)
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html

1.2 Tổng quan về bộ dữ liệu

Supermarket_Transactions.csv là bộ dữ liệu thống kê các thông tin khi khách hàng thực hiện các giao dịch mua hàng tại một siêu thị.

1.2.1 Danh sách các biến và ý nghĩa

names(data)
##  [1] "X"                 "PurchaseDate"      "CustomerID"       
##  [4] "Gender"            "MaritalStatus"     "Homeowner"        
##  [7] "Children"          "AnnualIncome"      "City"             
## [10] "StateorProvince"   "Country"           "ProductFamily"    
## [13] "ProductDepartment" "ProductCategory"   "UnitsSold"        
## [16] "Revenue"

Dưới đây là bảng tổng hợp các biến có trong bộ dữ liệu và ý nghĩa của biến đó:

Biến Mô tả
Unnamed Chỉ số dòng/ Số thứ tự
PurchaseDate Ngày thực hiện giao dịch
CustomerID ID khách hàng
Gender Giới tính của khách hàng (F: Nữ/ M: Nam)
MaritalStatus Tình trạng hôn nhân của khách hàng (S: Độc thân/ M: Đã kết hôn)
Homeowner Cho biết khách hàng có sở hữu nhà hay không (Y: Có/ N: Không)
Children Số con cái trong gia đình
AnnualIncome Thu nhập hằng năm của khách hàng (phân nhóm)
City Thành phố nơi khách hàng thực hiện giao dịch
StateorProvince Bang hoặc tỉnh
Country Quốc gia
ProductFamily Nhóm sản phẩm chính
ProductDepartment Bộ phận sản phẩm
ProductCategory Danh mục sản phẩm cụ thể
UnitsSold Số lượng sản phẩm bán ra
Revenue Doanh thu thu được từ giao dịch (tính bằng USD)

1.2.2 Cấu trúc bộ dữ liệu

Để có được cái nhìn tổng quan và bước đầu đánh giá tính phù hợp của tập dữ liệu với mục tiêu nghiên cứu, ta tiến hành kiểm tra cấu trúc của bộ dữ liệu bằng cách sử dụng hai hàm cơ bản trong R là dim()str().

  • Hàm dim() cho biết kích thước của bảng dữ liệu, cụ thể là số hàng (quan sát) và số cột (biến).
dim(data)
## [1] 14059    16

Kết quả trả về từ câu lệnh dim(data) cho thấy bộ dữ liệu bao gồm 14.059 quan sát (tương ứng với số lượt mua hàng hay giao dịch của khách hàng tại siêu thị) và 16 biến (tương ứng với các đặc điểm, thông tin liên quan đến khách hàng, sản phẩm và giao dịch).

  • Hàm str() cung cấp thông tin về cấu trúc dữ liệu, bao gồm tên các biến, kiểu dữ liệu của từng biến (ví dụ: số, chuỗi ký tự, biến phân loại), cũng như một số giá trị minh họa cho mỗi biến.
str(data)
## 'data.frame':    14059 obs. of  16 variables:
##  $ X                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ PurchaseDate     : chr  "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
##  $ CustomerID       : int  7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
##  $ Gender           : chr  "F" "M" "F" "M" ...
##  $ MaritalStatus    : chr  "S" "M" "M" "M" ...
##  $ Homeowner        : chr  "Y" "Y" "N" "Y" ...
##  $ Children         : int  2 5 2 3 3 3 2 2 3 1 ...
##  $ AnnualIncome     : chr  "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
##  $ City             : chr  "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
##  $ StateorProvince  : chr  "CA" "CA" "WA" "OR" ...
##  $ Country          : chr  "USA" "USA" "USA" "USA" ...
##  $ ProductFamily    : chr  "Food" "Food" "Food" "Food" ...
##  $ ProductDepartment: chr  "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
##  $ ProductCategory  : chr  "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
##  $ UnitsSold        : int  5 5 3 4 4 3 4 6 1 2 ...
##  $ Revenue          : num  27.38 14.9 5.52 4.44 14 ...

Hàm str() cho biết kiểu dữ liệu của các biến có trong bộ dữ liệu, kết quả của câu lệnh được thể hiện trong bảng dưới đây:

Biến định lượng Mô tả
PurchaseDate Ngày thực hiện giao dịch
CustomerID ID khách hàng
Children Số con cái trong gia đình
UnitsSold Số lượng sản phẩm bán ra
Revenue Doanh thu thu được từ giao dịch (tính bằng USD)
Biến định tính Mô tả
Gender Giới tính của khách hàng (F: Nữ/ M: Nam)
MaritalStatus Tình trạng hôn nhân của khách hàng (S: Độc thân/ M: Đã kết hôn)
Homeowner Cho biết khách hàng có sở hữu nhà hay không (Y: Có/ N: Không)
AnnualIncome Thu nhập hằng năm của khách hàng (phân nhóm)
City Thành phố nơi khách hàng thực hiện giao dịch
StateorProvince Bang hoặc tỉnh
Country Quốc gia
ProductFamily Nhóm sản phẩm chính
ProductDepartment Bộ phận sản phẩm
ProductCategory Danh mục sản phẩm cụ thể

Sau khi kiểm tra tổng quan về kích thước và cấu trúc của bộ dữ liệu, bước tiếp theo là hiển thị một phần nội dung cụ thể của dữ liệu để có cái nhìn trực quan hơn về thông tin bên trong. Việc này giúp người phân tích nhanh chóng nắm được bố cục bảng dữ liệu, tên các cột, định dạng hiển thị, cũng như nhận diện sơ bộ các giá trị bất thường hoặc không hợp lệ (nếu có).

  • Hàm head(data): hiển thị 6 dòng đầu tiên của bộ dữ liệu, đại diện cho những quan sát đầu tiên được ghi nhận.
head(data)
##   X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 1 1   2007-12-18       7223      F             S         Y        2
## 2 2   2007-12-20       7841      M             M         Y        5
## 3 3   2007-12-21       8374      F             M         N        2
## 4 4   2007-12-21       9619      M             M         Y        3
## 5 5   2007-12-22       1900      F             S         Y        3
## 6 6   2007-12-22       6696      F             M         Y        3
##    AnnualIncome          City StateorProvince Country ProductFamily
## 1   $30K - $50K   Los Angeles              CA     USA          Food
## 2   $70K - $90K   Los Angeles              CA     USA          Food
## 3   $50K - $70K     Bremerton              WA     USA          Food
## 4   $30K - $50K      Portland              OR     USA          Food
## 5 $130K - $150K Beverly Hills              CA     USA         Drink
## 6   $10K - $30K Beverly Hills              CA     USA          Food
##   ProductDepartment      ProductCategory UnitsSold Revenue
## 1       Snack Foods          Snack Foods         5   27.38
## 2           Produce           Vegetables         5   14.90
## 3       Snack Foods          Snack Foods         3    5.52
## 4            Snacks                Candy         4    4.44
## 5         Beverages Carbonated Beverages         4   14.00
## 6              Deli          Side Dishes         3    4.37
  • Hàm tail(data): hiển thị 6 dòng cuối cùng, giúp kiểm tra phần kết của tập dữ liệu, phát hiện các lỗi nhập liệu ở cuối bảng (nếu có).
tail(data)
##           X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 14054 14054   2009-12-29       2032      F             M         N        3
## 14055 14055   2009-12-29       9102      F             M         Y        2
## 14056 14056   2009-12-29       4822      F             M         Y        3
## 14057 14057   2009-12-31        250      M             S         Y        1
## 14058 14058   2009-12-31       6153      F             S         N        4
## 14059 14059   2009-12-31       3656      M             S         N        3
##       AnnualIncome        City StateorProvince Country  ProductFamily
## 14054  $10K - $30K      Yakima              WA     USA Non-Consumable
## 14055  $10K - $30K   Bremerton              WA     USA           Food
## 14056  $10K - $30K Walla Walla              WA     USA           Food
## 14057  $30K - $50K    Portland              OR     USA          Drink
## 14058  $50K - $70K     Spokane              WA     USA          Drink
## 14059  $50K - $70K    Portland              OR     USA Non-Consumable
##       ProductDepartment      ProductCategory UnitsSold Revenue
## 14054         Household       Paper Products         5   14.50
## 14055      Baking Goods         Baking Goods         3    9.64
## 14056      Frozen Foods           Vegetables         3    7.45
## 14057         Beverages Pure Juice Beverages         4    3.24
## 14058             Dairy                Dairy         2    4.00
## 14059         Household           Electrical         5   25.53

1.3 Kiểm tra và xử lý dữ liệu thiếu (NA) trong các cột định tính (Nếu có)

Trong quá trình xử lý dữ liệu, việc kiểm tra các giá trị bị thiếu (NA – Not Available) là bước quan trọng để đảm bảo chất lượng của tập dữ liệu trước khi tiến hành các phân tích thống kê hoặc mô hình hóa. Dữ liệu thiếu có thể làm sai lệch kết quả phân tích, gây ra sai số trong mô hình, hoặc ảnh hưởng đến độ chính xác và tính đại diện của kết luận nghiên cứu. Và các biến định tính cần kiểm tra gồm: Gender, MaritalStatus, Homeowner, AnnualIncome, City, StateorProvince, Country, ProductFamily, ProductDepartment, ProductCategory.

Để kiểm tra giá trị thiếu, hàm sapply() kết hợp với is.na() được sử dụng để quét toàn bộ các biến trên và đếm số lượng giá trị bị thiếu trong mỗi biến. Kết quả kiểm tra sẽ giúp xác định liệu có cần loại bỏ các dòng chứa NA, thay thế giá trị NA bằng giá trị phổ biến (mode) trong trường hợp biến định tính, hoặc thực hiện các phương pháp nội suy (imputation) phù hợp.

data_check <- c("Gender", "MaritalStatus", "Homeowner", "AnnualIncome", "City", "StateorProvince", "Country", "ProductFamily", "ProductDepartment", "ProductCategory")
sapply(data[data_check], function(x) sum(is.na(x)))
##            Gender     MaritalStatus         Homeowner      AnnualIncome 
##                 0                 0                 0                 0 
##              City   StateorProvince           Country     ProductFamily 
##                 0                 0                 0                 0 
## ProductDepartment   ProductCategory 
##                 0                 0

Trong đó:

  • sapply(...): áp dụng một hàm cho từng cột trong tập con của data.

  • function(x) sum(is.na(x)): với mỗi cột x, hàm này tính số lượng giá trị bị thiếu (NA) trong cột đó.

  • is.na(x): tạo ra một vector TRUE/FALSE với TRUE ở những vị trí có NA.

  • sum(...) đếm tổng số TRUE, tức là số lượng NA.

Kết quả cho thấy không tồn tại các ô dữ liệu trống/ khuyết ở các cột định tính trong bộ dữ liệu này.

1.4 Chuyển đổi dữ liệu (sang factor)

Trong quá trình xử lý và phân tích dữ liệu, việc xác định đúng kiểu dữ liệu của các biến là vô cùng quan trọng. Đặc biệt với các biến định tính (categorical variables), cần phải chuyển đổi sang kiểu dữ liệu factor trong R để đảm bảo các hàm thống kê, trực quan hóa hoặc mô hình hóa hiểu và xử lý chúng đúng cách.

Các biến định tính thường đại diện cho các đặc điểm phân loại không mang tính liên tục và nếu không được chuyển sang kiểu factor, các biến này có thể bị hiểu nhầm là biến dạng ký tự (character) hoặc tệ hơn là biến số, điều này có thể dẫn đến sai lệch trong kết quả phân tích, đặc biệt khi thực hiện hồi quy, phân tích phương sai (ANOVA), hoặc xây dựng các mô hình học máy. Do đó, ta tiến hành chuyển đổi các biến định tính sang kiểu factor bằng cách sử dụng hàm mutate()across() kết hợp trong dplyr. Sau khi thực hiện lệnh trên, việc gọi str(df) sẽ giúp ta kiểm tra lại một lần nữa để xác nhận rằng các biến định tính đã được chuyển sang kiểu factor một cách chính xác.

#chuyển đổi các cột định tính sang factor
df <- data %>% mutate(across(all_of(data_check), as.factor))
str(df)
## 'data.frame':    14059 obs. of  16 variables:
##  $ X                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ PurchaseDate     : chr  "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
##  $ CustomerID       : int  7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
##  $ Gender           : Factor w/ 2 levels "F","M": 1 2 1 2 1 1 2 1 2 2 ...
##  $ MaritalStatus    : Factor w/ 2 levels "M","S": 2 1 1 1 2 1 2 1 1 2 ...
##  $ Homeowner        : Factor w/ 2 levels "N","Y": 2 2 1 2 2 2 2 2 2 1 ...
##  $ Children         : int  2 5 2 3 3 3 2 2 3 1 ...
##  $ AnnualIncome     : Factor w/ 8 levels "$10K - $30K",..: 5 7 6 5 3 1 5 4 1 6 ...
##  $ City             : Factor w/ 23 levels "Acapulco","Bellingham",..: 8 8 4 12 3 3 13 23 2 15 ...
##  $ StateorProvince  : Factor w/ 10 levels "BC","CA","DF",..: 2 2 8 6 2 2 6 8 8 2 ...
##  $ Country          : Factor w/ 3 levels "Canada","Mexico",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ ProductFamily    : Factor w/ 3 levels "Drink","Food",..: 2 2 2 2 1 2 2 2 3 3 ...
##  $ ProductDepartment: Factor w/ 22 levels "Alcoholic Beverages",..: 20 18 20 21 4 11 13 6 15 14 ...
##  $ ProductCategory  : Factor w/ 45 levels "Baking Goods",..: 42 45 42 7 15 41 5 13 16 35 ...
##  $ UnitsSold        : int  5 5 3 4 4 3 4 6 1 2 ...
##  $ Revenue          : num  27.38 14.9 5.52 4.44 14 ...

Trong đó:

  • across(...): Hàm across() dùng trong mutate() để áp dụng một hàm cho nhiều cột cùng lúc.

  • all_of(data_check): Dùng để chỉ định rõ ràng các cột bạn muốn tác động đến (dựa vào tên cột trong vector data_check).

  • as.factor: Đây là hàm dùng để chuyển một biến sang kiểu factor, tức là kiểu dữ liệu phân loại (categorical).

Việc chuẩn hóa kiểu dữ liệu theo đúng bản chất không chỉ giúp phân tích chính xác hơn mà còn hỗ trợ quá trình trực quan hóa dữ liệu trở nên rõ ràng và có ý nghĩa hơn.

2 Phân tích mô tả một biến định tính

Phân tích mô tả (descriptive analysis) nhằm cung cấp cái nhìn tổng quan về các đặc điểm cơ bản của từng biến trong bộ dữ liệu. Đối với các biến định tính (còn gọi là biến phân loại – categorical variables), mục tiêu của phân tích mô tả là hiểu rõ phân phối tần suất xuất hiện của từng nhóm hoặc hạng mục trong biến đó, từ đó phát hiện các xu hướng hoặc đặc điểm đáng chú ý của dữ liệu.

Ở phần này, ta tập trung vào việc phân tích từng biến định tính một cách riêng lẻ, không xét mối quan hệ với các biến khác. Cụ thể, các biến định tính đã được chuyển sang kiểu factor (ở bước trước) sẽ được thống kê về số lượng và tỷ lệ phần trăm.

2.1 Biến Gender (Giới tính)

Thống kê tần suất

# Bảng tần số và tỷ lệ cho Gender
gender_freq <- table(df$Gender) #tạo bảng tần số
gender_prop <- prop.table(gender_freq) * 100

# Kết hợp thành bảng dễ nhìn
gender_summary <- data.frame(
  Category = names(gender_freq),
  Frequency = as.vector(gender_freq), 
  Percentage = round(as.vector(gender_prop), 4))
colnames(gender_summary) <- c("Category", "Frequency", "Percentage")

#Category: tên các nhóm giới tính (Male, Female,...)
#Frequency: tần số (số lượng)
#Percentage: tỷ lệ phần trăm (đã làm tròn 4 chữ số thập phân)


kable(gender_summary, align = "c", col.names = c("Giới tính", "Tần số", "Tỷ lệ (%)")) %>%
  kableExtra::kable_styling(full_width = FALSE, position = "center", bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Giới tính Tần số Tỷ lệ (%)
F 7170 50.9994
M 6889 49.0006

Trong đó:

  • kable(...): Dùng để hiển thị gender_summary dưới dạng bảng đẹp trong R Markdown / HTML.

  • align = "c": căn giữa các cột.

  • col.names = ...: đổi tên tiêu đề các cột (hiển thị bằng tiếng Việt).

  • kable_styling(...) (Thêm hiệu ứng Bootstrap):

  • "striped": xen kẽ màu dòng.

  • "hover": khi di chuột vào dòng, nó sáng lên.

  • full_width = FALSE: bảng không chiếm toàn bộ chiều ngang trang.

  • position = "center": căn giữa bảng trên trang.

  • row_spec(0, bold = TRUE): Làm đậm hàng đầu tiên (header – dòng tiêu đề cột).

  • column_spec(1:3, width = "4cm"): Đặt độ rộng cho từng cột là 4cm.

Vậy kết quả ở bảng thống kê cho thấy trong bộ dữ liệu Supermarket_Transactions về thông tin giao dịch của khách hàng tại siêu thị có 50.9993598% là thông tin giao dịch của nhóm khách hàng nữ và 49.0006402% là thông tin giao dịch của nhóm khách hàng nam.

Và thay vì chỉ nhìn các con số đơn thuần, việc trình bày dữ liệu dưới dạng đồ họa mang lại cái nhìn trực quan, dễ hiểu và dễ so sánh hơn, đồng thời hỗ trợ phát hiện nhanh các xu hướng, sự mất cân đối hoặc các đặc điểm nổi bật trong tập dữ liệu. Và số lượng và tỷ lệ khách hàng theo nhóm giới tính được thể hiện qua hai biểu đồ dưới đây:

library(patchwork) #Giúp xếp nhiều biểu đồ ggplot thành 1 khung duy nhất
## Warning: package 'patchwork' was built under R version 4.4.3
bar_plot <- ggplot(df, aes(x = Gender, fill = Gender)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = 0, size = 3) +
  labs(title = "Phân bố giới tính Khách hàng",
       x = "Giới tính",
       y = "Số lượng") + 
  theme_minimal() +
  scale_fill_manual(values = c("M" = "skyblue", "F" = "pink"))

gender_p <- as.data.frame(table(df$Gender))
colnames(gender_p) <- c("Category", "Count")

pie_plot <- ggplot(gender_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ Giới tính") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 3)

bar_plot + pie_plot

Trong đó:

  • patchwork: hỗ trợ xếp nhiều biểu đồ ggplot vào cùng 1 khung.

  • ggplot(df, aes(x = Gender, fill = Gender)): vẽ biểu đồ cột theo giới tính.

  • geom_bar(): tạo biểu đồ cột (mặc định là stat = “count”).

  • geom_text(...): thêm nhãn số lượng lên từng cột. Với stat = "count": tự đếm số lượng theo biến Gender, after_stat(count): hiển thị kết quả đếm. vjust = 0: đặt nhãn ở đầu cột. size = 3: cỡ chữ.

  • scale_fill_manual(...): tô màu cột theo giới tính (nam = xanh, nữ = hồng).

  • theme_minimal(): phong cách đơn giản, dễ đọc.

  • geom_bar(width = 1, stat = "identity"): Vẽ biểu đồ cột, mỗi cột có chiều cao bằng Count. width = 1: cột có chiều rộng đầy đủ để tạo thành hình tròn. stat = "identity": dùng trực tiếp giá trị từ Count (không tự đếm).

  • coord_polar("y", start=0): Chuyển biểu đồ cột sang biểu đồ tròn bằng hệ tọa độ polar. Trục y dùng để phân chia góc (slice).

  • theme_void(): Xóa bỏ toàn bộ các yếu tố không cần thiết trong biểu đồ.

  • geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 3): Hiển thị nhãn phần trăm lên các phần của biểu đồ tròn, với giá trị được tính từ tỉ lệ Count/sum(Count), được canh giữa mỗi phần và hiển thị với kích thước chữ là 3.

Nhận xét:

Dựa trên hai biểu đồ, có thể thấy rằng phân bố giới tính trong tập dữ liệu tương đối đồng đều giữa nam và nữ. Biểu đồ cột cho thấy số lượng nữ (F) chiếm 7170 người, cao hơn một chút so với nam (M) là 6889 người. Tỷ lệ này được thể hiện rõ hơn trong biểu đồ tròn, với nữ chiếm gần 51% và nam chiếm khoảng 49% tổng số quan sát. Như vậy, giới tính không có sự chênh lệch đáng kể, điều này cho thấy dữ liệu có sự phân bổ giới tương đối cân bằng, giúp tăng độ tin cậy khi phân tích các yếu tố liên quan đến giới tính.

2.2 Biến MaritalStatus (Tình trạng hôn nhân)

Thống kê tần suất

# Bảng tần số và tỷ lệ
mar_freq <- table(df$MaritalStatus)                     # Tần số
mar_prop <- prop.table(mar_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
mar_summary <- data.frame(
  Category = names(mar_freq),
  Frequency = as.vector(mar_freq),
  Percentage = round(as.vector(mar_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(mar_summary, align = "c", 
      col.names = c("Tình trạng hôn nhân", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Tình trạng hôn nhân Tần số Tỷ lệ (%)
M 6866 48.837
S 7193 51.163

Biểu đồ cột

ggplot(df, aes(x = MaritalStatus, fill = MaritalStatus)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5) +
  labs(title = "Phân bố tình trạng hôn nhân của Khách hàng",
       x = "Tình trạng hôn nhân",
       y = "Số lượng") + 
  theme_minimal() +
  scale_fill_manual(values = c("S" = "yellow", "M" = "violet"))

Biểu đồ tròn

mar_p <- as.data.frame(table(df$MaritalStatus))
colnames(mar_p) <- c("Category", "Count")
ggplot(mar_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ tình trạng hôn nhân của khách hàng") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5))

Nhận xét:

  • Vậy trong bộ dữ liệu này có 48.8370439% khách hàng là người đã kết hôn và 51.1629561% khách hàng là người độc thân.

  • Dữ liệu thống kê cho thấy sự phân bố tương đối đồng đều giữa hai nhóm khách hàng đã kết hôn và còn độc thân (lần lượt là 6866 khách hàng và 7193 khách hàng). Mức chênh lệch chỉ khoảng 2.32%, cho thấy không có sự mất cân đối đáng kể. Cả hai biểu đồ góp phần hỗ trợ việc truyền tải thông tin một cách trực quan, dễ hiểu với sự phân bố khá cân bằng này.

2.3 Biến Homeowner (Tình trạng sở hữu nhà)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
home_freq <- table(df$Homeowner)                     # Tần số
home_prop <- prop.table(home_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
home_summary <- data.frame(
  Category = names(home_freq),
  Frequency = as.vector(home_freq),
  Percentage = round(as.vector(home_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(home_summary, align = "c", 
      col.names = c("Sở hữu nhà", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Sở hữu nhà Tần số Tỷ lệ (%)
N 5615 39.9388
Y 8444 60.0612

Biểu đồ tròn

home_p <- as.data.frame(table(df$Homeowner))
colnames(home_p) <- c("Category", "Count")
ggplot(home_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ sở hữu nhà của khách hàng") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5)) +
  scale_fill_manual(values = c("Y" = "skyblue", "N" = "pink"))

Nhận xét:

  • Vậy trong bộ dữ liệu này có 39.9388292% khách hàng sở hữu nhà 60.0611708% khách hàng không sở hữu nhà.

  • Sự chênh lệch gần 20% cho thấy phần lớn khách hàng thuộc nhóm có sở hữu nhà (8444 khách). Biểu đồ tròn minh họa trực quan tỷ lệ này, nhìn chung, cả bảng thống kê và biểu đồ đều cho thấy xu hướng rõ ràng.

2.4 Biến AnnualIncome (Thu nhập hằng năm của khách hàng)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
income_freq <- table(df$AnnualIncome)                     # Tần số
income_prop <- prop.table(income_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
income_summary <- data.frame(
  Category = names(income_freq),
  Frequency = as.vector(income_freq),
  Percentage = round(as.vector(income_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(income_summary, align = "c", 
      col.names = c("Thu nhập hằng năm của khách hàng", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Thu nhập hằng năm của khách hàng Tần số Tỷ lệ (%)
$10K - $30K 3090 21.9788
$110K - $130K 643 4.5736
$130K - $150K 760 5.4058
$150K + 273 1.9418
$30K - $50K 4601 32.7264
$50K - $70K 2370 16.8575
$70K - $90K 1709 12.1559
$90K - $110K 613 4.3602

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = AnnualIncome, fill = AnnualIncome)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 2) +
  labs(title = "Phân bố mức thu nhập hằng năm của khách hàng",
       x = "Thu nhập",
       y = "Số lượng") + 
  theme_minimal()+theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

Dữ liệu thể hiện sự phân bố thu nhập hàng năm của khách hàng khá rõ ràng qua hai biểu đồ trực quan. Biểu đồ cột cho thấy nhóm khách hàng có thu nhập từ $50K – $70K chiếm số lượng lớn nhất với hơn 4.000 người, theo sau là nhóm $30K – $50K và $70K – $90K. Ngược lại, các nhóm thu nhập rất cao (trên $130K) hoặc rất thấp (dưới $30K) có số lượng khách hàng ít hơn đáng kể.

Biểu đồ tròn

#Biểu đồ tròn
income_p <- as.data.frame(table(df$AnnualIncome))
colnames(income_p) <- c("Category", "Count")
ggplot(income_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ mức thu nhập hằng năm của khách hàng") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 2)

Nhận xét:

Biểu đồ tròn giúp minh họa tỷ lệ phần trăm tương ứng giữa các nhóm thu nhập, trong đó ba nhóm thu nhập từ $30K đến $90K chiếm ưu thế rõ rệt. Cách hiển thị bằng màu sắc phân biệt và tỷ lệ diện tích hợp lý giúp người xem dễ dàng nhận biết được cơ cấu phân bố thu nhập trong toàn bộ dữ liệu. Vậy trong bộ dữ liệu này có:

  • 21.9788036% là khách hàng có thu nhập từ 10K - 30K.

  • 32.7263675% là khách hàng có thu nhập từ 30K - 50K.

  • 16.857529% là khách hàng có thu nhập từ 50K - 70K.

  • 12.1559144% là khách hàng có thu nhập từ 70K - 90K.

  • 4.3601963% là khách hàng có thu nhập từ 90K - 110K.

  • 4.5735828% là khách hàng có thu nhập từ 110K - 130K.

  • 5.4057899% là khách hàng có thu nhập từ 130K - 150K.

  • 1.9418166% là khách hàng có thu nhập trên 150K..

2.5 Biến City (Thành phố nơi khách hàng thực hiện giao dịch)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
city_freq <- table(df$City)                     # Tần số
city_prop <- prop.table(city_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
city_summary <- data.frame(
  Category = names(city_freq),
  Frequency = as.vector(city_freq),
  Percentage = round(as.vector(city_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(city_summary, align = "c", 
      col.names = c("Thành phố nơi khách hàng thực hiện giao dịch", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Thành phố nơi khách hàng thực hiện giao dịch Tần số Tỷ lệ (%)
Acapulco 383 2.7242
Bellingham 143 1.0171
Beverly Hills 811 5.7685
Bremerton 834 5.9321
Camacho 452 3.2150
Guadalajara 75 0.5335
Hidalgo 845 6.0104
Los Angeles 926 6.5865
Merida 654 4.6518
Mexico City 194 1.3799
Orizaba 464 3.3004
Portland 876 6.2309
Salem 1386 9.8585
San Andres 621 4.4171
San Diego 866 6.1598
San Francisco 130 0.9247
Seattle 922 6.5581
Spokane 875 6.2238
Tacoma 1257 8.9409
Vancouver 633 4.5025
Victoria 176 1.2519
Walla Walla 160 1.1381
Yakima 376 2.6744

Dữ liệu cho thấy số lượng giao dịch của khách hàng phân bố không đồng đều giữa các thành phố. Thành phố Salem có số lượng giao dịch cao nhất với 1.386 giao dịch (9.8584537%), theo sau là Tacoma (1.257 giao dịch, 8.940892%) và Portland (876 giao dịch, 6.2308841%). Ngược lại, một số thành phố như Guadalajara (0.5334661%), San Francisco (0.9246746%) và Bellingham (1.07%1.017142%) ghi nhận số lượng giao dịch rất thấp.

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = City, fill = City)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 2) +
  labs(title = "Phân bố số lượng giao dịch của khách hàng tại các thành phố",
       x = "Thành phố",
       y = "Số lượng") + 
  theme_minimal()+theme(axis.text.x = element_text(angle = 45, hjust = 1), legend.position = "bottom")

Nhận xét:

Biểu đồ cột minh họa trực quan sự chênh lệch này, cho phép người xem dễ dàng nhận ra các thành phố có hoạt động giao dịch nổi bật so với phần còn lại. Mỗi thành phố được mã hóa bằng một màu riêng biệt, giúp tăng tính trực quan và phân biệt nhóm.

2.6 Biến StateorProvince (Bang hoặc tỉnh)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
province_freq <- table(df$StateorProvince)                     # Tần số
province_prop <- prop.table(province_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
province_summary <- data.frame(
  Category = names(province_freq),
  Frequency = as.vector(province_freq),
  Percentage = round(as.vector(province_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(province_summary, align = "c", 
      col.names = c("Giao dịch của khách hàng (Bang/Tỉnh)", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Giao dịch của khách hàng (Bang/Tỉnh) Tần số Tỷ lệ (%)
BC 809 5.7543
CA 2733 19.4395
DF 815 5.7970
Guerrero 383 2.7242
Jalisco 75 0.5335
OR 2262 16.0893
Veracruz 464 3.3004
WA 4567 32.4845
Yucatan 654 4.6518
Zacatecas 1297 9.2254

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = StateorProvince, fill = StateorProvince)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 3) +
  labs(title = "Phân bố giao dịch của khách hàng theo từng Bang/Tỉnh",
       x = "Bang/Tỉnh",
       y = "Số lượng") + 
  theme_minimal()+theme(axis.text.x = element_text(angle = 45, hjust = 1))

#Vẽ biểu đồ cột thể hiện số lượng giao dịch của khách hàng theo từng bang/tỉnh, với màu sắc phân biệt từng bang/tỉnh, kèm nhãn số lượng trên mỗi cột và trục hoành được xoay nghiêng để dễ đọc.
#theme(axis.text.x = element_text(angle = 45, hjust = 1)) được dùng để xoay nhãn trục hoành (trục x) 45 độ và căn lề phải, giúp nhãn không bị chồng lên nhau và dễ đọc hơn.

Biểu đồ tròn

#Biểu đồ tròn
province_p <- as.data.frame(table(df$StateorProvince))
colnames(province_p) <- c("Category", "Count")
ggplot(province_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ giao dịch của khách hàng tại các Bang/Tỉnh") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 3)

Nhận xét:

Dữ liệu giao dịch tại siêu thị cho thấy sự phân bố không đồng đều giữa các bang/tỉnh, phản ánh mức độ quan tâm và tần suất mua sắm khác nhau của khách hàng theo khu vực. Dẫn đầu về số lượng giao dịch là bang WA (Washington) với 4.567 giao dịch, chiếm 32.4845295% tổng số, cho thấy đây có thể là thị trường trọng điểm hoặc khu vực có mật độ dân cư cao và hoạt động mua sắm sôi động. Điều này cũng hàm ý rằng khách hàng tại WA thể hiện sự quan tâm lớn hơn đến các giao dịch tại siêu thị, hoặc chuỗi siêu thị ở đây có mạng lưới phủ sóng rộng, thu hút nhiều người tiêu dùng.

Theo sau là CA (California) với 2.733 giao dịch (19.4395049%), OR (Oregon) với 2.262 giao dịch (16.0893378%) và Zacatecas với 1.297 giao dịch (9.2254072%). Các bang này cũng cho thấy mức độ tham gia tích cực từ khách hàng, phản ánh tiềm năng thị trường lớn tại những khu vực này. Ngược lại, Jalisco chỉ ghi nhận 75 giao dịch (0.5334661%), là khu vực có số lượng giao dịch thấp nhất trong toàn bộ dữ liệu, cho thấy mức độ quan tâm của khách hàng tại đây còn rất hạn chế hoặc thị trường siêu thị tại bang này chưa phát triển mạnh. Tương tự, các bang như Guerrero (2.7242%) và Veracruz (2.7242336%) cũng nằm trong nhóm có hoạt động giao dịch kém sôi động, có thể là do dân số ít, mạng lưới bán lẻ chưa phủ rộng, hoặc nhu cầu mua sắm thấp.

2.7 Biến Country (Quốc gia)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
country_freq <- table(df$Country)                     # Tần số
country_prop <- prop.table(country_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
country_summary <- data.frame(
  Category = names(country_freq),
  Frequency = as.vector(country_freq),
  Percentage = round(as.vector(country_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(country_summary, align = "c", 
      col.names = c("Giao dịch của khách hàng ở các quốc gia", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Giao dịch của khách hàng ở các quốc gia Tần số Tỷ lệ (%)
Canada 809 5.7543
Mexico 3688 26.2323
USA 9562 68.0134

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = Country, fill = Country)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 3) +
  labs(title = "Phân bố giao dịch của khách hàng tại các quốc gia",
       x = "Quốc gia",
       y = "Số lượng") + 
  theme_minimal()

Biểu đồ tròn

#Biểu đồ tròn
country_p <- as.data.frame(table(df$Country))
colnames(country_p) <- c("Category", "Count")
ggplot(country_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ giao dịch của khách hàng tại các quốc gia") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.4), size = 2.5)

Nhận xét:

Dữ liệu cho thấy phần lớn các giao dịch của khách hàng đến từ Hoa Kỳ (USA), với tổng cộng 9.562 giao dịch, chiếm đến 68.0133722% tổng số giao dịch. Điều này cho thấy thị trường Hoa Kỳ là thị trường trọng yếu với lượng khách hàng lớn và mức độ giao dịch cao. Có thể suy luận rằng Hoa Kỳ là nơi có hoạt động kinh doanh sôi động, khách hàng thường xuyên phát sinh giao dịch, và doanh nghiệp đang tập trung chiến lược tại quốc gia này.

Mexico xếp thứ hai với 3.688 giao dịch, tương đương 26.2323067%, cũng là một thị trường tiềm năng với mức độ quan tâm và tương tác khá cao từ phía khách hàng. Trong khi đó, Canada chỉ ghi nhận 809 giao dịch (5.7543211%), thể hiện mức độ giao dịch và sự quan tâm thấp hơn đáng kể. Do đó, Canada có thể không phải là thị trường mục tiêu chính hoặc cần có thêm chiến lược thu hút để gia tăng tương tác từ khách hàng tại quốc gia này.

2.8 Biến ProductFamily (Nhóm sản phẩm chính)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
productF_freq <- table(df$ProductFamily)                     # Tần số
productF_prop <- prop.table(productF_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
productF_summary <- data.frame(
  Category = names(productF_freq),
  Frequency = as.vector(productF_freq),
  Percentage = round(as.vector(productF_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(productF_summary, align = "c", 
      col.names = c("Nhóm sản phẩm", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Nhóm sản phẩm Tần số Tỷ lệ (%)
Drink 1250 8.8911
Food 10153 72.2171
Non-Consumable 2656 18.8918

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = ProductFamily, fill = ProductFamily)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 3) +
  labs(title = "Phân bố số giao dịch của khách hàng ở các nhóm sản phẩm",
       x = "Nhóm sản phẩm",
       y = "Số lượng") + 
  theme_minimal()

Biểu đồ tròn

#Biểu đồ tròn
productF_p <- as.data.frame(table(df$ProductFamily))
colnames(productF_p) <- c("Category", "Count")
ggplot(productF_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ giao dịch của khách hàng cho các nhóm sản phẩm") +
theme_void() +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 2.5)

Nhận xét:

Từ bảng thống kê và biểu đồ, có thể thấy rằng nhóm sản phẩm Food chiếm ưu thế rõ rệt với 10.153 giao dịch, tương đương 72.2170851% tổng số giao dịch. Điều này cho thấy khách hàng có xu hướng quan tâm và tiêu dùng các mặt hàng thực phẩm cao hơn đáng kể so với các nhóm sản phẩm còn lại. Việc này có thể bắt nguồn từ nhu cầu thiết yếu và tần suất tiêu dùng thường xuyên của nhóm thực phẩm trong đời sống hàng ngày.

Ngược lại, nhóm Drink chỉ ghi nhận 1.250 giao dịch (chiếm 8.8911018%) và Non-Consumable có 2.656 giao dịch (18.8918131%). Sự chênh lệch lớn giữa ba nhóm sản phẩm cho thấy mức độ hấp dẫn và ưu tiên của khách hàng đối với từng loại sản phẩm là khác nhau. Trong đó, các sản phẩm không tiêu dùng ngay (Non-Consumable) dù chiếm tỷ trọng khá hơn so với Drink nhưng vẫn thua xa Food, phản ánh mức độ giao dịch thấp hơn do có thể ít được tiêu dùng thường xuyên hoặc có giá trị cao hơn nên khách hàng cân nhắc nhiều hơn khi quyết định mua.

2.9 Biến ProductDepartment (Bộ phận sản phẩm)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
productD_freq <- table(df$ProductDepartment)                     # Tần số
productD_prop <- prop.table(productD_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
productD_summary <- data.frame(
  Category = names(productD_freq),
  Frequency = as.vector(productD_freq),
  Percentage = round(as.vector(productD_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(productD_summary, align = "c", 
      col.names = c("Bộ phận sản phẩm", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Bộ phận sản phẩm Tần số Tỷ lệ (%)
Alcoholic Beverages 356 2.5322
Baked Goods 425 3.0230
Baking Goods 1072 7.6250
Beverages 680 4.8368
Breakfast Foods 188 1.3372
Canned Foods 977 6.9493
Canned Products 109 0.7753
Carousel 59 0.4197
Checkout 82 0.5833
Dairy 903 6.4229
Deli 699 4.9719
Eggs 198 1.4084
Frozen Foods 1382 9.8300
Health and Hygiene 893 6.3518
Household 1420 10.1003
Meat 89 0.6330
Periodicals 202 1.4368
Produce 1994 14.1831
Seafood 102 0.7255
Snack Foods 1600 11.3806
Snacks 352 2.5037
Starchy Foods 277 1.9703

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = ProductDepartment, fill = ProductDepartment)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 2) +
  labs(title = "Phân bố số giao dịch của khách hàng ở các bộ phận sản phẩm",
       x = "Bộ phận sản phẩm",
       y = "Số lượng") + 
  theme_minimal() + theme(axis.text.x = element_text(angle = 50, hjust = 1), legend.position = "bottom")

Nhận xét:

  • Produce (Rau quả tươi) là bộ phận có số lượng giao dịch cao nhất với 1.994 lượt giao dịch, chiếm 14.1831%, cho thấy đây là mặt hàng được khách hàng lựa chọn nhiều nhất.

  • Snack Foods (Đồ ăn nhẹ) và Household (Đồ gia dụng) lần lượt xếp thứ hai và ba với 1.600 lượt (11.3806%) và 1.420 lượt (10.1003%), phản ánh nhu cầu lớn trong các mặt hàng tiêu dùng thiết yếu.

  • Các bộ phận như Frozen Foods, Baking Goods, và Canned Foods cũng có lượng giao dịch khá cao (trên 900 lượt), thể hiện xu hướng khách hàng quan tâm đến thực phẩm tiện lợi và có thể bảo quản lâu.

  • Ngược lại, các bộ phận như Carousel, Checkout, Meat, Seafood, và Canned Products có số lượng giao dịch thấp (dưới 200 lượt), chiếm tỷ lệ dưới 1% đến 2.5%. Điều này có thể do đây là các mặt hàng ít phổ biến hơn hoặc chỉ phục vụ các nhu cầu cụ thể.

Khách hàng có xu hướng tập trung mua sắm nhiều nhất ở các bộ phận sản phẩm liên quan đến nhu yếu phẩm hàng ngày như rau củ, đồ ăn nhẹ, và đồ gia dụng. Do đó, các nhà bán lẻ nên chú trọng vào việc tối ưu hóa danh mục sản phẩm, khuyến mãi và trưng bày tại những bộ phận này để thúc đẩy doanh số. Đồng thời, nên xem xét các chiến lược marketing hoặc cải thiện trải nghiệm mua sắm để tăng mức độ quan tâm đến các bộ phận có giao dịch thấp.

2.10 Biến ProductCategory (Danh mục sản phẩm cụ thể)

Thống kê tần suất

# Bảng tần suất và tỷ lệ
productC_freq <- table(df$ProductCategory)                     # Tần số
productC_prop <- prop.table(productC_freq) * 100                  # Tỷ lệ %

# Kết hợp lại
productC_summary <- data.frame(
  Category = names(productC_freq),
  Frequency = as.vector(productC_freq),
  Percentage = round(as.vector(productC_prop), 4))          # 4 số sau dấu phẩy

# In bảng đẹp
kable(productC_summary, align = "c", 
      col.names = c("Danh mục sản phẩm cụ thể", "Tần số", "Tỷ lệ (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1:3, width = "4cm")
Danh mục sản phẩm cụ thể Tần số Tỷ lệ (%)
Baking Goods 484 3.4426
Bathroom Products 365 2.5962
Beer and Wine 356 2.5322
Bread 425 3.0230
Breakfast Foods 417 2.9661
Candles 45 0.3201
Candy 352 2.5037
Canned Anchovies 44 0.3130
Canned Clams 53 0.3770
Canned Oysters 35 0.2490
Canned Sardines 40 0.2845
Canned Shrimp 38 0.2703
Canned Soup 404 2.8736
Canned Tuna 87 0.6188
Carbonated Beverages 154 1.0954
Cleaning Supplies 189 1.3443
Cold Remedies 93 0.6615
Dairy 903 6.4229
Decongestants 85 0.6046
Drinks 135 0.9602
Eggs 198 1.4084
Electrical 355 2.5251
Frozen Desserts 323 2.2975
Frozen Entrees 118 0.8393
Fruit 765 5.4414
Hardware 129 0.9176
Hot Beverages 226 1.6075
Hygiene 197 1.4012
Jams and Jellies 588 4.1824
Kitchen Products 217 1.5435
Magazines 202 1.4368
Meat 761 5.4129
Miscellaneous 42 0.2987
Packaged Vegetables 48 0.3414
Pain Relievers 192 1.3657
Paper Products 345 2.4539
Pizza 194 1.3799
Plastic Products 141 1.0029
Pure Juice Beverages 165 1.1736
Seafood 102 0.7255
Side Dishes 153 1.0883
Snack Foods 1600 11.3806
Specialty 289 2.0556
Starchy Foods 277 1.9703
Vegetables 1728 12.2911
#Tạo và hiển thị bảng tần suất và tỷ lệ phần trăm của biến `ProductCategory` dưới dạng bảng đẹp, căn giữa và có định dạng dễ đọc bằng `kable` và `kableExtra`**.

Biểu đồ cột

#Biểu đồ cột
ggplot(df, aes(x = ProductCategory, fill = ProductCategory)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 2) +
  labs(title = "Phân bố số giao dịch của khách hàng ở danh mục sản phẩm cụ thê",
       x = "Sản phẩm",
       y = "Số lượng") + 
  theme_minimal() + theme(axis.text.x = element_text(angle = 50, hjust = 1), legend.position = "bottom")

#Vẽ biểu đồ cột thể hiện số giao dịch của khách hàng theo từng danh mục sản phẩm, với số lượng được ghi trực tiếp trên cột, tên trục X được xoay nghiêng và chú thích đặt phía dưới biểu đồ.

Nhận xét:

  • Vegetables (Rau quả) là danh mục có số lượng giao dịch cao nhất với 1.728 lượt, chiếm 12.2911% tổng số giao dịch. Điều này cho thấy đây là mặt hàng được khách hàng ưa chuộng nhất trong các danh mục sản phẩm cụ thể.

  • Tiếp theo là Snack Foods (Đồ ăn nhẹ) với 1.600 lượt (11.3806%), và Dairy (Sản phẩm từ sữa) với 903 lượt (6.4229%). Đây đều là các mặt hàng tiêu dùng thiết yếu, phản ánh nhu cầu cao và thường xuyên của người tiêu dùng.

  • Các danh mục như Fruit (5.4414%), Meat (5.4129%), và Jams and Jellies (4.1824%) cũng có tỷ lệ giao dịch tương đối cao, cho thấy xu hướng người tiêu dùng quan tâm đến thực phẩm tươi, chế biến sẵn và đồ ăn kèm.

  • Ở chiều ngược lại, các danh mục như Miscellaneous (0.2987%), Canned Oysters (0.2490%), và Canned Shrimp (0.2703%) có số lượng giao dịch rất thấp, dưới 1%. Những mặt hàng này có thể chỉ đáp ứng các nhu cầu đặc thù, không phổ biến trong mua sắm hàng ngày.

Nhìn chung, khách hàng có xu hướng tập trung mua sắm vào các sản phẩm nhu yếu phẩm như rau củ, sữa, thịt, đồ ăn nhẹ – các mặt hàng có tính tiêu dùng lặp lại và mức độ thiết yếu cao.

3 Ước lượng Khoảng và kiểm định giả thuyết cho tỷ lệ ( Một biến)

3.1 Phân tích cho biến Gender (Giới tính) và hạng mục quan tâm: F (Female)

Biến Gender (Giới tính) được lựa chọn để phân tích vì giới tính là một yếu tố nhân khẩu học cơ bản nhưng có thể có ảnh hưởng đáng kể đến hành vi tiêu dùng, quyết định tài chính và xu hướng thực hiện các giao dịch. Và nhóm khách hàng nữ (Female) là nhóm có thể mang những đặc điểm hành vi tài chính khác biệt so với nam giới, từ đó ảnh hưởng đến các chiến lược marketing. Việc hiểu rõ tỷ lệ khách hàng nữ sẽ giúp doanh nghiệp xác định được mức độ chiếm lĩnh của nhóm này trong tập khách hàng hiện tại, từ đó xây dựng chiến lược phù hợp hơn với nhu cầu thực tế.

#Lấy số lượng cho từng hạng mục
gender_c <- table(df$Gender)

#Tổng số quan sát
total_gender <- sum(gender_c)
cat("Tổng số quan sát cho Gender:", total_gender, "\n")
## Tổng số quan sát cho Gender: 14059
#Số lượng hạng mục quan tâm (Nữ)
female_c <- gender_c["F"]
cat("Số lượng nữ:", female_c, "\n")
## Số lượng nữ: 7170
#Tính tổng số quan sát và số lượng nữ giới trong biến Gender, sau đó in kết quả ra màn hình.

Trong tập dữ liệu có tổng cộng 14.059 quan sát về giới tính khách hàng. Trong đó, có 7.170 khách hàng là nữ.

Ước lượng khoảng tin cậy 95% cho tỷ lệ khách hàng nữ

# Biến: Gender, Hạng mục quan tâm: F
n_female <- sum(df$Gender == "F")
n_total <- nrow(df)

# Sử dụng prop.test để tính khoảng tin cậy
prop_test_gender_F <- prop.test(x = n_female, n = n_total, conf.level = 0.95)
#Tính khoảng tin cậy 95% cho tỷ lệ khách hàng là nữ (Gender = "F") trong tổng số quan sát bằng kiểm định tỷ lệ (`prop.test`).

print(prop_test_gender_F$conf.int) #in kết quả
## [1] 0.5016931 0.5182886
## attr(,"conf.level")
## [1] 0.95

Trong đó: prop.test(x = n_female, n = n_total, conf.level = 0.95): Đây là hàm dùng để kiểm định tỷ lệ (proportion test) và đồng thời tính khoảng tin cậy (confidence interval) cho một tỷ lệ mẫu.

Dựa trên kết quả phân tích với độ tin cậy 95%, tỷ lệ khách hàng nữ trong tổng thể được ước lượng nằm trong khoảng từ 0.5016931 đến 0.5182886. Điều này cho thấy sự phân bố giới tính trong tập khách hàng tương đối cân bằng, tuy nhiên tỷ lệ nữ có xu hướng nhỉnh hơn một chút so với nam.

Kiểm định giả thuyết cho tỷ lệ khách hàng nữ

Để kiểm tra xem tỷ lệ khách hàng nữ có khác biệt đáng kể so với 50% hay không, ta tiến hành kiểm định giả thuyết:

\[\begin{cases} H_0: \text{Tỷ lệ khách hàng nữ trong tổng thể là 0.5.}\\ H_1: \text{Tỷ lệ khách hàng nữ trong tổng thể khác 0.5.} \end{cases}\]
#kiểm tra xem tỉ lệ thực tế (tỉ lệ quan sát được) có khác biệt so với tỉ lệ kỳ vọng p hay không.
prop_test_gender_F_H0 <- prop.test(x = n_female, n = n_total, p = 0.5, alternative = "two.sided")
#"two.sided": kiểm tra tỉ lệ khác không chỉ lớn hơn hoặc nhỏ hơn, mà khác biệt hai chiều (có thể nhỏ hơn hoặc lớn hơn 0.5).

print(prop_test_gender_F_H0)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_female out of n_total, null probability 0.5
## X-squared = 5.5765, df = 1, p-value = 0.0182
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5016931 0.5182886
## sample estimates:
##         p 
## 0.5099936

Kết quả kiểm định như sau:

  • Giá trị thống kê kiểm định (X²): 5.5765

  • Bậc tự do (df): 1

  • Giá trị p-value: 0.0182

  • Tỷ lệ mẫu (\(\hat{p}\)): 0.5099956

  • Khoảng tin cậy 95%: [0.5016931; 0.5182886]

Kết quả kiểm định cho thấy ở mức ý nghĩa 5%, giá trị p-value = 0.0182 < 0.05, nên ta bác bỏ giả thuyết \(H_0\), chấp nhận giả thuyết \(H_1\). Như vậy, có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng nữ trong tổng thể khác 0.5, tức là tỷ lệ nữ không hoàn toàn cân bằng với nam giới.

3.2 Phân tích cho biến MaritalStatus (Tình trạng hôn nhân của khách hàng) và hạng mục quan tâm: S (Khách hàng chưa kết hôn)

Tương tự biến Gender (Giới tính), biến MaritalStatus (Tình trạng hôn nhân) cũng là một trong những yếu tố xã hội quan trọng có thể ảnh hưởng đến hành vi tiêu dùng, mức độ rủi ro tài chính, xu hướng tiết kiệm, cũng như nhu cầu về các sản phẩm, dịch vụ tài chính. Và nhóm khách hàng chưa kết hôn (Single) được chọn làm đối tượng phân tích vì đây là nhóm tiềm năng có khả năng chi tiêu linh hoạt, ít ràng buộc tài chính hơn so với nhóm đã kết hôn hoặc ly hôn. Hơn nữa, hành vi tài chính và nhu cầu tiêu dùng của nhóm này có thể phản ánh xu hướng thị trường mới, đặc biệt trong các sản phẩm tài chính cá nhân, công nghệ tiêu dùng và đầu tư.

#Lấy số lượng cho từng hạng mục
mar_c <- table(df$MaritalStatus)

#Tổng số quan sát
total_mar <- sum(mar_c)
cat("Tổng số quan sát cho MaritalStatus:", total_mar, "\n")
## Tổng số quan sát cho MaritalStatus: 14059
#Số lượng hạng mục quan tâm (Khách hàng chưa kết hôn)
single_c <- mar_c["S"]
cat("Số lượng Khách hàng chưa kết hôn:", single_c, "\n")
## Số lượng Khách hàng chưa kết hôn: 7193

Tổng số quan sát về tình trạng hôn nhân là 14.059, trong đó có 7.193 khách hàng chưa kết hôn. Tỷ lệ khách hàng chưa kết hôn theo dữ liệu là khoảng 51.62%.

Ước lượng khoảng tin cậy 95% cho tỷ lệ khách hàng chưa kết hôn (độc thân)

# Biến: MaritalStatus, Hạng mục quan tâm: S
n_single <- sum(df$MaritalStatus == "S")
n_total <- nrow(df)

# Sử dụng prop.test để tính khoảng tin cậy
prop_test_mar_S <- prop.test(x = n_single, n = n_total, conf.level = 0.95)
print(prop_test_mar_S$conf.int)
## [1] 0.5033292 0.5199235
## attr(,"conf.level")
## [1] 0.95

Với mức tin cậy 95%, tỷ lệ khách hàng chưa kết hôn được ước lượng nằm trong khoảng từ 0.5033292 đến 0.5199235. Điều này cho thấy nhóm khách hàng chưa kết hôn chiếm tỷ lệ hơn một nửa tổng thể, cho thấy sự hiện diện đáng kể và có thể là nhóm khách hàng mục tiêu trong nhiều lĩnh vực.

Kiểm định giả thuyết cho tỷ lệ khách hàng chưa kết hôn

Bài toán kiểm định:

\[\begin{cases} H_0: \text{Tỷ lệ khách hàng chưa kết hôn trong tổng thể là 0.6.}\\ H_1: \text{Tỷ lệ khách hàng chưa kết hôn trong tổng thể khác 0.6.} \end{cases}\]
# Sử dụng kết quả từ prop.test đã chạy ở trên, hoặc chạy lại với p0
prop_test_mar_S_H0 <- prop.test(x = n_single, n = n_total, p = 0.6, alternative = "two.sided") # Hoặc "greater", "less" tùy H1

print(prop_test_mar_S_H0)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_single out of n_total, null probability 0.6
## X-squared = 457.1, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.5033292 0.5199235
## sample estimates:
##         p 
## 0.5116296

Với mức ý nghĩa 5% (\(\alpha = 0.05\)), giá trị p-value < \(2.2 e^{-16}\) < 0.05, do đó bác bỏ giả thuyết \(H_0\), chấp nhận giả thuyết \(H_1\). Vậy tỷ lệ khách hàng chưa kết hôn trong tổng thể khác 0.6. Như vậy, có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng chưa kết hôn trong tổng thể khác 0.6. Cụ thể, tỷ lệ khách hàng chưa kết hôn thực tế thấp hơn đáng kể so với tỷ lệ kỳ vọng là 60%. Điều này cho thấy doanh nghiệp cần xem xét lại các giả định về cơ cấu khách hàng theo tình trạng hôn nhân và có thể điều chỉnh chiến lược marketing, sản phẩm hoặc dịch vụ để phù hợp hơn với nhu cầu thực tế của nhóm khách hàng chưa kết hôn.

3.3 Phân tích cho biến ProductDepartment (Bộ phận sản phẩm) và hạng mục quan tâm: Canned Foods (Thực phẩm đóng hộp)

Biến ProductDepartment được lựa chọn phân tích nhằm tìm hiểu hành vi tiêu dùng theo từng loại sản phẩm khác nhau mà khách hàng lựa chọn. Đây là một biến quan trọng vì mỗi nhóm sản phẩm có đặc trưng tiêu dùng khác nhau, phản ánh sở thích, nhu cầu và xu hướng mua sắm của từng nhóm khách hàng trong dữ liệu.

Trong số các nhóm sản phẩm, nhóm Canned Foods (Thực phẩm đóng hộp) được chọn làm hạng mục quan tâm vì đây là loại sản phẩm phổ biến, có tần suất mua cao, thường gắn với hành vi tiêu dùng hằng ngày và ít bị ảnh hưởng bởi yếu tố thời vụ. Việc phân tích mức độ phổ biến của sản phẩm này sẽ giúp doanh nghiệp hiểu rõ hơn về xu hướng chi tiêu trong các danh mục thiết yếu, từ đó hỗ trợ chiến lược phân phối và tiếp thị phù hợp.

#Lấy số lượng cho từng hạng mục
productD_c <- table(df$ProductDepartment)

#Tổng số quan sát
total_productD <- sum(productD_c)
cat("Tổng số quan sát cho ProductDepartment:", total_productD, "\n")
## Tổng số quan sát cho ProductDepartment: 14059
#Số lượng hạng mục quan tâm (Thực phẩm đóng hộp)
canned_c <- productD_c["Canned Foods"]
cat("Số lượng giao dịch khách hàng có nhu cầu về thực phẩm đóng hộp:", canned_c, "\n")
## Số lượng giao dịch khách hàng có nhu cầu về thực phẩm đóng hộp: 977

Tổng số giao dịch ghi nhận theo biến ProductFamily là 14.059 Trong đó, số lượng giao dịch khách hàng có nhu cầu về thực phẩm đóng hộp là 977 giao dịch.

Ước lượng khoảng tin cậy 95%

# Biến: ProductDepartment, Hạng mục quan tâm: Drink
n_canned <- sum(df$ProductDepartment == "Canned Foods")
n_total <- nrow(df)

# Sử dụng prop.test để tính khoảng tin cậy
prop_test_productD_canned <- prop.test(x = n_canned, n = n_total, conf.level = 0.95)
print(prop_test_productD_canned$conf.int)
## [1] 0.06537142 0.07385147
## attr(,"conf.level")
## [1] 0.95

Với mức tin cậy 95%, tỷ lệ giao dịch thực phẩm đống hộp trong tổng số được ước lượng nằm trong khoảng từ 0.06537142 đến 0.07385147. Điều này cho thấy thực phẩm đóng hộp chiếm một tỷ lệ tương đối nhỏ trong tổng số giao dịch, tuy nhiên vẫn đáng chú ý vì tính chất thiết yếu và mức độ thường xuyên.

Kiểm định giả thuyết cho tỷ lệ giao dịch thức uống

Bài toán kiểm định:

\[\begin{cases} H_0: \text{Tỷ lệ khách hàng quan tâm đến thực phẩm đóng hộp trong tổng thể là 0.1.}\\ H_1: \text{Tỷ lệ khách hàng quan tâm đến thực phẩm đóng hộp trong tổng thể khác 0.1.} \end{cases}\]
# Sử dụng kết quả từ prop.test đã chạy ở trên, hoặc chạy lại với p0
prop_test_productD_canned_H0 <- prop.test(x = n_canned, n = n_total, p = 0.1, alternative = "two.sided") # Hoặc "greater", "less" tùy H1

print(prop_test_productD_canned_H0)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_canned out of n_total, null probability 0.1
## X-squared = 145.04, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.1
## 95 percent confidence interval:
##  0.06537142 0.07385147
## sample estimates:
##          p 
## 0.06949285

Kết quả kiểm định cho thấy ở mức ý nghĩa 5%, giá trị p-value < \(2.2 e^{-16}\) <0.05, do đó bác bỏ giả thuyết \(H_0\), chấp nhận giả thuyết \(H_1\). Như vậy, có đủ bằng chứng để kết luận rằng tỷ lệ khách hàng quan tâm đến thực phẩm đóng hộp khác biệt đáng kể so với tỷ lệ kỳ vọng là 10%.

Trên thực tế, tỷ lệ giao dịch thực phẩm đóng hộp chiếm khoảng 6.95%, thấp hơn so với mức 10%, cho thấy thực phẩm đóng hộp không phải là sản phẩm chính trong tập dữ liệu. Doanh nghiệp có thể xem xét kết hợp phân tích thêm các nhóm sản phẩm khác để có chiến lược phân loại khách hàng và sản phẩm phù hợp hơn, hoặc cân nhắc tăng cường quảng bá cho nhóm sản phẩm này nếu muốn đẩy mạnh tiêu dùng.

4 Phân tích mối quan hệ giữa hai biến định tính

4.1 Mối quan hệ giữa biến Gender và ProductFamily

Có một giả định phổ biến rằng giới tính có thể ảnh hưởng đến sở thích và quyết định mua các loại sản phẩm khác nhau. Và phụ nữ có thể có xu hướng mua sắm nhiều hơn ở các nhóm sản phẩm nhất định (ví dụ: thực phẩm tươi sống, đồ dùng gia đình), trong khi nam giới có thể tập trung vào các nhóm khác (ví dụ: đồ điện tử, công cụ, hoặc các loại thực phẩm chế biến sẵn). Phân tích cặp biến này giúp xác định xem xu hướng này có đúng trong bộ dữ liệu Supermarket_Transactions hay không và mức độ khác biệt giữa hai giới là bao nhiêu.

4.1.1 Bảng tần số chéo và tần suất

# Bảng tần số chéo
gender_product_table <- table(df$Gender, df$ProductFamily)
#Tạo bảng tần số chéo đếm số lần xuất hiện kết hợp giữa các giá trị của cột `Gender` và `ProductFamily` trong data frame `df`.

print(gender_product_table)
##    
##     Drink Food Non-Consumable
##   F   669 5149           1352
##   M   581 5004           1304

Dựa trên bảng tần số chéo giữa hai biến, ta thấy rằng ở cả hai giới, nhóm sản phẩm Food được tiêu thụ nhiều nhất, với số lượng là 5149 ở nữ và 5004 ở nam. Nhóm sản phẩm có số lượng tiêu thụ thấp nhất là Drink, với 669 lượt ở nữ và 581 lượt ở nam.

gender_product_prop_row <- prop.table(gender_product_table, margin = 1)
#Tính tỷ lệ phần trăm theo hàng (tỷ lệ có điều kiện theo từng giá trị của biến trong hàng) từ bảng đếm `gender_product_table`.

print(gender_product_prop_row)
##    
##          Drink       Food Non-Consumable
##   F 0.09330544 0.71813110     0.18856346
##   M 0.08433735 0.72637538     0.18928727

Khi phân tích tỷ lệ phần trăm theo từng giới tính, ta nhận thấy tỷ lệ lựa chọn các nhóm sản phẩm là khá tương đồng giữa nam và nữ. Cụ thể, tỷ lệ chọn nhóm Food ở nữ là 71.81%, và ở nam là 72.64%. Các tỷ lệ còn lại cho nhóm Drink và Non-Consumable cũng không có sự chênh lệch đáng kể. Nhìn chung, điều này cho thấy xu hướng tiêu dùng sản phẩm giữa hai giới không có sự khác biệt lớn.

4.1.2 Trực quan hoá mối quan hệ

Biểu đồ cột nhóm

ggplot(df, aes(x = Gender, fill = ProductFamily)) +
  geom_bar(position = "dodge") +
  labs(title = "Phân bố nhóm sản phẩm theo giới tính",
       x = "Giới tính",
       y = "Số lượng",
       fill = "Nhóm sản phẩm") +
  theme_minimal()+geom_text(stat = "count",
            aes(label = after_stat(count)),
            position = position_dodge(width = 0.9), vjust = -0.2,
            size = 3,
            color = "black")

#vẽ biểu đồ cột nhóm theo giới tính và nhóm sản phẩm, kèm nhãn số lượng từng cột. 

Trong đó:

  • geom_bar(): Vẽ biểu đồ cột. position = “dodge”: các cột của các nhóm sản phẩm sẽ đứng cạnh nhau (không chồng lên), tách biệt theo giới tính.

  • labs(…): Đặt tiêu đề biểu đồ và tên các trục, cùng tên chú thích màu.

  • position = position_dodge(width = 0.9): căn chỉnh nhãn theo vị trí cột (bằng đúng chiều rộng cột để không đè lên nhau).

  • vjust = -0.2: đẩy nhãn lên phía trên cột một chút (nằm ngay trên đỉnh cột).

Nhận xét: Biểu đồ cột nhóm thể hiện trực quan sự phân bố các nhóm sản phẩm theo giới tính. Từ biểu đồ, có thể dễ dàng nhận thấy rằng nhóm Food là nhóm chiếm ưu thế vượt trội so với hai nhóm còn lại ở cả hai giới. Nhóm Drink và Non-Consumable có số lượng thấp hơn nhiều và khá tương đương nhau giữa nam và nữ. Biểu đồ này góp phần minh họa rõ ràng cho kết quả thu được từ bảng tần suất chéo, đồng thời củng cố nhận định rằng không có sự khác biệt đáng kể trong hành vi tiêu dùng giữa nam và nữ theo nhóm sản phẩm.

4.1.3 Kiểm định thống kê (Kiểm định chi - bình phương)

Bài toán kiểm định:

\[\begin{cases} H_0: \text{Tỷ lệ mua các nhóm sản phẩm khác nhau không phụ thuộc vào giới tính.}\\ H_1: \text{Tỷ lệ mua các nhóm sản phẩm khác nhau phụ thuộc vào giới tính.} \end{cases}\]
# Thực hiện kiểm định Chi-bình phương để kiểm tra xem có mối liên hệ thống kê giữa hai biến định tính
chi_sq_test_gender_product <- chisq.test(gender_product_table)
print(chi_sq_test_gender_product)
## 
##  Pearson's Chi-squared test
## 
## data:  gender_product_table
## X-squared = 3.5185, df = 2, p-value = 0.1722

Trong đó:

  • chisq.test(): Hàm thực hiện kiểm định chi-square test of independence, kiểm tra xem 2 biến phân loại có độc lập với nhau hay không.

  • Nếu p-value nhỏ hơn mức ý nghĩa (ví dụ 0.05), thì bạn bác bỏ giả thuyết độc lập, tức có mối liên hệ giữa 2 biến.

Với mức ý nghĩa 5%, kết quả kiểm định cho thấy giá trị p-value = 0.1722 > 0.05, chấp nhận giả thuyết \(H_0\), bác bỏ giả thuyết \(H_1\). Vậy giới tính và nhóm sản phẩm là độc lập, không có mối liên hệ với nhau. Hay tỷ lệ mua các nhóm sản phẩm không phụ thuộc vào giới tính.

4.2 Mối quan hệ giữa biến MaritalStatus và Homeowner

Đây là hai biến đặc điểm nhân khẩu học quan trọng. Tình trạng hôn nhân (Độc thân/Đã kết hôn) và việc sở hữu nhà (Có/Không) thường liên quan đến các giai đoạn trong cuộc đời và tình hình tài chính của một người. Có thể có mối liên hệ giữa việc kết hôn và khả năng sở hữu nhà, hoặc giữa việc độc thân và tình trạng thuê nhà. Việc phân tích mối quan hệ giữa hai biến này giúp hiểu rõ hơn về cấu trúc nhân khẩu học của tệp khách hàng: Liệu khách hàng đã kết hôn có tỷ lệ sở hữu nhà cao hơn đáng kể so với khách hàng độc thân không? Mối liên hệ này có thể gián tiếp ảnh hưởng đến hành vi mua sắm (ví dụ: chủ nhà có thể mua các sản phẩm khác với người thuê nhà).

4.2.1 Bảng tần số chéo và tần suất

# Bảng tần số chéo
mar_home_table <- table(df$MaritalStatus, df$Homeowner)
print(mar_home_table)
##    
##        N    Y
##   M 1719 5147
##   S 3896 3297
# Giải thích lý do chọn tính theo hàng/cột/tổng
mar_home_prop_row <- prop.table(mar_home_table, margin = 1)
print(mar_home_prop_row)
##    
##             N         Y
##   M 0.2503641 0.7496359
##   S 0.5416377 0.4583623

Nhận xét: Dựa trên bảng tần số chéo giữa hai biến MaritalStatus (Tình trạng hôn nhân) và Homeowner (Sở hữu nhà), ta nhận thấy trong nhóm đã kết hôn (M), có 5.147 người sở hữu nhà (Y) và 1.719 người không sở hữu nhà (N). Trong khi đó, ở nhóm độc thân (S), số người không sở hữu nhà chiếm 3.896 và số người sở hữu nhà là 3.297. Điều này cho thấy tỉ lệ người đã kết hôn có xu hướng sở hữu nhà nhiều hơn người độc thân.

Khi xem xét tỉ lệ phần trăm theo từng hàng, kết quả cho thấy trong nhóm đã kết hôn, có khoảng 74.96% người sở hữu nhà và 25.04% không sở hữu nhà. Ngược lại, trong nhóm độc thân, 54.16% không sở hữu nhà và chỉ 45.84% có sở hữu nhà. Điều này củng cố nhận định rằng những người đã kết hôn có xu hướng sở hữu nhà cao hơn đáng kể so với những người độc thân.

4.2.2 Trực quan hoá mối quan hệ

Biểu đồ cột nhóm

ggplot(df, aes(x = MaritalStatus, fill = Homeowner)) +
  geom_bar(position = "dodge") +
  labs(title = "Phân bố nhóm sản phẩm theo giới tính",
       x = "Tình trạng hôn nhân",
       y = "Số lượng",
       fill = "Sở hữu nhà") +
  theme_minimal()+geom_text(stat = "count",
            aes(label = after_stat(count)),
            position = position_dodge(width = 0.9), vjust = -0.2,
            size = 3,
            color = "black")

Nhận xét: Biểu đồ cột nhóm cũng minh họa rõ ràng sự khác biệt này. Nhóm đã kết hôn có số lượng người sở hữu nhà cao vượt trội so với người không sở hữu nhà. Ngược lại, trong nhóm độc thân, số lượng người không sở hữu nhà lại cao hơn người sở hữu nhà. Sự phân bố này cho thấy có thể tồn tại mối liên hệ giữa tình trạng hôn nhân và khả năng sở hữu nhà, gợi ý rằng yếu tố hôn nhân có thể ảnh hưởng đến quyết định hoặc khả năng mua nhà của cá nhân.

4.2.3 Kiểm định thống kê

Bài toán kiểm định:

\[\begin{cases} H_0: \text{Tình trạng hôn nhân và việc sở hữu nhà là độc lập (không có mối liên hệ).}\\ H_1: \text{Tình trạng hôn nhân và việc sở hữu nhà có liên quan (Tỷ lệ sở hữu nhà phụ thuộc vào tình trạng hôn nhân).} \end{cases}\]
# Thực hiện kiểm định Chi-bình phương
chi_sq_test_mar_home <- chisq.test(mar_home_table)
print(chi_sq_test_mar_home)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  mar_home_table
## X-squared = 1241.2, df = 1, p-value < 2.2e-16

Nhận xét:

Kết quả kiểm định Chi-bình phương cho thấy biến tình trạng hôn nhân (MaritalStatus) và sở hữu nhà (Homeowner) có mối quan hệ với nhau khi p-value < \(2.2 e^{−16}\), nhỏ hơn mức ý nghĩa 5%. Do đó, ta bác bỏ giả thuyết \(H_0\) (hai biến độc lập) và chấp nhận giả thuyết \(H_1\) (hai biến có liên quan).

Quan sát bảng tần suất và biểu đồ cột cho thấy tỷ lệ người đã kết hôn sở hữu nhà là 74.96%, cao hơn nhiều so với người độc thân (45.84%). Điều này cho thấy những người đã kết hôn có xu hướng sở hữu nhà nhiều hơn, có thể do nhu cầu ổn định chỗ ở khi lập gia đình hoặc do khả năng tài chính tốt hơn khi có hai nguồn thu nhập. Ngược lại, người độc thân có tỷ lệ không sở hữu nhà cao hơn, phản ánh xu hướng thuê nhà hoặc chưa có nhu cầu ổn định lâu dài.

4.3 Mối quan hệ giữa biến AnnualIncome và ProductFamily

Thu nhập hàng năm (được phân loại thành các khoảng) là một chỉ số quan trọng về khả năng chi tiêu của khách hàng. Có mối liên hệ được kỳ vọng giữa mức thu nhập và loại sản phẩm mà khách hàng lựa chọn mua. Khách hàng có thu nhập cao hơn có thể có xu hướng mua các sản phẩm cao cấp, nhập khẩu, hoặc các mặt hàng không thiết yếu nhiều hơn, trong khi khách hàng có thu nhập thấp hơn có thể tập trung vào các mặt hàng thiết yếu, có giá phải chăng. Phân tích cặp biến này giúp xác định xem các nhóm thu nhập khác nhau có phân bổ chi tiêu khác nhau cho các loại sản phẩm (ProductFamily/ProductCategory) hay không, từ đó cung cấp thông tin cho chiến lược giá, marketing và phân loại hàng hóa.

4.3.1 Bảng tần số chéo và tần suất

# Bảng tần số chéo
income_product_table <- table(df$AnnualIncome, df$ProductFamily)
print(income_product_table)
##                
##                 Drink Food Non-Consumable
##   $10K - $30K     267 2232            591
##   $110K - $130K    59  468            116
##   $130K - $150K    56  556            148
##   $150K +          25  199             49
##   $30K - $50K     421 3340            840
##   $50K - $70K     193 1705            472
##   $70K - $90K     156 1221            332
##   $90K - $110K     73  432            108
# Giải thích lý do chọn tính theo hàng/cột/tổng
income_product_prop_row <- prop.table(income_product_table, margin = 1)
print(income_product_prop_row)
##                
##                      Drink       Food Non-Consumable
##   $10K - $30K   0.08640777 0.72233010     0.19126214
##   $110K - $130K 0.09175739 0.72783826     0.18040435
##   $130K - $150K 0.07368421 0.73157895     0.19473684
##   $150K +       0.09157509 0.72893773     0.17948718
##   $30K - $50K   0.09150185 0.72592915     0.18256901
##   $50K - $70K   0.08143460 0.71940928     0.19915612
##   $70K - $90K   0.09128145 0.71445290     0.19426565
##   $90K - $110K  0.11908646 0.70473083     0.17618271

Nhận xét: Trong nhóm có thu nhập từ $10K - $30K, có 267 người mua sản phẩm thuộc nhóm “Drink”, 2232 người mua sản phẩm thuộc nhóm “Food” và 591 người mua sản phẩm thuộc nhóm “Non-Consumable”. Trong khi đó, ở nhóm có thu nhập từ $30K - $50K, số người mua sản phẩm “Food” chiếm 3340, số người mua sản phẩm “Drink” là 421 và số người mua sản phẩm “Non-Consumable” là 849. Điều này cho thấy nhóm “Food” có xu hướng được mua nhiều nhất ở cả hai mức thu nhập này.

Khi xem xét tỉ lệ phần trăm, kết quả cho thấy trong nhóm có thu nhập từ $10K - $30K, có khoảng 8.64% người mua “Drink”, 72.23% người mua “Food” và 19.13% người mua “Non-Consumable”. Ngược lại, trong nhóm có thu nhập từ $30K - $50K, 9.15% mua “Drink”, 72.59% mua “Food” và 18.26% mua “Non-Consumable”. Điều này củng cố nhận định rằng nhóm “Food” luôn chiếm tỉ lệ lớn nhất trong cơ cấu mua hàng, bất kể mức thu nhập. Tuy nhiên, có một sự dịch chuyển nhỏ về tỉ lệ giữa các nhóm sản phẩm khi thu nhập thay đổi.

4.3.2 Trực quan hoá mối quan hệ

Biểu đồ cột nhóm

ggplot(df, aes(x = AnnualIncome, fill = ProductFamily)) +
  geom_bar(position = "dodge") +
  labs(title = "Phân bố nhóm sản phẩm theo mức thu nhập hằng năm của khách hàng",
       x = "Mức thu nhập",
       y = "Số lượng",
       fill = "Nhóm sản phẩm") +
  theme_minimal()+geom_text(stat = "count",
            aes(label = after_stat(count)),
            position = position_dodge(width = 0.9), vjust = -0.2,
            size = 2.5,
            color = "black")+theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

Dựa trên biểu đồ cột nhóm, chúng ta có thể nhận thấy rõ ràng sự phân bố số lượng sản phẩm được mua theo từng mức thu nhập. Cụ thể, nhóm sản phẩm “Food” (màu xanh lá cây) luôn chiếm số lượng cao nhất ở hầu hết các mức thu nhập, nổi bật nhất là ở các mức thu nhập trung bình như “$10K - $30K” và “$30K - $50K”, nơi cột “Food” cao vượt trội so với hai nhóm còn lại. Điều này khẳng định “Food” là nhóm sản phẩm được khách hàng mua nhiều nhất. Tiếp theo là nhóm “Non-Consumable” (màu xanh dương), với số lượng mua thấp hơn “Food” nhưng lại cao hơn “Drink” ở hầu hết các mức thu nhập, đồng thời có xu hướng giảm dần khi thu nhập tăng lên các mức cao hơn. Cuối cùng, nhóm “Drink” (màu đỏ) luôn có số lượng mua thấp nhất trong cả ba nhóm sản phẩm ở mọi mức thu nhập. Tóm lại, sự phân bố này minh họa mối liên hệ rõ ràng giữa mức thu nhập và lựa chọn nhóm sản phẩm của khách hàng, với “Food” là ưu tiên hàng đầu ở nhiều mức thu nhập, đặc biệt là các mức thấp và trung bình, cho thấy thứ tự ưu tiên giữa các nhóm sản phẩm khá ổn định dù số lượng mua có biến động tùy theo mức thu nhập.

4.3.3 Kiểm định thống kê

Bài toán kiểm định:

\[\begin{cases} H_0: \text{Thu nhập hàng năm và nhóm sản phẩm mua là độc lập (không có mối liên hệ).}\\ H_1: \text{Thu nhập hàng năm và nhóm sản phẩm mua có liên quan (tỷ lệ mua các nhóm sản phẩm khác nhau phụ thuộc vào mức thu nhập hàng năm).} \end{cases}\]
# Thực hiện kiểm định Chi-bình phương
chi_sq_test_income_product <- chisq.test(income_product_table)
print(chi_sq_test_income_product)
## 
##  Pearson's Chi-squared test
## 
## data:  income_product_table
## X-squared = 14.84, df = 14, p-value = 0.3892

Với mức ý nghĩa 5%, kết quả kiểm định cho thấy giá trị p-value = 0.3892 > 0.05, chấp nhận giả thuyết \(H_0\), bác bỏ giả thuyết \(H_1\). Tức là AnnualIncome và ProductFamily là độc lập, không có mối liên hệ thống kê rõ ràng. Điều này có nghĩa là thu nhập hàng năm của khách hàng không ảnh hưởng đáng kể đến việc họ lựa chọn dòng sản phẩm nào, hay nói cách khác, hành vi tiêu dùng giữa các nhóm thu nhập là tương đối giống nhau đối với các dòng sản phẩm đang được khảo sát.

5 Tổng kết và Thảo luận

5.1 Tổng kết

Dựa trên quá trình khám phá và phân tích thống kê mô tả cùng với kiểm định mối liên hệ giữa các biến định tính trong bộ dữ liệu Supermarket_Transactions, chúng ta đã thu được những hiểu biết quan trọng về đặc điểm nhân khẩu học và hành vi mua sắm tổng thể của khách hàng tại siêu thị này. Bộ dữ liệu gồm 14.059 quan sát và 16 biến, với các biến định tính chính như Giới tính, Tình trạng hôn nhân, Sở hữu nhà, Thu nhập hàng năm, thông tin Địa lý và Phân loại sản phẩm. Quan trọng là, không phát hiện giá trị thiếu (NA) trong các biến định tính đã kiểm tra, đảm bảo chất lượng dữ liệu cho phân tích.

Về đặc điểm nhân khẩu học và vị trí địa lý của khách hàng, dữ liệu cho thấy sự phân bổ giới tính khá cân bằng, với nữ giới chiếm tỷ lệ hơi nhỉnh hơn một chút (khoảng 51%), và kiểm định thống kê xác nhận tỷ lệ này khác biệt đáng kể so với 50%. Tình trạng hôn nhân cũng phân bổ tương đối đồng đều giữa nhóm Độc thân và Đã kết hôn, trong đó nhóm độc thân chiếm khoảng 51.6%. Đáng chú ý, phần lớn khách hàng là người sở hữu nhà, với tỷ lệ này cao hơn gần 20% so với người không sở hữu nhà. Về thu nhập, khách hàng tập trung chủ yếu ở các mức trung bình, đặc biệt là khoảng $50K – $70K, tiếp theo là $30K – $50K$70K – $90K. Phân bố địa lý cho thấy Hoa Kỳ (USA) là quốc gia có lượng giao dịch vượt trội (hơn 68%), trong đó các bang WA, CA, OR có số lượng giao dịch cao nhất. Mexico đứng thứ hai về lượng giao dịch, trong khi Canada chiếm tỷ lệ nhỏ nhất. Một số khu vực như Jalisco (Mexico) và Guadalajara có lượng giao dịch rất thấp.

Phân tích về hành vi mua sắm theo nhóm sản phẩm cho thấy sự tập trung rõ rệt vào một số danh mục nhất định. Nhóm sản phẩm chính Food chiếm tỷ lệ áp đảo trong tổng số giao dịch (hơn 70%), khẳng định vai trò thiết yếu của nhóm hàng này. Nhóm Non-ConsumableDrink lần lượt chiếm vị trí thứ hai và ba với tỷ lệ thấp hơn đáng kể. Khi đi sâu vào các bộ phận sản phẩm, Produce, Snack Foods, và Household ghi nhận số lượng giao dịch cao nhất, trong khi các danh mục cụ thể như Vegetables, Snack Foods, và Dairy phổ biến nhất. Ngược lại, các bộ phận hoặc danh mục sản phẩm như Carousel, Checkout, Canned Oysters/Shrimp, và Miscellaneous có lượng giao dịch rất thấp.

Cuối cùng, phân tích mối liên hệ giữa các cặp biến định tính đã mang lại những kết quả quan trọng. Kiểm định Chi-bình phương cho thấy không có mối liên hệ ý nghĩa thống kê giữa Giới tính (Gender) và Nhóm sản phẩm chính (ProductFamily) (p-value = 0.1722 > 0.05), chỉ ra rằng tỷ lệ mua các nhóm sản phẩm lớn không phụ thuộc đáng kể vào giới tính. Tương tự, không tìm thấy mối liên hệ ý nghĩa thống kê rõ ràng giữa Thu nhập hàng năm (AnnualIncome) và Nhóm sản phẩm chính (ProductFamily) (p-value = 0.3892 > 0.05), cho thấy tỷ lệ mua các nhóm sản phẩm chính này không phụ thuộc đáng kể vào mức thu nhập. Tuy nhiên, có mối liên hệ ý nghĩa thống kê rất mạnh giữa Tình trạng hôn nhân (MaritalStatus) và Việc sở hữu nhà (Homeowner) (p-value < 2.2e-16 < 0.05). Phân tích chi tiết cho thấy những khách hàng đã kết hôn có tỷ lệ sở hữu nhà cao hơn đáng kể (74.96%) so với những khách hàng độc thân (45.84%), phản ánh một xu hướng nhân khẩu học rõ rệt trong tập dữ liệu này.

5.2 Thảo luận

Phân tích dữ liệu giao dịch siêu thị dựa trên các biến định tính đã cung cấp những cái nhìn ban đầu về chân dung khách hàng và xu hướng mua sắm tổng thể. Tuy nhiên, để đưa ra các quyết định kinh doanh hiệu quả hơn, cần nhận thức rõ những hạn chế của phân tích này và xem xét các hướng nghiên cứu tiếp theo.

Hạn chế của phân tích

Phân tích hiện tại có một số hạn chế cần được ghi nhận:

  • Chất lượng dữ liệu: Mặc dù đã kiểm tra và xác nhận không có giá trị thiếu trong các biến định tính được khảo sát, tính chính xác và độ tin cậy của dữ liệu gốc (ví dụ: việc khách hàng khai báo thu nhập hoặc tình trạng hôn nhân) vẫn là một yếu tố cần cân nhắc.

  • Giới hạn của việc chỉ phân tích biến định tính: Bài tập chỉ tập trung khám phá mối quan hệ giữa các biến định tính. Việc không kết hợp phân tích mối liên hệ giữa các biến định tính với các biến định lượng như Số con cái (Children), Số lượng sản phẩm bán ra (UnitsSold), Doanh thu (Revenue) là một hạn chế đáng kể. Phân tích này chưa thể trả lời câu hỏi quan trọng về hành vi chi tiêu thực tế (ví dụ: thu nhập ảnh hưởng đến tổng doanh thu mua sắm như thế nào, hay tình trạng hôn nhân/số con cái có liên quan đến số lượng sản phẩm mua trong một giao dịch không?), làm mất đi nhiều góc nhìn sâu sắc về giá trị khách hàng.

  • Kích thước mẫu cho một số hạng mục con: Một số hạng mục trong các biến như Thành phố (City), Bang/Tỉnh (StateorProvince), Bộ phận sản phẩm (ProductDepartment), Danh mục sản phẩm (ProductCategory) có số lượng giao dịch rất thấp. Điều này có thể làm giảm tính đại diện và ý nghĩa thống kê của các phân tích hoặc kiểm định liên quan đến các hạng mục cụ thể này.

Một số đề xuất

Dựa trên những phát hiện chính từ phân tích các biến định tính, chúng ta có thể đưa ra một số đề xuất ban đầu cho doanh nghiệp:

  • Chiến lược Marketing và Nhắm mục tiêu: Do mối liên hệ rõ ràng giữa tình trạng hôn nhân và sở hữu nhà, doanh nghiệp có thể cân nhắc phát triển các chiến dịch marketing hoặc chương trình khuyến mãi đặc biệt nhắm vào nhóm khách hàng đã kết hôn và có sở hữu nhà. Nhóm này có thể quan tâm đến các sản phẩm gia dụng, sản phẩm số lượng lớn hoặc các dịch vụ liên quan đến nhà cửa. Ngược lại, cần nghiên cứu thêm để hiểu rõ nhu cầu đặc thù của nhóm độc thân hoặc nhóm không sở hữu nhà để có chiến lược tiếp cận phù hợp.

  • Quản lý danh mục sản phẩm và tồn kho: Kết quả cho thấy nhóm sản phẩm Food cùng các bộ phận/danh mục con như Produce/Vegetables, Snack Foods, Dairy, Household là những mặt hàng được mua nhiều nhất. Doanh nghiệp nên ưu tiên tối ưu hóa việc trưng bày, quản lý tồn kho và các hoạt động khuyến mãi cho nhóm sản phẩm thiết yếu này, đặc biệt là ở các khu vực có lượng giao dịch cao. Đồng thời, cần xem xét chiến lược cho các nhóm sản phẩm/danh mục có doanh số thấp – liệu có nên giảm quy mô, thay đổi vị trí trưng bày, hoặc tìm cách kích cầu thông qua các chương trình đặc biệt.

  • Chiến lược Phát triển thị trường theo địa lý: Tăng cường đầu tư và nguồn lực vào các thị trường trọng điểm như Hoa Kỳ (đặc biệt WA, CA, OR) và Mexico. Đối với các khu vực có lượng giao dịch thấp như Canada hoặc một số thành phố/bang/tỉnh cụ thể, cần nghiên cứu sâu hơn để xác định nguyên nhân và xây dựng chiến lược tiếp cận phù hợp (ví dụ: mở rộng mạng lưới, điều chỉnh danh mục sản phẩm cho phù hợp với văn hóa/nhu cầu địa phương, tăng cường hoạt động quảng bá trực tuyến hoặc ngoại tuyến).

Hướng nghiên cứu tiếp theo

  • Mối quan hệ giữa các đặc điểm định tính (Gender, MaritalStatus, Homeowner, AnnualIncome, Location) và các biến định lượng (Children, UnitsSold, Revenue): Làm thế nào các yếu tố nhân khẩu học và địa lý ảnh hưởng đến số lượng sản phẩm mua và tổng doanh thu của khách hàng? Điều này sẽ giúp định lượng giá trị của các phân khúc khách hàng khác nhau.

  • Phân tích sâu hơn về các cấp độ phân loại sản phẩm: Mặc dù Thu nhập hàng năm không có mối liên hệ ý nghĩa với Nhóm sản phẩm chính (ProductFamily), liệu có mối liên hệ giữa Thu nhập hoặc các đặc điểm khác với việc mua các Bộ phận (ProductDepartment) hoặc Danh mục (ProductCategory) sản phẩm cụ thể không? Ví dụ, khách hàng thu nhập cao có xu hướng mua các loại thịt hoặc hải sản đắt tiền hơn không?

  • Nghiên cứu chi tiết yếu tố địa lý: Liệu có sự khác biệt đáng kể trong xu hướng mua sắm các loại sản phẩm cụ thể giữa các bang, thành phố, hoặc quốc gia không? Điều này rất quan trọng cho việc tùy chỉnh danh mục hàng hóa tại từng địa điểm.

  • Phân tích hành vi mua sắm theo thời gian: Dữ liệu có chứa thông tin Ngày giao dịch (PurchaseDate). Việc phân tích xu hướng mua sắm theo mùa vụ, ngày trong tuần, hoặc các dịp đặc biệt có thể mang lại những hiểu biết giá trị về thời điểm khách hàng có nhu cầu mua sắm cao nhất.

  • Xây dựng mô hình Phân nhóm khách hàng (Customer Segmentation): Kết hợp tất cả các biến định tính và định lượng để phân loại khách hàng thành các nhóm có hành vi và đặc điểm tương đồng. Từ đó, doanh nghiệp có thể thiết kế các chiến lược marketing, sản phẩm và dịch vụ cá nhân hóa cho từng phân khúc.

Việc tiếp tục nghiên cứu theo những hướng này, đặc biệt là việc tích hợp phân tích các biến định lượng và sử dụng các kỹ thuật phân tích tiên tiến hơn, sẽ giúp doanh nghiệp có được cái nhìn toàn diện và sâu sắc hơn về khách hàng, từ đó đưa ra các quyết định chiến lược hiệu quả và dựa trên dữ liệu.