Bộ dữ liệu được sử dụng trong báo cáo này bao gồm thông tin của 3.900 cá nhân, phản ánh một số đặc điểm nhân khẩu học và hành vi mua sắm cơ bản của người tiêu dùng. Các biến trong dữ liệu bao gồm giới tính (Gender), nhóm tuổi (Age Group). Đặc biệt, dữ liệu còn ghi nhận trạng thái đăng ký thành viên (Subscription Status) – một chỉ báo quan trọng liên quan đến mức độ gắn kết của khách hàng với hệ thống bán lẻ.
#Đọc dữ liệu
a <- read.csv("C:/Users/Admin/Desktop/Shopping_Habit.csv",
header = TRUE, sep = ",")
#cấu trúc của dữ liệu
str(a)
## 'data.frame': 3900 obs. of 18 variables:
## $ Customer.ID : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Age : int 55 19 50 21 45 46 63 27 26 57 ...
## $ Gender : chr "Male" "Male" "Male" "Male" ...
## $ Item.Purchased : chr "Blouse" "Sweater" "Jeans" "Sandals" ...
## $ Category : chr "Clothing" "Clothing" "Clothing" "Footwear" ...
## $ Purchase.Amount..USD. : int 53 64 73 90 49 20 85 34 97 31 ...
## $ Location : chr "Kentucky" "Maine" "Massachusetts" "Rhode Island" ...
## $ Size : chr "L" "L" "S" "M" ...
## $ Color : chr "Gray" "Maroon" "Maroon" "Maroon" ...
## $ Season : chr "Winter" "Winter" "Spring" "Spring" ...
## $ Review.Rating : num 3.1 3.1 3.1 3.5 2.7 2.9 3.2 3.2 2.6 4.8 ...
## $ Subscription.Status : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Shipping.Type : chr "Express" "Express" "Free Shipping" "Next Day Air" ...
## $ Discount.Applied : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Promo.Code.Used : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Previous.Purchases : int 14 2 23 49 31 14 49 19 8 4 ...
## $ Payment.Method : chr "Venmo" "Cash" "Credit Card" "PayPal" ...
## $ Frequency.of.Purchases: chr "Fortnightly" "Fortnightly" "Weekly" "Weekly" ...
Bộ dữ liệu thực hành gồm 3900 quan sát, trong đó bao gồm 18 biến. Cụ thể như sau:
CustomerID: Mã định danh duy nhất của khách hàng, dùng để theo dõi và phân biệt từng cá nhân trong cơ sở dữ liệu, hỗ trợ phân tích hành vi khách hàng.
Age: Thể hiện độ tuổi – dùng để phân khúc khách hàng và xây dựng chiến lược marketing theo độ tuổi.
Gender: Giới tính của khách hàng (ví dụ: Nam, Nữ), giúp đánh giá sự khác biệt trong sở thích mua sắm giữa các nhóm giới tính.
Item Purchased: Tên sản phẩm cụ thể khách hàng đã chọn trong lần mua.
Category: Nhóm sản phẩm lớn hơn (như điện tử, quần áo…) giúp phân loại và phân tích xu hướng tiêu dùng.
Purchase Amount (USD): Giá trị tiền tệ của giao dịch, dùng để phân tích chi tiêu.
Location: Vị trí nơi mua hàng – giúp theo dõi thói quen theo vùng miền.
Size: Kích thước của sản phẩm (áp dụng với quần áo, giày dép…)
Color: Màu sắc sản phẩm, Tùy chọn màu của sản phẩm, phản ánh thị hiếu màu sắc.
Season: Mùa liên quan đến sản phẩm (xuân/hạ/thu/đông), ảnh hưởng đến chiến lược tồn kho và tiếp thị.
Review Rating: Đánh giá từ khách hàng.
Subscription Status: Trạng thái đăng ký, Khách hàng có sử dụng dịch vụ đăng ký không, thể hiện mức độ trung thành.
Shipping Type: Loại hình vận chuyển.
Discount Applied: Có áp dụng giảm giá không.
Promo Code Used: Cho biết khách hàng có dùng mã ưu đãi trong giao dịch hay không.
Previous Purchases: Số lượng lần mua trong quá khứ.
Payment Method: Phương thức thanh toán.
Frequency of Purchases: Tần suất mua hàng.
head(a)#Hiển thị một vài dòng đầu
tail(a)#Hiển thị một vài dòng cuối
Kết quả trên hiển thị 6 dòng đầu và 6 dòng cuối của dữ liệu.
# Chọn các biến định tính
a1 <- c("Gender","Item.Purchased", "Category","Location", "Size", "Color", "Season",
"Subscription.Status", "Discount.Applied", "Promo.Code.Used", "Payment.Method" , "Frequency.of.Purchases" )
print(a1)
## [1] "Gender" "Item.Purchased" "Category"
## [4] "Location" "Size" "Color"
## [7] "Season" "Subscription.Status" "Discount.Applied"
## [10] "Promo.Code.Used" "Payment.Method" "Frequency.of.Purchases"
# Tạo bộ dữ liệu mới chỉ chứa các biến định tính
b <- a[, a1]
str(b)
## 'data.frame': 3900 obs. of 12 variables:
## $ Gender : chr "Male" "Male" "Male" "Male" ...
## $ Item.Purchased : chr "Blouse" "Sweater" "Jeans" "Sandals" ...
## $ Category : chr "Clothing" "Clothing" "Clothing" "Footwear" ...
## $ Location : chr "Kentucky" "Maine" "Massachusetts" "Rhode Island" ...
## $ Size : chr "L" "L" "S" "M" ...
## $ Color : chr "Gray" "Maroon" "Maroon" "Maroon" ...
## $ Season : chr "Winter" "Winter" "Spring" "Spring" ...
## $ Subscription.Status : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Discount.Applied : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Promo.Code.Used : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Payment.Method : chr "Venmo" "Cash" "Credit Card" "PayPal" ...
## $ Frequency.of.Purchases: chr "Fortnightly" "Fortnightly" "Weekly" "Weekly" ...
Trong phạm vi bài làm này, chỉ thực hiện thao tác với các biến định tính bao gồm: Gender, Item Purchase, Category, Location, Size, Color, Season, Subscription Status”, Discount Applied, Promo CodeUsed, Payment Method , Frequency of Purchases.
Tiếp theo, em tiến hành Kiểm tra xem có giá trị thiếu (NA) trong các cột định tính hay không.
#Kiểm tra xem có giá trị thiếu (NA) trong các cột định tính
colSums(is.na(b))
## Gender Item.Purchased Category
## 0 0 0
## Location Size Color
## 0 0 0
## Season Subscription.Status Discount.Applied
## 0 0 0
## Promo.Code.Used Payment.Method Frequency.of.Purchases
## 0 0 0
Tất cả các cột định tính trong dataframe b đều có giá trị 0 cho số lượng giá trị thiếu (NA). Điều này có nghĩa là không có giá trị NA trong các cột định tính của bộ dữ liệu b.
Trước khi tiến hành các phân tích thống kê, việc chuyển đổi các biến định tính từ kiểu ký tự (character) sang kiểu phân loại (factor) là cần thiết nhằm đảm bảo rằng các hàm thống kê và mô hình phân tích sẽ xử lý chúng đúng cách. Trong R, các biến factor không chỉ giúp biểu diễn dữ liệu phân loại một cách chính xác hơn mà còn tối ưu hóa hiệu suất tính toán và cho phép áp dụng các phương pháp phân tích định tính như kiểm định Chi-bình phương hay mô hình hồi quy phân loại. Việc kiểm tra và xử lý kiểu dữ liệu phù hợp là bước tiền xử lý quan trọng, góp phần đảm bảo tính chính xác và hiệu quả của toàn bộ quy trình phân tích.
# Kiểm tra từng cột trong dataframe b
sapply(b, is.factor)
## Gender Item.Purchased Category
## FALSE FALSE FALSE
## Location Size Color
## FALSE FALSE FALSE
## Season Subscription.Status Discount.Applied
## FALSE FALSE FALSE
## Promo.Code.Used Payment.Method Frequency.of.Purchases
## FALSE FALSE FALSE
Kết quả là FALSE, vậy các biến cần thiết không phải kiểu factor. Vì vậy, bước tiếp t sẽ thực hiện Chuyển đổi các cột character sang factor.
# Chuyển đổi các cột character sang factor
b$Gender <- as.factor(b$Gender)
b$Item.Purchased <- as.factor(b$Item.Purchased)
b$Category <- as.factor(b$Category)
b$Location <- as.factor(b$Location)
b$Size <- as.factor(b$Size)
b$Color <- as.factor(b$Color)
b$Season <- as.factor(b$Season)
b$Subscription.Status <- as.factor(b$Subscription.Status)
b$Discount.Applied<- as.factor(b$Discount.Applied)
b$Promo.Code.Used<- as.factor(b$Promo.Code.Used)
b$Payment.Method<- as.factor(b$Payment.Method)
b$Frequency.of.Purchases<- as.factor(b$Frequency.of.Purchases)
#kiểm tra lại
sapply(b, is.factor)
## Gender Item.Purchased Category
## TRUE TRUE TRUE
## Location Size Color
## TRUE TRUE TRUE
## Season Subscription.Status Discount.Applied
## TRUE TRUE TRUE
## Promo.Code.Used Payment.Method Frequency.of.Purchases
## TRUE TRUE TRUE
Tất cả các biến sau khi chuyển đổi đều cho kết quả TRUE, nghĩa là việc chuyển đổi thành công và các biến đã sẵn sàng cho phân tích thống kê phù hợp với bản chất định tính của chúng. Điều này đảm bảo độ chính xác và hiệu quả khi áp dụng các phương pháp thống kê phân tích dữ liệu định tính trong các bước tiếp theo.
# Tính tần số và tần suất
Gender_freq <- table(b$Gender)
Gender_prop <- table(b$Gender) / sum(nrow(b))
print(Gender_freq)
##
## Female Male
## 1248 2652
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo dataframe cho bảng
table_data <- data.frame(
`Giới tính` = c("Nữ", "Nam"),
`Tần số` = as.numeric(Gender_freq),
`Tần suất (%)` = round(Gender_prop * 100, 2)
)
colnames(table_data) <- c("Giới tính", "Tần số", "Kí hiệu", "Tần suất (%)")
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Giới tính | Tần số | Kí hiệu | Tần suất (%) |
|---|---|---|---|
| Nữ | 1248 | Female | 32 |
| Nam | 2652 | Male | 68 |
Kết quả cho thấy sự phân phối khá cân đối giữa các nhóm. Cụ thể, tỷ lệ khách hàng nam và nữ chênh lệch khá lớn, với nữ chiếm 0.32 và nam chiếm 0.68, chỉ chênh lệch khoảng -0.36.
# Tạo biểu đồ cột và lưu vị trí
bar_positions <- barplot(Gender_freq,
main = "Phân phối khách hàng theo giới tính",
xlab = "Giới tính",
ylab = "Số lượng giao dịch",
col = c("#CC99FF", "#FFFF33"),
names.arg = c("Nữ", "Nam"),
ylim = c(0, max(Gender_freq) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions,
y = Gender_freq + 500, # Tăng khoảng cách nhãn lên 500 để hiển thị rõ
labels = Gender_freq, # Giá trị tần suất
pos = 3, # Đặt nhãn phía trên cột
col = "black", # Màu chữ đen
cex = 1.2) # Kích thước chữ lớn hơn
Biểu đồ cột mang tên “Phân phối khách hàng theo giới tính” được trình bày ở trên cung cấp một cái nhìn sơ bộ về sự phân bố số lượng giao dịch theo hai nhóm giới tính. Cụ thể, nam giới chiếm 68% tổng số giao dịch, trong khi nữ giới chỉ chiếm 32%. Điều này cho thấy nam giới là nhóm khách hàng chính, có xu hướng mua sắm nhiều hơn hoặc xuất hiện nhiều hơn trong tập dữ lu. Sự chênh lệch này có thể phản ánh đặc điểm của thị trường mục tiêu, chiến lược tiếp thị hiện tại. Do đó, doanh nghiệp nên xem xét lý do dẫn đến sự mất cân đối này và cân nhắc các chiến lược tiếp cận nhóm khách hàng nữ để mở rộng thị phần và tăng trưởng doanh thu hiệu quả hơn.
# Tính tần số và tần suất
Item.Purchase_freq <- table(b$Item.Purchased)
Item.Purchase_prop <- table(b$Item.Purchased) / sum(nrow(b))
# Tính tần số và tần suất
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo dataframe cho bảng
# Tạo dataframe cho bảng
table_data2 <- data.frame(
`Tình trạng` = names(Item.Purchase_freq),
`Tần số` = as.numeric(Item.Purchase_freq),
`Tần suất (%)` = round(Item.Purchase_prop * 100, 2)
)
colnames(table_data2) <- c("Mặt hàng","Tần số","Mặt hàng", "Tần suất (%)")
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data2, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Mặt hàng | Tần số | Mặt hàng | Tần suất (%) |
|---|---|---|---|
| Backpack | 143 | Backpack | 3.67 |
| Belt | 161 | Belt | 4.13 |
| Blouse | 171 | Blouse | 4.38 |
| Boots | 144 | Boots | 3.69 |
| Coat | 161 | Coat | 4.13 |
| Dress | 166 | Dress | 4.26 |
| Gloves | 140 | Gloves | 3.59 |
| Handbag | 153 | Handbag | 3.92 |
| Hat | 154 | Hat | 3.95 |
| Hoodie | 151 | Hoodie | 3.87 |
| Jacket | 163 | Jacket | 4.18 |
| Jeans | 124 | Jeans | 3.18 |
| Jewelry | 171 | Jewelry | 4.38 |
| Pants | 171 | Pants | 4.38 |
| Sandals | 160 | Sandals | 4.10 |
| Scarf | 157 | Scarf | 4.03 |
| Shirt | 169 | Shirt | 4.33 |
| Shoes | 150 | Shoes | 3.85 |
| Shorts | 157 | Shorts | 4.03 |
| Skirt | 158 | Skirt | 4.05 |
| Sneakers | 145 | Sneakers | 3.72 |
| Socks | 159 | Socks | 4.08 |
| Sunglasses | 161 | Sunglasses | 4.13 |
| Sweater | 164 | Sweater | 4.21 |
| T-shirt | 147 | T-shirt | 3.77 |
# Tạo biểu đồ cột và lưu vị trí
bar_positions2 <- barplot(Item.Purchase_freq,
main = "Phân phối khách hàng theo mặt hàng đã mua",
xlab = "Mặt hàng",
ylab = "Số lượng giao dịch",
col = c("#99FFFF", "#CCCCFF"),
names.arg = names(Item.Purchase_freq),
ylim = c(0, max(Item.Purchase_freq) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions2,
y = Item.Purchase_freq + 500, # Tăng khoảng cách nhãn lên 500 để hiển thị rõ
labels = Item.Purchase_freq, # Giá trị tần suất
pos = 3, # Đặt nhãn phía trên cột
col = "black", # Màu chữ đen
cex = 1.2) # Kích thước chữ lớn hơn
Kết quả trên cho thấy sự phân bố tương đối đồng đều giữa các mặt hàng thời trang. Các mặt hàng như Jewelry, Pants và Blouse có tần suất cao nhất (4.38%), cho thấy chúng được ưa chuộng nhiều hơn. Shirt và Dress cũng có tỷ lệ mua cao (trên 4.2%). Ngược lại, các sản phẩm như Jeans, Gloves và Backpack có tần suất thấp hơn (dưới 3.7%), cho thấy nhu cầu ít hơn. Nhìn chung, không có mặt hàng nào chiếm tỷ lệ vượt trội, phản ánh sự đa dạng trong sở thích tiêu dùng của khách hàng. Điều này gợi ý rằng doanh nghiệp nên duy trì danh mục sản phẩm phong phú để đáp ứng các nhu cầu khác nhau của thị trường.
# Tính tần số và tần suất
category_freq <- table(b$Category)
category_prop <- table(b$Category) / sum(nrow(b))
print(category_freq)
##
## Accessories Clothing Footwear Outerwear
## 1240 1737 599 324
# Tạo dataframe cho bảng
table_data3 <- data.frame(
`Danh mục` = names(category_freq),
`Tần số` = as.numeric(category_freq),
`Tần suất (%)` = round(category_prop * 100, 2)
)
colnames(table_data3) <- c("Danh mục", "Tần số", "Danh mục", "Tần suất (%)")
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data3, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Danh mục | Tần số | Danh mục | Tần suất (%) |
|---|---|---|---|
| Accessories | 1240 | Accessories | 31.79 |
| Clothing | 1737 | Clothing | 44.54 |
| Footwear | 599 | Footwear | 15.36 |
| Outerwear | 324 | Outerwear | 8.31 |
# Tạo bảng màu (đủ cho số danh mục)
num_categories <- length(category_freq)
colors <- c("#0066CC", "#00CC99", "#FF6666", "#FFCC00")[1:num_categories] # Chọn màu đủ
# Tạo biểu đồ cột và lưu vị trí
bar_positions3 <- barplot(category_freq,
main = "Phân phối khách hàng theo danh mục sản phẩm", # Thêm main =
xlab = "Danh mục sản phẩm",
ylab = "Số lượng giao dịch",
col = colors, # Biến colors đã định nghĩa
names.arg = names(category_freq), # Sử dụng tên danh mục
ylim = c(0, max(category_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions3,
y = category_freq + max(category_freq, na.rm = TRUE) * 0.05, # Khoảng cách động
labels = category_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 1.2) # Kích thước chữ
Kết quả cho thấy Clothing (Trang phục) là danh mục được ưa chuộng nhất, chiếm 44.54% tổng số giao dịch. Điều này phản ánh xu hướng tiêu dùng tập trung mạnh vào các sản phẩm cơ bản và thiết yếu. Accessories (Phụ kiện) đứng thứ hai với 31.79%, cho thấy vai trò quan trọng của các mặt hàng bổ trợ trong hành vi mua sắm của khách hàng. Trong khi đó, Footwear (Giày dép) và Outerwear (Áo khoác, áo choàng) lần lượt chiếm 15.36% và 8.31%, có thể do ảnh hưởng bởi yếu tố thời tiết, nhu cầu theo mùa hoặc mức giá cao hơn. Nhìn chung, hơn 76% các sản phẩm được mua thuộc về nhóm Clothing và Accessories.
# Tính tần số và tần suất
Location_freq <- table(b$Location)
Location_prop <- table(b$Location) / sum(nrow(b))
print(Location_freq)
##
## Alabama Alaska Arizona Arkansas California
## 89 72 65 79 95
## Colorado Connecticut Delaware Florida Georgia
## 75 78 86 68 79
## Hawaii Idaho Illinois Indiana Iowa
## 65 93 92 79 69
## Kansas Kentucky Louisiana Maine Maryland
## 63 79 84 77 86
## Massachusetts Michigan Minnesota Mississippi Missouri
## 72 73 88 80 81
## Montana Nebraska Nevada New Hampshire New Jersey
## 96 87 87 71 67
## New Mexico New York North Carolina North Dakota Ohio
## 81 87 78 83 77
## Oklahoma Oregon Pennsylvania Rhode Island South Carolina
## 75 74 74 63 76
## South Dakota Tennessee Texas Utah Vermont
## 70 77 77 71 85
## Virginia Washington West Virginia Wisconsin Wyoming
## 77 73 81 75 71
# Tạo dataframe cho bảng
table_data4 <- data.frame(
`Địa điểm` = names(Location_freq),
`Tần số` = as.numeric(Location_freq),
`Tần suất (%)` = round(Location_prop * 100, 2)
)
colnames(table_data4) <- c("Địa điểm", "Tần số", "Địa điểm", "Tần suất (%)")
# Tạo bảng kẻ
# Tạo bảng kẻ
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
library(knitr)
library(kableExtra)
kable(table_data4, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Địa điểm | Tần số | Địa điểm | Tần suất (%) |
|---|---|---|---|
| Alabama | 89 | Alabama | 2.28 |
| Alaska | 72 | Alaska | 1.85 |
| Arizona | 65 | Arizona | 1.67 |
| Arkansas | 79 | Arkansas | 2.03 |
| California | 95 | California | 2.44 |
| Colorado | 75 | Colorado | 1.92 |
| Connecticut | 78 | Connecticut | 2.00 |
| Delaware | 86 | Delaware | 2.21 |
| Florida | 68 | Florida | 1.74 |
| Georgia | 79 | Georgia | 2.03 |
| Hawaii | 65 | Hawaii | 1.67 |
| Idaho | 93 | Idaho | 2.38 |
| Illinois | 92 | Illinois | 2.36 |
| Indiana | 79 | Indiana | 2.03 |
| Iowa | 69 | Iowa | 1.77 |
| Kansas | 63 | Kansas | 1.62 |
| Kentucky | 79 | Kentucky | 2.03 |
| Louisiana | 84 | Louisiana | 2.15 |
| Maine | 77 | Maine | 1.97 |
| Maryland | 86 | Maryland | 2.21 |
| Massachusetts | 72 | Massachusetts | 1.85 |
| Michigan | 73 | Michigan | 1.87 |
| Minnesota | 88 | Minnesota | 2.26 |
| Mississippi | 80 | Mississippi | 2.05 |
| Missouri | 81 | Missouri | 2.08 |
| Montana | 96 | Montana | 2.46 |
| Nebraska | 87 | Nebraska | 2.23 |
| Nevada | 87 | Nevada | 2.23 |
| New Hampshire | 71 | New Hampshire | 1.82 |
| New Jersey | 67 | New Jersey | 1.72 |
| New Mexico | 81 | New Mexico | 2.08 |
| New York | 87 | New York | 2.23 |
| North Carolina | 78 | North Carolina | 2.00 |
| North Dakota | 83 | North Dakota | 2.13 |
| Ohio | 77 | Ohio | 1.97 |
| Oklahoma | 75 | Oklahoma | 1.92 |
| Oregon | 74 | Oregon | 1.90 |
| Pennsylvania | 74 | Pennsylvania | 1.90 |
| Rhode Island | 63 | Rhode Island | 1.62 |
| South Carolina | 76 | South Carolina | 1.95 |
| South Dakota | 70 | South Dakota | 1.79 |
| Tennessee | 77 | Tennessee | 1.97 |
| Texas | 77 | Texas | 1.97 |
| Utah | 71 | Utah | 1.82 |
| Vermont | 85 | Vermont | 2.18 |
| Virginia | 77 | Virginia | 1.97 |
| Washington | 73 | Washington | 1.87 |
| West Virginia | 81 | West Virginia | 2.08 |
| Wisconsin | 75 | Wisconsin | 1.92 |
| Wyoming | 71 | Wyoming | 1.82 |
# Tạo bảng màu (đủ cho số địa điểm)
num_locations <- length(Location_freq)
colors <- rainbow(num_locations, s = 0.6) # Tạo màu động, nhạt hơn để dễ nhìn
# Tạo biểu đồ cột và lưu vị trí
bar_positions4 <- barplot(Location_freq,
main = "Phân phối khách hàng theo địa điểm",
xlab = "Địa điểm",
ylab = "Số lượng giao dịch",
col = colors,
names.arg = names(Location_freq), # Sử dụng tên địa điểm
las = 2, # Xoay nhãn trục x 90 độ để tránh chồng lấn
cex.names = 0.6, # Giảm kích thước nhãn vì nhiều địa điểm
ylim = c(0, max(Location_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions4,
y = Location_freq + 500, # Tăng khoảng cách nhãn lên 500 để hiển thị rõ
labels = Location_freq, # Giá trị tần suất
pos = 3, # Đặt nhãn phía trên cột
col = "black", # Màu chữ đen
cex = 0.8) # Kích thước chữ nhỏ hơn do nhiều cột
Kết quả phân bố tần suất theo địa phương phản ánh một sự phân bổ tương đối đồng đều về hoạt động mua sắm của khách hàng trên toàn lãnh thổ Hoa Kỳ. Mặc dù không có sự chênh lệch cực đoan nào, một số bang nổi bật với tỷ lệ mua sắm cao hơn trung bình, điển hình như Montana (2.46%), California (2.44%), Idaho (2.38%) và Illinois (2.36%). Những địa phương này có thể đang sở hữu các điều kiện thuận lợi như mật độ dân số cao, thu nhập ổn định hoặc hạ tầng thương mại phát triển, từ đó tạo nên sức mua lớn hơn so với mặt bằng chung.
Ngược lại, các bang như Kansas (1.62%) và Rhode Island (1.62%) lại cho thấy tần suất giao dịch tương đối thấp, có thể là do quy mô dân số nhỏ hơn hoặc mức độ thâm nhập thị trường của doanh nghiệp chưa sâu rộng. Tuy vậy, sự hiện diện của khách hàng ở hầu hết các bang cho thấy mức độ lan tỏa toàn quốc của thương hiệu hoặc nền tảng phân phối, mở ra tiềm năng cho các chiến lược cá nhân hóa theo vùng hoặc tối ưu hóa mạng lưới cung ứng.
# Tính tần số và tần suất
size_freq <- table(b$Size)
size_prop <- table(b$Size) / sum(nrow(b))
print(size_freq)
##
## L M S XL
## 1053 1755 663 429
# Tạo dataframe cho bảng
table_data5 <- data.frame(
`Kích cỡ` = names(size_freq),
`Tần số` = as.numeric(size_freq),
`Tần suất (%)` = round(size_prop * 100, 2)
)
colnames(table_data5) <- c("Kích cỡ", "Tần số", "Kích cỡ", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data5, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Kích cỡ | Tần số | Kích cỡ | Tần suất (%) |
|---|---|---|---|
| L | 1053 | L | 27 |
| M | 1755 | M | 45 |
| S | 663 | S | 17 |
| XL | 429 | XL | 11 |
# Tạo bảng màu (cố định cho số kích cỡ)
num_sizes <- length(size_freq)
colors <- c("#0066CC", "#00CC99", "#FF6666", "#FFCC00")[1:num_sizes] # Chọn màu đủ
# Tạo biểu đồ cột
bar_positions5 <- barplot(size_freq,
main = "Phân phối khách hàng theo kích cỡ",
xlab = "Kích cỡ",
ylab = "Số lượng giao dịch",
col = colors, # Sử dụng bảng màu cố định
names.arg = names(size_freq), # Sử dụng tên kích cỡ
las = 1, # Nhãn trục x nằm ngang (ít giá trị)
cex.names = 0.9, # Kích thước nhãn trục x phù hợp
ylim = c(0, max(size_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions5,
y = size_freq + max(size_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = size_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.8) # Kích thước chữ nhỏ hơn
Bảng phân bố tần suất theo kích cỡ cho thấy kích cỡ M (Trung bình) chiếm ưu thế rõ rệt với 45% tổng số lượng sản phẩm được mua, cho thấy đây là kích cỡ phổ biến và được ưa chuộng nhất trong nhóm khách hàng hiện tại. Tiếp theo là kích cỡ L với 27%, cho thấy sự quan tâm không nhỏ đến phân khúc khách hàng có vóc dáng lớn hơn trung bình.
Trong khi đó, kích cỡ S chiếm 17%, phản ánh một bộ phận khách hàng nhỏ hơn, có thể là thanh thiếu niên, người có vóc dáng nhỏ, hoặc phụ nữ. Kích cỡ XL chỉ chiếm 11%, cho thấy nhu cầu ở phân khúc kích cỡ lớn hơn là có nhưng tương đối hạn chế.
# Tính tần số và tần suất
color_freq <- table(b$Color)
color_prop <- table(b$Color) / sum(nrow(b))
print(color_freq)
##
## Beige Black Blue Brown Cyan Charcoal Gold Gray
## 147 167 152 141 166 153 138 159
## Green Indigo Lavender Magenta Maroon Olive Orange Peach
## 169 147 147 152 158 177 154 149
## Pink Purple Red Silver Teal Turquoise Violet White
## 153 151 148 173 172 145 166 142
## Yellow
## 174
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo dataframe cho bảng
table_data6 <- data.frame(
`Màu sắc` = names(color_freq),
`Tần số` = as.numeric(color_freq),
`Tần suất (%)` = round(color_prop * 100, 2)
)
colnames(table_data6) <- c("Màu sắc", "Tần số", "Màu sắc", "Tần suất (%)")
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data6, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Màu sắc | Tần số | Màu sắc | Tần suất (%) |
|---|---|---|---|
| Beige | 147 | Beige | 3.77 |
| Black | 167 | Black | 4.28 |
| Blue | 152 | Blue | 3.90 |
| Brown | 141 | Brown | 3.62 |
| Cyan | 166 | Cyan | 4.26 |
| Charcoal | 153 | Charcoal | 3.92 |
| Gold | 138 | Gold | 3.54 |
| Gray | 159 | Gray | 4.08 |
| Green | 169 | Green | 4.33 |
| Indigo | 147 | Indigo | 3.77 |
| Lavender | 147 | Lavender | 3.77 |
| Magenta | 152 | Magenta | 3.90 |
| Maroon | 158 | Maroon | 4.05 |
| Olive | 177 | Olive | 4.54 |
| Orange | 154 | Orange | 3.95 |
| Peach | 149 | Peach | 3.82 |
| Pink | 153 | Pink | 3.92 |
| Purple | 151 | Purple | 3.87 |
| Red | 148 | Red | 3.79 |
| Silver | 173 | Silver | 4.44 |
| Teal | 172 | Teal | 4.41 |
| Turquoise | 145 | Turquoise | 3.72 |
| Violet | 166 | Violet | 4.26 |
| White | 142 | White | 3.64 |
| Yellow | 174 | Yellow | 4.46 |
# Tạo biểu đồ cột
bar_positions6 <- barplot(color_freq,
main = "Phân phối khách hàng theo màu sắc",
xlab = "Màu sắc",
ylab = "Số lượng giao dịch",
col =rainbow(length(color_freq)), # Sử dụng bảng màu cố định
names.arg = names(color_freq), # Sử dụng tên màu
las = 2, # Xoay nhãn trục x 90 độ để dễ đọc
cex.names = 0.8, # Kích thước nhãn trục x
ylim = c(0, max(color_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions6,
y = color_freq + max(color_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = color_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.9) # Kích thước chữ
Kết quả phân bố tần suất theo màu sắc sản phẩm phản ánh rõ sự đa dạng về thị hiếu người tiêu dùng, đồng thời giúp doanh nghiệp xác định những tông màu được ưa chuộng nhất.
Trong số 25 màu được liệt kê, Yellow (4.46%), Silver (4.44%), Olive (4.54%), và Teal (4.41%) là những màu nổi bật, có mức tiêu thụ cao nhất. Điều này cho thấy người tiêu dùng đang có xu hướng quan tâm đến những sắc thái tươi sáng hoặc độc đáo, phản ánh tính cá nhân hóa cao trong lựa chọn sản phẩm.
Ngược lại, các màu như Gold (3.54%), Brown (3.62%), và White (3.64%) có tỷ lệ thấp hơn, cho thấy sức hút tương đối hạn chế. Dù vậy, nhóm màu trung tính như Black (4.28%), Gray (4.08%), và Beige (3.77%) vẫn giữ được vị trí ổn định, thể hiện sự ưa chuộng tính linh hoạt và dễ phối đồ.
# Tính tần số và tần suất
season_freq <- table(b$Season)
season_prop <- table(b$Season) / sum(nrow(b))
print(season_freq)
##
## Fall Spring Summer Winter
## 975 999 955 971
# Tạo dataframe cho bảng
table_data7 <- data.frame(
`Mùa` = names(season_freq),
`Tần số` = as.numeric(season_freq),
`Tần suất (%)` = round(season_prop * 100, 2)
)
colnames(table_data7) <- c("Mùa", "Tần số", "Mùa", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data7, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Mùa | Tần số | Mùa | Tần suất (%) |
|---|---|---|---|
| Fall | 975 | Fall | 25.00 |
| Spring | 999 | Spring | 25.62 |
| Summer | 955 | Summer | 24.49 |
| Winter | 971 | Winter | 24.90 |
# Tạo bảng màu (cố định cho 4 mùa)
num_seasons <- length(season_freq)
colors <- c("#0066CC", "#00CC99", "#FF6666", "#FFCC00")[1:num_seasons] # ✅ Sửa đúng cách trích màu
# Tạo biểu đồ cột
bar_positions7 <- barplot(season_freq,
main = "Phân phối khách hàng theo mùa",
xlab = "Mùa",
ylab = "Số lượng giao dịch",
col = colors,
names.arg = names(season_freq),
las = 1,
cex.names = 1,
ylim = c(0, max(season_freq, na.rm = TRUE) * 1.2))
# Thêm nhãn số trên mỗi cột
text(x = bar_positions7,
y = season_freq + max(season_freq, na.rm = TRUE) * 0.05,
labels = season_freq,
pos = 3,
col = "black",
cex = 0.9)
Kết quả phân phối tần suất mua sắm theo mùa cho thấy sự phân bổ khá đồng đều trong hành vi tiêu dùng của khách hàng trong suốt cả năm. Cụ thể, mùa Xuân chiếm tỷ trọng cao nhất với 25.62% tổng số lượt mua, tiếp đến là mùa Thu (25.00%), mùa Đông (24.90%) và mùa Hè (24.49%). Sự chênh lệch không đáng kể giữa các mùa phản ánh tính ổn định trong nhu cầu mua sắm của người tiêu dùng, cho thấy hoạt động mua sắm không chịu tác động mạnh bởi yếu tố thời vụ. Tuy nhiên, sự nhỉnh hơn nhẹ của mùa Xuân có thể liên quan đến nhu cầu làm mới trang phục và chuẩn bị cho các dịp lễ hội đầu năm.
# Tính tần số và tần suất
subscriptionstatus_freq <- table(b$Subscription.Status)
subscriptionstatus_prop <- table(b$Subscription.Status) / sum(nrow(b))
print(subscriptionstatus_freq)
##
## No Yes
## 2843 1057
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo dataframe cho bảng
table_data8 <- data.frame(
`Trạng thái đăng ký` = names(subscriptionstatus_freq),
`Tần số` = as.numeric(subscriptionstatus_freq),
`Tần suất (%)` = round(subscriptionstatus_prop * 100, 2))
colnames(table_data8) <- c("Trạng thái đăng ký", "Tần số", "Trạng thái đăng ký", "Tần suất(%)")
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data8, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Trạng thái đăng ký | Tần số | Trạng thái đăng ký | Tần suất(%) |
|---|---|---|---|
| No | 2843 | No | 72.9 |
| Yes | 1057 | Yes | 27.1 |
# Tạo biểu đồ cột
bar_positions8 <- barplot(subscriptionstatus_freq,
main = "Phân phối khách hàng theo trạng thái đăng ký",
xlab = "Trạng thái đăng ký",
ylab = "Số lượng giao dịch",
col = c("#FF99CC", "#00CC99"),
las = 1, # nhãn trục x để ngang
cex.names = 0.8, # Giảm kích thước chữ nhãn trục x
ylim = c(0, max(subscriptionstatus_freq) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions8,
y = subscriptionstatus_freq + 200, # Tăng khoảng cách nhãn lên 200 để hiển thị rõ
labels = subscriptionstatus_freq, # Giá trị tần suất
pos = 3, # Đặt nhãn phía trên cột
col = "black", # Màu chữ đen
cex = 0.9) # Kích thước chữ
Phân tích tần suất đăng ký cho thấy phần lớn khách hàng chưa đăng ký tài khoản hoặc chương trình thành viên của doanh nghiệp. Cụ thể, 72.9% người tiêu dùng thuộc nhóm “Không đăng ký”, trong khi chỉ có 27.1% đã thực hiện đăng ký. Sự chênh lệch đáng kể này phản ánh một tiềm năng lớn cho việc mở rộng tệp khách hàng thân thiết thông qua các chiến lược khuyến khích đăng ký hiệu quả hơn. Việc người tiêu dùng chưa sẵn sàng đăng ký có thể xuất phát từ các nguyên nhân như quy trình đăng ký phức tạp, thiếu lợi ích rõ ràng, hoặc lo ngại về quyền riêng tư. Do đó, doanh nghiệp cần rà soát lại trải nghiệm người dùng, đồng thời thiết kế lại các chính sách ưu đãi dành riêng cho người đăng ký để gia tăng tỷ lệ chuyển đổi và phát triển mối quan hệ lâu dài với khách hàng.
# Tính tần số và tần suất
discountapplied_freq <- table(b$Discount.Applied)
discountapplied_prop <- table(b$Discount.Applied) / sum(nrow(b))
print(discountapplied_freq)
##
## No Yes
## 2223 1677
# Tạo dataframe cho bảng
table_data9 <- data.frame(
`Trạng thái giảm giá` = names(discountapplied_freq),
`Tần số` = as.numeric(discountapplied_freq),
`Tần suất (%)` = round(discountapplied_prop * 100, 2)
)
colnames(table_data9) <- c("Trạng thái giảm giá", "Tần số","Trạng thái giảm giá", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data9, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Trạng thái giảm giá | Tần số | Trạng thái giảm giá | Tần suất (%) |
|---|---|---|---|
| No | 2223 | No | 57 |
| Yes | 1677 | Yes | 43 |
num_discounts <- length(discountapplied_freq)
colors <- c("#FF99CC", "#00CC99")[1:num_discounts] # Chọn màu đủ
# Tạo biểu đồ cột
bar_positions9 <- barplot(discountapplied_freq,
main = "Phân phối khách hàng theo trạng thái giảm giá",
xlab = "Trạng thái giảm giá",
ylab = "Số lượng giao dịch",
col = colors, # Sử dụng bảng màu cố định
names.arg = names(discountapplied_freq), # Tên trạng thái
las = 1, # Nhãn trục x nằm ngang (ít giá trị)
cex.names = 1, # Kích thước nhãn trục x rõ ràng
ylim = c(0, max(discountapplied_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions9,
y = discountapplied_freq + max(discountapplied_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = discountapplied_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.9) # Kích thước chữ
Kết quả thống kê về trạng thái giảm giá cho thấy rằng có 57% giao dịch không đi kèm với chương trình giảm giá, trong khi 43% còn lại có áp dụng hình thức khuyến mãi. Tỷ lệ tương đối cao của các giao dịch có giảm giá phản ánh vai trò quan trọng của các chương trình ưu đãi trong chiến lược kích cầu tiêu dùng. Tuy nhiên, việc hơn một nửa số giao dịch không cần đến giảm giá để hoàn tất cho thấy vẫn tồn tại một nhóm khách hàng sẵn sàng chi trả theo mức giá gốc. Điều này mở ra cơ hội cho doanh nghiệp tối ưu hóa chính sách định giá, kết hợp hài hòa giữa giá trị sản phẩm và kỳ vọng của khách hàng, từ đó nâng cao doanh thu mà vẫn đảm bảo khả năng cạnh tranh.
# Tính tần số và tần suất
promocodeused_freq <- table(b$Promo.Code.Used)
promocodeused_prop <- table(b$Promo.Code.Used) / sum(nrow(b))
print(promocodeused_freq)
##
## No Yes
## 2223 1677
# Tạo dataframe cho bảng
table_data10 <- data.frame(
`Trạng thái sử dụng mã khuyến mãi` = names(promocodeused_freq),
`Tần số` = as.numeric(promocodeused_freq),
`Tần suất (%)` = round(promocodeused_prop * 100, 2)
)
colnames(table_data10) <- c("Trạng thái sử dụng mã khuyến mãi", "Tần số", "Trạng thái sử dụng mã khuyến mãi ", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data10, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Trạng thái sử dụng mã khuyến mãi | Tần số | Trạng thái sử dụng mã khuyến mãi | Tần suất (%) |
|---|---|---|---|
| No | 2223 | No | 57 |
| Yes | 1677 | Yes | 43 |
# Tạo biểu đồ cột
bar_positions10 <- barplot(promocodeused_freq,
main = "Phân phối khách hàng theo trạng thái sử dụng mã khuyến mãi",
xlab = "Trạng thái sử dụng mã khuyến mãi",
ylab = "Số lượng giao dịch",
col = colors, # Sử dụng bảng màu cố định
names.arg = names(promocodeused_freq), # Tên trạng thái
las = 1, # Nhãn trục x nằm ngang (ít giá trị)
cex.names = 1, # Kích thước nhãn trục x rõ ràng
ylim = c(0, max(promocodeused_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions10,
y = promocodeused_freq + max(promocodeused_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = promocodeused_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.9) # Kích thước chữ
Phân tích trạng thái sử dụng mã khuyến mãi cho thấy 43% các giao dịch có áp dụng mã giảm giá, trong khi 57% không sử dụng mã khuyến mãi. Tỷ lệ sử dụng mã khuyến mãi khá cao, cho thấy mã giảm giá là một công cụ quan trọng thúc đẩy hành vi mua sắm của khách hàng. Việc gần một nửa số giao dịch tận dụng mã khuyến mãi chứng tỏ hiệu quả của các chương trình tiếp thị trong việc thu hút và giữ chân khách hàng. Tuy nhiên, tỷ lệ 57% không sử dụng mã cũng cho thấy vẫn có nhóm khách hàng không phụ thuộc vào ưu đãi, điều này giúp doanh nghiệp cân bằng giữa chính sách khuyến mãi và duy trì giá trị sản phẩm trên thị trường.
# Tính tần số và tần suất
paymentmethod_freq <- table(b$Payment.Method)
paymentmethod_prop <- table(b$Payment.Method) / sum(nrow(b))
print(paymentmethod_freq)
##
## Bank Transfer Cash Credit Card Debit Card PayPal
## 612 670 671 636 677
## Venmo
## 634
# Tạo dataframe cho bảng
table_data11 <- data.frame(
`Phương thức thanh toán` = names(paymentmethod_freq),
`Tần số` = as.numeric(paymentmethod_freq),
`Tần suất (%)` = round(paymentmethod_prop * 100, 2)
)
colnames(table_data11) <- c("Phương thức thanh toán", "Tần số", "Phương thức thanh toán", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data11, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Phương thức thanh toán | Tần số | Phương thức thanh toán | Tần suất (%) |
|---|---|---|---|
| Bank Transfer | 612 | Bank Transfer | 15.69 |
| Cash | 670 | Cash | 17.18 |
| Credit Card | 671 | Credit Card | 17.21 |
| Debit Card | 636 | Debit Card | 16.31 |
| PayPal | 677 | PayPal | 17.36 |
| Venmo | 634 | Venmo | 16.26 |
# Tạo bảng màu (đủ cho số phương thức)
num_methods <- length(paymentmethod_freq)
colors <- c("#0066CC", "#00CC99", "#FF6666", "#FFCC00", "#9933CC", "#33CCCC")[1:num_methods] # Chọn màu đủ
# Tạo biểu đồ cột
bar_positions11 <- barplot(paymentmethod_freq,
main = "Phân phối khách hàng theo phương thức thanh toán",
xlab = "Phương thức thanh toán",
ylab = "Số lượng giao dịch",
col = colors, # Sử dụng bảng màu cố định
names.arg = names(paymentmethod_freq), # Tên phương thức
las = 1, # Xoay nhãn trục x để ngang
cex.names = 0.8, # Giảm kích thước nhãn trục x
ylim = c(0, max(paymentmethod_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions11,
y = paymentmethod_freq + max(paymentmethod_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = paymentmethod_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.9) # Kích thước chữ
Phân tích dữ liệu phương thức thanh toán cho thấy sự phân bổ tương đối cân bằng giữa các hình thức sử dụng. Trong đó, PayPal chiếm tỷ lệ cao nhất với 17,36%, theo sát là thẻ tín dụng (Credit Card) và thanh toán tiền mặt (Cash) với tỷ lệ lần lượt là 17,21% và 17,18%. Các phương thức khác như chuyển khoản ngân hàng (Bank Transfer), thẻ ghi nợ (Debit Card) và Venmo cũng có tỷ lệ tương đối đồng đều, dao động từ 15,69% đến 16,31%. Kết quả này phản ánh xu hướng đa dạng hóa các hình thức thanh toán mà người tiêu dùng ưu tiên, đồng thời cho thấy nhu cầu về sự thuận tiện và linh hoạt trong quá trình giao dịch. Do đó, việc duy trì đa dạng các phương thức thanh toán là cần thiết để đáp ứng kỳ vọng của khách hàng cũng như nâng cao hiệu quả kinh doanh.
# Tính tần số và tần suất
frequencyofpurchases_freq <- table(b$Frequency.of.Purchases)
frequencyofpurchases_prop <- table(b$Frequency.of.Purchases) / sum(nrow(b))
print(frequencyofpurchases_freq)
##
## Annually Bi-Weekly Every 3 Months Fortnightly Monthly
## 572 547 584 542 553
## Quarterly Weekly
## 563 539
# Tạo dataframe cho bảng
table_data12 <- data.frame(
`Tần suất mua hàng` = names(frequencyofpurchases_freq),
`Tần số` = as.numeric(frequencyofpurchases_freq),
`Tần suất (%)` = round(frequencyofpurchases_prop * 100, 2)
)
colnames(table_data12) <- c("Tần suất mua hàng", "Tần số", "Tần suất mua hàng ", "Tần suất (%)")
# Đặt mã hóa UTF-8 để hỗ trợ tiếng Việt
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
# Tạo bảng kẻ
library(knitr)
library(kableExtra)
kable(table_data12, format = "markdown", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Tần suất mua hàng | Tần số | Tần suất mua hàng | Tần suất (%) |
|---|---|---|---|
| Annually | 572 | Annually | 14.67 |
| Bi-Weekly | 547 | Bi-Weekly | 14.03 |
| Every 3 Months | 584 | Every 3 Months | 14.97 |
| Fortnightly | 542 | Fortnightly | 13.90 |
| Monthly | 553 | Monthly | 14.18 |
| Quarterly | 563 | Quarterly | 14.44 |
| Weekly | 539 | Weekly | 13.82 |
num_frequencies <- length(frequencyofpurchases_freq)
colors <- c("#0066CC", "#00CC99", "#FF6666", "#FFCC00", "#9933CC", "#33CCCC", "#CC3366")[1:num_frequencies] # Chọn màu đủ
# Tạo biểu đồ cột
bar_positions12 <- barplot(frequencyofpurchases_freq,
main = "Phân phối khách hàng theo tần suất mua hàng",
xlab = "Tần suất mua hàng",
ylab = "Số lượng giao dịch",
col = colors, # Sử dụng bảng màu cố định
names.arg = names(frequencyofpurchases_freq), # Tên tần suất
las = 2, # Xoay nhãn trục x 90 độ để dễ đọc
cex.names = 0.8, # Giảm kích thước nhãn trục x
ylim = c(0, max(frequencyofpurchases_freq, na.rm = TRUE) * 1.2)) # Mở rộng trục y lên 120%
# Thêm nhãn số trên mỗi cột
text(x = bar_positions12,
y = frequencyofpurchases_freq + max(frequencyofpurchases_freq, na.rm = TRUE) * 0.05, # Khoảng cách nhãn động
labels = frequencyofpurchases_freq, # Giá trị tần số
pos = 3, # Đặt nhãn trên cột
col = "black", # Màu chữ
cex = 0.9) # Kích thước chữ
Kết quả cho thấy sự phân bổ tương đối đồng đều giữa các khoảng thời gian khác nhau. Trong đó, nhóm khách hàng mua hàng theo chu kỳ mỗi ba tháng (Every 3 Months) chiếm tỷ lệ cao nhất với 14,97%, tiếp theo là nhóm mua hàng hàng quý (Quarterly) với 14,44%, và mua hàng hàng năm (Annually) chiếm 14,67%. Các nhóm còn lại như mua hàng hàng tháng (Monthly), hai tuần một lần (Bi-Weekly), hàng tuần (Weekly) và mỗi hai tuần (Fortnightly) cũng dao động quanh mức 13,8% đến 14,2%. Kết quả này phản ánh đa dạng về thói quen mua sắm của khách hàng, cho thấy nhu cầu và tần suất tiêu dùng có sự phân hóa nhẹ,
Ước lượng khoảng tin cậy cho tỷ lệ mẫu
Trong thống kê suy diễn, chúng ta thường cần ước lượng một tham số tổng thểdựa trên dữ liệu mẫu. Đối với tỷ lệ, khoảng tin cậy (confidence interval – CI) được xác định bằng cách sử dụng tỷ lệ mẫu \(\hat{p}\), độ lệch chuẩn và phân phối chuẩn chuẩn hóa.
$$ Tỷ lệ mẫu được tính bằng:
\[ \hat{p} = \frac{x}{n} \]
Khoảng tin cậy 95% cho tỷ lệ:
\[ CI = \hat{p} \pm z_{\alpha/2} \cdot \sqrt{ \frac{ \hat{p}(1 - \hat{p}) }{n} } \]
Trong đó:
\(\hat{p}\): tỷ lệ mẫu
\(z_{\alpha/2} \approx 1.96\): giá trị tới hạn từ phân phối chuẩn chuẩn hóa với mức tin cậy 95%
\(n\): kích thước mẫu
Kiểm định giả thuyết cho một tỷ lệ
Giả sử ta muốn kiểm tra xem tỷ lệ mẫu có khác một giá trị giả định \(p_0\) hay không. Khi đó, kiểm định giả thuyết được đặt như sau:
Giả thuyết kiểm định:
\[ H_0: p = p_0 \quad \text{vs} \quad H_1: p \neq p_0 \]
Thống kê kiểm định:
\[ z = \frac{ \hat{p} - p_0 }{ \sqrt{ \frac{ p_0 (1 - p_0) }{n} } } \]
Cách tính p-value (kiểm định hai phía):
\[ p\text{-value} = 2 \cdot (1 - \Phi(|z|)) \] $$
x <- table(b$Gender)[["Female"]]
n <- sum(table(b$Gender))
CI<- prop.test(x,n,conf.level = 0.95,correct = TRUE)
cat("Tỷ lệ mẫu ước lượng \n \n",
CI[["estimate"]],"\n \n",
"Khoảng ước lượng 95% \n \n",CI[["conf.int"]])
## Tỷ lệ mẫu ước lượng
##
## 0.32
##
## Khoảng ước lượng 95%
##
## 0.3054166 0.3349408
Kết quả phân tích cho thấy với mức độ tin cậy 95%, tỷ lệ khách hàng nữ trong tổng thể được ước lượng nằm trong khoảng từ 30.54% đến 33.49%. Điều này cung cấp một phạm vi hợp lý phản ánh tỷ lệ nữ giới tham gia giao dịch trong mẫu nghiên cứu.
CI<- prop.test(x,n,conf.level = 0.95,p = 0.5 ,correct = TRUE)
CI
##
## 1-sample proportions test with continuity correction
##
## data: x out of n, null probability 0.5
## X-squared = 504.72, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.3054166 0.3349408
## sample estimates:
## p
## 0.32
Đặt giả thuyết:
H₀: Tỷ lệ khách hàng nữ trong tổng thể là 0.5 (tức 50%).
H₁: Tỷ lệ khách hàng nữ trong tổng thể khác 0.5.
Vì p-value = 4.695e-10 < 0.05, nên chúng ta bác bỏ giả thuyết H₀ tại mức ý nghĩa 5%. Vậy Tỷ lệ khách hàng nữ trong tổng thể khác 0.5
# Trích xuất số lượng "Fall" và tổng số giao dịch
x<- table(b$Season)[["Fall"]]
n <- sum(table(b$Season))
CI <- prop.test(x,n,conf.level = 0.95,correct = TRUE)
cat("Tỷ lệ mẫu ước lượng \n \n",
CI[["estimate"]],"\n \n",
"Khoảng ước lượng 95% \n \n",CI[["conf.int"]])
## Tỷ lệ mẫu ước lượng
##
## 0.25
##
## Khoảng ước lượng 95%
##
## 0.2365348 0.2639618
Với độ tin cậy 95%, tỷ lệ giao dịch diễn ra trong mùa Thu (Fall) được ước tính nằm trong khoảng từ 23.65% đến 26.39%. Khoảng tin cậy này phản ánh sự ổn định và mức độ phổ biến của mùa Thu trong tổng số giao dịch.
CI<- prop.test(x,n,conf.level = 0.95,p = 1/4 ,correct = TRUE)
CI
##
## 1-sample proportions test without continuity correction
##
## data: x out of n, null probability 1/4
## X-squared = 0, df = 1, p-value = 1
## alternative hypothesis: true p is not equal to 0.25
## 95 percent confidence interval:
## 0.2366606 0.2638314
## sample estimates:
## p
## 0.25
Đặt giả thuyết:
H₀: Tỷ lệ khách hàng thực hiện giao dịch trong mùa thu trong tổng thể p=0.25
H₁: Tỷ lệ khách hàng thực hiện giao dịch trong mùa thu trong tổng thể p khác 0.25
Với mức ý nghĩa 5%, vì p-value = 1 > 0.05, ta không đủ bằng chứng để bác bỏ giả thuyết không ( H₀).Nói cách khác, tỷ lệ mẫu quan sát được là 25% hoàn toàn phù hợp với giả định ban đầu.
# Trích xuất số lượng "M" và tổng số giao dịch
x <- table(b$Size)[["M"]]
n <- sum(table(b$Size))
CI <- prop.test(x,n,conf.level = 0.95,correct = TRUE)
cat("Tỷ lệ mẫu ước lượng \n \n",
CI[["estimate"]],"\n \n",
"Khoảng ước lượng 95% \n \n",CI[["conf.int"]])
## Tỷ lệ mẫu ước lượng
##
## 0.45
##
## Khoảng ước lượng 95%
##
## 0.4343155 0.4657837
Khoảng tin cậy [ 0.4343155, 0.4657837]. Điều này có nghĩa là: Với độ tin cậy 95%, ta ước lượng rằng tỷ lệ giao dịch thuộc nhóm “M” trong tổng thể nằm trong khoảng từ 43.43% đến 46.58%
CI<- prop.test(x,n,conf.level = 0.95,p = 1/2 ,correct = TRUE,alternative = "less")
CI
##
## 1-sample proportions test with continuity correction
##
## data: x out of n, null probability 1/2
## X-squared = 38.8, df = 1, p-value = 2.347e-10
## alternative hypothesis: true p is less than 0.5
## 95 percent confidence interval:
## 0.000000 0.463262
## sample estimates:
## p
## 0.45
Đặt giả thuyết:
Giả thuyết H₀: Tỷ lệ của giao dịch có kích cỡ “M” là 0.5 (50%).
Giả thuyết H₁: Tỷ lệ của giao dịch có kích cỡ “M” khác 0.5
Với mức ý nghĩa 5%, vì p-value = 2.347e-10 < 0.05, ta bác bỏ giả thuyết H₀. Nói cách khác, Tỷ lệ của giao dịch có kích cỡ “M” khác 0.5.
Kiểm định thống kê: Kiểm định Chi-bình phương
Trong thống kê, kiểm định Chi-bình phương độc lập (Chi-square test of independence) được sử dụng để kiểm tra xem hai biến phân loại có độc lập với nhau hay không. Dữ liệu thường được trình bày dưới dạng bảng chéo (contingency table).
Giả thuyết kiểm định
\(H_0\): Hai biến là độc lập (không có mối quan hệ).
\(H_1\): Hai biến không độc lập (có mối quan hệ).
Công thức thống kê kiểm định
Giá trị thống kê Chi-bình phương được tính theo công thức: \[ \chi^2 = \sum \frac{(O_i - E_i)^2}{E_i} \]
Trong đó:
\(O_{ij}\): Tần số quan sát tại ô thứ \((i, j)\).
\(E_{ij}\): Tần số kỳ vọng tại ô thứ \((i, j)\), được tính bằng:
Tần suất kỳ vọng \(E_{ij}\) được tính theo công thức:
\[ E_{ij} = \frac{(Tổng \text{ hàng}_i) \times (Tổng \text{ cột}_j)}{Tổng \text{ số quan sát}} \]
# Tạo bảng tần suất chéo cho Gender và Category
contingency_table <- table(b$Gender, b$Category)
cat("\nBảng tần suất chéo cho Gender và Category:\n")
##
## Bảng tần suất chéo cho Gender và Category:
print(contingency_table)
##
## Accessories Clothing Footwear Outerwear
## Female 392 556 199 101
## Male 848 1181 400 223
# Tính tỷ lệ phần trăm theo hàng
contingency_table_prop <- prop.table(contingency_table, margin = 1) * 100
cat("\nTỷ lệ phần trăm theo hàng cho Gender và Category:\n")
##
## Tỷ lệ phần trăm theo hàng cho Gender và Category:
print(round(contingency_table_prop, 1))
##
## Accessories Clothing Footwear Outerwear
## Female 31.4 44.6 15.9 8.1
## Male 32.0 44.5 15.1 8.4
library(ggplot2)
library(dplyr)
library(scales)
# Chuyển sang data frame
df_prop <- as.data.frame(contingency_table_prop)
colnames(df_prop) <- c("Gender", "Category", "Percentage")
# Vẽ biểu đồ cột nhóm
ggplot(df_prop, aes(x = Gender, y = Percentage, fill = Category)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.6) +
geom_text(aes(label = paste0(round(Percentage, 1), "%")),
position = position_dodge(width = 0.8),
vjust = -0.5,
size = 3.8,
color = "black") +
scale_fill_brewer(palette = "Pastel2") +
labs(
title = "Tỷ lệ phần trăm Loại sản phẩm theo Giới tính",
x = "Giới tính",
y = "Tỷ lệ (%)",
fill = "Loại sản phẩm"
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, hjust = 0.5),
legend.position = "top",
axis.text.x = element_text(angle = 0, vjust = 0.5),
panel.grid.major.x = element_blank()
)
Kết quả phân tích bảng cho thấy sự phân bổ tương đối đồng đều giữa nam và nữ trong việc lựa chọn các loại sản phẩm, phản ánh thị hiếu tiêu dùng khá tương đồng giữa hai giới trong mẫu khảo sát. Cụ thể, tỷ lệ lựa chọn sản phẩm Clothing chiếm tỷ trọng cao nhất ở cả hai nhóm giới tính, với 44.6% ở nữ và 44.5% ở nam, cho thấy đây là danh mục được ưa chuộng nhất. Đối với sản phẩm Accessories, tỷ lệ lựa chọn giữa hai giới cũng gần như tương đương (31.4% ở nữ và 32.0% ở nam), phản ánh xu hướng tiêu dùng tương đối cân bằng.
Tuy nhiên, có sự khác biệt nhẹ trong nhóm sản phẩm Footwear, khi nữ giới có tỷ lệ lựa chọn cao hơn một chút (15.9%) so với nam (15.1%), trong khi đối với nhóm Outerwear, nam giới có xu hướng tiêu dùng cao hơn nữ giới với tỷ lệ 8.4% so với 8.1%.
Để xác định xem mối quan hệ giữa Gender và Category có ý nghĩa thống kê hay không, cần thực hiện thêm kiểm định (như kiểm định Chi-bình phương).
# Thực hiện kiểm định Chi-bình phương
chi_test <- chisq.test(contingency_table)
# Báo cáo kết quả
cat("Giá trị Chi-bình phương:", chi_test$statistic, "\n")
## Giá trị Chi-bình phương: 0.5984208
cat("Bậc tự do (df):", chi_test$parameter, "\n")
## Bậc tự do (df): 3
cat("Giá trị p:", chi_test$p.value, "\n")
## Giá trị p: 0.8967938
Giả thuyết H₀: Hai biến Gender và Category độc lập với nhau, tức là không có mối liên hệ.
Giả thuyết H₁: Hai biến Gender và Category có liên quan với nhau, tức là có mối liên hệ.
Vì p-value =0.8967938 > 0.05, nên chưa đủ cơ sở để bác bỏ giả thuyết H₀ ở mức ý nghĩa 5%. Nghĩa là không có bằng chứng thống kê đủ mạnh để khẳng định rằng giới tính và loại sản phẩm có mối quan hệ phụ thuộc lẫn nhau. Nói cách khác, sự phân bố tỷ lệ các loại sản phẩm trong mẫu khảo sát là tương đối giống nhau giữa nam và nữ, điều này cũng phù hợp với quan sát từ bảng phân phối tỷ lệ phần trăm theo hàng đã trình bày trước đó.
Về mặt thực tiễn, điều này hàm ý rằng giới tính không phải là yếu tố ảnh hưởng đáng kể đến sự khác biệt trong lựa chọn danh mục sản phẩm trong mẫu dữ liệu nghiên cứu
# Tạo bảng tần suất chéo cho Gender và Frequency.of.Purchases
contingency_table <- table(b$Gender, b$Frequency.of.Purchases)
cat("\nBảng tần suất chéo cho Gender và Frequency.of.Purchases:\n")
##
## Bảng tần suất chéo cho Gender và Frequency.of.Purchases:
print(contingency_table)
##
## Annually Bi-Weekly Every 3 Months Fortnightly Monthly Quarterly Weekly
## Female 185 188 186 163 185 169 172
## Male 387 359 398 379 368 394 367
# Tính tỷ lệ phần trăm theo hàng
contingency_table_prop <- prop.table(contingency_table, margin = 1) * 100
cat("\nTỷ lệ phần trăm theo hàng cho Gender và Frequency.of.Purchases:\n")
##
## Tỷ lệ phần trăm theo hàng cho Gender và Frequency.of.Purchases:
print(round(contingency_table_prop, 1))
##
## Annually Bi-Weekly Every 3 Months Fortnightly Monthly Quarterly Weekly
## Female 14.8 15.1 14.9 13.1 14.8 13.5 13.8
## Male 14.6 13.5 15.0 14.3 13.9 14.9 13.8
library(ggplot2)
library(dplyr)
library(scales)
# Chuyển bảng tỷ lệ thành data frame
df_prop <- as.data.frame(contingency_table_prop)
colnames(df_prop) <- c("Gender", "Frequency", "Percentage")
# Vẽ biểu đồ cột nhóm
ggplot(df_prop, aes(x = Gender, y = Percentage, fill = Frequency)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.6) +
geom_text(aes(label = paste0(round(Percentage, 1), "%")),
position = position_dodge(width = 0.8),
vjust = -0.5,
size = 3.8,
color = "black") +
scale_fill_brewer(palette = "Set2") +
labs(
title = "Tỷ lệ phần trăm Tần suất mua hàng theo Giới tính",
x = "Giới tính",
y = "Tỷ lệ (%)",
fill = "Tần suất mua hàng"
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, hjust = 0.5),
legend.position = "top",
axis.text.x = element_text(angle = 0, vjust = 0.5),
panel.grid.major.x = element_blank()
)
Phân tích cho thấy sự phân bố tần suất mua hàng giữa nam và nữ là tương đối đồng đều, không có sự sai khác rõ rệt nào về mặt tỷ lệ phần trăm giữa các nhóm tần suất. Cụ thể, đối với nhóm Weekly, cả nam và nữ đều có cùng tỷ lệ 13.8%, cho thấy mức độ tương đồng tuyệt đối về thói quen mua hàng hàng tuần giữa hai giới.
Ở các nhóm tần suất khác, sự khác biệt giữa tỷ lệ phần trăm của nam và nữ nhìn chung không đáng kể. Ví dụ, trong nhóm Bi-Weekly, nữ giới chiếm 15.1%, cao hơn một chút so với nam (13.5%), trong khi ở nhóm Fortnightly, nam giới lại cao hơn (14.3%) so với nữ (13.1%). Những sự chênh lệch nhỏ này có thể phản ánh sự dao động ngẫu nhiên trong hành vi mua sắm cá nhân, hơn là một xu hướng có tính hệ thống.
Một điểm đáng chú ý là ở nhóm Quarterly, nam giới có tỷ lệ 14.9%, cao hơn nữ (13.5%), nhưng khoảng cách vẫn không đủ lớn để đưa ra kết luận có ý nghĩa thống kê nếu không được hỗ trợ bởi một kiểm định chính thức.
Tổng thể, bảng phân phối tỷ lệ phần trăm này cho thấy tính nhất quán và tương đối cân bằng về hành vi tiêu dùng giữa hai giới trong mẫu khảo sát, phản ánh rằng giới tính có thể không phải là yếu tố phân biệt rõ rệt đối với tần suất mua hàng
# Thực hiện kiểm định Chi-bình phương
chi_test <- chisq.test(contingency_table)
# Báo cáo kết quả
cat("Giá trị Chi-bình phương:", chi_test$statistic, "\n")
## Giá trị Chi-bình phương: 3.928009
cat("Bậc tự do (df):", chi_test$parameter, "\n")
## Bậc tự do (df): 6
cat("Giá trị p:", chi_test$p.value, "\n")
## Giá trị p: 0.6864183
Giả thuyết H₀: Hai biến Gender và Frequency of Purchases độc lập với nhau, tức là không có mối liên hệ.
Giả thuyết H₁: Hai biến Gender và Frequency of Purchases có liên quan với nhau, tức là có mối liên hệ.
Vì p-value = 0.6864183 > 0.05, ta chưa đủ bằng chứng để bác bỏ giả thuyết không (H₀) tại mức ý nghĩa 5%. Nói cách khác, chưa có bằng chứng thống kê đủ mạnh để khẳng định rằng có mối quan hệ phụ thuộc giữa giới tính và tần suất mua hàng trong dữ liệu khảo sát.
Kết quả này hoàn toàn phù hợp với bảng tỷ lệ phần trăm theo hàng đã được trình bày trước đó, khi tỷ lệ các mức tần suất mua hàng giữa nam và nữ gần như đồng đều, không có sự sai khác đáng kể. Về mặt thực tiễn, điều này gợi ý rằng giới tính không phải là một yếu tố ảnh hưởng rõ rệt đến hành vi tiêu dùng xét theo khía cạnh tần suất mua sắm.
Từ góc độ nghiên cứu thị trường, các nhà quản lý hoặc nhà tiếp thị có thể cân nhắc rằng việc phân khúc khách hàng theo giới tính có thể không mang lại giá trị gia tăng đáng kể trong việc dự báo hay điều chỉnh các chiến lược theo tần suất tiêu dùng – ít nhất là trong bối cảnh và tập dữ liệu hiện tại.
# Tạo bảng tần suất chéo cho Category và Season
contingency_table <- table(b$Category, b$Season)
cat("\nBảng tần suất chéo cho Category và Season:\n")
##
## Bảng tần suất chéo cho Category và Season:
print(contingency_table)
##
## Fall Spring Summer Winter
## Accessories 324 301 312 303
## Clothing 427 454 408 448
## Footwear 136 163 160 140
## Outerwear 88 81 75 80
# Tính tỷ lệ phần trăm theo hàng
contingency_table_prop <- prop.table(contingency_table, margin = 1) * 100
cat("\nTỷ lệ phần trăm theo hàng cho Category và Season:\n")
##
## Tỷ lệ phần trăm theo hàng cho Category và Season:
print(round(contingency_table_prop, 1))
##
## Fall Spring Summer Winter
## Accessories 26.1 24.3 25.2 24.4
## Clothing 24.6 26.1 23.5 25.8
## Footwear 22.7 27.2 26.7 23.4
## Outerwear 27.2 25.0 23.1 24.7
library(ggplot2)
library(dplyr)
library(scales)
# Chuyển sang data frame
df_prop <- as.data.frame(contingency_table_prop)
colnames(df_prop) <- c("Category", "Season", "Percentage")
# Vẽ biểu đồ cột nhóm
ggplot(df_prop, aes(x = Category, y = Percentage, fill = Season)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.6) +
geom_text(aes(label = paste0(round(Percentage, 1), "%")),
position = position_dodge(width = 0.8),
vjust = -0.5,
size = 3.5,
color = "black") +
scale_fill_brewer(palette = "Set2") +
labs(
title = "Tỷ lệ phần trăm Mùa theo Loại sản phẩm",
x = "Loại sản phẩm",
y = "Tỷ lệ (%)",
fill = "Mùa"
) +
scale_y_continuous(labels = label_percent(scale = 1), limits = c(0, max(df_prop$Percentage) + 5)) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, hjust = 0.5),
legend.position = "top",
axis.text.x = element_text(angle = 30, hjust = 1),
panel.grid.major.x = element_blank()
)
Kết quả phản ánh sự phân bố lựa chọn sản phẩm theo mùa và loại hàng hóa, từ đó giúp làm sáng tỏ những xu hướng tiêu dùng mang tính thời vụ trong mẫu khảo sát. Tuy nhiên, một điểm đáng chú ý là sự phân bổ phần trăm trong từng loại sản phẩm theo các mùa không cho thấy sự khác biệt rõ rệt, mà thay vào đó là một mức dao động nhẹ, phản ánh sự tương đối đồng đều giữa các mùa trong mỗi danh mục.
Cụ thể, đối với nhóm Accessories, tỷ lệ lựa chọn dao động từ 24.3% (Spring) đến 26.1% (Fall) – một biên độ rất hẹp. Điều này cho thấy phụ kiện là mặt hàng ít chịu ảnh hưởng của tính thời vụ, có thể được tiêu dùng ổn định quanh năm. Tương tự, nhóm Clothing có sự phân bố gần như đồng đều, với tỷ lệ cao nhất vào mùa Spring (26.1%) và thấp nhất vào mùa Summer (23.5%), cho thấy nhu cầu quần áo là khá liên tục và thích ứng tốt với mọi mùa.
Đáng chú ý hơn là danh mục Footwear, với tỷ lệ cao nhất vào mùa Spring (27.2%) và Summer (26.7%), trong khi mùa Winter (23.4%) ghi nhận tỷ lệ thấp hơn, điều này có thể liên quan đến hành vi thay đổi giày dép linh hoạt hơn trong thời tiết ấm áp, trong khi vào mùa đông, việc mua sắm giày dép mới có thể bị hạn chế hơn do đặc thù thời tiết và nhu cầu ổn định.
Ngược lại, Outerwear – nhóm sản phẩm vốn có tính thời vụ cao – lại có tỷ lệ lựa chọn cao nhất vào mùa Fall (27.2%), phù hợp với giai đoạn chuyển mùa và nhu cầu tăng lên về áo khoác. Tuy nhiên, tỷ lệ không quá thấp ở các mùa còn lại cũng cho thấy có thể người tiêu dùng mua sắm áo khoác ngoài các mùa lạnh vì nhiều lý do khác nhau (chuẩn bị trước, khuyến mãi, du lịch…).
Tổng kết lại, bảng số liệu phản ánh rằng tính thời vụ trong tiêu dùng là có, nhưng không thực sự rõ rệt trong mẫu khảo sát này, ngoại trừ một số tín hiệu nhẹ từ nhóm Footwear và Outerwear. Để củng cố các kết luận mang tính khẳng định hơn, cần tiến hành kiểm định thống kê như Chi-bình phương, qua đó đánh giá xem liệu mối quan hệ giữa loại sản phẩm và mùa có ý nghĩa thống kê hay chỉ là dao động ngẫu nhiên.
# Thực hiện kiểm định Chi-bình phương
chi_test <- chisq.test(contingency_table)
# Báo cáo kết quả
cat("Giá trị Chi-bình phương:", chi_test$statistic, "\n")
## Giá trị Chi-bình phương: 7.933669
cat("Bậc tự do (df):", chi_test$parameter, "\n")
## Bậc tự do (df): 9
cat("Giá trị p:", chi_test$p.value, "\n")
## Giá trị p: 0.5408444
Giả thuyết H₀: Hai biến Category và Season độc lập với nhau, tức là không có mối liên hệ.
Giả thuyết H₁: Hai biến Category và Season có liên quan với nhau, tức là có mối liên hệ.
Vì p-value = 0.5408444 > 0.05, ta chưa có đủ bằng chứng để bác bỏ giả thuyết H₀.Điều này có nghĩa là không có bằng chứng thống kê đủ mạnh để kết luận rằng có mối quan hệ phụ thuộc giữa loại sản phẩm và mùa trong năm.
NKết quả này củng cố cho nhận định từ bảng tỷ lệ phần trăm theo hàng được trình bày trước đó, trong đó sự phân bố của từng loại sản phẩm theo mùa là khá đồng đều, với biên độ dao động không lớn. Điều này cho thấy rằng hành vi tiêu dùng các loại sản phẩm trong mẫu khảo sát là tương đối ổn định và ít chịu ảnh hưởng bởi yếu tố mùa vụ.
Về mặt thực tiễn, kết quả này gợi ý rằng các chiến lược phân phối và tiếp thị theo mùa đối với các danh mục sản phẩm như Clothing, Footwear, Accessories, Outerwear có thể không cần phải điều chỉnh quá mạnh mẽ theo mùa. Thay vào đó, các yếu tố khác như giá cả, khuyến mãi, xu hướng thời trang hoặc các dịp đặc biệt có thể đóng vai trò quan trọng hơn trong việc thúc đẩy nhu cầu theo thời gian.
Tỷ số rủi ro (RR) là tỷ lệ giữa xác suất xảy ra sự kiện ở nhóm phơi nhiễm so với nhóm không phơi nhiễm. Nó thể hiện mức tăng (hoặc giảm) tương đối về nguy cơ.
Cách tính:
\[ RR = \frac{a / (a + b)}{c / (c + d)} \]
Ý nghĩa:
\(RR = 1\): Không có sự khác biệt nguy cơ giữa hai nhóm
\(RR > 1\): Nhóm A có nguy cơ cao hơn
\(RR < 1\): Nhóm A có nguy cơ thấp hơn
Rủi ro tương đối (Relative Risk/Risk Ratio) của biến Gender và Subscription Status
Tính Relative Risk (RR) giữa giới tính và trạng thái đăng ký, trong đó
Female là nhóm tham chiếu
Male là nhóm “phơi nhiễm” (exposed)
“Yes” là biến cố quan tâm (case – đã đăng ký)
# Tải thư viện
library(epitools)
# Tạo bảng chéo
cross_table <- table(b$Gender, b$Subscription.Status)
# Sắp xếp: Female là hàng đầu (exposed), Yes là cột thứ 2 (biến cố quan tâm)
cross_table <- cross_table[c("Female", "Male"), c("No", "Yes")]
# In bảng có tổng cộng
print(addmargins(cross_table))
##
## No Yes Sum
## Female 1244 4 1248
## Male 1599 1053 2652
## Sum 2843 1057 3900
riskratio(cross_table)
## $data
##
## No Yes Total
## Female 1244 4 1248
## Male 1599 1053 2652
## Total 2843 1057 3900
##
## $measure
## risk ratio with 95% C.I.
## estimate lower upper
## Female 1.0000 NA NA
## Male 123.8824 46.51611 329.9252
##
## $p.value
## two-sided
## midp.exact fisher.exact chi.square
## Female NA NA NA
## Male 0 2.045619e-205 6.3672e-147
##
## $correction
## [1] FALSE
##
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
Kết quả phân tích cho thấy sự khác biệt rất đáng kể về tỷ lệ xảy ra biến cố “Yes” giữa hai giới. Tỷ lệ nam giới phản ứng “Yes” đạt 39,7%, trong khi tỷ lệ này ở nữ giới chỉ là 0,32%. Tỷ số Risk Ratio = 123.8824 cho biết xác suất để khách hàng nam đăng kí thành viên cao gấp 123.8824 so với khách hàng nữ, với khoảng tin cậy 95% từ 46,52 đến 329,93, cho thấy mức chênh lệch là cực kỳ lớn và có ý nghĩa thống kê rõ rệt.
Với nhóm nữ được chọn làm nhóm tham chiếu (RR = 1), kết quả này đồng nghĩa với việc nam giới có nguy cơ xảy ra biến cố “Yes” cao hơn khoảng 124 lần so với nữ giới.
Khái niệm
Odds (Tỷ lệ cược) của một sự kiện là tỉ số giữa xác suất sự kiện xảy ra với xác suất sự kiện không xảy ra.
Odd Ratio (Tỷ số chênh) là một thước đo được sử dụng phổ biến trong thống kê, đặc biệt là trong nghiên cứu dịch tễ học, để đánh giá mối liên hệ giữa phơi nhiễm và kết quả.
Cách tính:
\[ OR = \frac{a/b}{c/d} = \frac{a \cdot d}{b \cdot c} \]
Ý nghĩa:
\(OR = 1\): Không có sự khác biệt odds giữa hai nhóm
\(OR > 1\): Odds xảy ra sự kiện ở nhóm A cao hơn
\(OR < 1\): Odds ở nhóm A thấp hơn
# Tính odds của nhóm Female:
# Odds = số người đăng ký (Yes) / số người không đăng ký (No)
odd_F <- cross_table["Female", "Yes"] / cross_table["Female", "No"]
# Tính odds của nhóm Male:
odd_M <- cross_table["Male", "Yes"] / cross_table["Male", "No"]
# In odds của từng nhóm
cat("🎯 Odds nhóm Female:", odd_F, "\n")
## 🎯 Odds nhóm Female: 0.003215434
cat("🎯 Odds nhóm Male:", odd_M, "\n\n")
## 🎯 Odds nhóm Male: 0.6585366
Odds được hiểu là tỷ lệ giữa số người xảy ra biến cố (Yes) và số người không xảy ra biến cố (No). Từ kết quả trên:
Odds của nhóm nữ (Female) là 0.0032, nghĩa là trung bình cứ 1 người nữ xảy ra biến cố “Yes” thì có khoảng 311 người nữ không xảy ra biến cố.
Odds của nhóm nam (Male) là 0.6585, nghĩa là cứ 1 người nam xảy ra biến cố “Yes” thì có khoảng 1,52 người nam không xảy ra biến cố.
library(vcd)
library(DescTools)
# Cách 2: Dùng hàm OddsRatio() từ thư viện DescTools
or_result <- OddsRatio(cross_table)
cat("📌 Odds Ratio :", or_result, "\n")
## 📌 Odds Ratio : 204.8049
Tỷ số odds (Odds Ratio) giữa nam và nữ là khoảng 205, cho thấy rằng tỷ lệ nam giới đăng kí thành viên so với không đăng kí cao hơn 204.8049 lần so với tỷ lệ đó ở nữ
# Tải thư viện
library(epitools)
# Tạo bảng chéo
cross_table <- table(b$Gender, b$Subscription.Status)
cross_table <- cross_table[c("Male", "Female"), c("Yes", "No")]
# In bảng có tổng cộng
print(addmargins(cross_table))
##
## Yes No Sum
## Male 1053 1599 2652
## Female 4 1244 1248
## Sum 1057 2843 3900
riskratio(cross_table)
## $data
##
## Yes No Total
## Male 1053 1599 2652
## Female 4 1244 1248
## Total 1057 2843 3900
##
## $measure
## risk ratio with 95% C.I.
## estimate lower upper
## Male 1.000000 NA NA
## Female 1.653221 1.602685 1.70535
##
## $p.value
## two-sided
## midp.exact fisher.exact chi.square
## Male NA NA NA
## Female 0 2.045619e-205 6.3672e-147
##
## $correction
## [1] FALSE
##
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
RR=1.653 có nghĩa là xác suất để khách hàng nữ không đăng kí thành viên cao gấp 1.653 lần so với khách hàng nam.
library(vcd)
library(DescTools)
# Dùng hàm OddsRatio() từ thư viện DescTools
or_result <- OddsRatio(cross_table)
cat("📌 Odds Ratio :", or_result, "\n")
## 📌 Odds Ratio : 204.8049
OR=1.653 có nghĩa là tỷ lệ để khách hàng nữ không đăng kí thành viên so với đăng kí cao gấp 1.653 lần so với tỷ lệ đó ở nam giới