library(readr)
## Warning: package 'readr' was built under R version 4.3.3
library(ggplot2)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(skimr)
library(psych)
## Warning: package 'psych' was built under R version 4.3.3
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
library(csv)
## Warning: package 'csv' was built under R version 4.3.3
d <- read.csv("C:/Users/ASUS/Downloads/Supermarket Transactions.csv", header = T)
names(d)
## [1] "X" "PurchaseDate" "CustomerID"
## [4] "Gender" "MaritalStatus" "Homeowner"
## [7] "Children" "AnnualIncome" "City"
## [10] "StateorProvince" "Country" "ProductFamily"
## [13] "ProductDepartment" "ProductCategory" "UnitsSold"
## [16] "Revenue"
Tên biến | Ý nghĩa |
---|---|
X | Ngày mua hàng (định dạng YYYY-MM-DD ). |
CustomerID | Mã định danh duy nhất cho mỗi khách hàng. |
Gender | Giới tính của khách hàng (M = Male, F =
Female). |
MaritalStatus | Tình trạng hôn nhân (S = Single, M =
Married). |
Homeowner | Khách hàng có sở hữu nhà hay không (Y = Yes,
N = No). |
Children | Số lượng con nhỏ trong gia đình (số nguyên). |
AnnualIncome | Khoảng thu nhập hàng năm (ví dụ <$25K ,
$25K–$50K , …). |
City | Thành phố sinh sống. |
StateorProvince | Bang hoặc tỉnh tương ứng với thành phố. |
Country | Quốc gia nơi giao dịch diễn ra. |
ProductFamily | Nhóm sản phẩm cấp cao (ví dụ Food, Drink, …). |
ProductDepartment | Bộ phận sản phẩm trong nhóm (ví dụ Beverages, Snack Foods, …). |
ProductCategory | Hạng mục sản phẩm cụ thể (ví dụ Carbonated Beverages, Candy, …). |
UnitsSold | Số lượng đơn vị bán ra trong mỗi giao dịch. |
Revenue | Doanh thu thu về từ giao dịch (đơn vị tiền tệ, ví dụ USD). |
dim(d)
## [1] 14059 16
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 ...
dldt <- c("Gender", "MaritalStatus", "Homeowner","City", "StateorProvince", "Country", "ProductFamily", "ProductDepartment", "ProductCategory","AnnualIncome")
dldt
## [1] "Gender" "MaritalStatus" "Homeowner"
## [4] "City" "StateorProvince" "Country"
## [7] "ProductFamily" "ProductDepartment" "ProductCategory"
## [10] "AnnualIncome"
dt <- d[, dldt]
str(dt)
## 'data.frame': 14059 obs. of 10 variables:
## $ Gender : chr "F" "M" "F" "M" ...
## $ MaritalStatus : chr "S" "M" "M" "M" ...
## $ Homeowner : chr "Y" "Y" "N" "Y" ...
## $ 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" ...
## $ AnnualIncome : chr "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
head(dt)
## Gender MaritalStatus Homeowner City StateorProvince Country
## 1 F S Y Los Angeles CA USA
## 2 M M Y Los Angeles CA USA
## 3 F M N Bremerton WA USA
## 4 M M Y Portland OR USA
## 5 F S Y Beverly Hills CA USA
## 6 F M Y Beverly Hills CA USA
## ProductFamily ProductDepartment ProductCategory AnnualIncome
## 1 Food Snack Foods Snack Foods $30K - $50K
## 2 Food Produce Vegetables $70K - $90K
## 3 Food Snack Foods Snack Foods $50K - $70K
## 4 Food Snacks Candy $30K - $50K
## 5 Drink Beverages Carbonated Beverages $130K - $150K
## 6 Food Deli Side Dishes $10K - $30K
tail(dt)
## Gender MaritalStatus Homeowner City StateorProvince Country
## 14054 F M N Yakima WA USA
## 14055 F M Y Bremerton WA USA
## 14056 F M Y Walla Walla WA USA
## 14057 M S Y Portland OR USA
## 14058 F S N Spokane WA USA
## 14059 M S N Portland OR USA
## ProductFamily ProductDepartment ProductCategory AnnualIncome
## 14054 Non-Consumable Household Paper Products $10K - $30K
## 14055 Food Baking Goods Baking Goods $10K - $30K
## 14056 Food Frozen Foods Vegetables $10K - $30K
## 14057 Drink Beverages Pure Juice Beverages $30K - $50K
## 14058 Drink Dairy Dairy $50K - $70K
## 14059 Non-Consumable Household Electrical $50K - $70K
any(is.na(dt))
## [1] FALSE
Vậy bộ dữ liệu không có giá trị thiếu
dt <- data.frame(lapply(dt, as.factor))
# Kiểm tra kiểu dữ liệu của từng biến trong dldt
sapply(dt, class)
## Gender MaritalStatus Homeowner City
## "factor" "factor" "factor" "factor"
## StateorProvince Country ProductFamily ProductDepartment
## "factor" "factor" "factor" "factor"
## ProductCategory AnnualIncome
## "factor" "factor"
Bảng tần số
#Lập bảng tần số biến Gender
tanso_gender <- table(dt$Gender)
tanso_gender
##
## F M
## 7170 6889
Biểu đồ
# Vẽ biểu đồ cột cho bảng tần số Gender
barplot(
tanso_gender,
main = "Tần số theo giới tính",
xlab = "Giới tính",
ylab = "Số quan sát",
las = 1,
col = c("blue", "tomato"),
border = "white")
Bảng tần suất
#Lập bảng tần suất của biến Gender
tansuat_gender <- tanso_gender/sum(nrow(dt))
tansuat_gender
##
## F M
## 0.5099936 0.4900064
Biểu đồ
# Màu cho từng lát
cols <- c("pink", "green")
# Nhãn phần trăm
nhangender <- paste0(round(tansuat_gender * 100, 1), "%")
# Vẽ pie chart không nhãn
pie(
tansuat_gender,
labels = NA, # ẩn nhãn ngay trên lát
main = "Tần suất theo giới tính",
col = cols,
border = "white"
)
# Thêm legend bên ngoài góc phải
legend(
x = "topright",
legend = paste(names(tansuat_gender), nhangender),
fill = cols,
)
Nhận xét:
counts <- table(dt$Gender)
diff_count <- abs(counts["F"] - counts["M"])
Vậy trong bộ dữ liệu này có 50.9993598 % nữ và 49.0006402% nam.
Trong bộ dữ liệu, số lượng nữ là 7170, số lượng nam là
Bảng tần số
#Lập bảng tần số biến Homeowner
tanso_homeowner <- table(dt$Homeowner)
tanso_homeowner
##
## N Y
## 5615 8444
Biểu đồ
barplot(
tanso_homeowner,
main = "tần số biến khách hàng có sở hửu nhà",
xlab = "sỡ hữu nhà",
ylab = "số lượng",
las = 1,
col = c("orange","purple"),
border = "white"
)
Bảng tần suất
#Lập bảng tần suất của biến Homeowner
tansuat_homeowner <- tanso_homeowner/sum(nrow(dt))
tansuat_homeowner
##
## N Y
## 0.3993883 0.6006117
Biểu đồ
# màu cho từng lát
cols <- c("lightblue","lightpink")
# nhãn phần trăm
nhanhomeowner <- paste0(round(tansuat_homeowner*100,1),"%")
# vẽ pie chart không nhãn
pie(
tansuat_homeowner,
labels = NA,
main = "tần số biến khách hàng có sở hửu nhà",
col = cols,
border = "white")
# thêm legend bên ngoài góc phải
legend(
x = "topright",
legend = paste(names(tansuat_homeowner),nhanhomeowner),
fill = cols
)
Nhận xét:
counts_homeowner <- table(dt$Homeowner)
diff_homeowner <- abs(counts_homeowner["Y"] - counts_homeowner["N"])
Vậy trong bộ dữ liệu này có 39.9388292 % không có nhà và 60.0611708% có nhà.
Số lượng người sở hữu nhà là 8444, số lượng người không sở hữu là 5615.
Sự chênh lệch về số lượng giữa hai nhóm là 2829 người, nghĩa là số người có nhà nhiều hơn khá đáng kể so với số người không có nhà.
Bảng tần số
#Lập bảng tần số của biến MaritalStatus
tanso_maritalStatus <- table(dt$MaritalStatus)
tanso_maritalStatus
##
## M S
## 6866 7193
Biểu đồ
# Vẽ biểu đồ cột cho MaritalStatus
barplot(
tanso_maritalStatus,
main = "Tần số biến tình trạng hôn nhân",
xlab = "tình trạng hôn nhân",
ylab = "Số quan sát",
las = 1,
col = c("yellow", "green"),
border = "white"
)
Bảng tần suất
#Lập bảng tần suất của biến MaritalStatus
tansuat_maritalStatus <- tanso_maritalStatus/sum(nrow(dt))
tansuat_maritalStatus
##
## M S
## 0.4883704 0.5116296
Biểu đồ
# Nhãn phần trăm
nhanmaritalStatus <- paste0( round(tansuat_maritalStatus * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_maritalStatus,
labels = NA,
main = "Tần suất biến MaritalStatus",
col = rainbow(length(nhanmaritalStatus)),
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_maritalStatus),nhanmaritalStatus),
fill = rainbow(length(nhanmaritalStatus))
)
Nhận xét:
# Đếm số người kết hôn (M) và độc thân (S)
ms_counts <- table(dt$MaritalStatus)
# Chênh lệch về số lượng giữa hai nhóm
ms_diff <- abs(ms_counts["M"] - ms_counts["S"])
Vậy trong bộ dữ liệu này có 48.8370439 % đã kết hôn và 51.1629561% độc thân.
Trong bộ dữ liệu này có 6866 người đã kết hôn và 7193 người độc thân. Nhóm kết hôn nhiều hơn nhóm độc thân 327 người.
Bảng tần số
# Lập bảng tần số biến City
tanso_city <- table(dt$City)
# Sắp xếp giảm dần để xem các thành phố phổ biến nhất
tanso_city <- sort(tanso_city, decreasing = TRUE)
# Hiển thị toàn bộ bảng tần số
tanso_city
##
## Salem Tacoma Los Angeles Seattle Portland
## 1386 1257 926 922 876
## Spokane San Diego Hidalgo Bremerton Beverly Hills
## 875 866 845 834 811
## Merida Vancouver San Andres Orizaba Camacho
## 654 633 621 464 452
## Acapulco Yakima Mexico City Victoria Walla Walla
## 383 376 194 176 160
## Bellingham San Francisco Guadalajara
## 143 130 75
Biểu đồ
barplot(
tanso_city,
main = "Tần số biến thành phố",
cex.names = 0.4,
xlab = "Số quan sát",
ylab = "Thành phố",
las = 1, # xoay nhãn trục y ngang
col = "steelblue",
border = "white",
horiz = TRUE # vẽ thanh ngang để đọc nhãn dễ hơn
)
Bảng tần suất
tansuat_city <- tanso_city/sum(nrow(dt))
tansuat_city
##
## Salem Tacoma Los Angeles Seattle Portland
## 0.098584537 0.089408920 0.065865282 0.065580767 0.062308841
## Spokane San Diego Hidalgo Bremerton Beverly Hills
## 0.062237712 0.061597553 0.060103848 0.059321431 0.057685468
## Merida Vancouver San Andres Orizaba Camacho
## 0.046518245 0.045024539 0.044170994 0.033003770 0.032150224
## Acapulco Yakima Mexico City Victoria Walla Walla
## 0.027242336 0.026744434 0.013798990 0.012518671 0.011380610
## Bellingham San Francisco Guadalajara
## 0.010171420 0.009246746 0.005334661
Biểu đồ
# Màu cho từng lát
cols <- rainbow(length(tansuat_city))
# Nhãn phần trăm
nhancity <- paste0( round(tansuat_city * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_city,
labels = NA,
main = "Tần suất biến city",
col = cols,
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_city),nhancity),
fill = cols,
bty = "n", # bỏ viền
cex = 0.5, # thu nhỏ chữ
ncol = 2, # chia thành 2 cột
x.intersp = 0.5, # giãn khoảng cách chữ–ký hiệu ngang
y.intersp = 0.7 # giãn khoảng cách giữa các dòng
)
Nhận xét:
Trong bộ dữ liệu này, thành phố có tỷ lệ giao dịch cao nhất là Salem với khoảng 9.86%, tiếp theo là Tacoma (8.94%), Los Angeles (6.59%) và Seattle (6.56%).
Các thành phố nhỏ hơn như Hidalgo (6.01%) hoặc Guadalajara (0.53%) có tỷ lệ thấp hơn nhiều.
Điều này cho thấy giao dịch chủ yếu tập trung ở một số thành phố lớn với dân số hoặc hoạt động kinh tế cao hơn. Các thành phố nhỏ hơn đóng góp ít hơn vào tổng số giao dịch, có thể do quy mô thị trường nhỏ hoặc mức độ phổ biến của sản phẩm thấp.
Ngoài ra, việc phân bố này cũng có thể phản ánh chiến lược tiếp thị hoặc kênh phân phối mà siêu thị đang tập trung vào các khu vực đô thị lớn.
Bảng tần số
#Lập bảng tần số của biến StateorProvince
tanso_stateorProvince <- table(dt$StateorProvince)
tanso_stateorProvince
##
## BC CA DF Guerrero Jalisco OR Veracruz WA
## 809 2733 815 383 75 2262 464 4567
## Yucatan Zacatecas
## 654 1297
Biểu đồ
barplot(
tanso_stateorProvince,
main = "Tần số biến bang hoặc tỉnh",
cex.names = 0.4,
xlab = "Số quan sát",
ylab = "bang hoặc tỉnh",
las = 1, # xoay nhãn trục y ngang
col = "green",
border = "white",
horiz = TRUE # vẽ thanh ngang để đọc nhãn dễ hơn
)
Bảng tần suất
#Lập bảng tần suất của biến StateorProvince
tansuat_stateorProvince <- tanso_stateorProvince/sum(nrow(dt))
tansuat_stateorProvince
##
## 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
Đồ thị
# Màu cho từng lát
cols <- rainbow(length(tansuat_stateorProvince))
# Nhãn phần trăm
nhanstateorProvince <- paste0( round(tansuat_stateorProvince * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_stateorProvince,
labels = NA,
main = "Tần suất biến bang hoặc tỉnh",
col = cols,
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_stateorProvince),nhanstateorProvince),
fill = cols,
bty = "n", # bỏ viền
cex = 0.5, # thu nhỏ chữ
ncol = 2, # chia thành 2 cột
)
Nhận xét: Trong bộ dữ liệu này, bang hoặc tỉnh có tỷ lệ giao dịch lớn nhất là WA với khoảng 32.48%, tiếp theo là CA (19.44%) và OR (16.09%). Các bang như Jalisco (0.53%) và Guerrero (2.72%) chiếm tỷ lệ thấp hơn. Như vậy, dữ liệu cho thấy sự tập trung giao dịch cao ở một số bang chính.
Bảng tần số
#Lập bảng tần số của biến Country
tanso_country <- table(dt$Country)
tanso_country
##
## Canada Mexico USA
## 809 3688 9562
Biểu đồ
barplot(
tanso_country,
main = "tần số biến quốc gia",
xlab = "quốc gia",
ylab = "số lượng",
las = 1,
col = c("brown","orange","pink"),
border = "white"
)
Bảng tần suất
#Lập bảng tần suất của biến Country
tansuat_country <- tanso_country/sum(nrow(dt))
tansuat_country
##
## Canada Mexico USA
## 0.05754321 0.26232307 0.68013372
Biểu đồ
# Nhãn phần trăm
nhancountry <- paste0( round(tansuat_country * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_country,
labels = NA,
main = "Tần suất biến quốc gia",
col = rainbow(length(nhancountry)),
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_country),nhancountry),
fill = rainbow(length(nhancountry)),
bty ="n"
)
Nhận xét:
# Đếm số bản ghi theo quốc gia
cty_counts <- table(dt$Country)
# Chênh lệch về số lượng giữa quốc gia đông nhất và ít nhất
cty_diff <- max(cty_counts) - min(cty_counts)
Vậy trong bộ dữ liệu này có 5.7543211 % ở Canada, 26.2323067% ở Mexico và 68.0133722% ở USA.
Quốc gia đông nhất có 9562, quốc gia ít nhất có r
min(cty_counts)
.
Sự chênh lệch giữa hai quốc gia này là 8753 người.
Bảng tần số
#Lập bảng tần số của biến ProductFamily
tanso_productFamily <- table(dt$ProductFamily)
tanso_productFamily
##
## Drink Food Non-Consumable
## 1250 10153 2656
Biểu đồ
barplot(
tanso_productFamily,
main = "tần số biến nhóm sản phẩm",
xlab = "nhóm sản phẩm",
ylab = "số lượng",
las = 1,
col = c("yellow","purple","pink"),
border = "white"
)
Bảng tần suất
#Lập bảng tần suất của biến ProductFamily
tansuat_productFamily <- tanso_productFamily/sum(nrow(dt))
tansuat_productFamily
##
## Drink Food Non-Consumable
## 0.08891102 0.72217085 0.18891813
Biểu đồ
cols <- c("lightblue","lightpink","lightgreen")
# Nhãn phần trăm
nhanproductFamily <- paste0( round(tansuat_productFamily * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_productFamily,
labels = NA,
main = "Tần suất biến nhóm sản phẩm",
col = cols,
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_productFamily),nhanproductFamily),
fill = cols,
)
Nhận xét:
Bảng tần số
# Lập bảng tần số
tanso_productDepartment <- table(dt$ProductDepartment)
tanso_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
Biểu đồ
barplot(
tanso_productDepartment,
main = "Tần số biến bộ phận sản phẩm trong nhóm",
cex.names = 0.4,
xlab = "Số quan sát",
ylab = "",
las = 1, # xoay nhãn trục y ngang
col = "lightblue",
border = "white",
horiz = TRUE # vẽ thanh ngang để đọc nhãn dễ hơn
)
Bảng tần suất
tansuat_productDepartment <-tanso_productDepartment/sum(nrow(dt))
tansuat_productDepartment
##
## 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
Nhận xét:
Bảng tần số
tanso_productCategory <- table(dt$ProductCategory)
tanso_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
Biểu đồ
barplot(
tanso_productCategory,
main = "Tần số biến hạng mục sản phẩm cụ thể",
cex.names = 0.4,
xlab = "Số quan sát",
ylab = "",
las = 1, # xoay nhãn trục y ngang
col = "lightpink",
border = "white",
horiz = TRUE # vẽ thanh ngang để đọc nhãn dễ hơn
)
Bảng tần suất
tansuat_productCategory <- tanso_productCategory/sum(nrow(dt))
tansuat_productCategory
##
## 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
Nhận xét:
Bảng tần số
# Bảng tần suất cho AnnualIncome
tanso_annualIncome <- table(dt$AnnualIncome)
tanso_annualIncome
##
## $10K - $30K $110K - $130K $130K - $150K $150K + $30K - $50K
## 3090 643 760 273 4601
## $50K - $70K $70K - $90K $90K - $110K
## 2370 1709 613
Biểu đồ
barplot(
tanso_annualIncome,
main = "Tần số theo Thu nhập",
cex.names = 0.4,
xlab = "AnnualIncome",
ylab = "số thu nhập",
las = 1, # xoay nhãn trục y ngang
col = "lightblue",
border = "white",
horiz = TRUE # vẽ thanh ngang để đọc nhãn dễ hơn
)
Bảng tần suất
tansuat_annualIncome <- tanso_annualIncome/sum(nrow(dt))
tansuat_annualIncome
##
## $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
Biểu đồ
# Màu cho từng lát
cols <- rainbow(length(tansuat_annualIncome))
# Nhãn phần trăm
nhanannualIncome <- paste0( round(tansuat_annualIncome * 100, 1), "%")
# Vẽ pie chart ẩn nhãn
pie(
tansuat_annualIncome,
labels = NA,
main = "Tần suất biến thu nhập",
col = cols,
border = "white")
# Thêm legend bên ngoài
legend(
x ="topright",
legend = paste(names(tansuat_annualIncome),nhanannualIncome),
fill = cols,
bty = "n", # bỏ viền
cex = 0.5, # thu nhỏ chữ
ncol = 2, # chia thành 2 cột
x.intersp = 0.5, # giãn khoảng cách chữ–ký hiệu ngang
y.intersp = 0.7 # giãn khoảng cách giữa các dòng
)
Nhận xét:
Sự phân bố thu nhập không đều phản ánh cơ cấu khách hàng của siêu thị hoặc đơn vị khảo sát: tập trung nhiều ở các nhóm thu nhập trung bình đến trung cao, trong khi nhóm thu nhập quá thấp hoặc quá cao xuất hiện ít hơn.
Đây có thể là dấu hiệu để doanh nghiệp điều chỉnh chiến lược tiếp cận thị trường, như tập trung nhiều hơn vào các nhóm thu nhập đang chiếm ưu thế, hoặc mở rộng các chính sách ưu đãi để thu hút nhóm khách hàng ít phổ biến hơn.
# Tổng số bản ghi (n)
n <- nrow(dt)
Giả thuyết đặt ra như sau:
H₀: p = p₀
H₁: p ≠ p₀
# 1) Đếm số khách nữ
count_female <- sum(dt$Gender == "F")
# 2) Đặt H₀: p_F = 0.50; H₁: p_F ≠ 0.50
p0 <- 0.5
# 3) Thực hiện prop.test
res_female <- prop.test(x = count_female,
n = n,
p = p0,
conf.level= 0.95)
print(res_female)
##
## 1-sample proportions test with continuity correction
##
## data: count_female out of n, null probability p0
## X-squared = 5.5765, df = 1, p-value = 0.0182
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5016931 0.5182886
## sample estimates:
## p
## 0.5099936
Nhận xét
Ta có p-value = 0.0182 < α = 0.05, bác H₀ (tỉ lệ nữ = 0.5) và chấp nhận H₁: tỉ lệ nữ khác 50% ở mức ý nghĩa 5%.
Khoảng tin cậy 95% cho tỉ lệ nữ là [0.5017, 0.5183], không chứa 0.5, củng cố rằng tỉ lệ nữ thực sự cao hơn 50%.
Ước tính tỉ lệ nữ trong mẫu là p̂ ≈ 0.51 (51%), nghĩa là tỉ lệ nữ vượt ngưỡng 50% khoảng 1%.
count_owner <- sum(dt$Homeowner == "Y")
p0_owner <- 0.50 # Giả thuyết H₀: 50% là có sỡ hữu nhà
res_owner <- prop.test(x = count_owner,
n = n,
p = p0_owner,
conf.level= 0.95)
print(res_owner)
##
## 1-sample proportions test with continuity correction
##
## data: count_owner out of n, null probability p0_owner
## X-squared = 568.86, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5924537 0.6087145
## sample estimates:
## p
## 0.6006117
Nhận xét
Ta có p-value < 2.2e-16 < α = 0.05, nên bác bỏ H₀ (tỉ lệ sở hữu nhà = 0.5) và chấp nhận H₁: tỉ lệ chủ sở hữu khác 50% ở mức ý nghĩa 5%.
Khoảng tin cậy 95% cho tỉ lệ chủ sở hữu là [0.5925, 0.6087], không bao gồm 0.5, khẳng định tỉ lệ chủ sở hữu thực sự cao hơn 50%.
Ước tính tỉ lệ chủ sở hữu trong mẫu là p̂ ≈ 0.6006 (60.06%), nghĩa là tỉ lệ chủ sở hữu vượt 50% khoảng 10%.
count_food <- sum(dt$ProductFamily == "Food")
p0_food <- 0.50 # H₀: 50% giao dịch thuộc nhóm Food
res_food <- prop.test(x = count_food,
n = n,
p = p0_food,
conf.level= 0.95)
print(res_food)
##
## 1-sample proportions test with continuity correction
##
## data: count_food out of n, null probability p0_food
## X-squared = 2774.9, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.7146709 0.7295489
## sample estimates:
## p
## 0.7221709
Nhận xét
Ta có p-value < 2.2e-16 < α = 0.05, nên bác bỏ H₀ (tỉ lệ food = 0.5) và chấp nhận H₁: tỉ lệ food khác 50% ở mức ý nghĩa 5%.
Khoảng tin cậy 95% cho tỉ lệ food là [0.7147, 0.7295], không bao gồm 0.5, khẳng định tỉ lệ food thực sự cao hơn 50%.
Ước tính tỉ lệ food trong mẫu là p̂ ≈ 0.7222 (72.22%), nghĩa là tỉ lệ food vượt ngưỡng 50% khoảng 22%—một chênh lệch đáng kể cả về thực tiễn và thống kê.
# Bảng chéo counts
tab_gf <- table(Gender = dt$Gender, ProductFamily = dt$ProductFamily)
tab_gf
## ProductFamily
## Gender Drink Food Non-Consumable
## F 669 5149 1352
## M 581 5004 1304
# Tỉ lệ theo hàng (row‐%)
pct_gf <- round(prop.table(tab_gf, margin = 1) * 100, 1)
pct_gf
## ProductFamily
## Gender Drink Food Non-Consumable
## F 9.3 71.8 18.9
## M 8.4 72.6 18.9
Nhận xét
Drink
Về số lượng: nữ có 669 giao dịch so với 581 của nam, nhiều hơn 88 giao dịch.
Về tỉ lệ: nữ chiếm 9.3% tổng giao dịch của mình, nam chiếm 8.4%, chênh +0.9%.
Vậy phụ nữ có xu hướng mua đồ uống hơi nhiều hơn nam, nhưng chênh chưa đến 1%.
Food
Về số lượng: nữ 5.149 giao dịch, nam 5.004, nhiều hơn 145 giao dịch.
Về tỉ lệ: nữ 71.8%, nam 72.6%, chênh −0.8%.
Vậy dù có nhiều giao dịch Food hơn về con số tuyệt đối, vì tổng giao dịch của nữ cũng nhiều hơn, nên tỉ lệ lại thấp hơn nam một chút.
Non-Consumable
Về số lượng: nữ 1.352 giao dịch, nam 1.304, nhiều hơn 48 giao dịch.
Về tỉ lệ: cả hai đều 18.9%, chênh 0.0%.
vậy sự khác biệt thật sự rất nhỏ, tỉ lệ ngang bằng.
library(ggplot2)
gf_df <- as.data.frame(table(Gender = dt$Gender, ProductFamily = dt$ProductFamily))
ggplot( gf_df, aes(x = ProductFamily,y = Freq, fill = Gender, group = Gender)) +
geom_col(position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(
name = "Giới tính",
values = c("F" = "lightgreen", "M" = "yellow"),
labels = c("Nữ", "Nam")
) +
labs(
title = "Số giao dịch theo sản phẩm & giới tính",
x = "Nhóm sản phẩm",
y = "Số giao dịch"
) +
theme_minimal()
Giả thuyết kiểm định:
H₀: Giới và nhóm sản phẩmlà hai biến độc lập.
H₁: Giới và nhóm sản phẩm có liên quan.
test_gf <- chisq.test(tab_gf)
test_gf
##
## Pearson's Chi-squared test
##
## data: tab_gf
## X-squared = 3.5185, df = 2, p-value = 0.1722
Nhận xét
tab_mo <- table(Marital = dt$MaritalStatus, Owner = dt$Homeowner)
tab_mo
## Owner
## Marital N Y
## M 1719 5147
## S 3896 3297
pct_mo <- round(prop.table(tab_mo, margin = 1) * 100, 1)
pct_mo
## Owner
## Marital N Y
## M 25.0 75.0
## S 54.2 45.8
# Giả sử tab_mo đã được tạo như trên
diff_owner_count <- tab_mo["M", "Y"] - tab_mo["S", "Y"]
diff_not_owner_count <- tab_mo["S", "N"] - tab_mo["M", "N"]
Nhận xét
Trong bộ dữ liệu, có 3896 người độc thân không sở hữu nhà và 3297 người độc thân sở hữu nhà. Ngoài ra, có 1719 người đã kết hôn không sở hữu nhà và 5147 người đã kết hôn sở hữu nhà.
Số người đã kết hôn sở hữu nhà nhiều hơn người độc thân là 1850 người.
Người độc thân không sở hữu nhà nhiều hơn người đã kết hôn là 2177 người.
library(ggplot2)
mo_df <- as.data.frame(table(Marital = dt$MaritalStatus, Owner = dt$Homeowner))
ggplot( mo_df, aes(x = Marital,y = Freq, fill = Owner, group = Owner)) +
geom_col(position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(
name = "Sở hữu nhà",
values = c("Y" = "lightblue","N" = "lightpink"),
labels = c("Có", "Không")
) +
labs(
title = "Số khách có/không sở hữu nhà theo tình trạng hôn nhân",
x = "Tình trạng hôn nhân",
y = "Số khách hàng"
) +
theme_minimal()
Giả thuyết kiểm định:
H₀: Tình trạng hôn nhân và việc sở hữu nhà là hai biến độc lập.
H₁: Tình trạng hôn nhân và việc sở hữu nhà có liên quan.
test_mo <- chisq.test(tab_mo)
test_mo
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: tab_mo
## X-squared = 1241.2, df = 1, p-value < 2.2e-16
Nhận xét
tab_ap <- table(Income = dt$AnnualIncome, Category = dt$ProductCategory)
tab_ap
## Category
## Income Baking Goods Bathroom Products Beer and Wine Bread
## $10K - $30K 119 85 80 108
## $110K - $130K 18 16 14 23
## $130K - $150K 22 19 15 24
## $150K + 11 8 3 10
## $30K - $50K 151 116 121 134
## $50K - $70K 86 50 61 63
## $70K - $90K 59 51 39 50
## $90K - $110K 18 20 23 13
## Category
## Income Breakfast Foods Candles Candy Canned Anchovies Canned Clams
## $10K - $30K 111 6 76 10 12
## $110K - $130K 7 1 16 2 1
## $130K - $150K 28 2 19 1 3
## $150K + 7 1 8 1 1
## $30K - $50K 143 21 127 14 20
## $50K - $70K 62 7 60 8 6
## $70K - $90K 42 7 29 6 7
## $90K - $110K 17 0 17 2 3
## Category
## Income Canned Oysters Canned Sardines Canned Shrimp Canned Soup
## $10K - $30K 5 8 9 98
## $110K - $130K 4 2 0 19
## $130K - $150K 3 1 2 17
## $150K + 1 1 0 8
## $30K - $50K 10 18 16 137
## $50K - $70K 5 5 7 67
## $70K - $90K 5 3 2 50
## $90K - $110K 2 2 2 8
## Category
## Income Canned Tuna Carbonated Beverages Cleaning Supplies
## $10K - $30K 13 36 47
## $110K - $130K 3 6 8
## $130K - $150K 5 3 7
## $150K + 3 6 4
## $30K - $50K 28 51 51
## $50K - $70K 19 20 35
## $70K - $90K 10 23 25
## $90K - $110K 6 9 12
## Category
## Income Cold Remedies Dairy Decongestants Drinks Eggs Electrical
## $10K - $30K 23 174 22 30 37 74
## $110K - $130K 2 38 4 9 9 20
## $130K - $150K 6 49 5 8 15 21
## $150K + 3 17 0 4 4 8
## $30K - $50K 32 299 31 46 67 114
## $50K - $70K 12 160 8 19 36 57
## $70K - $90K 10 126 10 16 20 47
## $90K - $110K 5 40 5 3 10 14
## Category
## Income Frozen Desserts Frozen Entrees Fruit Hardware Hot Beverages
## $10K - $30K 75 20 150 31 48
## $110K - $130K 17 10 29 3 11
## $130K - $150K 17 5 48 10 9
## $150K + 8 2 10 1 5
## $30K - $50K 112 35 252 41 79
## $50K - $70K 44 21 136 25 33
## $70K - $90K 36 18 104 13 26
## $90K - $110K 14 7 36 5 15
## Category
## Income Hygiene Jams and Jellies Kitchen Products Magazines Meat
## $10K - $30K 36 137 47 49 156
## $110K - $130K 6 31 5 17 41
## $130K - $150K 14 32 14 9 52
## $150K + 4 8 3 1 14
## $30K - $50K 62 185 74 65 253
## $50K - $70K 37 103 51 36 115
## $70K - $90K 29 71 20 18 100
## $90K - $110K 9 21 3 7 30
## Category
## Income Miscellaneous Packaged Vegetables Pain Relievers Paper Products
## $10K - $30K 10 9 42 70
## $110K - $130K 1 1 7 19
## $130K - $150K 6 1 8 17
## $150K + 0 2 5 8
## $30K - $50K 8 20 61 101
## $50K - $70K 14 8 34 67
## $70K - $90K 2 7 30 46
## $90K - $110K 1 0 5 17
## Category
## Income Pizza Plastic Products Pure Juice Beverages Seafood Side Dishes
## $10K - $30K 50 41 34 17 36
## $110K - $130K 13 6 9 3 2
## $130K - $150K 12 7 5 8 8
## $150K + 1 2 5 5 3
## $30K - $50K 59 33 52 44 53
## $50K - $70K 31 31 25 11 23
## $70K - $90K 15 17 26 12 23
## $90K - $110K 13 4 9 2 5
## Category
## Income Snack Foods Specialty Starchy Foods Vegetables
## $10K - $30K 329 65 70 385
## $110K - $130K 85 13 18 74
## $130K - $150K 83 18 15 87
## $150K + 35 5 5 32
## $30K - $50K 533 96 85 551
## $50K - $70K 274 50 48 300
## $70K - $90K 184 32 28 215
## $90K - $110K 77 10 8 84
pct_ap <- round(prop.table(tab_ap, margin = 1) * 100, 1)
pct_ap
## Category
## Income Baking Goods Bathroom Products Beer and Wine Bread
## $10K - $30K 3.9 2.8 2.6 3.5
## $110K - $130K 2.8 2.5 2.2 3.6
## $130K - $150K 2.9 2.5 2.0 3.2
## $150K + 4.0 2.9 1.1 3.7
## $30K - $50K 3.3 2.5 2.6 2.9
## $50K - $70K 3.6 2.1 2.6 2.7
## $70K - $90K 3.5 3.0 2.3 2.9
## $90K - $110K 2.9 3.3 3.8 2.1
## Category
## Income Breakfast Foods Candles Candy Canned Anchovies Canned Clams
## $10K - $30K 3.6 0.2 2.5 0.3 0.4
## $110K - $130K 1.1 0.2 2.5 0.3 0.2
## $130K - $150K 3.7 0.3 2.5 0.1 0.4
## $150K + 2.6 0.4 2.9 0.4 0.4
## $30K - $50K 3.1 0.5 2.8 0.3 0.4
## $50K - $70K 2.6 0.3 2.5 0.3 0.3
## $70K - $90K 2.5 0.4 1.7 0.4 0.4
## $90K - $110K 2.8 0.0 2.8 0.3 0.5
## Category
## Income Canned Oysters Canned Sardines Canned Shrimp Canned Soup
## $10K - $30K 0.2 0.3 0.3 3.2
## $110K - $130K 0.6 0.3 0.0 3.0
## $130K - $150K 0.4 0.1 0.3 2.2
## $150K + 0.4 0.4 0.0 2.9
## $30K - $50K 0.2 0.4 0.3 3.0
## $50K - $70K 0.2 0.2 0.3 2.8
## $70K - $90K 0.3 0.2 0.1 2.9
## $90K - $110K 0.3 0.3 0.3 1.3
## Category
## Income Canned Tuna Carbonated Beverages Cleaning Supplies
## $10K - $30K 0.4 1.2 1.5
## $110K - $130K 0.5 0.9 1.2
## $130K - $150K 0.7 0.4 0.9
## $150K + 1.1 2.2 1.5
## $30K - $50K 0.6 1.1 1.1
## $50K - $70K 0.8 0.8 1.5
## $70K - $90K 0.6 1.3 1.5
## $90K - $110K 1.0 1.5 2.0
## Category
## Income Cold Remedies Dairy Decongestants Drinks Eggs Electrical
## $10K - $30K 0.7 5.6 0.7 1.0 1.2 2.4
## $110K - $130K 0.3 5.9 0.6 1.4 1.4 3.1
## $130K - $150K 0.8 6.4 0.7 1.1 2.0 2.8
## $150K + 1.1 6.2 0.0 1.5 1.5 2.9
## $30K - $50K 0.7 6.5 0.7 1.0 1.5 2.5
## $50K - $70K 0.5 6.8 0.3 0.8 1.5 2.4
## $70K - $90K 0.6 7.4 0.6 0.9 1.2 2.8
## $90K - $110K 0.8 6.5 0.8 0.5 1.6 2.3
## Category
## Income Frozen Desserts Frozen Entrees Fruit Hardware Hot Beverages
## $10K - $30K 2.4 0.6 4.9 1.0 1.6
## $110K - $130K 2.6 1.6 4.5 0.5 1.7
## $130K - $150K 2.2 0.7 6.3 1.3 1.2
## $150K + 2.9 0.7 3.7 0.4 1.8
## $30K - $50K 2.4 0.8 5.5 0.9 1.7
## $50K - $70K 1.9 0.9 5.7 1.1 1.4
## $70K - $90K 2.1 1.1 6.1 0.8 1.5
## $90K - $110K 2.3 1.1 5.9 0.8 2.4
## Category
## Income Hygiene Jams and Jellies Kitchen Products Magazines Meat
## $10K - $30K 1.2 4.4 1.5 1.6 5.0
## $110K - $130K 0.9 4.8 0.8 2.6 6.4
## $130K - $150K 1.8 4.2 1.8 1.2 6.8
## $150K + 1.5 2.9 1.1 0.4 5.1
## $30K - $50K 1.3 4.0 1.6 1.4 5.5
## $50K - $70K 1.6 4.3 2.2 1.5 4.9
## $70K - $90K 1.7 4.2 1.2 1.1 5.9
## $90K - $110K 1.5 3.4 0.5 1.1 4.9
## Category
## Income Miscellaneous Packaged Vegetables Pain Relievers Paper Products
## $10K - $30K 0.3 0.3 1.4 2.3
## $110K - $130K 0.2 0.2 1.1 3.0
## $130K - $150K 0.8 0.1 1.1 2.2
## $150K + 0.0 0.7 1.8 2.9
## $30K - $50K 0.2 0.4 1.3 2.2
## $50K - $70K 0.6 0.3 1.4 2.8
## $70K - $90K 0.1 0.4 1.8 2.7
## $90K - $110K 0.2 0.0 0.8 2.8
## Category
## Income Pizza Plastic Products Pure Juice Beverages Seafood Side Dishes
## $10K - $30K 1.6 1.3 1.1 0.6 1.2
## $110K - $130K 2.0 0.9 1.4 0.5 0.3
## $130K - $150K 1.6 0.9 0.7 1.1 1.1
## $150K + 0.4 0.7 1.8 1.8 1.1
## $30K - $50K 1.3 0.7 1.1 1.0 1.2
## $50K - $70K 1.3 1.3 1.1 0.5 1.0
## $70K - $90K 0.9 1.0 1.5 0.7 1.3
## $90K - $110K 2.1 0.7 1.5 0.3 0.8
## Category
## Income Snack Foods Specialty Starchy Foods Vegetables
## $10K - $30K 10.6 2.1 2.3 12.5
## $110K - $130K 13.2 2.0 2.8 11.5
## $130K - $150K 10.9 2.4 2.0 11.4
## $150K + 12.8 1.8 1.8 11.7
## $30K - $50K 11.6 2.1 1.8 12.0
## $50K - $70K 11.6 2.1 2.0 12.7
## $70K - $90K 10.8 1.9 1.6 12.6
## $90K - $110K 12.6 1.6 1.3 13.7
Nhận xét
Nhóm thu nhập từ "$30K - $50K"
ghi nhận số giao dịch
cao nhất ở hầu hết các danh mục, ví dụ:
Điều này có thể là do nhóm thu nhập trung lưu có khả năng chi tiêu cao nhưng vẫn ưu tiên các mặt hàng thiết yếu.
Nhóm thu nhập thấp ("$10K - $30K"
) cũng có lượng
giao dịch tương đối lớn, đặc biệt ở:
Điều này cho thấy nhu cầu với sản phẩm cơ bản, giá cả phải chăng vẫn rất cao.
Ngược lại, nhóm thu nhập cao ("$130K - $150K"
,
"$150K +"
) có số giao dịch thấp hơn rõ rệt, ví dụ:
Có thể do số mẫu nhóm thu nhập cao ít hơn hoặc họ ưu tiên mua sắm online, sản phẩm cao cấp hơn.
Giả thuyết kiểm định:
H₀: Hai biến khoảng thu nhập hằng năm và hạng mục sản phẩm là độc lập.
H₁: Hai biến khoảng thu nhập hằng năm và hạng mục sản phẩm có mối liên quan.
test_sp <- chisq.test(tab_ap)
## Warning in chisq.test(tab_ap): Chi-squared approximation may be incorrect
test_sp
##
## Pearson's Chi-squared test
##
## data: tab_ap
## X-squared = 295.23, df = 308, p-value = 0.6897
Nhận xét
Tuần này, chúng ta đi sâu vào suy diễn thống kê trên bảng ngẫu nhiên (Contingency Table), đặc biệt tập trung vào:
Đọc dữ liệu và khám phá
library("csv")
data <- read.csv("C:/Users/ASUS/Downloads/Supermarket Transactions.csv", header = T)
str(data)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
## $ CustomerID : int 7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
## $ Gender : chr "F" "M" "F" "M" ...
## $ MaritalStatus : chr "S" "M" "M" "M" ...
## $ Homeowner : chr "Y" "Y" "N" "Y" ...
## $ Children : int 2 5 2 3 3 3 2 2 3 1 ...
## $ AnnualIncome : chr "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
## $ City : chr "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
## $ StateorProvince : chr "CA" "CA" "WA" "OR" ...
## $ Country : chr "USA" "USA" "USA" "USA" ...
## $ ProductFamily : chr "Food" "Food" "Food" "Food" ...
## $ ProductDepartment: chr "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
## $ ProductCategory : chr "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
## $ UnitsSold : int 5 5 3 4 4 3 4 6 1 2 ...
## $ Revenue : num 27.38 14.9 5.52 4.44 14 ...
Đầu tiên, ta sẽ sử dụng 2 biến định tính: Gender (Giới tính) và Homeowner (Có sở hữu nhà hay không) để tiến hành đưa ra ví dụ cũng như phân tích.
Bảng ngẫu nhiên (contingency table) là công cụ thống kê dùng để trình bày tần số của các biến phân loại. Trong trường hợp đơn giản nhất – bảng 2x2 – bảng có dạng:
Biến B = Yes | Biến B = No | |
---|---|---|
Biến A = Yes | a | b |
Biến A = No | c | d |
Trong phân tích thống kê, bảng 2x2 thường dùng để:
Bảng có thể sinh ra từ các phân phối như:
Các bước thực hiện trong R
table_gender_homeowner <- table(data$Gender, data$Homeowner)
table_gender_homeowner
##
## N Y
## F 2826 4344
## M 2789 4100
Lý thuyết: Kiểm định Chi-square
Dùng để kiểm tra xem hai biến phân loại có độc lập thống kê không.
Chỉ số kiểm định: \[ X^2 = \sum \frac{(O_{ij} - E_{ij})^2}{E_{ij}} \]
Trong đó:
Nếu p-value < 0.05, ta có đủ cơ sở để bác bỏ H₀ → Có bằng chứng về sự phụ thuộc giữa hai biến.
Các bước thực hiện trong R
chisq.test(table_gender_homeowner, correct = FALSE)
##
## Pearson's Chi-squared test
##
## data: table_gender_homeowner
## X-squared = 1.6788, df = 1, p-value = 0.1951
Khái niệm: Relative Risk (RR) là tỷ lệ giữa xác suất xảy ra sự kiện ở nhóm tiếp xúc so với nhóm không tiếp xúc.
Công thức:
\[ RR = \frac{\frac{a}{a+b}}{\frac{c}{c+d}} \]
Diễn giải:
Khái niệm: Odds Ratio (OR) là tỷ lệ giữa odds xảy ra sự kiện ở nhóm tiếp xúc so với nhóm không tiếp xúc.
Công thức:
\[ OR = \frac{\frac{a}{b}}{\frac{c}{d}} = \frac{a \times d}{b \times c} \]
Diễn giải:
Các bước thực hiện trên R
# Lấy số liệu
a <- table_gender_homeowner["F", "Y"]
b <- table_gender_homeowner["F", "N"]
c <- table_gender_homeowner["M", "Y"]
d <- table_gender_homeowner["M", "N"]
# Tính Odds
odds_female <- a / b
odds_male <- c / d
# Odds Ratio (OR)
or <- odds_female / odds_male
# Relative Risk (RR)
risk_female <- a / (a + b)
risk_male <- c / (c + d)
rr <- risk_female / risk_male
list(
odds_female = odds_female,
odds_male = odds_male,
OR = or,
RR = rr
)
## $odds_female
## [1] 1.537155
##
## $odds_male
## [1] 1.470061
##
## $OR
## [1] 1.04564
##
## $RR
## [1] 1.017989
Khoảng tin cậy 95% cho Odds Ratio
Do OR không phân phối chuẩn, nên lấy log(OR) để xây dựng khoảng tin cậy:
\[ CI_{log(OR)} = \log(OR) \pm Z \cdot SE_{log(OR)} \]
Với: \[ SE = \sqrt{\frac{1}{a} + \frac{1}{b} + \frac{1}{c} + \frac{1}{d}} \]
Chuyển về thang OR bằng hàm mũ: \(e^{CI}\).
Các bước thực hiện trên R
se_log_or <- sqrt(1/a + 1/b + 1/c + 1/d)
z <- 1.96 # hệ số cho 95%
ci_lower <- exp(log(or) - z * se_log_or)
ci_upper <- exp(log(or) + z * se_log_or)
c(ci_lower, ci_upper)
## [1] 0.9773755 1.1186731
Nhận xét:
Kết luận cần đi kèm với kiểm định Chi-square và khoảng tin cậy, không nên chỉ nhìn vào OR/RR.
Đây là một ví dụ điển hình cho việc sử dụng Odds Ratio trong kinh tế/xã hội học để mô tả mối liên hệ giữa hai đặc điểm phân loại.
Tạo bảng tần số
# Bảng tần số chéo giữa MaritalStatus và Homeowner
tbl <- table(data$MaritalStatus, data$Homeowner)
tbl
##
## N Y
## M 1719 5147
## S 3896 3297
Nhận xét
Khách hàng đã kết hôn (M): Có tới 5147 người sở hữu nhà ở, chiếm phần lớn trong nhóm này, trong khi chỉ có 1719 người không sở hữu nhà.
Khách hàng độc thân (S): Ngược lại, nhóm này có xu hướng không sở hữu nhà ở cao hơn với 3896 người, trong khi số người sở hữu nhà chỉ là 3297 người.
Kiểm định Chi-square
chi_test <- chisq.test(tbl)
chi_test
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: tbl
## X-squared = 1241.2, df = 1, p-value < 2.2e-16
Kết quả kiểm định:
Giá trị thống kê Chi-bình phương: X-squared = 1241.2
Bậc tự do: df = 1
Giá trị p: p-value < 2.2e-16
Kết luận:
Tính Odds Ratio và Relative Risk
# Lọc dữ liệu: chỉ lấy Married và Single
data2 <- subset(data, MaritalStatus %in% c("M", "S"))
# Tạo bảng 2x2
tbl2 <- table(data2$MaritalStatus, data2$Homeowner)
tbl2
##
## N Y
## M 1719 5147
## S 3896 3297
# Tính toán Odds Ratio và Relative Risk
library(epiR)
## Loading required package: survival
## Package epiR 2.0.84 is loaded
## Type help(epi.about) for summary information
## Type browseVignettes(package = 'epiR') to learn how to use epiR for applied epidemiological analyses
##
epi_result <- epi.2by2(tbl2, method = "cohort.count", conf.level = 0.95)
epi_result
## Outcome+ Outcome- Total Inc risk *
## Exposure+ 1719 5147 6866 25.04 (24.02 to 26.08)
## Exposure- 3896 3297 7193 54.16 (53.00 to 55.32)
## Total 5615 8444 14059 39.94 (39.13 to 40.75)
##
## Point estimates and 95% CIs:
## -------------------------------------------------------------------
## Inc risk ratio 0.46 (0.44, 0.48)
## Inc odds ratio 0.28 (0.26, 0.30)
## Attrib risk in the exposed * -29.13 (-30.67, -27.59)
## Attrib fraction in the exposed (%) -116.34 (-126.59, -106.62)
## Attrib risk in the population * -14.22 (-15.63, -12.82)
## Attrib fraction in the population (%) -35.62 (-35.74, -35.46)
## -------------------------------------------------------------------
## Uncorrected chi2 test that OR = 1: chi2(1) = 1242.432 Pr>chi2 = <0.001
## Fisher exact test that OR = 1: Pr>chi2 = <0.001
## Wald confidence limits
## CI: confidence interval
## * Outcomes per 100 population units
Bảng chéo tần suất giữa MaritalStatus và Homeowner
Marital Status | Không sở hữu nhà (N) | Có sở hữu nhà (Y) | Tổng cộng |
---|---|---|---|
Married (M) | 1,719 | 5,147 | 6,866 |
Single (S) | 3,896 | 3,297 | 7,193 |
Tổng cộng | 5,615 | 8,444 | 14,059 |
Tỷ lệ hiện mắc (Incidence Risk)
Những người độc thân có xác suất không sở hữu nhà cao hơn gấp đôi so với người đã kết hôn.
Relative Risk (RR)
Nguy cơ không sở hữu nhà ở nhóm đã kết hôn chỉ bằng 46% so với nhóm độc thân.
Odds Ratio (OR)
Xác suất không sở hữu nhà ở nhóm đã kết hôn thấp hơn 72% so với nhóm độc thân.
Risk Difference và Attribution
Điều này cho thấy rằng việc kết hôn có thể giúp giảm đáng kể rủi ro không sở hữu nhà ở cấp độ cá nhân lẫn dân số.
Kiểm định ý nghĩa thống kê
Kết quả kiểm định cho thấy mối liên hệ giữa tình trạng hôn nhân và việc sở hữu nhà là rất có ý nghĩa thống kê (p < 0.001).
Kết luận:
Trong hoạt động này, chúng ta sẽ sử dụng dữ liệu Supermarket Transactions để phân tích mối liên hệ giữa các biến nhị phân. Mục tiêu là:
Bộ dữ liệu “Supermarket Transactions” phản ánh các giao dịch mua hàng của khách hàng tại một siêu thị trong một khoảng thời gian cụ thể. Mỗi dòng dữ liệu tương ứng với một giao dịch, bao gồm thông tin nhân khẩu học (giới tính, loại thành viên, chi nhánh), đặc điểm sản phẩm (loại sản phẩm, kênh thanh toán), và các yếu tố hành vi tiêu dùng (thời gian mua sắm, mức độ hài lòng, giá trị đơn hàng,…). Tập dữ liệu gồm 14.059 quan sát và 16 biến, cung cấp nền tảng chi tiết để phân tích hành vi khách hàng và hiệu quả kinh doanh của siêu thị.
# Đọc file
library("csv")
data <- read.csv("C:/Users/ASUS/Downloads/Supermarket Transactions.csv", header = T)
# Hiển thị cấu trúc dữ liệu
str(data)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
## $ CustomerID : int 7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
## $ Gender : chr "F" "M" "F" "M" ...
## $ MaritalStatus : chr "S" "M" "M" "M" ...
## $ Homeowner : chr "Y" "Y" "N" "Y" ...
## $ Children : int 2 5 2 3 3 3 2 2 3 1 ...
## $ AnnualIncome : chr "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
## $ City : chr "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
## $ StateorProvince : chr "CA" "CA" "WA" "OR" ...
## $ Country : chr "USA" "USA" "USA" "USA" ...
## $ ProductFamily : chr "Food" "Food" "Food" "Food" ...
## $ ProductDepartment: chr "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
## $ ProductCategory : chr "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
## $ UnitsSold : int 5 5 3 4 4 3 4 6 1 2 ...
## $ Revenue : num 27.38 14.9 5.52 4.44 14 ...
# Hiển thị vài dòng đầu và cuối
head(data)
## X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 1 1 2007-12-18 7223 F S Y 2
## 2 2 2007-12-20 7841 M M Y 5
## 3 3 2007-12-21 8374 F M N 2
## 4 4 2007-12-21 9619 M M Y 3
## 5 5 2007-12-22 1900 F S Y 3
## 6 6 2007-12-22 6696 F M Y 3
## AnnualIncome City StateorProvince Country ProductFamily
## 1 $30K - $50K Los Angeles CA USA Food
## 2 $70K - $90K Los Angeles CA USA Food
## 3 $50K - $70K Bremerton WA USA Food
## 4 $30K - $50K Portland OR USA Food
## 5 $130K - $150K Beverly Hills CA USA Drink
## 6 $10K - $30K Beverly Hills CA USA Food
## ProductDepartment ProductCategory UnitsSold Revenue
## 1 Snack Foods Snack Foods 5 27.38
## 2 Produce Vegetables 5 14.90
## 3 Snack Foods Snack Foods 3 5.52
## 4 Snacks Candy 4 4.44
## 5 Beverages Carbonated Beverages 4 14.00
## 6 Deli Side Dishes 3 4.37
tail(data)
## X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 14054 14054 2009-12-29 2032 F M N 3
## 14055 14055 2009-12-29 9102 F M Y 2
## 14056 14056 2009-12-29 4822 F M Y 3
## 14057 14057 2009-12-31 250 M S Y 1
## 14058 14058 2009-12-31 6153 F S N 4
## 14059 14059 2009-12-31 3656 M S N 3
## AnnualIncome City StateorProvince Country ProductFamily
## 14054 $10K - $30K Yakima WA USA Non-Consumable
## 14055 $10K - $30K Bremerton WA USA Food
## 14056 $10K - $30K Walla Walla WA USA Food
## 14057 $30K - $50K Portland OR USA Drink
## 14058 $50K - $70K Spokane WA USA Drink
## 14059 $50K - $70K Portland OR USA Non-Consumable
## ProductDepartment ProductCategory UnitsSold Revenue
## 14054 Household Paper Products 5 14.50
## 14055 Baking Goods Baking Goods 3 9.64
## 14056 Frozen Foods Vegetables 3 7.45
## 14057 Beverages Pure Juice Beverages 4 3.24
## 14058 Dairy Dairy 2 4.00
## 14059 Household Electrical 5 25.53
# Chuyển các biến định tính phù hợp sang factor
factor <- c("Gender", "MaritalStatus", "Homeowner", "AnnualIncome",
"City", "StateorProvince", "Country",
"ProductFamily", "ProductDepartment", "ProductCategory")
# Kiểm tra biến nào tồn tại trong data
factor <- intersect(factor, names(data))
# Chuyển sang factor
data[factor] <- lapply(data[factor], as.factor)
# Kiểm tra lại cấu trúc
str(data)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
## $ CustomerID : int 7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
## $ Gender : 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 ...
Giải thích các biến
Bộ dữ liệu ghi lại thông tin về các giao dịch mua hàng của khách hàng, bao gồm thông tin nhân khẩu học, thông tin sản phẩm, số lượng bán ra và doanh thu. Dữ liệu bao gồm 14059 quan sát và 16 biến. Dưới đây là mô tả chi tiết các biến có trong bộ dữ liệu:
Tên Biến | Ý Nghĩa |
---|---|
PurchaseDate | Ngày giao dịch mua hàng diễn ra (định dạng ngày/tháng/năm). |
CustomerID | Mã định danh duy nhất cho mỗi khách hàng. |
Gender | Giới tính của khách hàng: M (Nam), F (Nữ). |
MaritalStatus | Tình trạng hôn nhân: S (Độc thân), M (Đã kết hôn). |
Homeowner | Tình trạng sở hữu nhà: Y (Có), N (Không). |
Children | Số lượng con cái của khách hàng. |
AnnualIncome | Mức thu nhập hàng năm theo khoảng (Ví dụ: $30K - $50K). |
City | Thành phố nơi khách hàng thực hiện giao dịch. |
StateorProvince | Bang hoặc tỉnh (ví dụ: CA cho California, OR cho Oregon). |
Country | Quốc gia. |
ProductFamily | Nhóm sản phẩm chính: Food (Thực phẩm), Drink (Đồ uống), Non-Consumable (Không tiêu dùng). |
ProductDepartment | Bộ phận sản phẩm như Snack Foods, Frozen Foods, v.v. |
ProductCategory | Danh mục sản phẩm cụ thể hơn, ví dụ: Candy, Beer and Wine. |
UnitsSold | Số lượng đơn vị sản phẩm đã bán trong giao dịch đó. |
Revenue | Doanh thu từ giao dịch (tính theo USD). |
table_gender_home <- table(data$Gender, data$Homeowner)
table_gender_home
##
## N Y
## F 2826 4344
## M 2789 4100
Dựa vào bảng trên:
Nữ (F) có tổng cộng 7170 người, trong đó 4344 người sở hữu nhà, chiếm khoảng 60.6%.
Nam (M) có tổng cộng 6889 người, với 4100 người sở hữu nhà, tương ứng khoảng 59.5%.
Nhận xét:
Tỷ lệ sở hữu nhà của nữ có vẻ nhỉnh hơn một chút so với nam (khoảng
60.6% so với 59.5%), tuy nhiên sự khác biệt này là khá nhỏ.
Để đánh giá rõ ràng hơn về mức độ liên hệ giữa hai biến, ta sẽ tiếp tục
tính các chỉ số định lượng như:
Hiệu hai tỷ lệ (Difference in Proportions), Relative Risk (RR), Odds
Ratio (OR).
prop_table <- prop.table(table_gender_home, margin = 1)
prop_table
##
## N Y
## F 0.3941423 0.6058577
## M 0.4048483 0.5951517
diff_prop <- prop_table[1, "Y"] - prop_table[2, "N"]
diff_prop
## [1] 0.2010094
Tỷ lệ sở hữu nhà:
Ở nữ là 0.6059 (tức là 60.6%)
Ở nam là 0.5952 (tức là 59.5%)
Hiệu hai tỷ lệ giữa nữ và nam là 0.201, tương đương 20.1 điểm phần trăm.
Kết luận:
Tỷ lệ nữ sở hữu nhà cao hơn nam khoảng 1.00%, tuy nhiên mức chênh lệch này khá nhỏ và chưa thể kết luận có ý nghĩa thống kê nếu chưa tính khoảng tin cậy (confidence interval) hoặc thực hiện các kiểm định thống kê chính thức như kiểm định z hoặc chi bình phương.
library(epitools)
##
## Attaching package: 'epitools'
## The following object is masked from 'package:survival':
##
## ratetable
rr_result <- riskratio(table_gender_home)
rr_result$measure
## risk ratio with 95% C.I.
## estimate lower upper
## F 1.0000000 NA NA
## M 0.9823291 0.9561812 1.009192
Dựa vào kết quả ta thấy Relative Risk (RR) của nam so với nữ là 0.9823. Khoảng tin cậy 95% của RR nằm trong khoảng từ 0.9562 đến 1.0092.
Kết luận:
RR < 1 cho thấy nam có tỷ lệ sở hữu nhà thấp hơn nữ một chút (chỉ còn
khoảng 98.23% so với nữ). Tuy nhiên, vì khoảng tin cậy 95% bao gồm giá
trị 1.0, nên không có bằng chứng đủ mạnh để kết luận sự khác biệt này có
ý nghĩa thống kê. Nói cách khác, tỷ lệ sở hữu nhà giữa nam và nữ có thể
coi là tương đương.
library(epitools)
or_result <- oddsratio(table_gender_home)
or_result
## $data
##
## N Y Total
## F 2826 4344 7170
## M 2789 4100 6889
## Total 5615 8444 14059
##
## $measure
## odds ratio with 95% C.I.
## estimate lower upper
## F 1.000000 NA NA
## M 0.956381 0.8938974 1.023169
##
## $p.value
## two-sided
## midp.exact fisher.exact chi.square
## F NA NA NA
## M 0.195158 0.1964833 0.1950884
##
## $correction
## [1] FALSE
##
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
or_result$conf.int
## NULL
Phân tích bảng thì giữa hai nhóm giới tính (F và M) cho thấy:
Do tất cả các giá trị p đều lớn hơn mức ý nghĩa thông thường (α = 0.05), không có sự khác biệt có ý nghĩa thống kê giữa nhóm nam và nữ về biến được phân tích.
Như vậy, kết quả cho thấy không có mối liên quan rõ rệt giữa giới tính và biến, theo phân tích odds ratio và các kiểm định xác suất tương ứng.