I. Tìm hiểu và chuẩn bị dữ liệu

1.1. Đọc file tmp.csv vào R

Bộ dữ liệu Supermarket Transactions (Giao dịch Siêu thị) là một tập hợp dữ liệu mô phỏng các giao dịch mua hàng được thực hiện tại một chuỗi siêu thị gồm 16 biến và 14059 quan sát . Dữ liệu này chứa nhiều thông tin phong phú liên quan đến hành vi tiêu dùng của khách hàng, đặc điểm nhân khẩu học và chi tiết sản phẩm. Cụ thể, mỗi bản ghi đại diện cho một giao dịch riêng biệt, bao gồm các biến như: PurchaseDate, CustomerID, Gender, MaritalStatus, Homeowner, Children, AnnualIncome, City, StateorProvince, Country, ProductFamily, ProductDepartment, ProductCategory, UnitsSold, Revenue.

Các biến trong dữ liệu được phân loại thành ba nhóm chính:

Identifier / ID Variables — Biến định danh: Đây là các biến dùng để phân biệt từng đối tượng quan sát, không mang ý nghĩa thống kê, gồm:

PurchaseDate — Ngày mua hàng

CustomerID — Mã khách hàng

Categorical / Qualitative Variables — Biến định tính: Bao gồm các biến phân loại không có giá trị số học, gồm:

Gender — Giới tính

MaritalStatus — Tình trạng hôn nhân

Homeowner — Sở hữu nhà

AnnualIncome — Thu nhập hàng năm

City — Thành phố

StateorProvince — Bang hoặc tỉnh

Country — Quốc gia

ProductFamily — Nhóm ngành hàng

ProductDepartment — Bộ phận sản phẩm

ProductCategory — Danh mục sản phẩm

Numerical / Quantitative Variables — Biến định lượng: Bao gồm các biến có thể đo lường và có giá trị số học, gồm:

Children — Số lượng con

UnitsSold — Số lượng bán

Revenue — Doanh thu

1.2. Hiển thị cấu trúc của dữ liệu

# Hiển thị cấu trúc của dữ liệu
str(d)
## '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 ...

Bộ dữ liệu phản ánh các thông tin giao dịch mua hàng của khách hàng cá nhân, bao gồm dữ liệu về thời gian, đặc điểm nhân khẩu học của khách hàng, địa lý, thông tin sản phẩm và kết quả giao dịch (đơn vị bán và doanh thu). Nhìn chung, cấu trúc của bộ dữ liệu này khá đầy đủ và hợp lý để phục vụ cho nhiều mục tiêu phân tích khác nhau như: phân tích hành vi khách hàng, mô hình hóa doanh thu, phân khúc thị trường, hay phân tích xu hướng tiêu dùng theo thời gian và không gian.

1.3. Hiển thị một vài dòng đầu và cuối của dữ liệu

# Hiển thị một vài dòng đầu tiên
head(d,6)
##   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
# Hiển thị một vài dòng cuối cùng
tail(d,6)
##           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.4. Kiểm tra xem có giá trị thiếu (NA) trong các cột định tính

# Kiểm tra giá trị thiếu (NA) trong các cột định tính
qual_cols <- c("Gender", "MaritalStatus", "Homeowner", "City", "StateorProvince", 
               "AnnualIncome", "Country", "ProductFamily", "ProductDepartment", "ProductCategory")

# Kiểm tra NA theo cột định tính
colSums(is.na(d[qual_cols]))
##            Gender     MaritalStatus         Homeowner              City 
##                 0                 0                 0                 0 
##   StateorProvince      AnnualIncome           Country     ProductFamily 
##                 0                 0                 0                 0 
## ProductDepartment   ProductCategory 
##                 0                 0
# Hàm tính mode
get_mode <- function(x) {
  ux <- unique(x[!is.na(x)])
  ux[which.max(tabulate(match(x, ux)))]
}

Kết quả trả về từ đoạn mã cho thấy rằng không có giá trị thiếu (NA) trong bất kỳ cột định tính nào thuộc danh sách qual_cols, bao gồm các biến như Gender, MaritalStatus, Homeowner, City, StateorProvince, AnnualIncome, Country, ProductFamily, ProductDepartment và ProductCategory. Tất cả các cột đều có tổng số NA bằng 0, điều này chứng tỏ dữ liệu định tính đang đầy đủ và sạch, không cần thực hiện thao tác thay thế giá trị thiếu. Việc kiểm tra điều kiện trước khi thay thế là một thực hành tốt, giúp đảm bảo tính toàn vẹn và tránh thay đổi không cần thiết đối với dữ liệu.

1.5. Chuyển đổi các biến cần thiết sang kiểu factor

# Chuyển đổi các cột cần thiết sang factor nếu chưa phải
for (col in qual_cols) {
  if (!is.factor(d[[col]])) {
    d[[col]] <- as.factor(d[[col]])
  }
}

# Kiểm tra lại cấu trúc sau khi chuyển đổi
str(d)
## '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 ...

Dữ liệu gồm 14.059 quan sát với 16 biến, trong đó nhiều biến định tính đã được đưa về dạng factor. Việc chuyển các biến như Gender, MaritalStatus, Homeowner, City, StateorProvince, Country, ProductFamily, ProductDepartment và ProductCategory sang dạng factor là hoàn toàn hợp lý. Điều này giúp biểu diễn rõ ràng các biến phân loại, hỗ trợ hiệu quả cho các bước phân tích thống kê, mô hình hóa cũng như trực quan hóa dữ liệu. Ngoài ra, factor còn giúp tiết kiệm bộ nhớ hơn so với chuỗi ký tự khi xử lý các giá trị lặp lại.

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

2.1. Biến Gender

table(d$Gender)
## 
##    F    M 
## 7170 6889
tmp <- table(d$Gender)/sum(nrow(d))
tmp
## 
##         F         M 
## 0.5099936 0.4900064

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

# Tính tần suất và phần trăm
df_gender <- d %>%
  count(Gender) %>%
  mutate(prop = n / sum(n),
         pct = paste0(round(prop * 100), "%"))

# Vẽ biểu đồ cột
ggplot(df_gender, aes(x = Gender, y = n, fill = Gender)) +
  geom_bar(stat = "identity", width = 0.6, color = "black") +  # Viền đen quanh cột
  scale_fill_manual(values = c("M" = "yellow", "F" = "pink")) +  # Màu theo Gender
  geom_text(aes(label = pct), vjust = -0.5, size = 5) +  # Hiển thị % trên cột
  labs(title = "Bar Plot - Gender", x = "Gender", y = "Frequency") +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

# Tính tần suất
df_gender <- d %>%
  count(Gender) %>%
  mutate(prop = n / sum(n),
         pct = paste0(round(prop * 100), "%"))

# Vẽ biểu đồ tròn
ggplot(df_gender, aes(x = "", y = prop, fill = Gender)) +
  geom_bar(stat = "identity", width = 1, color = "black") +  # Viền đen quanh miếng
  coord_polar("y", start = 0) +  # Biểu đồ hình tròn
  scale_fill_manual(values = c("M" = "yellow", "F" = "pink")) +  # Màu theo Gender
  geom_text(aes(label = pct), position = position_stack(vjust = 0.5)) +  # Hiện % ở giữa
  labs(title = "Pie Chart - Gender", x = NULL, y = NULL, fill = "Gender") +
  theme_minimal(base_size = 14) +
  theme(
    axis.text = element_blank(),
    axis.ticks = element_blank(),
    panel.grid = element_blank(),
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

Biến Gender: Biến này phản ánh giới tính của khách hàng với hai giá trị: nam (M) và nữ (F). Trong tổng số 14.059 quan sát, số lượng nữ là 7.170 người (chiếm 51%), còn nam là 6.889 người (49%). Tỷ lệ này cho thấy giới tính trong mẫu dữ liệu khá cân đối, không có sự chênh lệch đáng kể giữa hai nhóm.

2.2. Biến MaritalStatus

table(d$MaritalStatus)
## 
##    M    S 
## 6866 7193
tmp <- table(d$MaritalStatus)/sum(nrow(d))
tmp
## 
##         M         S 
## 0.4883704 0.5116296
df_marital <- d %>%
  count(MaritalStatus)

ggplot(df_marital, aes(x = reorder(MaritalStatus, -n), y = n, fill = MaritalStatus)) +
  geom_bar(stat = "identity", color = "black", width = 0.7) +  # Viền đen
  scale_fill_brewer(palette = "Set2") +  # Màu tự động đẹp
  labs(title = "Bar Plot - Marital Status", x = "Marital Status", y = "Frequency") +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text = element_text(color = "black"),
    axis.title = element_text(face = "bold")
  )

df_marital <- d %>%
  count(MaritalStatus) %>%
  mutate(Percent = round(100 * n / sum(n), 2))

ggplot(df_marital, aes(x = "", y = n, fill = MaritalStatus)) +
  geom_bar(stat = "identity", width = 1, color = "black") +  # Viền đen
  coord_polar("y", start = 0) +
  theme_void(base_size = 14) +
  scale_fill_brewer(palette = "Set2") +  # Bảng màu tự động đẹp
  labs(title = "Pie Chart - Marital Status") +
  geom_text(aes(label = paste0(Percent, "%")), position = position_stack(vjust = 0.5)) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

Biến MaritalStatus: Phản ánh tình trạng hôn nhân của khách hàng. Trong dữ liệu, có 7.193 người độc thân (51.16%) và 6.866 người đã kết hôn (48.84%). Mặc dù tỷ lệ khá cân bằng, nhưng nhóm độc thân chiếm ưu thế nhẹ.

2.3. Biến Homeowner

table(d$Homeowner)
## 
##    N    Y 
## 5615 8444
tmp <- table(d$Homeowner)/sum(nrow(d))
tmp
## 
##         N         Y 
## 0.3993883 0.6006117
df_home <- d %>%
  count(Homeowner)

ggplot(df_home, aes(x = reorder(Homeowner, -n), y = n, fill = Homeowner)) +
  geom_bar(stat = "identity", color = "black", width = 0.7) +
  scale_fill_manual(values = c("Y" = "#FFD1DC", "N" = "#D8EEDF")) +
  labs(title = "Bar Plot - Homeowner", x = "Homeowner", y = "Frequency") +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

df_home <- df_home %>%
  mutate(Percent = round(100 * n / sum(n), 2))

ggplot(df_home, aes(x = "", y = n, fill = Homeowner)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  coord_polar("y") +
  theme_void() +
  scale_fill_manual(values = c("Y" = "#FFD1DC", "N" = "#D8EEDF")) +
  labs(title = "Pie Chart - Homeowner") +
  geom_text(aes(label = paste0(Percent, "%")), position = position_stack(vjust = 0.5))

Biến Homeowner: Thể hiện việc khách hàng có sở hữu nhà ở hay không. Có 8.444 người (60.06%) có nhà và 5.615 người (39.94%) không có nhà. Điều này cho thấy phần lớn khách hàng trong tập dữ liệu có điều kiện kinh tế tương đối ổn định.

2.4. Biến City

table(d$City)
## 
##      Acapulco    Bellingham Beverly Hills     Bremerton       Camacho 
##           383           143           811           834           452 
##   Guadalajara       Hidalgo   Los Angeles        Merida   Mexico City 
##            75           845           926           654           194 
##       Orizaba      Portland         Salem    San Andres     San Diego 
##           464           876          1386           621           866 
## San Francisco       Seattle       Spokane        Tacoma     Vancouver 
##           130           922           875          1257           633 
##      Victoria   Walla Walla        Yakima 
##           176           160           376
tmp <- table(d$City)/sum(nrow(d))
tmp
## 
##      Acapulco    Bellingham Beverly Hills     Bremerton       Camacho 
##   0.027242336   0.010171420   0.057685468   0.059321431   0.032150224 
##   Guadalajara       Hidalgo   Los Angeles        Merida   Mexico City 
##   0.005334661   0.060103848   0.065865282   0.046518245   0.013798990 
##       Orizaba      Portland         Salem    San Andres     San Diego 
##   0.033003770   0.062308841   0.098584537   0.044170994   0.061597553 
## San Francisco       Seattle       Spokane        Tacoma     Vancouver 
##   0.009246746   0.065580767   0.062237712   0.089408920   0.045024539 
##      Victoria   Walla Walla        Yakima 
##   0.012518671   0.011380610   0.026744434
df_city <- d %>%
  count(City)

ggplot(df_city, aes(x = reorder(City, -n), y = n, fill = City)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  labs(title = "Bar Plot - City", x = "City", y = "Frequency") +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1, face = "italic")  # xoay 45 độ + nghiêng
  )

Biến City: Phản ánh nơi sinh sống của khách hàng theo thành phố. Dữ liệu ghi nhận 23 thành phố, trong đó Bremerton (5.93%), Beverly Hills (5.77%) và Camacho (3.22%) là các khu vực có lượng khách hàng cao hơn hẳn. Phân bố khách hàng giữa các thành phố cho thấy sự đa dạng về mặt địa lý.

2.5. Biến StateorProvince

table(d$StateorProvince)
## 
##        BC        CA        DF  Guerrero   Jalisco        OR  Veracruz        WA 
##       809      2733       815       383        75      2262       464      4567 
##   Yucatan Zacatecas 
##       654      1297
tmp <- table(d$StateorProvince)/sum(nrow(d))
tmp
## 
##          BC          CA          DF    Guerrero     Jalisco          OR 
## 0.057543211 0.194395049 0.057969984 0.027242336 0.005334661 0.160893378 
##    Veracruz          WA     Yucatan   Zacatecas 
## 0.033003770 0.324845295 0.046518245 0.092254072
# Bước 1: Tạo biến df_state bằng cách đếm số lượng từng bang/tỉnh
df_state <- d%>%
  count(StateorProvince, name = "n")

# Bước 2: Vẽ biểu đồ cột
ggplot(df_state, aes(x = reorder(StateorProvince, -n), y = n, fill = StateorProvince)) +
  geom_bar(stat = "identity", color = "black", width = 0.7) +
  scale_fill_brewer(palette = "Set3") +
  labs(title = "Bar Plot - State or Province", x = "State/Province", y = "Frequency") +
  theme_minimal() +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

Biến StateorProvince: Cho biết tên bang hoặc tỉnh nơi khách hàng cư trú. California (CA) có tỷ lệ cao nhất (19.44%), tiếp theo là Distrito Federal (DF) với 5.8%. Một số khu vực khác như Jalisco hay Guerrero chỉ chiếm tỷ lệ nhỏ, dưới 3%, cho thấy khách hàng tập trung ở một số bang nhất định.

2.6. Biến Country

table(d$Country)
## 
## Canada Mexico    USA 
##    809   3688   9562
tmp <- table(d$Country)/sum(nrow(d))
tmp
## 
##     Canada     Mexico        USA 
## 0.05754321 0.26232307 0.68013372
df_country <- d %>%
  count(Country)

ggplot(df_country, aes(x = reorder(Country, -n), y = n, fill = Country)) +
  geom_bar(stat = "identity", color = "black", width = 0.7) +
  scale_fill_manual(values = c(
    "USA" = "#FFD54F",
    "Mexico" = "#4DB6AC",
    "Canada" = "#BA68C8"
    # Thêm màu cho các nước khác ở đây
  )) +
  labs(title = "Bar Plot - Country", x = "Country", y = "Frequency") +
  theme_minimal() +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", hjust = 0.5)
  )

df_country <- df_country %>%
  mutate(Percent = round(100 * n / sum(n), 2))

ggplot(df_country, aes(x = "", y = n, fill = Country)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  coord_polar("y") +
  theme_void() +
  scale_fill_manual(values = c(
    "USA" = "#FFD54F",
    "Mexico" = "#4DB6AC",
    "Canada" = "#BA68C8"
    # Thêm màu cho các nước khác ở đây
  )) +
  labs(title = "Pie Chart - Country") +
  geom_text(aes(label = paste0(Percent, "%")), position = position_stack(vjust = 0.5))

Biến Country: Thể hiện quốc gia cư trú của khách hàng. Hoa Kỳ chiếm đa số với 68.01%, kế đến là Mexico (26.23%) và Canada (5.75%). Sự chênh lệch lớn giữa các quốc gia cho thấy mẫu dữ liệu nghiêng về phía khách hàng từ Mỹ, điều này cần lưu ý trong quá trình phân tích.

2.7. Biến ProductFamily

table(d$ProductFamily)
## 
##          Drink           Food Non-Consumable 
##           1250          10153           2656
tmp <- table(d$ProductFamily)/sum(nrow(d))
tmp
## 
##          Drink           Food Non-Consumable 
##     0.08891102     0.72217085     0.18891813
df_family <- d %>%
  count(ProductFamily)

ggplot(df_family, aes(x = reorder(ProductFamily, -n), y = n, fill = ProductFamily)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  labs(title = "Bar Plot - Product Family", x = "Product Family", y = "Frequency") +
  theme_minimal() + theme(legend.position = "none")

df_family <- df_family %>%
  mutate(Percent = round(100 * n / sum(n), 2))

ggplot(df_family, aes(x = "", y = n, fill = ProductFamily)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  coord_polar("y") + theme_void() +
  labs(title = "Pie Chart - Product Family") +
  geom_text(aes(label = paste0(Percent, "%")), position = position_stack(vjust = 0.5))

Biến ProductFamily: Chia sản phẩm thành ba nhóm chính: Food, Drink và Non-Consumable. Nhóm Food chiếm tỷ lệ cao nhất với 72.22%, tiếp theo là Non-Consumable (18.89%) và Drink (8.89%). Đây là dấu hiệu cho thấy sản phẩm thực phẩm đóng vai trò chủ đạo trong tiêu dùng.

2.8. Biến ProductDepartment

table(d$ProductDepartment)
## 
## Alcoholic Beverages         Baked Goods        Baking Goods           Beverages 
##                 356                 425                1072                 680 
##     Breakfast Foods        Canned Foods     Canned Products            Carousel 
##                 188                 977                 109                  59 
##            Checkout               Dairy                Deli                Eggs 
##                  82                 903                 699                 198 
##        Frozen Foods  Health and Hygiene           Household                Meat 
##                1382                 893                1420                  89 
##         Periodicals             Produce             Seafood         Snack Foods 
##                 202                1994                 102                1600 
##              Snacks       Starchy Foods 
##                 352                 277
tmp <- table(d$ProductDepartment)/sum(nrow(d))
tmp
## 
## Alcoholic Beverages         Baked Goods        Baking Goods           Beverages 
##         0.025321858         0.030229746         0.076250089         0.048367594 
##     Breakfast Foods        Canned Foods     Canned Products            Carousel 
##         0.013372217         0.069492852         0.007753041         0.004196600 
##            Checkout               Dairy                Deli                Eggs 
##         0.005832563         0.064229319         0.049719041         0.014083505 
##        Frozen Foods  Health and Hygiene           Household                Meat 
##         0.098300021         0.063518031         0.101002916         0.006330464 
##         Periodicals             Produce             Seafood         Snack Foods 
##         0.014368020         0.141830856         0.007255139         0.113806103 
##              Snacks       Starchy Foods 
##         0.025037343         0.019702682
df_department <- d %>%
  count(ProductDepartment)

# Tạo màu cho từng nhóm
colors <- setNames(scales::hue_pal()(nrow(df_department)), df_department$ProductDepartment)

# Biểu đồ cột màu đầy đủ
ggplot(df_department, aes(x = reorder(ProductDepartment, -n), y = n, fill = ProductDepartment)) +
  geom_bar(stat = "identity", color = "black") +
  scale_fill_manual(values = colors) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Bar Plot - Product Department", x = "Product Department", y = "Frequency")

Biến Product Department: Cho thấy Produce (Rau củ quả) là nhóm sản phẩm có tần suất cao nhất (14.18%), tiếp theo là Snack Foods (11.38%) và Frozen Foods (9.83%), phản ánh nhu cầu tiêu dùng lớn và thường xuyên. Các nhóm như Household (10.1%) và Baking Goods (7.63%) cũng có mức tiêu thụ khá. Ngược lại, các nhóm như Meat (0.63%), Checkout (0.58%), và Seafood (0.73%) có tần suất thấp, cho thấy mức độ mua sắm hạn chế. Sự phân bố này giúp doanh nghiệp xác định các nhóm sản phẩm chủ lực để ưu tiên phát triển, đồng thời cân nhắc chiến lược với các nhóm ít phổ biến.

2.9. Biến ProductCategory

table(d$ProductCategory)
## 
##         Baking Goods    Bathroom Products        Beer and Wine 
##                  484                  365                  356 
##                Bread      Breakfast Foods              Candles 
##                  425                  417                   45 
##                Candy     Canned Anchovies         Canned Clams 
##                  352                   44                   53 
##       Canned Oysters      Canned Sardines        Canned Shrimp 
##                   35                   40                   38 
##          Canned Soup          Canned Tuna Carbonated Beverages 
##                  404                   87                  154 
##    Cleaning Supplies        Cold Remedies                Dairy 
##                  189                   93                  903 
##        Decongestants               Drinks                 Eggs 
##                   85                  135                  198 
##           Electrical      Frozen Desserts       Frozen Entrees 
##                  355                  323                  118 
##                Fruit             Hardware        Hot Beverages 
##                  765                  129                  226 
##              Hygiene     Jams and Jellies     Kitchen Products 
##                  197                  588                  217 
##            Magazines                 Meat        Miscellaneous 
##                  202                  761                   42 
##  Packaged Vegetables       Pain Relievers       Paper Products 
##                   48                  192                  345 
##                Pizza     Plastic Products Pure Juice Beverages 
##                  194                  141                  165 
##              Seafood          Side Dishes          Snack Foods 
##                  102                  153                 1600 
##            Specialty        Starchy Foods           Vegetables 
##                  289                  277                 1728
tmp <- table(d$ProductCategory)/sum(nrow(d))
tmp
## 
##         Baking Goods    Bathroom Products        Beer and Wine 
##          0.034426346          0.025962017          0.025321858 
##                Bread      Breakfast Foods              Candles 
##          0.030229746          0.029660716          0.003200797 
##                Candy     Canned Anchovies         Canned Clams 
##          0.025037343          0.003129668          0.003769827 
##       Canned Oysters      Canned Sardines        Canned Shrimp 
##          0.002489508          0.002845153          0.002702895 
##          Canned Soup          Canned Tuna Carbonated Beverages 
##          0.028736041          0.006188207          0.010953837 
##    Cleaning Supplies        Cold Remedies                Dairy 
##          0.013443346          0.006614980          0.064229319 
##        Decongestants               Drinks                 Eggs 
##          0.006045949          0.009602390          0.014083505 
##           Electrical      Frozen Desserts       Frozen Entrees 
##          0.025250729          0.022974607          0.008393200 
##                Fruit             Hardware        Hot Beverages 
##          0.054413543          0.009175617          0.016075112 
##              Hygiene     Jams and Jellies     Kitchen Products 
##          0.014012376          0.041823743          0.015434953 
##            Magazines                 Meat        Miscellaneous 
##          0.014368020          0.054129028          0.002987410 
##  Packaged Vegetables       Pain Relievers       Paper Products 
##          0.003414183          0.013656732          0.024539441 
##                Pizza     Plastic Products Pure Juice Beverages 
##          0.013798990          0.010029163          0.011736254 
##              Seafood          Side Dishes          Snack Foods 
##          0.007255139          0.010882709          0.113806103 
##            Specialty        Starchy Foods           Vegetables 
##          0.020556227          0.019702682          0.122910591
df_cat <- d %>%
  count(ProductCategory)

ggplot(df_cat, aes(x = reorder(ProductCategory, -n), y = n, fill = ProductCategory)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Bar Plot - Product Category", x = "Product Category", y = "Frequency") +
  theme(
    legend.position = "none",
    axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1, face = "italic")  # xoay 45 độ + nghiêng
  )

Biến ProductCategory: Là cấp độ phân loại chi tiết nhất trong sản phẩm. Các danh mục phổ biến gồm Baking Goods (3.44%), Bread (3.02%) và Beer and Wine (2.53%). Mặc dù tỷ lệ không cao, nhưng tổng thể các danh mục thể hiện cấu trúc sản phẩm phong phú, đáp ứng nhiều loại nhu cầu tiêu dùng.

2.10. Biến AnnualIncome

table(d$AnnualIncome)
## 
##   $10K - $30K $110K - $130K $130K - $150K       $150K +   $30K - $50K 
##          3090           643           760           273          4601 
##   $50K - $70K   $70K - $90K  $90K - $110K 
##          2370          1709           613
tmp <- table(d$AnnualIncome)/sum(nrow(d))
tmp
## 
##   $10K - $30K $110K - $130K $130K - $150K       $150K +   $30K - $50K 
##    0.21978804    0.04573583    0.05405790    0.01941817    0.32726367 
##   $50K - $70K   $70K - $90K  $90K - $110K 
##    0.16857529    0.12155914    0.04360196
df_AnnualIncome <- d %>%
  count(AnnualIncome)

ggplot(df_AnnualIncome, aes(x = reorder(AnnualIncome, -n), y = n, fill = AnnualIncome)) +
  geom_bar(stat = "identity", width = 1, color = "black") +
  labs(title = "Bar Plot - AnnualIncome", x = "AnnualIncome", y = "Frequency") +
  theme_minimal() + theme(legend.position = "none")

Nhận xét: Biểu đồ trên thể hiện tần suất của các nhóm thu nhập hàng năm khác nhau. Nhìn chung, thu nhập phân bố không đồng đều và có xu hướng tập trung chủ yếu ở mức trung bình - thấp. Cụ thể, nhóm thu nhập từ 30.000 đến 50.000 USD chiếm tỷ lệ cao nhất với hơn 4.500 người, tiếp theo là nhóm 10.000 đến 30.000 USD với khoảng 3.100 người. Các nhóm thu nhập cao hơn như 50.000 – 70.000 USD và 70.000 – 90.000 USD có số lượng giảm dần, lần lượt khoảng 2.400 và 1.700 người. Đáng chú ý, những người có thu nhập từ 90.000 USD trở lên chiếm tỷ lệ rất nhỏ, đặc biệt nhóm trên 150.000 USD là thấp nhất với dưới 500 người. Điều này cho thấy phân bố thu nhập trong dữ liệu là không đồng đều và nghiêng về phía thu nhập thấp, phản ánh bức tranh thu nhập có sự chênh lệch lớn và phần lớn tập trung ở các mức dưới 70.000 USD mỗi năm.

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

3.1. Xác định hạng mục quan tâm

“Female” trong Gender, “Y” trong Homeowner, “Food” trong ProductFamily

3.2. Ước lượng khoảng tin cậy và kiểm định giả thuyết

3.2.1. Gender – Hạng mục quan tâm: “Female” – H0: tỷ lệ = 0.5

# Đếm số lượng khách hàng nữ
n_female <- sum(d$Gender == "F")

#Tổng số quan sát
n_total <- nrow(d)

#Tính khoảng tin cậy 95% cho tỷ lệ nữ
prop.test(n_female, n_total, correct = FALSE) 
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_female out of n_total, 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

Kiểm định giả thuyết

Đặt giả thuyết:

  • \(H_0\): Tỷ lệ nữ = 0.5

  • \(H_1\): Tỷ lệ nữ ≠ 0.5

Ý nghĩa: Với độ tin cậy 95%, ta có thể kết luận rằng tỷ lệ nữ giới trong tổng số khách hàng rơi vào khoảng từ 50,17% đến 51,83%.

3.2.2. HomeOwner – Hạng mục quan tâm: “Y” – H0: tỷ lệ = 0.6

# Đếm số lượng khách hàng sở hữu nhà 
n_yes <- sum(d$Homeowner == "Y")

#Tổng số quan sát
n_total <- nrow(d)

#Tính khoảng tin cậy 95% cho tỷ lệ có nhà ở
prop.test(n_yes, n_total, correct = FALSE) 
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_yes out of n_total, null probability 0.5
## X-squared = 569.26, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5924894 0.6086791
## sample estimates:
##         p 
## 0.6006117

Ý nghĩa: Với độ tin cậy 95% cho thấy rằng tỷ lệ thực tế nằm trong khoảng từ 59,25% đến 60,87%. Điều này đồng nghĩa với việc, nếu cùng một khảo sát được lặp lại nhiều lần với cùng phương pháp lấy mẫu, thì khoảng 95% trong số đó sẽ cho kết quả tỷ lệ nằm trong khoảng này. Kết quả kiểm định cho thấy giá trị p rất nhỏ (p < 2.2e-16), do đó có bằng chứng thống kê mạnh để bác bỏ giả thuyết rằng tỷ lệ thực tế bằng 50%.

Kiểm định giả thuyết

Đặt giả thuyết:

  • \(H_0\): Tỷ lệ khách hàng sở hữu nhà = 0.6

  • \(H_1\): Tỷ lệ khách hàng chưa sở hữu nhà ≠ 0.6

prop.test(n_yes, n_total, p=0.6, correct = FALSE)  
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_yes out of n_total, null probability 0.6
## X-squared = 0.02192, df = 1, p-value = 0.8823
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.5924894 0.6086791
## sample estimates:
##         p 
## 0.6006117

Kết quả kiểm định cho thấy giá trị Chi-squared là 0.02192 với 1 bậc tự do và giá trị p là 0.8823. Với mức ý nghĩa 5%, do p-value > 0.05, ta không bác bỏ giả thuyết H₀, tức là giả thuyết cho rằng tỷ lệ thực tế bằng với tỷ lệ giả định 0.6.

3.2.3. ProductFamily – Hạng mục quan tâm: “Food” – H0: tỷ lệ ≥ 0.7 (alternative = “greater”)

# Đếm số lượng khách hàng chọn ProductFamily là "F" (Food)
n_food <- sum(d$ProductFamily == "F")

# Tổng số quan sát
n_total <- nrow(d)

# Tính khoảng tin cậy  
prop.test(n_food, n_total, correct = FALSE)
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_food out of n_total, null probability 0.5
## X-squared = 14059, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.0000000000 0.0002731638
## sample estimates:
## p 
## 0

Với độ tin cậy 95% cho tỷ lệ quan sát được là từ 0.0000 đến 0.00027, nghĩa là tỷ lệ khách hàng thuộc nhóm sản phẩm Food gần như bằng 0 trong mẫu dữ liệu.

Kiểm định giả thuyết

Đặt giả thuyết:

  • \(H_0\): Tỷ lệ sản phẩm thuộc nhóm “Food” = 0.7

  • \(H_1\): Tỷ lệ sản phẩm thuộc nhóm “Food” ≥ 0.7

prop.test(n_food, n_total, p=0.7, correct = FALSE)  
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_food out of n_total, null probability 0.7
## X-squared = 32804, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.7
## 95 percent confidence interval:
##  0.0000000000 0.0002731638
## sample estimates:
## p 
## 0

Kiểm định tỷ lệ một mẫu được thực hiện nhằm đánh giá xem tỷ lệ thực tế khách hàng thuộc nhóm ProductFamily = “F” (Food) có khác biệt đáng kể so với tỷ lệ giả định là 0.7 hay không. Kết quả kiểm định cho thấy giá trị Chi-squared = 32,804, với 1 bậc tự do và p-value < 2.2e-16, cực kỳ nhỏ so với mức ý nghĩa 5%. Do đó, ta bác bỏ giả thuyết H₀, tức là giả thuyết cho rằng tỷ lệ thực tế bằng 0.7.

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

4.1. Biến Gender và MaritalStatus

4.1.1. Bảng tần suất chéo

# Bảng tần suất chéo
tab1 <- table(d$Gender, d$MaritalStatus)
prop1 <- prop.table(tab1, margin = 1)  # Tỷ lệ theo hàng

# In bảng tần suất và tỷ lệ
cat("Bảng tần suất:\n"); print(tab1)
## Bảng tần suất:
##    
##        M    S
##   F 3602 3568
##   M 3264 3625
cat("\nTỷ lệ theo hàng:\n"); print(round(prop1, 3))
## 
## Tỷ lệ theo hàng:
##    
##         M     S
##   F 0.502 0.498
##   M 0.474 0.526

4.1.2. Trực quan hóa

ggplot(d, aes(x = Gender, fill = MaritalStatus)) +
  geom_bar(position = "fill", color = "black") +
  labs(title = "Phân bố Tình trạng hôn nhân theo Giới tính", x = "Gender", y = "Tỷ lệ", fill = " MaritalStatus") +
  theme_minimal() +
   theme(axis.text.x = element_text(angle = 45, hjust = 1)) 

Nhận xét: Biểu đồ cột chồng giữa hai biến Gender (giới tính) và MaritalStatus (tình trạng hôn nhân) cho thấy sự phân bố số lượng cá nhân theo từng giới tính và tình trạng hôn nhân tương ứng. Cả hai nhóm giới tính đều có cơ cấu tình trạng hôn nhân khá đồng đều, khi phần màu đại diện cho người đã kết hôn (M - Married) và người độc thân (S - Single) gần như chia đều trong mỗi cột. Điều này gợi ý rằng không có sự khác biệt rõ ràng trong tình trạng hôn nhân giữa các giới, tức là giới tính không ảnh hưởng đáng kể đến việc một người đã kết hôn hay còn độc thân.

4.1.3. Kiểm định Thống kê (Kiểm định Chi-bình phương)

Giả thuyết kiểm định:

  • \(H_0\):: Giới tính và tình trạng hôn nhân là hai biến độc lập.

  • \(H_1\):: Giới tính và tình trạng hôn nhân có liên quan.

Thực hiện kiểm định Chi-bình phương

chi_test <- chisq.test(tab1)
chi_test
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tab1
## X-squared = 11.365, df = 1, p-value = 0.0007485

Kết quả kiểm định cho thấy giá trị Chi-squared là 11.365 với 1 bậc tự do và giá trị p tương ứng là 0.0007485. Với mức ý nghĩa 5%, do p-value nhỏ hơn 0.05, ta bác bỏ giả thuyết H₀, tức là giả thuyết cho rằng giới tính và tình trạng hôn nhân độc lập với nhau. Điều này cho thấy có mối quan hệ có ý nghĩa thống kê giữa giới tính và tình trạng hôn nhân trong tập dữ liệu khảo sát. Nói cách khác, sự khác biệt trong giới tính có liên quan đến sự khác biệt trong tình trạng hôn nhân, và mối quan hệ này không phải do ngẫu nhiên.

4.2. Biến ProductFamily và StateorProvince

4.2.1. Bảng tần suất chéo

# Bảng tần suất chéo
tab2 <- table(d$ProductFamily, d$StateorProvince)
prop2 <- prop.table(tab2, margin = 1)  # Tỷ lệ theo hàng

# In bảng tần suất và tỷ lệ
cat("Bảng tần suất (ProductFamily vs StateOrProvince):\n"); print(tab2)
## Bảng tần suất (ProductFamily vs StateOrProvince):
##                 
##                    BC   CA   DF Guerrero Jalisco   OR Veracruz   WA Yucatan
##   Drink            69  258   65       41       5  199       44  399      48
##   Food            580 1974  598      272      57 1629      322 3287     494
##   Non-Consumable  160  501  152       70      13  434       98  881     112
##                 
##                  Zacatecas
##   Drink                122
##   Food                 940
##   Non-Consumable       235
cat("\nTỷ lệ theo hàng:\n"); print(round(prop2, 3))
## 
## Tỷ lệ theo hàng:
##                 
##                     BC    CA    DF Guerrero Jalisco    OR Veracruz    WA
##   Drink          0.055 0.206 0.052    0.033   0.004 0.159    0.035 0.319
##   Food           0.057 0.194 0.059    0.027   0.006 0.160    0.032 0.324
##   Non-Consumable 0.060 0.189 0.057    0.026   0.005 0.163    0.037 0.332
##                 
##                  Yucatan Zacatecas
##   Drink            0.038     0.098
##   Food             0.049     0.093
##   Non-Consumable   0.042     0.088

4.2.2. Trực quan hóa

# Vẽ biểu đồ cột chồng
ggplot(d, aes(x = StateorProvince, fill = ProductFamily)) +
  geom_bar(position = "fill", color = "black") +
  scale_fill_brewer(palette = "Set2") +  
  labs(
    title = "Phân bố các nhóm sản phẩm theo bang/tỉnh",
    x = "Tỉnh/Bang",
    y = "Số lượng",
    fill = "Dòng sản phẩm"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) 

Nhận xét: Nhóm sản phẩm “Food” chiếm tỷ lệ lớn nhất tại tất cả các bang/tỉnh, dao động khoảng từ 70% đến 75%. Điều này cho thấy nhóm thực phẩm là sản phẩm chủ lực và phổ biến nhất trên toàn bộ các khu vực.

Nhóm “Non-Consumable” (phi tiêu dùng) có tỷ lệ tương đối ổn định, khoảng 20–25% ở hầu hết các bang, cho thấy vai trò thứ hai trong cơ cấu sản phẩm, không quá vượt trội nhưng vẫn giữ vị trí quan trọng.

Nhóm “Drink” (đồ uống) chiếm tỷ trọng nhỏ nhất trong cả ba nhóm sản phẩm, với tỷ lệ dưới 10% tại tất cả các bang. Tuy nhiên, tỷ lệ này có sự dao động nhẹ giữa các khu vực, ví dụ như BC, Veracruz hay Yucatán có tỷ lệ Drink cao hơn một chút so với các bang còn lại.

Không có sự khác biệt quá rõ rệt giữa các bang, cho thấy sự đồng đều trong cơ cấu phân phối sản phẩm giữa các khu vực, mặc dù vẫn có những chênh lệch nhẹ ở từng nhóm.

4.2.3. Kiểm định Chi-bình phương

Giả thuyết kiểm định:

  • \(H_0\): ProductFamily và StateorProvince là hai biến độc lập.

  • \(H_1\): ProductFamily và StateorProvince có liên quan.

Thực hiện kiểm định Chi-bình phương

chi_test <- chisq.test(tab2)
chi_test
## 
##  Pearson's Chi-squared test
## 
## data:  tab2
## X-squared = 12.3, df = 18, p-value = 0.8314

Kết quả kiểm định cho thấy giá trị Chi-squared là 12.3 với 18 bậc tự do và giá trị p là 0.8314. Với mức ý nghĩa thông thường là 5%, do p-value lớn hơn 0.05, ta không bác bỏ giả thuyết H₀, tức là giả thuyết cho rằng StateorProvince và ProductFamily là độc lập với nhau. Nói cách khác, không có bằng chứng thống kê để khẳng định rằng việc phân phối các nhóm sản phẩm có sự khác biệt đáng kể giữa các bang hoặc tỉnh. Mối quan hệ (nếu có) giữa hai biến này có thể là do yếu tố ngẫu nhiên.

4.3. Biến AnnualIncome và Homeowner

4.3.1. Bảng tần suất chéo

# Bảng tần suất chéo
tab3 <- table(d$AnnualIncome, d$Homeowner)
prop3 <- prop.table(tab3, margin = 1)  # Tỷ lệ theo hàng

# In bảng tần suất và tỷ lệ
cat("Bảng tần suất (AnnualIncome vs Homeowner):\n"); print(tab3)
## Bảng tần suất (AnnualIncome vs Homeowner):
##                
##                    N    Y
##   $10K - $30K   1359 1731
##   $110K - $130K  119  524
##   $130K - $150K  136  624
##   $150K +         48  225
##   $30K - $50K   2087 2514
##   $50K - $70K   1063 1307
##   $70K - $90K    686 1023
##   $90K - $110K   117  496
cat("\nTỷ lệ theo hàng:\n"); print(round(prop3, 3))
## 
## Tỷ lệ theo hàng:
##                
##                     N     Y
##   $10K - $30K   0.440 0.560
##   $110K - $130K 0.185 0.815
##   $130K - $150K 0.179 0.821
##   $150K +       0.176 0.824
##   $30K - $50K   0.454 0.546
##   $50K - $70K   0.449 0.551
##   $70K - $90K   0.401 0.599
##   $90K - $110K  0.191 0.809

4.3.2. Trực quan hóa

# Vẽ biểu đồ cột chồng
ggplot(data = d, aes(x = AnnualIncome, fill = Homeowner)) +
  geom_bar(position = "fill", color = "black") +
  scale_fill_brewer(palette = "Set3") +  
  labs(
    title = "Biểu đồ cột chồng: AnnualIncome vs Homeowner",
    x = "Thu nhập hàng năm",
    y = "Số lượng",
    fill = "Chủ sở hữu nhà"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét: Biểu đồ cột chồng thể hiện mối quan hệ giữa thu nhập hàng năm (Annual Income) và tình trạng sở hữu nhà (Homeowner). Các cột được chia thành hai phần: người sở hữu nhà (Y - màu xanh) và không sở hữu nhà (N - màu đỏ).

Một số nhận xét nổi bật từ biểu đồ:

Nhóm thu nhập $30K - $50K có số lượng người cao nhất, trong đó phần lớn là người sở hữu nhà, cho thấy đây là mức thu nhập phổ biến và đủ khả năng để sở hữu nhà.

Nhóm thu nhập $10K - $30K cũng có số lượng lớn, nhưng tỷ lệ người không sở hữu nhà cao hơn so với nhóm trên, phản ánh khả năng tài chính hạn chế trong việc sở hữu nhà.

Ở các nhóm thu nhập cao hơn ($110K trở lên), số lượng người giảm đáng kể. Tuy nhiên, đa số họ đã sở hữu nhà, cho thấy mối liên hệ giữa thu nhập cao và khả năng sở hữu tài sản.

Đặc biệt, ở nhóm $150K+, dù số lượng ít nhưng gần như tất cả đều là chủ sở hữu nhà, phù hợp với kỳ vọng rằng thu nhập cao gắn liền với khả năng sở hữu bất động sản.

Ngược lại, ở nhóm $50K - $70K và $70K - $90K, tỷ lệ sở hữu nhà và không sở hữu nhà tương đối cân bằng, cho thấy đây là mức thu nhập “chuyển tiếp” giữa hai nhóm đối tượng.

Tóm lại, biểu đồ cho thấy xu hướng rõ ràng: thu nhập càng cao thì tỷ lệ sở hữu nhà càng lớn, đồng thời mức thu nhập trung bình ($30K - $50K) là phổ biến nhất trong dân số khảo sát.

4.3.3. Kiểm định Chi-bình phương

Giả thuyết kiểm định:

  • \(H_0\): AnnualIncome và Homeowner là hai biến độc lập.

  • \(H_1\): AnnualIncome và Homeowner có liên quan.

Thực hiện kiểm định Chi-bình phương

chi_test <- chisq.test(tab3)
chi_test
## 
##  Pearson's Chi-squared test
## 
## data:  tab3
## X-squared = 546.37, df = 7, p-value < 2.2e-16

Kết quả kiểm định cho thấy giá trị Chi-squared là 546.37 với 7 bậc tự do và giá trị p rất nhỏ, nhỏ hơn 2.2e-16. Với mức ý nghĩa 5%, do p-value < 0.05, ta bác bỏ giả thuyết H₀, tức là giả thuyết cho rằng hai biến này độc lập với nhau. Điều này cho thấy có mối quan hệ có ý nghĩa thống kê giữa mức thu nhập và tình trạng sở hữu nhà ở trong tập dữ liệu khảo sát. Nói cách khác, sự khác biệt trong thu nhập hàng năm có liên quan đến khả năng sở hữu nhà ở của cá nhân.

V. Tổng kết và thảo luận

5.1. Tóm tắt những phát hiện chính

Phân tích các biến định tính cho thấy một số đặc điểm nổi bật về khách hàng và hành vi mua sắm. Cụ thể, có sự khác biệt rõ rệt giữa các nhóm giới tính và tình trạng hôn nhân, cho thấy những đặc điểm nhân khẩu học có thể ảnh hưởng đến hành vi tiêu dùng. Bên cạnh đó, mối liên hệ giữa quốc gia và việc sở hữu nhà cho thấy xu hướng sở hữu nhà ở Mỹ cao hơn so với các quốc gia khác. Điều này có thể phản ánh mức sống, thu nhập hoặc chính sách nhà ở khác biệt giữa các quốc gia. Ngoài ra, sự phân bố giữa các thành phố và bang (StateOrProvince) cho thấy hoạt động mua sắm tập trung nhiều ở một số khu vực nhất định, phản ánh tiềm năng thị trường không đồng đều.

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

Một số hạn chế đáng chú ý bao gồm: chất lượng dữ liệu có thể chưa đồng nhất, có khả năng tồn tại sai sót trong ghi chép hoặc thiếu dữ liệu. Việc chỉ phân tích các biến định tính không cho phép đánh giá mức độ tác động định lượng giữa các yếu tố. Hơn nữa, một số hạng mục con có kích thước mẫu nhỏ, khiến kết luận có thể chưa đủ mạnh. Ngoài ra, không có dữ liệu định lượng như thu nhập, chi tiêu hay tần suất mua sắm để đánh giá sâu hơn về hành vi tiêu dùng.

5.3. Đề xuất

Từ các phát hiện, doanh nghiệp có thể cá nhân hóa chiến lược marketing dựa trên đặc điểm nhân khẩu học như giới tính, tình trạng hôn nhân và khu vực địa lý. Ví dụ, các chiến dịch quảng bá nhà ở có thể tập trung mạnh hơn vào thị trường Mỹ. Đồng thời, phân bổ nguồn lực phù hợp hơn cho những khu vực có số lượng khách hàng tiềm năng cao. Việc phân nhóm khách hàng theo đặc điểm định tính cũng có thể hỗ trợ phân loại sản phẩm hiệu quả hơn.

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

Nếu có thêm thời gian và dữ liệu, có thể mở rộng phân tích bằng cách kết hợp với các biến định lượng như thu nhập, chi tiêu hàng tháng hoặc lịch sử mua hàng để hiểu sâu hơn về hành vi tiêu dùng. Ngoài ra, một câu hỏi quan trọng là liệu các đặc điểm nhân khẩu học có ảnh hưởng đến loại sản phẩm khách hàng mua hay không? Một hướng nghiên cứu khác là xem xét sự thay đổi hành vi tiêu dùng theo thời gian hoặc theo mùa để hỗ trợ dự báo nhu cầu hiệu quả hơn.