Phân tích dữ liệu và các biến định tính (nhiệm vụ 2)


1 Phần 1: Tìm hiểu và Chuẩn bị Dữ liệu

1.1 Đọc dữ liệu

# Tải các gói thư viện cần thiết
library(readxl)   # Gói này dùng để đọc file Excel (.xls, .xlsx) vào R
## Warning: package 'readxl' was built under R version 4.4.3
library(DT)       # Gói này cung cấp chức năng hiển thị bảng dữ liệu dạng tương tác (DataTable) trong R Markdown hoặc Shiny
## Warning: package 'DT' was built under R version 4.4.3
# Gán file dữ liệu
Supermarket_Transactions <- read_excel("D:/tai/Supermarket Transactions.xlsx")
## New names:
## • `` -> `...1`
# Hiển thị bảng dữ liệu
datatable(Supermarket_Transactions)
## 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 Sơ lược chi tiết

1.2.1 Cấu trúc dữ liệu

str(Supermarket_Transactions)
## tibble [14,059 × 16] (S3: tbl_df/tbl/data.frame)
##  $ ...1             : num [1:14059] 1 2 3 4 5 6 7 8 9 10 ...
##  $ PurchaseDate     : POSIXct[1:14059], format: "2007-12-18" "2007-12-20" ...
##  $ CustomerID       : num [1:14059] 7223 7841 8374 9619 1900 ...
##  $ Gender           : chr [1:14059] "F" "M" "F" "M" ...
##  $ MaritalStatus    : chr [1:14059] "S" "M" "M" "M" ...
##  $ Homeowner        : chr [1:14059] "Y" "Y" "N" "Y" ...
##  $ Children         : num [1:14059] 2 5 2 3 3 3 2 2 3 1 ...
##  $ AnnualIncome     : chr [1:14059] "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
##  $ City             : chr [1:14059] "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
##  $ StateorProvince  : chr [1:14059] "CA" "CA" "WA" "OR" ...
##  $ Country          : chr [1:14059] "USA" "USA" "USA" "USA" ...
##  $ ProductFamily    : chr [1:14059] "Food" "Food" "Food" "Food" ...
##  $ ProductDepartment: chr [1:14059] "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
##  $ ProductCategory  : chr [1:14059] "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
##  $ UnitsSold        : num [1:14059] 5 5 3 4 4 3 4 6 1 2 ...
##  $ Revenue          : num [1:14059] 27.38 14.9 5.52 4.44 14 ...

Bộ dữ liệu được sử dụng trong phân tích này bao gồm 14.059 quan sát và 16 biến. Các biến trong bộ dữ liệu phản ánh thông tin nhân khẩu học, hành vi mua hàng và các đặc điểm liên quan đến khách hàng trong siêu thị. Cụ thể, các biến bao gồm:

  • …1: Số thứ tự

  • PurchaseDate: Ngày thực hiện giao dịch mua hàng.

  • CustomerID: Mã định danh duy nhất của 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: Khách hàng có sở hữu nhà hay không (Y: có, N: không).

  • Children: Số lượng con cái của khách hàng.

  • AnnualIncome: Thu nhập hàng năm của khách hàng, được phân loại theo khoảng giá trị.

  • City: Thành phố cư trú của khách hàng.

  • StateorProvince: Bang hoặc tỉnh thành nơi khách hàng cư trú.

  • Country: Quốc gia của khách hàng.

  • ProductFamily: Nhóm sản phẩm chính, phân loại theo đặc tính chung.

  • ProductDepartment: Nhóm sản phẩm nằm trong sản phẩm chính, giúp phân loại sản phẩm cụ thể hơn.

  • ProductCategory: Danh mục cụ thể của sản phẩm, mô tả chi tiết hơn về loại mặt hàng.

  • UnitsSold: Số lượng đơn vị sản phẩm được bán trong giao dịch.

  • Revenue: Doanh thu thu được từ giao dịch.

Việc kiểm tra cấu trúc và xem trước dữ liệu cho thấy bộ dữ liệu đã được nhập thành công, các biến có tên rõ ràng và phù hợp, tạo nền tảng thuận lợi cho các bước phân tích kế tiếp.

head(Supermarket_Transactions)# Hiển thị các dòng đầu của dữ liệu
## # A tibble: 6 × 16
##    ...1 PurchaseDate        CustomerID Gender MaritalStatus Homeowner Children
##   <dbl> <dttm>                   <dbl> <chr>  <chr>         <chr>        <dbl>
## 1     1 2007-12-18 00:00:00       7223 F      S             Y                2
## 2     2 2007-12-20 00:00:00       7841 M      M             Y                5
## 3     3 2007-12-21 00:00:00       8374 F      M             N                2
## 4     4 2007-12-21 00:00:00       9619 M      M             Y                3
## 5     5 2007-12-22 00:00:00       1900 F      S             Y                3
## 6     6 2007-12-22 00:00:00       6696 F      M             Y                3
## # ℹ 9 more variables: AnnualIncome <chr>, City <chr>, StateorProvince <chr>,
## #   Country <chr>, ProductFamily <chr>, ProductDepartment <chr>,
## #   ProductCategory <chr>, UnitsSold <dbl>, Revenue <dbl>
tail(Supermarket_Transactions)# Hiển thị các dòng cuối của dữ liệu
## # A tibble: 6 × 16
##    ...1 PurchaseDate        CustomerID Gender MaritalStatus Homeowner Children
##   <dbl> <dttm>                   <dbl> <chr>  <chr>         <chr>        <dbl>
## 1 14054 2009-12-29 00:00:00       2032 F      M             N                3
## 2 14055 2009-12-29 00:00:00       9102 F      M             Y                2
## 3 14056 2009-12-29 00:00:00       4822 F      M             Y                3
## 4 14057 2009-12-31 00:00:00        250 M      S             Y                1
## 5 14058 2009-12-31 00:00:00       6153 F      S             N                4
## 6 14059 2009-12-31 00:00:00       3656 M      S             N                3
## # ℹ 9 more variables: AnnualIncome <chr>, City <chr>, StateorProvince <chr>,
## #   Country <chr>, ProductFamily <chr>, ProductDepartment <chr>,
## #   ProductCategory <chr>, UnitsSold <dbl>, Revenue <dbl>

Hai câu lệnh được dùng để hiển thị 6 dòng đầu và 6 dòng cuối của dữ liệu, nhằm hỗ trợ việc kiểm tra sơ bộ nội dung và định dạng các biến.

1.2.2 Lọc các dữ liệu định tính

  • Qua quá trình quan sát và kiểm tra, trong tổng số 16 biến có đến 10 biến là biến định tính, phù hợp để phân loại và phân tích trong các bước tiếp theo.
dt <- c("Gender", "Homeowner", "MaritalStatus","AnnualIncome", "City", "StateorProvince", "Country", "ProductFamily", "ProductDepartment","ProductCategory")

1.2.3 Tạo dữ liệu mới với các biến định tính

df_dt <- Supermarket_Transactions[,dt]

1.2.4 Kiểm tra giá trị bị thiếu

  • Bước quan trọng cần xử lý vì nếu bỏ qua có thể làm sai lệch kết quả phân tích. Cách khắc phục thường dùng bao gồm loại bỏ quan sát, thay thế bằng giá trị trung bình, mode hoặc sử dụng kỹ thuật dự đoán để điền dữ liệu.
colSums(is.na(df_dt))
##            Gender         Homeowner     MaritalStatus      AnnualIncome 
##                 0                 0                 0                 0 
##              City   StateorProvince           Country     ProductFamily 
##                 0                 0                 0                 0 
## ProductDepartment   ProductCategory 
##                 0                 0

Dữ liệu cho thấy trong 10 biến được khảo sát, không có biến nào chứa giá trị thiếu (NA).

1.2.5 Chuyển đổi đổi dữ liệu (kiểu factor)

  • Bước thực hiện để giúp R nhận diện đúng các biến phân loại, phục vụ cho việc phân tích, mô hình hóa và trực quan hóa dữ liệu chính xác hơn.
df <- lapply(df, function(x) {  if(is.character(x)) factor(x) else x})# lapply() áp dụng hàm cho từng cột trong df_dt.

Dòng lệnh sau thực hiện việc chuyển đổi tất cả các cột có kiểu dữ liệu character trong df_dt thành kiểu factor, giữ nguyên các cột khác không đổi.

2 Phần 2: Phân tích Mô tả Một biến Định tính (Univariate Descriptive Analysis)

2.1 Gender (Giới tính)

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(knitr)
## Warning: package 'knitr' was built under R version 4.4.3
library(scales)
## Warning: package 'scales' was built under R version 4.4.3
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.4.3
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
# Tạo bảng tóm tắt
df_1 <- df_dt %>%
  count(Gender, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`), label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Hiển thị bảng
df_1 %>%
  select(Gender, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Giới tính", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.1 Phân phối theo giới tính - GENDER"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.1 Phân phối theo giới tính - GENDER
Giới tính Tần số Tỷ lệ (%)
F 7170 50.9994
M 6889 49.0006

Vậy trong bộ dữ liệu có 50.9993598% nữ và 49.0006402% nam

2.1.1 Biểu diễn dưới dạng biểu đồ

library(dplyr)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(RColorBrewer)
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.4.3
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
# Biểu đồ tròn (Pie chart)
p1 <- ggplot(df_1, aes(x = "", y = percent, fill = Gender)) +
  geom_col(width = 1, color = "black") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
  labs(title = "Tỷ lệ (%) mua hàng theo giới tính") +
  scale_fill_brewer(palette = "Set3") +
  theme_void()
# Biểu đồ cột Tần số
p2 <- ggplot(df_1, aes(x = Gender, y = `Tần số`, fill = Gender)) +
  geom_col(width = 0.6, color = "black") +
  geom_text(aes(label = `Tần số`), vjust = -0.5) +
  labs(title = "Tần số mua hàng (Gender)", x = "Giới tính", y = "Số lượng") +
  scale_fill_brewer(palette = "Set3") +
  theme_minimal()
# Hiển thị cả hai biểu đồ cạnh nhau
grid.arrange(p1, p2, ncol = 2)

Kết quá cho thấy tỷ lệ nữ chiếm ưu thế hơn nam, với mức chênh lệch giới tính khoảng 1.9987197% (281 đơn hàng).

2.2 Homeowner (Sở hữu nhà)

# Tạo bảng tóm tắt
df_2 <- df_dt %>%
  count(Homeowner, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`), label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Hiển thị bảng
df_2 %>%
  select(Homeowner, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Sở hữu nhà", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.2 Phân phối theo chủ sở hữu nhà"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.2 Phân phối theo chủ sở hữu nhà
Sở hữu nhà Tần số Tỷ lệ (%)
N 5615 39.9388
Y 8444 60.0612

Vậy trong bộ dữ liệu có 39.9388292% người không sở hữu nhà và 60.0611708% người sở hữu nhà.

2.2.1 Biểu diễn dưới dạng biểu đồ

# Biểu đồ tròn (Pie chart)
p3 <- ggplot(df_2, aes(x = "", y = percent, fill = Homeowner)) +
  geom_col(width = 1, color = "black") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
  labs(title = "Tỷ lệ (%) khách hàng sở hữu nhà") +
  scale_fill_brewer(palette = "Set2") +
  theme_void()
# Biểu đồ cột Tần số
p4 <- ggplot(df_2, aes(x = Homeowner, y = `Tần số`, fill = Homeowner)) +
  geom_col(width = 0.6, color = "black") +
  geom_text(aes(label = `Tần số`), vjust = -0.5) +
  labs(title = "Tần số mua hàng (Homeowner)", x = "Sở hữu nhà", y = "Số lượng") +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal()
# Hiển thị cả hai biểu đồ cạnh nhau
grid.arrange(p3, p4, ncol = 2)

Kết quả cho thấy phần lớn người mua hàng là chủ sở hữu nhà, với sự chênh lệch khoảng 20.1223416% khá cao so với nhóm không sở hữu nhà, chênh lệch khoảng 2.828 đơn hàng trong khoảng thời gian thống kê.

2.3 MaritalStatus (Tình trạng hôn nhân)

# Tạo bảng tóm tắt
df_3 <- df_dt %>%
  count(MaritalStatus, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`), label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Hiển thị bảng
df_3 %>%
  select(MaritalStatus, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Tình trạng hôn nhân", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.3 Phân phối theo tình trạng hôn nhân"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.3 Phân phối theo tình trạng hôn nhân
Tình trạng hôn nhân Tần số Tỷ lệ (%)
M 6866 48.837
S 7193 51.163

Vậy trong bộ dữ liệu có tỷ lệ 48.8370439% đã kết hôn và 51.1629561% chưa kết hôn/ độc thân.

2.3.1 Biểu diễn dưới dạng biểu đồ

# Biểu đồ tròn (Pie chart)
p5 <- ggplot(df_3, aes(x = "", y = percent, fill = MaritalStatus)) +
  geom_col(width = 1, color = "black") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
  labs(title = "Tỷ lệ (%) khách hàng đã/chưa kết hôn") +
  scale_fill_brewer(palette = "Set1") +
  theme_void()
# Biểu đồ cột Tần số
p6 <- ggplot(df_3, aes(x = MaritalStatus, y = `Tần số`, fill = MaritalStatus)) +
  geom_col(width = 0.6, color = "black") +
  geom_text(aes(label = `Tần số`), vjust = -0.5) +
  labs(title = "Tần số mua hàng (MaritalStatus)", x = "Sở hữu nhà", y = "Số lượng") +
  scale_fill_brewer(palette = "Set1") +
  theme_minimal()
# Hiển thị cả hai biểu đồ cạnh nhau
grid.arrange(p5, p6, ncol = 2)

Kết quả cho thấy người độc thân có tỷ lệ/Tần số mua hàng cao hơn, với sự chênh lệch khoảng 2.3259122% với số khách hàng đã lập gia đình, chênh lệch khoảng 327 đơn hàng trong khoảng thời gian thống kê.

2.4 AnnualIncome (Thu nhập hằng năm)

# Tạo bảng tóm tắt
df_4 <- df_dt %>%
  count(AnnualIncome, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_4 %>%
  select(AnnualIncome, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Tình trạng hôn nhân", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.4 Phân phối theo thu nhập hằng năm"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.4 Phân phối theo thu nhập hằng năm
Tình trạng hôn nhân 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

Dữ liệu khảo sát ghi nhận 8 khoảng thu nhập khác nhau, bao gồm:

  • Thu nhập 10k-30K USD/năm chiếm 21.9788036%
  • Thu nhập 110k-130k USD/năm chiếm 4.5735828%
  • Thu nhập 130k-150k USD/năm chiếm 5.4057899%
  • Thu nhập 150k+ USD/năm chiếm 1.9418166%
  • Thu nhập 30k-50k USD/năm chiếm 32.7263675%
  • Thu nhập 50k-70k USD/năm chiếm 16.857529%
  • Thu nhập 70k-90k USD/năm chiếm 12.1559144%
  • Thu nhập 90k-110k USD/năm chiếm 4.3601963%

2.4.1 Biểu diễn dưới dạng biểu đồ

ggplot(df_4, aes(x = reorder(AnnualIncome, -`Tần số`), y = `Tần số`, fill = AnnualIncome)) +
  geom_col(width = 0.5, color = "black") +
  geom_text(
    aes(label = paste0(`Tần số`, " (", scales::percent(percent, accuracy = 0.1), ")")),
    vjust = -0.5, size = 3, color = "black"
  ) +
  labs(
    title = "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, size = 9),
    legend.position = "none"  )

Kết quả phân tích cho thấy phần lớn khách hàng tập trung trong nhóm thu nhập từ $10K đến $90K, nổi bật nhất là nhóm có thu nhập $30K–$50K, chiếm tỷ trọng cao nhất. Tuy nhiên, khi thu nhập tăng lên, đặc biệt từ mức $90K trở đi, số lượng khách hàng có xu hướng giảm đáng kể. Đáng chú ý, nhóm khách hàng có thu nhập từ $150K trở lên là nhóm có tỷ lệ mua hàng thấp nhất trong toàn bộ mẫu khảo sát.

Sự chênh lệch giữa hai nhóm thu nhập này là rất lớn, cụ thể: tỷ lệ khách hàng thuộc nhóm $150K+ thấp hơn nhóm $90K–$120K là 30.7845508%, tương ứng với 4,328 đơn hàng trong giai đoạn thống kê.

2.5 Country (Quốc gia)

# Tạo bảng tóm tắt
df_5 <- df_dt %>%
  count(Country, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_5 %>%
  select(Country, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Quốc gia", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.5 Phân phối theo quốc gia"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.5 Phân phối theo quốc gia
Quốc gia Tần số Tỷ lệ (%)
Canada 809 5.7543
Mexico 3688 26.2323
USA 9562 68.0134

Dữ liệu khảo sát được thu thập từ 3 quốc gia khác nhau, bao gồm:

  • Quốc gia Canada chiếm 5.7543211%
  • Quốc gia Mexico chiếm 26.2323067%
  • Quốc gia Hoa Kỳ (USA) chiếm 68.0133722%

2.5.1 Biểu diễn dưới dạng biểu đồ

# Biểu đồ tròn (Pie chart)
p7 <- ggplot(df_5, aes(x = "", y = percent, fill = Country)) +
  geom_col(width = 1, color = "black") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
  labs(title = "Tỷ lệ (%) khách hàng đến từ các quốc gia") +
  scale_fill_brewer(palette = "Dark2") +
  theme_void()
# Biểu đồ cột Tần số
p8 <- ggplot(df_5, aes(x = Country, y = `Tần số`, fill = Country)) +
  geom_col(width = 0.6, color = "black") +
  geom_text(aes(label = `Tần số`), vjust = -0.5) +
  labs(title = "Tần số mua hàng (Country)", x = "Sở hữu nhà", y = "Số lượng") +
  scale_fill_brewer(palette = "Dark2") +
  theme_minimal()
# Hiển thị cả hai biểu đồ cạnh nhau
grid.arrange(p7, p8, ncol = 2)

Kết quả phân tích cho thấy thị phần khách hàng đến từ Hoa Kỳ (USA) chiếm tỷ trọng lớn nhất, vượt hơn một nửa tổng số đơn hàng được thống kê. Ngược lại, Canada là quốc gia có số lượng đơn hàng thấp nhất trong ba quốc gia được khảo sát.

Mức chênh lệch về số lượng đơn hàng giữa Hoa Kỳ và Canada là rất lớn, lên tới 62.2590511% tương đương khoảng 8.753 đơn hàng trong thời gian thống kê.

2.6 StateorProvince (Bang hoặc tỉnh)

# Tạo bảng tóm tắt
df_6 <- df_dt %>%
  count(StateorProvince, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_6 %>%
  select(StateorProvince, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Bang/Tỉnh", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.6 Phân phối theo bang/tỉnh"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.6 Phân phối theo bang/tỉnh
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

Dữ liệu khảo sát ghi nhận tại 9 Bang/ tỉnh khác nhau từ 3 quốc gia, bao gồm:

  • Bang/ Tỉnh BC chiếm 5.7543211%
  • Bang/ Tỉnh CA chiếm 19.4395049%
  • Bang/ Tỉnh DF chiếm 5.7969984%
  • Bang/ Tỉnh Guerrero chiếm 2.7242336%
  • Bang/ Tỉnh Jalisco chiếm 0.5334661%
  • Bang/ Tỉnh OR chiếm 16.0893378%
  • Bang/ Tỉnh Veracruz chiếm 3.300377%
  • Bang/ Tỉnh WA chiếm 32.4845295%
  • Bang/ Tỉnh Zacatecas chiếm 4.6518245%

2.6.1 Biểu diễn dưới dạng biểu đồ

ggplot(df_6, aes(x = reorder(StateorProvince, -`Tần số`), y = `Tần số`, fill = StateorProvince)) +
  geom_col(width = 0.5, color = "black") +
  geom_text(
    aes(label = paste0(`Tần số`, " (", scales::percent(percent, accuracy = 0.1), ")")),
    vjust = -0.5, size = 3, color = "black"
  ) +
  labs(
    title = "Phân bố khách hàng theo Bang/Tỉnh",
    x = "Bang/Tỉnh",
    y = "Số lượng"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 9),
    legend.position = "none"  )

Kết quả phân tích theo từng bang/tỉnh cho thấy sự chênh lệch đáng kể về lượng đơn hàng giữa các khu vực. Cụ thể, bang WA ghi nhận số lượng đơn hàng cao nhất, trong khi Jalisco là địa phương có lượng đơn hàng thấp nhất. Mức chênh lệch giữa hai khu vực này là khoảng 31.9510634% tương đương khoảng 4.567 đơn hàng trong thời gian thống kê.

2.7 City (Thành phố)

# Tạo bảng tóm tắt
df_7 <- df_dt %>%
  count(City, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_7 %>%
  select(City, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Thành phố", "Tần số", "Tỷ lệ (%)"),
    caption = "Bảng 2.7 Phân phối theo thành phố",
    align = "c"  ) %>% kable_styling(
    bootstrap_options = c("striped", "hover"),   full_width = FALSE, position = "center"  )
Bảng 2.7 Phân phối theo thành phố
Thành phố 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 khảo sát ghi nhận tại 23 thành phố khác nhau từ 3 quốc gia, sơ lược:

  • Thành phố Acapulco chiếm 2.7242336%
  • Thành phố Bellingham chiếm 1.017142%
  • Thành phố Beverly Hills chiếm 5.7685468%
  • Thành phố Bremerton chiếm 5.9321431%
  • ….
  • Thành phố Vancouver chiếm 4.5024539%
  • Thành phố Victoria chiếm 1.2518671%
  • Thành phố Walla Walla chiếm 1.138061%
  • Thành phố Yakima chiếm 2.6744434%

2.7.1 Biểu diễn dưới dạng biểu đồ

ggplot(df_7, aes(x = reorder(City, -`Tần số`), y = `Tần số`, fill = City)) +
  geom_col(width = 0.5, color = "black") +
  geom_text(
    aes(label = scales::percent(percent, accuracy = 0.1)),
    vjust = -0.5, size = 3, color = "black"
  ) +
  labs(
    title = "Phân bố khách hàng theo thành phố",
    x = "Thành phố",
    y = "Số lượng"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 9),
    legend.position = "none"  )

Kết quả phân tích theo từng thành phố cho thấy sự chênh lệch đáng kể về lượng đơn hàng giữa các khu vực. Cụ thể, thành phố Salem ghi nhận số lượng đơn hàng cao nhất, trong khi Guadalajara là địa phương có lượng đơn hàng thấp nhất. Mức chênh lệch giữa hai khu vực này là khoảng 9.3249876% tương đương khoảng 1.311 đơn hàng trong thời gian thống kê.

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

# Tạo bảng tóm tắt
df_8 <- df_dt %>%
  count(ProductFamily, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_8 %>%
  select(ProductFamily, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Thành phố", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.8 Phân phối theo nhóm sản phẩm chính"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.8 Phân phối theo nhóm sản phẩm chính
Thành phố Tần số Tỷ lệ (%)
Drink 1250 8.8911
Food 10153 72.2171
Non-Consumable 2656 18.8918

Dữ liệu khảo sát được xếp vào từ 3 nhóm sản phẩm chính, bao gồm:

  • Drink chiếm 8.8911018%
  • Food chiếm 72.2170851%
  • Non-Consumable chiếm 18.8918131%

2.8.1 Biểu diễn dưới dạng biểu đồ

# Biểu đồ tròn (Pie chart)
p9 <- ggplot(df_8, aes(x = "", y = percent, fill = ProductFamily)) +
  geom_col(width = 1, color = "black") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
  labs(title = "Tỷ lệ (%) lựa chọn nhóm sản phẩm chính") +
  scale_fill_brewer(palette = "Accent") +
  theme_void()
# Biểu đồ cột Tần số
p10 <- ggplot(df_8, aes(x = ProductFamily, y = `Tần số`, fill = ProductFamily)) +
  geom_col(width = 0.6, color = "black") +
  geom_text(aes(label = `Tần số`), vjust = 0) +
  labs(title = "Tần số mua hàng (ProductFamily)", x = "Nhóm sản phẩm chính", y = "Số lượng") +
  scale_fill_brewer(palette = "Accent") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Hiển thị cả hai biểu đồ cạnh nhau
grid.arrange(p9, p10, ncol = 2)

Kết quả phân tích cho thấy thị phần khách hàng sẽ mua nhóm sản phẩm chính là Food chiếm tỷ trọng lớn nhất, vượt hơn một nửa tổng số đơn hàng được thống kê. Ngược lại, nhóm sản phẩm Non-Consumable có số lượng đơn hàng thấp nhất trong ba quốc gia được khảo sát.

Mức chênh lệch về số lượng đơn hàng giữa hai nhóm sản phẩm này là rất lớn, lên tới 53.3252721% tương đương khoảng 8.903 đơn hàng trong thời gian thống kê.

2.9 ProductDepartment (Bộ phận sản phẩm/nhóm phụ)

# Tạo bảng tóm tắt
df_9 <- df_dt %>%
  count(ProductDepartment, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_9 %>%
  select(ProductDepartment, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Bộ phận sản phẩm", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.9 Phân phối theo bộ phận sản phẩm"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center")
Bảng 2.9 Phân phối theo bộ phận sản phẩm
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

Dữ liệu khảo sát được xếp vào 22 nhóm (bộ phận sản phẩm) khác nhau từ 3 nhóm sản phẩm chính, sơ lược:

  • Nhóm sản phẩm Alcoholic Beverages chiếm 2.5321858%
  • Nhóm sản phẩm Baked Goods chiếm 3.0229746%
  • Nhóm sản phẩm Baking Goods chiếm 7.6250089%
  • Nhóm sản phẩm Beverages chiếm 4.8367594%
  • ….
  • Nhóm sản phẩm Seafood chiếm 0.7255139%
  • Nhóm sản phẩm Snack Foods chiếm 11.3806103%
  • Nhóm sản phẩm Snacks chiếm 2.5037343%
  • Nhóm sản phẩm Starchy Foods chiếm 1.9702682%

2.9.1 Biểu diễn dưới dạng biểu đồ

ggplot(df_9, aes(x = reorder(ProductDepartment, -`Tần số`), y = `Tần số`, fill = ProductDepartment)) +
  geom_col(width = 0.5, color = "black") +
  geom_text(
    aes(label = scales::percent(percent, accuracy = 0.1)),
    vjust = -0.5, size = 3, color = "black"
  ) +
  labs(
    title = "Nhu cầu khách hàng theo từng 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 = 45, hjust = 1, size = 9),
    legend.position = "none"  )

Kết quả phân tích theo các nhóm sản phẩm phụ (hoặc bộ phận sản phẩm) cho thấy sự chênh lệch đáng kể về số lượng đơn hàng giữa các nhóm. Nhóm sản phẩm Produce ghi nhận số lượng đơn hàng cao nhất, trong khi nhóm Carousel là nhóm có lượng đơn hàng thấp nhất. Mức chênh lệch giữa hai nhóm này ước tính khoảng 13.7634256% tương đương khoảng 1.935 đơn hàng trong thời gian thống kê.

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

# Tạo bảng tóm tắt
df_10 <- df_dt %>%
  count(ProductCategory, name = "Tần số") %>%
  mutate(
    percent = `Tần số` / sum(`Tần số`),
    label = percent(percent, accuracy = 0.1),
    `Tỷ lệ (%)` = round(percent * 100, 4)  )
# Chỉ chọn các cột cần hiển thị
df_10 %>%
  select(ProductCategory, `Tần số`, `Tỷ lệ (%)`) %>%
  kable(
    format = "html",
    col.names = c("Danh mục sản phẩm cụ thể", "Tần số", "Tỷ lệ (%)"),
    align = "c",
    caption = "Bảng 2.10 Phân phối theo danh mục sản phẩm cụ thể"
  ) %>%
  kable_styling(c("striped", "hover"), full_width = FALSE, position = "center") 
Bảng 2.10 Phân phối theo danh mục sản phẩm cụ thể
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

Dữ liệu khảo sát được xếp vào 45 nhóm (danh mục sản phẩm cụ thể) khác nhau từ 3 nhóm sản phẩm chính, sơ lược:

  • Sản phẩm Baking Goods chiếm 3.4426346%
  • Sản phẩm Bathroom Products chiếm 2.5962017%
  • Sản phẩm Beer and Wine chiếm 2.5321858%
  • Sản phẩm Bread chiếm 3.0229746%
  • ….
  • Sản phẩm Snack Foods chiếm 11.3806103%
  • Sản phẩm Specialty chiếm 2.0556227%
  • Sản phẩm Starchy Foods chiếm 1.9702682%
  • Sản phẩm Vegetables chiếm 12.2910591%

2.10.1 Biểu diễn dưới dạng biểu đồ

ggplot(df_10, aes(x = reorder(ProductCategory, -`Tần số`), y = `Tần số`, fill = ProductCategory)) +
  geom_col(width = 0.5, color = "black") +
   geom_text(
    aes(label = scales::percent(percent, accuracy = 0.1)),
    vjust = 0, size = 2.5, color = "black", angle = 90, hjust = 0
  ) +
  labs(
    title = "Nhu cầu khách hàng theo từng danh mục sản phẩm cụ thể",
    x = "Danh mục sản phẩm cụ thể",
    y = "Số lượng"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 9),
    legend.position = "none"  )

Kết quả phân tích theo từng danh mục sản phẩm cụ thể cho thấy sự chênh lệch đáng kể về số lượng đơn hàng giữa các nhóm. Sản phẩm Vegetables ghi nhận số lượng đơn hàng cao nhất, trong khi Canned Oysters là sản phẩm có lượng đơn hàng thấp nhất. Mức chênh lệch giữa hai nhóm này ước tính khoảng 12.0421083% tương đương khoảng 1.693 đơn hàng trong thời gian thống kê.

3 Phần 3: Ước lượng Khoảng và Kiểm định Giả thuyết cho Tỷ lệ (Một biến)

3.1 Ước lượng và kiểm định tỷ lệ trong mô hình Bernoulli

Giả sử biến ngẫu nhiên chuẩn tắc chuẩn \(Z \sim N(0,1)\). Với một mức xác suất \(p \in (0,1)\), giá trị tới hạn \(z_p\) được định nghĩa sao cho:

\[ P(Z > z_p) = p \quad \text{hay tương đương} \quad \Phi(z_p) = 1 - p \]

trong đó \(\Phi(z_p)\) là hàm phân phối tích lũy (CDF) của phân phối chuẩn.

Khi thực hiện \(n\) phép thử độc lập theo phân phối Bernoulli với xác suất thành công chưa biết là \(p\). Gọi \(x\) là số lần thành công trong \(n\) phép thử này. Khi đó, tỷ lệ mẫu (sample proportion) được ước lượng bởi:

\[ \hat{p} = \frac{x}{n} \]

Tỷ lệ mẫu \(\hat{p}\) là một ước lượng không chệch của \(p\) và được dùng làm cơ sở cho việc xây dựng khoảng tin cậy và thực hiện kiểm định giả thuyết cho tỷ lệ thành công thực sự trong tổng thể.

3.2 Khoảng tin cậy cho tỷ lệ

Với mức ý nghĩa \(\alpha\) ( thông thường 95%, 99%, 90%), khoảng tin cậy \(100(1 - \alpha)\%\) cho tỷ lệ \(p\) được tính bằng công thức:

\[ \left[ \hat{p} - z_{\alpha/2} \cdot \sqrt{ \frac{\hat{p}(1 - \hat{p})}{n} }, \quad \hat{p} + z_{\alpha/2} \cdot \sqrt{ \frac{\hat{p}(1 - \hat{p})}{n} } \right] \]

Trong đó:

  • \(z_{\alpha/2}\): giá trị tới hạn từ phân phối chuẩn chuẩn.
  • \(\sqrt{ \frac{\hat{p}(1 - \hat{p})}{n} }\): sai số chuẩn (standard error).
  • \(E = z_{\alpha/2} \cdot \text{SE}\): biên sai số (margin of error).

3.2.1 Các dạng kiểm định giả thuyết cho tỷ lệ

Trong thống kê, kiểm định giả thuyết cho tỷ lệ thường dùng để xác định xem tỷ lệ mẫu \(\hat{p}\) có khác biệt một cách có ý nghĩa thống kê so với một tỷ lệ giả định \(p_0\) trong tổng thể.

  • Kiểm định hai phía (Two-sided test):
    • Giả thuyết không \(H_0: p = p_0\)
    • Giả thuyết đối \(H_a: p \neq p_0\)
    • Ý nghĩa: Kiểm tra xem tỷ lệ thực tế có khác đáng kể so với giả định hay không.
  • Kiểm định một phía (phía trên) (One-sided test, upper tail):
    • Giả thuyết không \(H_0: p = p_0\)
    • Giả thuyết đối \(H_a: p > p_0\)
    • Ý nghĩa: Kiểm tra xem tỷ lệ có cao hơn một cách đáng kể so với kỳ vọng.
  • Kiểm định một phía (phía dưới) (One-sided test, lower tail):
    • Giả thuyết không \(H_0: p = p_0\)
    • Giả thuyết đối \(H_a: p < p_0\)
    • Ý nghĩa: Kiểm tra xem tỷ lệ có thấp hơn đáng kể so với giả định ban đầu.

3.3 Xây dựng khoảng tin cậy (95%)

# Hàm tính khoảng tin cậy cho tỷ lệ mẫu 
conf_int_prop <- function(x, n, conf.level = 0.95) {
  p_hat <- x / n                             # tỷ lệ lấy mẫu
  alpha <- 1 - conf.level
  z_crit <- qnorm(1 - alpha/2)              # giá trị tới hạn z_alpha/2
  SE <- sqrt(p_hat * (1 - p_hat) / n)      # sai số chuẩn (standard error)
  ME <- z_crit * SE                        # biên sai số (margin of error)
  lower <- p_hat - ME
  upper <- p_hat + ME
  data <- c(p_hat, z_crit, ME, lower, upper)
  names(data) <- c("Tỷ lệ mẫu", "Z tới hạn", "Sai số biên", "CI lower", "CI upper")
  return(data)}

3.3.1 Xét giới tính nữ trong biến Genger

Gender <- sum(df_dt$Gender == "F")
conf_int_prop(Gender, nrow(df_dt), 0.95)
##   Tỷ lệ mẫu   Z tới hạn Sai số biên    CI lower    CI upper 
## 0.509993598 1.959963985 0.008263311 0.501730287 0.518256910

Dựa trên kết quả phân tích, tỷ lệ mẫu của giới tính nữ trong tập dữ liệu đạt khoảng 51%. Với mức độ tin cậy 95%, ta có thể kết luận rằng tỷ lệ nữ trong toàn bộ quần thể mà mẫu đại diện nằm trong khoảng từ 50.17% đến 51.83%.

Khoảng tin cậy này khá hẹp, phản ánh rằng cỡ mẫu được sử dụng là đủ lớn và tỷ lệ ước lượng có độ chính xác cao, với sai số biên chỉ khoảng 0.8%. Điều này cho thấy kết quả có mức độ tin cậy cao trong việc phản ánh tỷ lệ giới tính thực tế của tổng thể.

Hơn nữa, do khoảng tin cậy tập trung xung quanh mốc 50%, có thể nhận thấy rằng phân bố giới tính trong tổng thể là tương đối cân bằng, không có sự chênh lệch đáng kể giữa nam và nữ.

3.3.1.1 Kiểm định giả thuyết

Giả thuyết

  • \(H_0: p = 0.5\) (Tỷ lệ giới tính nữ trong tổng thể là đúng 50%)
  • \(H_1: p \neq 0.5\) (Tỷ lệ giới tính nữ khác 50%)
prop.test(x=Gender, n=nrow(df_dt), p=0.5, correct=FALSE)
## 
##  1-sample proportions test without continuity correction
## 
## data:  Gender out of nrow(df_dt), null probability 0.5
## X-squared = 5.6164, df = 1, p-value = 0.01779
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5017287 0.5182531
## sample estimates:
##         p 
## 0.5099936

Kết quả kiểm định tỷ lệ mẫu đơn không hiệu chỉnh liên tục

  • Giá trị thống kê: \(\chi^2\) = 5.6164, \(df\) = 1
  • \(p-value\) = 0.01779
  • Ước lượng mẫu: \(\hat{p}\) = 0.5100
  • Khoảng tin cậy 95%: (0.5017; 0.5183)

Kết luận:

  • Với \(p-value\) = 0,01779 < 0,05, có đủ cơ sở để bác bỏ giả thuyết \(H_0\). Điều này cho thấy tỷ lệ giới tính nữ không bằng đúng 50%, và tỷ lệ thực tế nằm trong khoảng từ 50,17% đến 51,83%.

3.3.2 Xét khoảng thu nhập $10k-$30k trong biến AnnualIncome

AnnualIncome <- sum(df_dt$AnnualIncome == "$10K - $30K")
conf_int_prop(AnnualIncome, nrow(df_dt), 0.95)
##   Tỷ lệ mẫu   Z tới hạn Sai số biên    CI lower    CI upper 
## 0.219788036 1.959963985 0.006845091 0.212942946 0.226633127

Dựa trên kết quả phân tích, tỷ lệ mẫu có thu nhập trong khoảng $10k–$30k (mức thu nhập thấp nhất trong khảo sát) chiếm khoảng 22%. Với mức độ tin cậy 95%, ta có thể kết luận rằng tỷ lệ thu nhập trong khoảng này của toàn bộ quần thể nằm trong khoảng từ 21.29% đến 22.66%.

Khoảng tin cậy này tương đối hẹp, cho thấy cỡ mẫu được sử dụng là đủ lớn và tỷ lệ ước lượng có độ chính xác cao, với sai số biên chỉ khoảng 0.6%. Điều này chứng tỏ kết quả có mức độ tin cậy cao trong việc phản ánh tỷ lệ thu nhập thực tế của tổng thể.

Hơn nữa, do khoảng tin cậy tập trung quanh mức 22%, có thể nhận thấy rằng phân bố thu nhập trong khoảng $10k–$30k có sự chênh lệch đáng kể so với các mức thu nhập khác trong khảo sát.

3.3.2.1 Kiểm định giả thuyết

Giả thuyết

  • \(H_0: p = 0.2\) (Tỷ lệ thu nhập trong khoảng $10k–$30k trong tổng thể là đúng 20%)
  • \(H_1: p \neq 0.2\) (Tỷ lệ thu nhập trong khoảng $10k–$30k khác 20%)
prop.test(x=AnnualIncome, n=nrow(df_dt), p=0.2, correct=FALSE)
## 
##  1-sample proportions test without continuity correction
## 
## data:  AnnualIncome out of nrow(df_dt), null probability 0.2
## X-squared = 34.406, df = 1, p-value = 4.472e-09
## alternative hypothesis: true p is not equal to 0.2
## 95 percent confidence interval:
##  0.2130200 0.2267092
## sample estimates:
##        p 
## 0.219788

Kết quả kiểm định tỷ lệ mẫu đơn không hiệu chỉnh liên tục

  • Giá trị thống kê: \(\chi^2\) = 34.406, \(df\) = 1
  • \(p-value\) = 4.472e-09
  • Ước lượng mẫu: \(\hat{p}\) = 0.2198
  • Khoảng tin cậy 95%: (0.2130; 0.2267)

Kết luận:

  • Với \(p-value\) = 4.472e-09 < 0,05, có đủ cơ sở để bác bỏ giả thuyết \(H_0\). Điều này cho thấy tỷ lệ thu nhập trong khoảng $10k–$30k không bằng đúng 20%, và tỷ lệ thực tế nằm trong khoảng từ 21,29% đến 22,66%.

3.3.3 Xét nhóm sản phẩm (Produce) trong biến ProductDepartment

ProductDepartment <- sum(df_dt$ProductDepartment == "Produce")
conf_int_prop(ProductDepartment, nrow(df_dt), 0.95)
##   Tỷ lệ mẫu   Z tới hạn Sai số biên    CI lower    CI upper 
## 0.141830856 1.959963985 0.005766904 0.136063952 0.147597759

Dựa trên kết quả phân tích, tỷ lệ mẫu thuộc nhóm sản phẩm Produce (nhóm chiếm tỷ trọng cao nhất) chiếm khoảng 14%. Với mức độ tin cậy 95%, ta có thể kết luận rằng tỷ lệ nhóm sản phẩm Produce trong toàn bộ quần thể nằm trong khoảng từ 13.61% đến 14.76%.

Khoảng tin cậy này tương đối hẹp, cho thấy cỡ mẫu được sử dụng là đủ lớn và tỷ lệ ước lượng có độ chính xác cao, với sai số biên chỉ khoảng 0.58%. Điều này khẳng định kết quả có mức độ tin cậy cao trong việc phản ánh tỷ lệ thực tế của tổng thể.

Hơn nữa, do khoảng tin cậy tập trung quanh mức 14%, có thể nhận thấy rằng phân bố nhóm sản phẩm Produce có sự khác biệt đáng kể so với các nhóm sản phẩm khác trong khảo sát.

3.3.3.1 Kiểm định giả thuyết

Giả thuyết

  • \(H_0: p = 0.14\) (Tỷ lệ nhóm sản phẩm Produce trong tổng thể là đúng 14%)
  • \(H_1: p \neq 0.14\) (Tỷ lệ nhóm sản phẩm Produce khác 14%)
prop.test(x=ProductDepartment, n=nrow(df_dt), p=0.14, correct=FALSE)
## 
##  1-sample proportions test without continuity correction
## 
## data:  ProductDepartment out of nrow(df_dt), null probability 0.14
## X-squared = 0.39141, df = 1, p-value = 0.5316
## alternative hypothesis: true p is not equal to 0.14
## 95 percent confidence interval:
##  0.1361617 0.1476956
## sample estimates:
##         p 
## 0.1418309

Kết quả kiểm định tỷ lệ mẫu đơn không hiệu chỉnh liên tục

  • Giá trị thống kê: \(\chi^2\) = 0.3914, \(df\) = 1
  • \(p-value\) = 0.5316
  • Ước lượng mẫu: \(\hat{p}\) = 0.1418
  • Khoảng tin cậy 95%: (0.1362; 0.1477)

Kết luận:

Với \(p-value\) = 0,516 > 0,05, không có đủ cơ sở để bác bỏ giả thuyết \(H_0\). Điều này cho thấy tỷ lệ thu nhập trong khoảng $10k–$30k trong tổng thể có thể coi là bằng đúng 14%. Mặc dù tỷ lệ mẫu quan sát được là 14,18%, sự chênh lệch này là không đáng kể về mặt thống kê. Nói cách khác, sự khác biệt giữa tỷ lệ quan sát và tỷ lệ giả định có thể chỉ là do yếu tố ngẫu nhiên trong quá trình chọn mẫu.

3.3.4 Xét thành phố Salem trong biến City

City <- sum(df_dt$City == "Salem")
conf_int_prop(City, nrow(df_dt), 0.95)
##   Tỷ lệ mẫu   Z tới hạn Sai số biên    CI lower    CI upper 
## 0.098584537 1.959963985 0.004927626 0.093656910 0.103512163

Dựa trên kết quả phân tích, tỷ lệ mẫu thuộc thành phố Salem chiếm khoảng 9,96%. Với mức độ tin cậy 95%, ta có thể kết luận rằng tỷ lệ dân số của thành phố này trong toàn bộ quần thể nằm trong khoảng từ 9.37% đến 10.35%.

Khoảng tin cậy này tương đối hẹp, cho thấy cỡ mẫu được sử dụng là đủ lớn và tỷ lệ ước lượng có độ chính xác cao, với sai số biên chỉ khoảng 0.49%. Điều này khẳng định kết quả có mức độ tin cậy cao trong việc phản ánh tỷ lệ thực tế của tổng thể.

Hơn nữa, do khoảng tin cậy tập trung quanh mức 9,96%, có thể nhận thấy rằng tỷ lệ của thành phố Salem cao hơn đáng kể so với các địa phương khác trong khảo sát, cho thấy sự phân bố dân cư không đồng đều giữa các khu vực.

3.3.4.1 Kiểm định giả thuyết

Giả thuyết

  • \(H_0: p = 0.1\) (Tỷ lệ thành phố Salem trong tổng thể là đúng 10%)
  • \(H_1: p \neq 0.1\) (Tỷ lệ thành phố Salem khác 10%)
prop.test(x=City, n=nrow(df_dt), p=0.1, correct=FALSE)
## 
##  1-sample proportions test without continuity correction
## 
## data:  City out of nrow(df_dt), null probability 0.1
## X-squared = 0.31297, df = 1, p-value = 0.5759
## alternative hypothesis: true p is not equal to 0.1
## 95 percent confidence interval:
##  0.09376602 0.10362236
## sample estimates:
##          p 
## 0.09858454

Kết quả kiểm định tỷ lệ mẫu đơn không hiệu chỉnh liên tục

  • Giá trị thống kê: \(\chi^2\) = 0.313, \(df\) = 1
  • \(p-value\) = 0.5759
  • Ước lượng mẫu: \(\hat{p}\) = 0.0986
  • Khoảng tin cậy 95%: (0.0938; 0.1036)

Kết luận:

Với \(p-value\) = 0,5759 > 0,05, không có đủ cơ sở để bác bỏ giả thuyết \(H_0\). Điều này cho thấy tỷ lệ mua hàng tại thành phố Salem trong tổng thể có thể coi là bằng đúng 10%. Mặc dù tỷ lệ mẫu quan sát được là 9,96%, sự chênh lệch này là không đáng kể về mặt thống kê. Nói cách khác, sự khác biệt giữa tỷ lệ quan sát và tỷ lệ giả định có thể chỉ là do yếu tố ngẫu nhiên trong quá trình chọn mẫu.

3.3.5 Phân hóa 2 trạng thái

Giả thuyết

  • \(p_C = p_M\) (tỷ lệ mua hàng 2 quốc gia Canada và Mexico bằng nhau)
  • \(p_C \neq p_M\) (tỷ lệ mua hàng 2 quốc gia Canada và Mexico khác nhau)
# Hàm tính khoảng tin cậy một phía cho tỷ lệ mẫu
x <- table(df_dt$Country)

prop.test(c(x[["Canada"]],x[["Mexico"]]),c(sum(x),sum(x)),correct = TRUE)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  c(x[["Canada"]], x[["Mexico"]]) out of c(sum(x), sum(x))
## X-squared = 2192.5, df = 1, p-value < 2.2e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.2130785 -0.1964812
## sample estimates:
##     prop 1     prop 2 
## 0.05754321 0.26232307

Kết quả kiểm định tỷ lệ mẫu đơn không hiệu chỉnh liên tục

  • Giá trị thống kê: \(\chi^2\) = 2192.5, \(df\) = 1
  • \(p-value\) < 2.2e-16
  • Ước lượng mẫu: \(\hat{p_1}\) = 0.05754321, \(\hat{p_2}\) = 0.26232307
  • Khoảng tin cậy 95%: (-0.2130785; -0.1964812)

Kết luận:

Với \(p-value\) < 2.2e-16 < 0,05, có đủ cơ sở để bác bỏ giả thuyết \(H_0\). Điều này cho thấy tỷ lệ mua hàng tại 2 quốc gia Canada và Mexico là khác nhau. Hay gọi là có sự chênh lệch đáng kể.

4 Phần 4: Phân tích Mối quan hệ giữa Hai biến Định tính (Bivariate Analysis)

4.1 Gender và ProductFamily

Cần thiết phải xem xét liệu giới tính có thực sự ảnh hưởng đến nhu cầu mua sắm các loại sản phẩm chính hay không, cũng như liệu có sự khác biệt đáng kể trong sự lựa chọn các nhóm sản phẩm giữa các giới tính hay không.

4.1.1 Bảng tần suất (%) chéo

library(tidyr)
## Warning: package 'tidyr' was built under R version 4.4.3
library(janitor)  # Hỗ trợ làm sạch dữ liệu và tạo bảng Tần số chéo nhiều biến.
## Warning: package 'janitor' was built under R version 4.4.3
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
# Tạo bảng Tần số chéo và tính tỷ lệ phần trăm theo hàng (giới tính)
df_dt %>%
  tabyl (Gender, ProductFamily,) %>%              # Tạo bảng chéo Tần số, đếm Tần số
  adorn_percentages("row") %>%                  # Tính tỷ lệ phần trăm theo hàng
  adorn_pct_formatting(digits = 2) %>%          # Định dạng phần trăm (ví dụ: 45.2%)
  kable(
    format = "html",
    caption = "Bảng 4.1: Bảng tần suất (%) chéo giữa giới tính và danh mục sản phẩm chính",
    align = "c"
  ) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover"))  # Làm đẹp bảng: kẻ sọc, hover
Bảng 4.1: Bảng tần suất (%) chéo giữa giới tính và danh mục sản phẩm chính
Gender Drink Food Non-Consumable
F 9.33% 71.81% 18.86%
M 8.43% 72.64% 18.93%

Lưu ý: Kết quả phản ánh sự tương đồng trong hành vi mua sắm giữa các giới tính đối với các nhóm sản phẩm chính, đặc biệt là nhóm sản phẩm không tiêu hao, cho thấy mức độ ưu tiên tương tự nhau mức chênh lệch dưới 1%.

So sánh tỷ lệ phân phối sản phẩm giữa hai giới cho thấy nam giới có xu hướng ưa chuộng các danh mục như Food và Non-Consumable hơn so với nữ giới, thể hiện qua tỷ trọng tổng thể cao hơn ở các nhóm sản phẩm này.

4.1.2 Trực quan hóa dữ liệu

4.1.2.1 Biểu đồ cột nhóm

# Tính Tần số và phần trăm theo ProductFamily và Gender
df_summary <- df_dt %>%
  group_by(ProductFamily, Gender) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(ProductFamily) %>%
  mutate(pct = n / sum(n) * 100)

# Vẽ biểu đồ với nhãn là số lượng và %
ggplot(df_summary, aes(x = ProductFamily, y = n, fill = Gender)) +
  geom_bar(stat = "identity", position = position_dodge(0.9)) +
  geom_text(aes(label = paste0(n, "\n(", sprintf("%.1f", pct), "%)")), # Hiển thị cả số lượng (n) và % (pct) trên cột
            position = position_dodge(0.9),
            vjust = 1, size = 3) +
  labs(title = "Phân phối sản phẩm chính theo giới tính",
       x = "Danh mục sản phẩm",
       y = "Số lượng",
       fill = "Giới tính") +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal() 

4.1.2.2 Biểu đồ cột chồng

ggplot(df_summary, aes(x = ProductFamily, y = n, fill = Gender)) +
  geom_bar(stat = "identity") +
  labs(
    title = "Phân phối sản phẩm chính theo giới tính",
    x = "Danh mục sản phẩm",
    y = "Số lượng",
    fill = "Giới tính"
  ) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal()

Ghi chú:

Biểu đồ tiếp tục phản ánh rõ sự khác biệt trong hành vi tiêu dùng giữa các danh mục sản phẩm chính khi được phân tách theo giới tính. Cụ thể, danh mục Food vẫn duy trì mức chênh lệch đáng kể giữa hai giới, với tỷ lệ chênh lệch là 1,42% (tương ứng 145 đơn hàng). Điều này cho thấy đây là nhóm sản phẩm có sức mua cao và thể hiện rõ nét sự phân hóa trong hành vi tiêu dùng theo giới.

Ngược lại, danh mục Drink – nhóm có tỷ lệ mua sắm thấp nhất – thể hiện mức độ ưu tiên thấp hơn từ cả hai giới. Tuy nhiên, vẫn ghi nhận sự chênh lệch giới tính ở mức 7,04% (tương ứng 88 đơn hàng).

Nhìn chung, tổng số đơn hàng từ khách hàng nữ đều cao hơn so với nam giới ở cả ba danh mục sản phẩm chính, phản ánh xu hướng tiêu dùng chủ động và tích cực hơn từ phía nữ giới trong các nhóm hàng hóa được khảo sát

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

Giả thuyết

  • \(H_0:\) Giới tính và nhóm sản phẩm chính không có mối quan hệ thống kê đáng kể, tức là chúng độc lập.
  • \(H_1:\) Giới tính và nhóm sản phẩm chính có mối quan hệ thống kê đáng kể, tức là chúng có liên kết với nhau.
# Tạo bảng Tần số giữa Gender và ProductFamily
table_chisq <- table(df_dt$Gender, df_dt$ProductFamily)

# Thực hiện kiểm định Chi-squared
chi1 <- chisq.test(table_chisq)

# In kết quả kiểm định
print(chi1)
## 
##  Pearson's Chi-squared test
## 
## data:  table_chisq
## X-squared = 3.5185, df = 2, p-value = 0.1722

Kết quả kiểm định Chi-squared

  • Giá trị thống kê: \(\chi^2\) = 3.5185
  • Bậc tự do: \(df\) = 2
  • Giá trị \(p-value\) = 0.1722

Kết luận:

Với \(p-value\) = 0.1722 > 0.05, ta không có bằng chứng để bác bỏ giả thuyết \(H_0\).
Do đó, hai biến quan sát có không có mối liên hệ với nhau, nghĩa là 2 biến độc lập.

4.2 AnnualIncome và Homeowner

Cần thiết phải xem xét kỹ lưỡng liệu thu nhập có ảnh hưởng đáng kể đến việc sở hữu nhà của khách hàng hay không.

4.2.1 Bảng tần suất (%) chéo

library(tidyr)
library(janitor)  # Hỗ trợ làm sạch dữ liệu và tạo bảng Tần số chéo nhiều biến.
# Tạo bảng Tần số chéo và tính tỷ lệ phần trăm theo hàng (giới tính)
df_dt %>%
  tabyl(Homeowner, AnnualIncome) %>%              # Tạo bảng chéo Tần số, đếm Tần số
  adorn_percentages("row") %>%                  # Tính tỷ lệ phần trăm theo từng hàng
  adorn_pct_formatting(digits = 2) %>%          # Định dạng phần trăm (ví dụ: 45.2%)
  kable(
    format = "html",
    caption = "Bảng 4.2: Bảng tần suất (%) chéo thu nhập và việc sở hữu nhà",
    align = "c"
  ) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover"))  # Làm đẹp bảng: kẻ sọc, hover
Bảng 4.2: Bảng tần suất (%) chéo thu nhập và việc sở hữu nhà
Homeowner $10K - $30K $110K - $130K $130K - $150K $150K + $30K - $50K $50K - $70K $70K - $90K $90K - $110K
N 24.20% 2.12% 2.42% 0.85% 37.17% 18.93% 12.22% 2.08%
Y 20.50% 6.21% 7.39% 2.66% 29.77% 15.48% 12.12% 5.87%

Lưu ý: Kết quả cho thấy hành vi mua sắm giữa nhóm khách hàng có và không có nhà ở có thể chịu ảnh hưởng bởi mức thu nhập. Phần lớn khách hàng không sở hữu nhà có thu nhập dao động trong khoảng $10k - $90k, với sự chênh lệch đáng kể so với nhóm có nhà – vốn chiếm phần lớn trong phân khúc khách hàng chính. Đáng chú ý, theo khảo sát, đa số khách hàng có thu nhập trên $90k hầu như sở hữu nhà và thể hiện sức mua cao hơn so với nhóm còn lại.

So sánh tỷ lệ phân phối sản phẩm giữa hai nhóm khách hàng này cho thấy sự chênh lệch rõ rệt ở các phân khúc thu nhập khác nhau.

4.2.2 Trực quan hóa dữ liệu

4.2.2.1 Biểu đồ cột nhóm

# Tính Tần số và phần trăm theo ProductFamily và Gender
df_summary <- df_dt %>%
  group_by(Homeowner, AnnualIncome) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(AnnualIncome) %>%
  mutate(pct = n / sum(n) * 100)

# Vẽ biểu đồ với nhãn là số lượng và phần trăm theo nhóm thu nhập và tình trạng sở hữu nhà
ggplot(df_summary, aes(x = AnnualIncome, y = n, fill = Homeowner)) +
  geom_bar(stat = "identity", position = position_dodge(0.9)) +
  geom_text(aes(label = paste0(n, "\n(", sprintf("%.1f", pct), "%)")),  # Hiển thị cả số lượng (n) và % (pct) trên cột
            position = position_dodge(0.9),
            vjust = 0.5, size = 3) +
  labs(title = "Phân phối số đơn hàng theo thu nhập và tình trạng sở hữu nhà",
       x = "Nhóm thu nhập hằng năm",
       y = "Số lượng đơn hàng",
       fill = "Tình trạng sở hữu nhà") +
  scale_fill_brewer(palette = "Pastel1") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

4.2.2.2 Biểu đồ cột chồng

ggplot(df_summary, aes(x = AnnualIncome, y = n, fill = Homeowner)) +
  geom_bar(stat = "identity") +
  labs(title = "Phân phối số đơn hàng theo thu nhập và tình trạng sở hữu nhà",
       x = "Nhóm thu nhập hằng năm",
       y = "Số lượng đơn hàng",
       fill = "Tình trạng sở hữu nhà") +
  scale_fill_brewer(palette = "Pastel1") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ghi chú:

Biểu đồ tiếp tục thể hiện rõ sự khác biệt trong hành vi tiêu dùng giữa các nhóm thu nhập, khi được phân tách theo trạng thái sở hữu nhà. Cụ thể, trong nhóm thu nhập từ $30k–$50k, mức chênh lệch về sức mua giữa khách hàng có và chưa sở hữu nhà vẫn duy trì ở mức đáng kể, với tỷ lệ 9,3% (tương đương 427 đơn hàng).

Đáng chú ý, nhóm khách hàng có thu nhập trên $150k lại ghi nhận tỷ lệ mua hàng thấp nhất, với mức chênh lệch 64,83% (tương ứng 177 đơn hàng), cho thấy sự suy giảm rõ rệt trong nhu cầu mua sắm ở phân khúc thu nhập cao này.

Điều này cho thấy tổng số lượng đơn hàng từ nhóm khách hàng sở hữu nhà đều cao hơn so với nhóm chưa sở hữu nhà ở cả 9 nhóm thu nhập hằng năm được khảo sát. Kết quả phản ánh xu hướng tiêu dùng tích cực và ổn định hơn từ nhóm khách hàng có nhà, bất kể mức thu nhập tương ứng

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

Giả thuyết

  • \(H_0:\) Mức thu nhập hằng năm và tình trạng sở hữu nhà không có mối quan hệ thống kê đáng kể, tức là chúng độc lập.
  • \(H_1:\)Mức thu nhập hằng năm và tình trạng sở hữu nhà có mối quan hệ thống kê đáng kể, tức là chúng có liên kết với nhau.
# Tạo bảng Tần số giữa Gender và ProductFamily
table_chisq <- table(df_dt$AnnualIncome, df_dt$Homeowner)

# Thực hiện kiểm định Chi-squared
chi2 <- chisq.test(table_chisq)

# In kết quả kiểm định
print(chi2)
## 
##  Pearson's Chi-squared test
## 
## data:  table_chisq
## X-squared = 546.37, df = 7, p-value < 2.2e-16

Kết quả kiểm định Chi-squared

  • Giá trị thống kê: \(\chi^2\) = 546.37
  • Bậc tự do: \(df\) = 7
  • Giá trị \(p-value\) < 2.2e-16

Kết luận:

Với \(p-value\) = 2.2e-16 < 0.05, ta có bằng chứng để bác bỏ giả thuyết \(H_0\), chấp nhận \(H_1\).
Điều này cho thấy giữa hai biến quan sát tồn tại mối liên hệ có ý nghĩa thống kê, tức là chúng có sự liên kết đáng kể với nhau.

4.3 StateorProvince và AnnualIncome

Việc phân tích thu nhập theo từng Bang/Tỉnh đến là cần thiết nhằm đánh giá xem yếu tố địa lý có ảnh hưởng đến nhu cầu mua sắm của khách hàng hay không. Đồng thời, điều này cũng giúp nhận diện rõ liệu có sự khác biệt đáng kể nào trong cơ cấu thu nhập giữa các địa phương, cũng như xác định Bang/Tỉnh nào đang thực sự chiếm ưu thế về mức thu nhập – từ đó gợi ý tiềm năng tiêu dùng vượt trội

4.3.1 Bảng tần suất (%) chéo

# Tạo bảng Tần số chéo và tính tỷ lệ phần trăm theo hàng (giới tính)
df_dt %>%
  tabyl (StateorProvince, AnnualIncome) %>%              # Tạo bảng chéo Tần số, đếm Tần số
  adorn_percentages("row") %>%                  # Tính tỷ lệ phần trăm theo hàng
  adorn_pct_formatting(digits = 2) %>%          # Định dạng phần trăm (ví dụ: 45.2%)
  kable(
    format = "html",
    caption = "Bảng 4.3: Bảng tần suất (%) chéo giữa thu nhập và bang/tỉnh",
    align = "c"
  ) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover"))  # Làm đẹp bảng: kẻ sọc, hover
Bảng 4.3: Bảng tần suất (%) chéo giữa thu nhập và bang/tỉnh
StateorProvince $10K - $30K $110K - $130K $130K - $150K $150K + $30K - $50K $50K - $70K $70K - $90K $90K - $110K
BC 21.26% 6.06% 5.56% 1.98% 36.59% 15.57% 9.89% 3.09%
CA 21.92% 4.76% 4.54% 2.34% 32.49% 17.97% 11.38% 4.61%
DF 21.72% 4.05% 7.36% 1.35% 35.09% 15.95% 10.80% 3.68%
Guerrero 31.85% 3.92% 3.92% 2.61% 27.15% 15.67% 10.97% 3.92%
Jalisco 38.67% 2.67% 4.00% 0.00% 22.67% 17.33% 12.00% 2.67%
OR 22.72% 4.11% 5.84% 1.19% 32.01% 16.71% 12.11% 5.31%
Veracruz 18.32% 7.33% 7.54% 1.08% 30.60% 22.41% 9.91% 2.80%
WA 22.01% 4.23% 5.45% 2.43% 32.89% 16.82% 12.28% 3.90%
Yucatan 17.28% 3.52% 5.50% 2.29% 35.17% 13.00% 16.06% 7.19%
Zacatecas 21.13% 5.47% 4.70% 1.08% 31.77% 16.58% 14.88% 4.39%

Lưu ý: Kết quả phân tích cho thấy hành vi mua sắm của khách hàng tại các Bang/Tỉnh có thể chịu ảnh hưởng đáng kể bởi mức thu nhập. Phần lớn khách hàng tập trung trong nhóm thu nhập từ $10k đến $90k, trong đó khoảng $30k–$50k thường chiếm tỷ trọng cao nhất. Tuy nhiên, có hai ngoại lệ đáng chú ý là các thành phố GuerreroJalisco, nơi nhóm khách hàng có thu nhập $10k–$30k lại chiếm ưu thế vượt trội.

So sánh tỷ lệ phân phối sản phẩm giữa các nhóm thu nhập và khu vực địa lý cũng cho thấy sự chênh lệch đáng kể.

4.3.2 Trực quan hóa dữ liệu

4.3.2.1 Biểu đồ cột nhóm

ggplot(df_dt, aes(x = StateorProvince, fill = AnnualIncome)) +
  geom_bar(position = position_dodge(width = 0.8)) +
  geom_text(stat = "count", 
            aes(label = after_stat(count)), 
            position = position_dodge(width = 0.8), 
            vjust = -0.3, size = 2.5, check_overlap = TRUE) +
  labs(title = "Phân phối đơn hàng theo thu nhập và bang/tỉnh",
       x = "Bang/Tỉnh", y = "Số đơn hàng", fill = "Thu nhập") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "bottom")

4.3.3 Biểu đồ cột chồng

ggplot(df_dt, aes(x = StateorProvince, fill = AnnualIncome)) +
  geom_bar() +
  labs(title = "Phân phối đơn hàng theo thu nhập và bang/tỉnh",
       x = "Bang/Tỉnh", y = "Số đơn hàng", fill = "Thu nhập") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "bottom")

Ghi chú:

Biểu đồ tiếp tục làm rõ sự khác biệt trong hành vi tiêu dùng giữa các nhóm thu nhập, đặc biệt khi được phân tích chi tiết theo từng bang/tỉnh. Trong đó, bang WA (Washington) nổi bật với tổng số lượng đơn hàng cao nhất, theo sau là CA (California) và OR (Oregon). Khoảng cách giữa nhóm dẫn đầu và các bang còn lại là tương đối lớn, cho thấy sự tập trung tiêu dùng đáng kể tại một số khu vực nhất định..

Ngược lại, các thành phố như Jalisco và Guerrero ghi nhận tỷ lệ đơn hàng thấp nhất, phản ánh mức thu nhập phổ biến tại đây chủ yếu nằm trong khoảng $10k–$30k. Điều này cho thấy nhu cầu tiêu dùng từ các phân khúc thu nhập cao tại hai khu vực này đang ở mức rất hạn chế, có thể bắt nguồn từ đặc điểm kinh tế - xã hội hoặc sự khác biệt trong thói quen chi tiêu của cư dân địa phương.

Từ kết quả này, có thể thấy rằng nhóm khách hàng tại bang WA cùng với các nhóm thu nhập trong khoảng $10k – $90k là đối tượng đóng góp chính vào tổng doanh số. Do đó, các chiến lược định vị sản phẩm, đặc biệt là về giá bán, nên ưu tiên nhắm tới phân khúc thu nhập trung bình này

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

Giả thuyết

  • \(H_0:\) Mức thu nhập hằng năm tại bang/tỉnh không có mối quan hệ thống kê đáng kể, tức là chúng độc lập.
  • \(H_1:\)Mức thu nhập hằng năm tại bang/ tỉnh có mối quan hệ thống kê đáng kể, tức là chúng có liên kết với nhau.
# Tạo bảng Tần số giữa Gender và ProductFamily
table_chisq <- table(df_dt$AnnualIncome, df_dt$StateorProvince)

# Thực hiện kiểm định Chi-squared
chi3 <- chisq.test(table_chisq)
## Warning in stats::chisq.test(x, y, ...): Chi-squared approximation may be
## incorrect
# In kết quả kiểm định
print(chi3)
## 
##  Pearson's Chi-squared test
## 
## data:  table_chisq
## X-squared = 181.72, df = 63, p-value = 1.893e-13

Kết quả kiểm định Chi-squared

  • Giá trị thống kê: \(\chi^2\) = 181.72
  • Bậc tự do: \(df\) = 63
  • Giá trị \(p-value\) = 1.893e-13

Kết luận:

Với \(p-value\) = 2.2e-16 < 0.05, ta có bằng chứng để bác bỏ giả thuyết \(H_0\), chấp nhận \(H_1\).
Điều này cho thấy giữa hai biến quan sát tồn tại mối liên hệ có ý nghĩa thống kê, tức là chúng có sự liên kết đáng kể với nhau.

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

5.1 Tóm tắt phát hiện sơ bộ từ 10 biến quan sát

  • Giới tính: Tỷ lệ nam và nữ trong mẫu không có sự khác biệt đáng kể. Ước lượng tỷ lệ nữ dao động quanh mức 50%, phản ánh sự phân bổ gần như cân bằng giữa hai giới.

  • Tình trạng sở hữu nhà: Khách hàng sở hữu nhà chiếm tỷ lệ cao hơn đáng kể so với nhóm chưa sở hữu nhà, cho thấy nhóm này chiếm ưu thế trong dữ liệu.

  • Tình trạng hôn nhân: Nhóm độc thân chiếm tỷ lệ cao hơn, nhưng sự chênh lệch giữa các nhóm hôn nhân không lớn, cho thấy sự phân bố tương đối đồng đều.

  • Thu nhập hàng năm: Phần lớn khách hàng tập trung trong nhóm thu nhập từ $10k-$90k, nổi bật nhất là khoảng thu nhập $30k-$50k với ước lượng tỷ lệ dao động chiếm gần 20%. Tỷ lệ khách hàng giảm dần khi thu nhập tăng cao, phản ánh phân bố chủ yếu thuộc tầng lớp trung lưu.

  • Quốc gia: Khách hàng đến từ Hoa Kỳ (USA) chiếm hơn một nửa tổng số đơn hàng, cho thấy đây là thị trường chủ lực và quan trọng nhất.

  • Thành phố: Thành phố Salem ghi nhận số lượng đơn hàng cao nhất, chiếm khoảng 10%, tương thích với dự báo từ kiểm định tỷ lệ.

  • Phân khúc sản phẩm chính: Nhóm sản phẩm Food là phân khúc được ưa chuộng nhất, chiếm trên 50% tổng số đơn hàng, phản ánh rõ xu hướng tiêu dùng tập trung vào thực phẩm.

  • Bộ phận sản phẩm phụ: Trong các bộ phận sản phẩm, nhóm Produce dẫn đầu với tỷ trọng khoảng 14%, phù hợp với ước lượng từ kiểm định tỷ lệ.

  • Danh mục cụ thể: Sản phẩm thuộc nhóm Vegetables được lựa chọn nhiều hơn hẳn so với các danh mục khác, thể hiện ưu tiên rõ ràng trong lựa chọn sản phẩm.

  • Mối quan hệ giữa các biến: Không phát hiện mối liên hệ đáng kể giữa giới tínhnhóm sản phẩm chính, cho phép phân tích hai yếu tố này một cách độc lập. Tuy nhiên, thu nhập hàng năm lại có mối liên hệ chặt chẽ với thành phố cư trútình trạng sở hữu nhà, cho thấy những yếu tố này ảnh hưởng đáng kể đến hành vi tiêu dùng và khả năng chi tiêu của khách hàng.

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

Nghiên cứu chủ yếu tập trung vào các biến định tính để phân tích hành vi tiêu dùng, chưa khai thác sâu các biến định lượng quan trọng như doanh thu (Revenue) và số lượng sản phẩm bán ra (UnitsSold), vốn có thể ảnh hưởng đáng kể đến phân nhóm khách hàng và lựa chọn sản phẩm. Ngoài ra, biến đặc điểm gia đình như số lượng con cái (Children) cũng chưa được xem xét, trong khi đây là yếu tố có thể tác động trực tiếp đến khả năng mua hàng của hộ gia đình.

Phạm vi nghiên cứu giới hạn ở 3 quốc gia, tập trung chủ yếu vào thị trường sử dụng đồng USD, bỏ qua sự đa dạng của các thị trường khác với đặc điểm kinh tế và thu nhập khác biệt. Về phương pháp, các kiểm định dựa trên giả định mẫu đủ lớn và phân nhóm đồng đều. Khi mẫu nhỏ hoặc phân nhóm không đồng đều, kết quả có thể không chính xác, dẫn đến cảnh báo như “Chi-squared approximation may be incorrect”. Ngoài ra, các mô hình hiện tại chưa khai thác các tương tác phức tạp giữa các biến, hạn chế khả năng giải thích hành vi tiêu dùng thực tế.

5.3 Đề xuất cải tiến

  • Mở rộng nghiên cứu bằng cách bổ sung các biến định lượng có sẵn như doanh thu (Revenue), số lượng sản phẩm bán ra (UnitsSold) và số lượng con cái (Children), nhằm phân tích sâu sắc hơn ảnh hưởng đa chiều của các yếu tố nội lực.

  • Bổ sung đặc điểm gia đình như số thành viên trong hộ, đồng thời tích hợp các biến nhân khẩu học bổ sung như tuổi, trình độ học vấn, nghề nghiệp, tình trạng việc làm, cùng với các biến kinh tế vĩ mô như tỷ lệ thất nghiệp, lạm phát, tốc độ tăng trưởng GDP của khu vực nghiên cứu, nhằm làm rõ hơn tác động của các yếu tố xã hội và kinh tế đến khả năng chi tiêu.

  • Mở rộng phạm vi nghiên cứu sang các quốc gia và thị trường đa dạng hơn, nhằm tăng tính tổng quát của kết quả và so sánh sự khác biệt về hành vi tiêu dùng dựa trên đặc điểm kinh tế và văn hóa riêng biệt.

  • Áp dụng các phương pháp kiểm định phù hợp với đặc điểm mẫu nhỏ và cấu trúc dữ liệu phức tạp, như kiểm định phi tham số hoặc mô hình hồi quy đa biến với biến phân loại, nhằm nâng cao độ chính xác và độ tin cậy của phân tích.

  • Khai thác các mô hình tương tác và phân tích đa chiều để hiểu rõ hơn các mối quan hệ phức tạp giữa các biến định tính và định lượng trong hành vi tiêu dùng, từ đó đưa ra những kết luận sâu sắc và toàn diện hơn.

5.4 Câu hỏi mở/Hướng nghiên cứu tiếp theo

  • Mối quan hệ giữa doanh thu, số lượng sản phẩm bán ra với thu nhập, độ tuổi và đặc điểm hộ gia đình là gì?
  • Ảnh hưởng của sự hiện diện con cái đến xu hướng chi tiêu và lựa chọn sản phẩm theo từng nhóm gia đình ra sao?
  • Hành vi tiêu dùng biến đổi như thế nào theo chu kỳ kinh tế khi xem xét các yếu tố vĩ mô như lạm phát và tỷ lệ thất nghiệp?
  • Ứng dụng các mô hình phân cụm (clustering) có thể giúp phát hiện các nhóm khách hàng tiềm ẩn trong các phân nhóm nhỏ không đồng đều không?
  • Liệu có thể kết hợp các yếu tố nhân khẩu và hành vi để xây dựng chiến dịch marketing cá nhân hóa hiệu quả hơn?
  • Những yếu tố nào có khả năng dự đoán hành vi mua lại và giá trị vòng đời khách hàng khi có dữ liệu theo thời gian?