Cuốn sách của Peter K. Dunn và Gordon K. Smyth. cung cấp một cái nhìn tổng quan về một cuốn sách giáo khoa về các mô hình tuyến tính tổng quát (GLM) với các ví dụ trong R. Cuốn sách tập trung vào việc làm rõ các kết nối giữa hồi quy tuyến tính và GLM, đồng thời giới thiệu các chủ đề và công cụ nâng cao không thường thấy trong các giới thiệu GLM tiêu chuẩn. Nó đề cập đến các khía cạnh thực tế của việc xây dựng mô hình, bao gồm việc lựa chọn biến giải thích, xử lý sự biến đổi trong dữ liệu, và áp dụng các phép biến đổi để cải thiện mô hình. Ngoài ra, cuốn sách thảo luận về chẩn đoán mô hình bằng cách sử dụng các loại phần dư và đo lường ảnh hưởng khác nhau, cũng như phân tích các loại dữ liệu cụ thể, chẳng hạn như tỷ lệ (mô hình nhị thức), số đếm (mô hình Poisson và nhị thức âm), và dữ liệu liên tục dương (mô hình Gamma và Gaussian nghịch đảo). Cuối cùng, nó giới thiệu khái niệm về phân phối Tweedie như một khuôn khổ rộng hơn. Một điểm nổi bật và xuyên suốt của sách là việc minh họa các khái niệm và kỹ thuật bằng cách sử dụng phần mềm R thông qua nhiều ví dụ và bộ dữ liệu thực tế. Dưới đây là sơ đồ tóm tắt giúp chúng ta có cái nhìn khái quát về cuốn sách này.
Hình 1.1. Sơ đồ tóm tắt các chương của cuốn sách Generalized Linear Models With Examples in R
Chương 1 giúp chúng ta hiểu bản chất của mô hình thống kê, phân biệt giữa phần có thể giải thích được và phần ngẫu nhiên, cũng như cách bắt đầu xây dựng mô hình hồi quy với sự hỗ trợ của biểu đồ, mã hóa biến và phần mềm R.
Giới thiệu mô hình thống kê, bao gồm các khái niệm cơ bản:
Biến phản hồi (response variable): biến được giải thích (ký hiệu là y).
Biến giải thích (explanatory variables): các biến dùng để giải thích y (ký hiệu x1, x2, x3,…xp).
Thành phần hệ thống (systematic component): phần mô hình hóa kỳ vọng của y.
Thành phần ngẫu nhiên (random component): phần không giải thích được, có tính ngẫu nhiên.
Cách mô tả và mã hóa dữ liệu:
Dữ liệu gồm các biến liên tục hoặc phân loại.
Biến phân loại cần được mã hóa (coding) trước khi đưa vào mô hình.
Trong R, sử dụng factor() hoặc model.matrix() để mã hóa.
Khẳng định: “All models are wrong, but some are useful”: Mô hình không bao giờ hoàn hảo, nhưng có thể hữu ích trong phân tích và dự đoán.
Một số công thức quan trọng:
🔹 Mô hình hồi quy tuyến tính tổng quát:
\[ \mu_i = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_p x_p \]
🔹 Mô hình hồi quy tuyến tính đơn giản:
\[ Y_i = \beta_0 + \beta_1 X_i + \varepsilon_i,\quad \varepsilon_i \sim \mathcal{N}(0, \sigma^2) \]
🔹 Residual (phần dư):
\[ e_i = y_i - \hat{y}_i \] 💡 Ghi nhớ nhanh
Mô hình thống kê gồm: phần hệ thống + phần ngẫu nhiên.
Biểu đồ và xử lý biến là bước đầu tiên quan trọng.
Mục tiêu mô hình ảnh hưởng đến cách xây dựng: nếu muốn dự đoán, nên chọn mô hình chính xác; nếu muốn giải thích, chọn mô hình đơn giản và dễ hiểu.
R hỗ trợ rất mạnh việc xây dựng mô hình: lm(), glm() và các gói dữ liệu như GLMsData.
Chương này trình bày chi tiết về mô hình hồi quy tuyến tính, từ hồi quy đơn đến hồi quy bội, cách ước lượng hệ số và đánh giá ý nghĩa thống kê. Nội dung chính - Hồi quy tuyến tính đơn giản: 1 biến giải thích
Hồi quy tuyến tính bội: nhiều biến giải thích
Ước lượng hệ số bằng phương pháp bình phương tối thiểu (OLS)
Đánh giá sai số, hệ số, giá trị dự đoán bằng độ lệch chuẩn và kiểm định t
Công thức cần nhớ
🔹 Mô hình hồi quy đơn:
\[ Y_i = \beta_0 + \beta_1 X_i + \varepsilon_i \] 🔹 Hồi quy tuyến tính bội:
\[ Y_i = \beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip} + \varepsilon_i \] 🔹 Công thức ước lượng hệ số (OLS):
\[ \hat{\beta} = (X^T X)^{-1} X^T Y \] 🔹 Sai số phần dư:
\[ e_i = y_i - \hat{y}_i \] 🔹 Phương sai sai số:
\[ \hat{\sigma}^2 = \frac{1}{n - p - 1} \sum_{i=1}^n e_i^2 \] 💡 Ghi nhớ nhanh - Dùng lm() trong R để ước lượng mô hình.
Đọc bảng summary(lm_model) để kiểm định hệ số.
So sánh mô hình bằng AIC, BIC khi cần chọn giữa các mô hình.
Chương này giúp đánh giá độ phù hợp của mô hình hồi quy: kiểm tra giả định, phát hiện ngoại lệ và cách cải thiện mô hình. 🔍 Nội dung chính - Giả định quan trọng: tuyến tính, phương sai không đổi, độc lập, chuẩn hóa
Residual plots kiểm tra tuyến tính và phương sai
QQ plots kiểm tra phân phối chuẩn
Leverage và influence: tìm điểm dữ liệu ảnh hưởng mạnh
Biến đổi dữ liệu: log, Box-Cox, polynomial, spline để cải thiện mô hình
Kiểm tra collinearity: VIF, biểu hiện của đa cộng tuyến
🧮 Công thức cần nhớ
🔹 Residual chuẩn hóa:
\[ r_i = \frac{e_i}{\hat{\sigma} \sqrt{1 - h_{ii}}} \] 🔹 Cook’s distance:
\[ D_i = \frac{r_i^2}{p \cdot \hat{\sigma}^2} \cdot \frac{h_{ii}}{(1 - h_{ii})^2} \]
💡 Ghi nhớ nhanh - Kiểm tra đồ thị trước khi tin vào kết quả mô hình.
Biến đổi log hoặc đa thức khi quan hệ không tuyến tính.
Sử dụng plot(lm_model) trong R để kiểm tra giả định.
Chương này giới thiệu MLE – nền tảng để xây dựng các mô hình tổng quát hóa hồi quy tuyến tính (GLMs). 🔍 Nội dung chính - MLE tìm giá trị tham số làm tối đa hóa xác suất quan sát được dữ liệu.
MLE áp dụng cho mô hình không chuẩn (phi tuyến, nhị phân, Poisson…).
Dẫn dắt đến generalized linear models.
🧮 Công thức cần nhớ
🔹 Hàm hợp lý:
\[ L(\theta) = \prod_{i=1}^n f(y_i | \theta) \] 🔹 Log-likelihood:
\[ \ell(\theta) = \sum_{i=1}^n \log f(y_i | \theta) \] 🔹 Điều kiện cực đại (score function):
\[ \frac{\partial \ell(\theta)}{\partial \theta} = 0 \] 🔹 Thông tin Fisher kỳ vọng:
\[ I(\theta) = -\mathbb{E} \left[ \frac{\partial^2 \ell(\theta)}{\partial \theta^2} \right] \] 💡 Ghi nhớ nhanh
MLE là nền tảng để suy ra GLM.
Các mô hình nhị phân, đếm, phân phối lệch… cần MLE thay vì OLS.
R tự động dùng MLE trong glm().
Cấu trúc mô hình tuyến tính tổng quát – GLM.
Nội dung chính
GLM mở rộng hồi quy tuyến tính để xử lý:
Biến nhị phân (0/1), biến đếm (Poisson), biến dương liên tục (Gamma…)
Không yêu cầu phân phối chuẩn hay phương sai không đổi.
GLM gồm 3 thành phần chính:
Thành phần ngẫu nhiên (Random component)
Yi ~ phân phối thuộc họ phân tán mũ (EDM)
Thành phần hệ thống (Systematic component)
Predictor tuyến tính
\[ \eta_i = \beta_0 + \beta_1 x_{i1} + \dots + \beta_p x_{ip} \] - Hàm liên kết (Link function)
\[ g(\mu_i) = \eta_i \] 🧮 Công thức cần nhớ
🔹 Cấu trúc GLM đầy đủ:
\[ Y_i \sim \text{EDM}(\mu_i, \phi) \quad \text{với} \quad g(\mu_i) = \eta_i = x_i^T \beta \]
🔹 Ví dụ các hàm liên kết:
Mô hình | Link function | \(g(\mu)\) |
---|---|---|
Nhị phân (logistic) | logit | \(\log \left( \frac{\mu}{1 - \mu} \right)\) |
Đếm (Poisson) | log | \(\log(\mu)\) |
Gamma | inverse | \(\mu^{-1}\) hoặc log |
💡 Ghi nhớ nhanh
GLM = phân phối phù hợp + hàm liên kết + predictor tuyến tính
Hàm glm() trong R: tự chọn link + family
Họ phân tán mũ (EDM): Binomial, Poisson, Gamma… đều thuộc GLM
Ước lượng trong GLM 🔍 Nội dung chính
GLM sử dụng MLE (maximum likelihood) để ước lượng các hệ số.
Sử dụng thuật toán Fisher scoring để giải phương trình phi tuyến.
🧮 Công thức cần nhớ
🔹 Hàm hợp lý tổng quát:
\[ \ell(\beta) = \sum_{i=1}^n \left[ \frac{y_i \theta_i - b(\theta_i)}{a(\phi)} + c(y_i, \phi) \right] \] 🔹 Score function (đạo hàm log-likelihood theo β):
\[ U(\beta) = \frac{\partial \ell}{\partial \beta} \] 🔹 Công thức Fisher scoring (cập nhật β):
\[ \beta^{(t+1)} = \beta^{(t)} + \left[ I(\beta^{(t)}) \right]^{-1} U(\beta^{(t)}) \] 🔹 Deviance (độ lệch): Dùng để đánh giá độ phù hợp của mô hình
\[ D = 2 \left[ \ell_{\text{max}}(\text{mô hình đầy đủ}) - \ell(\text{mô hình đang xét}) \right] \] 💡 Ghi nhớ nhanh
R tự động sử dụng Fisher scoring để tìm nghiệm trong glm().
summary(glm_model) cung cấp hệ số, sai số chuẩn, kiểm định.
Deviance thấp = mô hình phù hợp tốt.
Suy luận thống kê GLM.
🔍 Nội dung chính
Kiểm định giả thuyết và xây dựng khoảng tin cậy cho các hệ số trong GLM.
So sánh các mô hình bằng Likelihood Ratio Test, Wald Test, và Score Test.
🧮 Công thức cần nhớ
🔹 Wald test:
\[ Z = \frac{\hat{\beta}_j}{\text{SE}(\hat{\beta}_j)} \quad \Rightarrow \quad \text{đối chiếu với } \mathcal{N}(0,1) \] 🔹 Khoảng tin cậy cho hệ số:
\[ \hat{\beta}_j \pm z_{\alpha/2} \cdot \text{SE}(\hat{\beta}_j) \] 🔹 Likelihood Ratio Test (LRT):
\[ D = 2 \left[ \ell_{\text{full}} - \ell_{\text{reduced}} \right] \sim \chi^2_{df} \] 🔹 AIC (Akaike Information Criterion):
\[ \text{AIC} = -2 \ell + 2k \] 💡 Ghi nhớ nhanh
Wald test: dễ dùng, phổ biến, nhưng không chính xác khi mẫu nhỏ.
LRT: so sánh 2 mô hình lồng nhau — rất mạnh, dùng nhiều khi kiểm định biến.
Score test: dùng khi chưa có ước lượng đầy đủ.
R hỗ trợ tất cả bằng anova(), confint(), AIC(), BIC()…
Chẩn đoán mô hình tuyến tính tổng quát
🔍 Nội dung chính
Chương này hướng dẫn cách kiểm tra giả định của mô hình GLM và xác định các điểm dữ liệu bất thường:
Trình bày các loại residuals phù hợp với GLM: Pearson, Deviance, Quantile.
Phân tích leverage và ảnh hưởng của từng điểm dữ liệu.
Xử lý vấn đề đa cộng tuyến (collinearity).
Áp dụng quasi-likelihood và extended quasi-likelihood khi không xác định được phân phối cụ thể.
Cung cấp hướng dẫn thực hành trong R để chuẩn đoán mô hình.
🧮 Công thức cần nhớ
🔹 Pearson residual:
\[ r_P = \frac{y - \hat{\mu}}{\sqrt{V(\hat{\mu})}} \] 🔹 Deviance residual:
\[ r_D = \text{sign}(y - \hat{\mu}) \cdot \sqrt{2 \cdot d(y, \hat{\mu})} \] 🔹 Unit deviance (dùng trong quasi-likelihood):
\[ d(y, \mu) = 2 \int_{\mu}^{y} \frac{y - u}{V(u)} \, du \] 💡 Ghi nhớ nhanh
Residuals giúp đánh giá sự phù hợp của mô hình – nên dùng bản chuẩn hóa.
Quantile residuals tốt cho dữ liệu rời rạc, đặc biệt trong Poisson và logistic.
Quan sát có leverage cao hoặc Cook’s distance lớn → cần chú ý loại bỏ hoặc kiểm tra kỹ.
Collinearity gây nhiễu ước lượng hệ số – xử lý bằng giảm số biến hoặc biến đổi biến.
Khi xuất hiện overdispersion, dùng quasi-Poisson hoặc quasi-binomial thay thế phân phối chuẩn.
(Mô hình cho tỷ lệ – Phân phối nhị thức)
🔍 Nội dung chính
Sử dụng GLM với phân phối nhị thức để mô hình hóa tỷ lệ (proportions).
Giới thiệu các hàm liên kết: logit, probit, cloglog, log, cauchit.
Diễn giải kết quả theo xác suất, odds và odds ratio.
Phân tích liều ED50 – điểm mà xác suất thành công là 0.5.
Kiểm tra overdispersion và giới thiệu quasi-binomial GLMs.
Hạn chế của các kiểm định phù hợp khi dữ liệu là nhị phân.
🧮 Công thức cần nhớ
\[ \text{logit}(\mu) = \log \left( \frac{\mu}{1 - \mu} \right) \]
\[ \text{Var}(y) = \phi \mu(1 - \mu) \] 💡 Ghi nhớ nhanh
GLM nhị thức phù hợp khi dữ liệu là số lần thành công trên tổng số thử.
Với overdispersion, dùng quasi-binomial (family = quasibinomial()).
logit là liên kết mặc định; dễ diễn giải kết quả bằng odds.
Với dữ liệu nhị phân, các kiểm định goodness-of-fit có thể sai lệch.
(Mô hình đếm – Phân phối Poisson và nhị thức âm)
🔍 Nội dung chính
Mô hình Poisson GLM thường dùng để xử lý dữ liệu đếm.
Nếu có overdispersion, thay bằng mô hình quasi-Poisson hoặc negative binomial.
Mô hình log-linear dùng khi tất cả biến giải thích là định tính.
Mô hình tỷ lệ được xử lý bằng offset.
Dữ liệu bảng chéo (contingency tables) cũng dùng Poisson GLM.
🧮 Công thức cần nhớ
\[ \text{Var}(y) = \mu \quad \text{(Poisson)}, \quad \text{Var}(y) = \mu + \frac{\mu^2}{k} \quad \text{(Negative Binomial)} \]
\[ \text{log}(\mu) = X\beta \]
💡 Ghi nhớ nhanh
Dùng glm(…, family=poisson()) cho mô hình Poisson.
Dùng glm.nb() từ package MASS cho negative binomial GLM.
Overdispersion làm SE bị đánh giá thấp → dễ kết luận sai.
offset(log(exposure)) rất quan trọng khi mô hình hóa tỷ lệ đếm.
(Dữ liệu liên tục dương – Phân phối Gamma và Gauss nghịch đảo)
🔍 Nội dung chính
Dữ liệu liên tục dương thường có phương sai tăng theo trung bình.
Dùng GLM với phân phối Gamma khi dữ liệu có lệch phải nhẹ.
Dùng phân phối inverse Gaussian khi dữ liệu lệch phải mạnh hơn.
Các hàm liên kết: log, identity, inverse.
Ước lượng hệ số phân tán ϕ.
🧮 Công thức cần nhớ
\[ V(\mu) = \mu^2 \quad \text{(Gamma)}, \quad V(\mu) = \mu^3 \quad \text{(Inverse Gaussian)} \]
\[ \text{log}(\mu) = X\beta \]
💡 Ghi nhớ nhanh
Dùng family = Gamma(link=“log”) hoặc inverse.gaussian.
Với inverse Gaussian, MLE cho ϕ là chính xác hơn Pearson.
Mô hình hóa thời gian giữa các sự kiện → dùng Gamma GLM.
Mô hình hóa thời gian tới khi đạt ngưỡng → dùng inverse Gaussian.
(Họ phân phối Tweedie – Tổng quát hóa EDMs)
🔍 Nội dung chính
Tweedie là họ phân phối có hàm phương sai.
Bao gồm normal (ξ = 0), Poisson (ξ = 1), Gamma (ξ = 2), inverse Gaussian (ξ = 3).
Cho phép mô hình hóa dữ liệu liên tục có giá trị 0 chính xác.
Dùng được khi dữ liệu là tổng hợp giữa Poisson và Gamma.
🧮 Công thức cần nhớ
\[ \text{Var}(y) = \phi \mu^\xi \]
\[ \pi_0 = \exp\left( -\frac{\mu^{2 - \xi}}{\phi(2 - \xi)} \right) \] 💡 Ghi nhớ nhanh
Dùng tweedie.profile() để ước lượng chỉ số ξ.
Dùng package tweedie hoặc statmod để fit mô hình.
Phù hợp khi dữ liệu có nhiều số 0 nhưng cũng là liên tục.
Link function thường dùng nhất là log.
Ở chương này, tác giả tập trung vào các bài tập mở rộng.
🔍 Nội dung chính
Tổng hợp bài tập thực hành không phân theo chương.
Không hướng dẫn cụ thể → đòi hỏi tư duy mô hình hóa độc lập.
Bao gồm từ dữ liệu tỷ lệ, đếm, liên tục dương, cho đến Tweedie.
💡 Ghi nhớ nhanh
Phần này dành cho ôn luyện toàn bộ kỹ năng GLM.
Nhiều bài tập yêu cầu tư duy chọn đúng mô hình và link.
Thích hợp dùng để kiểm tra năng lực tổng hợp trước khi làm nghiên cứu hoặc thi.
#Thực hiện đọc file CSV
data <- read.csv("/Users/lengoctuongvy/Downloads/TLHK2:2025/T2_PHÂN TÍCH DỮ LIỆU ĐỊNH TÍNH/Book2.csv")
head(data,10)
X | PurchaseDate | CustomerID | Gender | MaritalStatus | Homeowner | Children | AnnualIncome | City | StateorProvince | Country | ProductFamily | ProductDepartment | ProductCategory | UnitsSold | Revenue |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 12/18/2007 | 7223 | F | S | Y | 2 | $30K - $50K | Los Angeles | CA | USA | Food | Snack Foods | Snack Foods | 5 | 27.38 |
2 | 12/20/2007 | 7841 | M | M | Y | 5 | $70K - $90K | Los Angeles | CA | USA | Food | Produce | Vegetables | 5 | 14.90 |
3 | 12/21/2007 | 8374 | F | M | N | 2 | $50K - $70K | Bremerton | WA | USA | Food | Snack Foods | Snack Foods | 3 | 5.52 |
4 | 12/21/2007 | 9619 | M | M | Y | 3 | $30K - $50K | Portland | OR | USA | Food | Snacks | Candy | 4 | 4.44 |
5 | 12/22/2007 | 1900 | F | S | Y | 3 | $130K - $150K | Beverly Hills | CA | USA | Drink | Beverages | Carbonated Beverages | 4 | 14.00 |
6 | 12/22/2007 | 6696 | F | M | Y | 3 | $10K - $30K | Beverly Hills | CA | USA | Food | Deli | Side Dishes | 3 | 4.37 |
7 | 12/23/2007 | 9673 | M | S | Y | 2 | $30K - $50K | Salem | OR | USA | Food | Frozen Foods | Breakfast Foods | 4 | 13.78 |
8 | 12/25/2007 | 354 | F | M | Y | 2 | $150K + | Yakima | WA | USA | Food | Canned Foods | Canned Soup | 6 | 7.34 |
9 | 12/25/2007 | 1293 | M | M | Y | 3 | $10K - $30K | Bellingham | WA | USA | Non-Consumable | Household | Cleaning Supplies | 1 | 2.41 |
10 | 12/25/2007 | 7938 | M | S | N | 1 | $50K - $70K | San Diego | CA | USA | Non-Consumable | Health and Hygiene | Pain Relievers | 2 | 8.96 |
Dữ liệu Supermarket Transactions lưu trữ chi tiết các giao dịch mua sắm trong chuỗi siêu thị, đồng thời bao gồm thông tin về khách hàng, vị trí địa lý và đặc điểm sản phẩm. Bộ dữ liệu này rất hữu ích để phân tích thói quen tiêu dùng, phân loại nhóm khách hàng, cũng như đánh giá hiệu quả kinh doanh dựa trên sản phẩm, vùng miền và đặc điểm nhân khẩu học.
Ta tiến hành xem các biến có trong bộ dư liệu và mô tả ý nghĩa của các biến đó.
names(data)
## [1] "X" "PurchaseDate" "CustomerID"
## [4] "Gender" "MaritalStatus" "Homeowner"
## [7] "Children" "AnnualIncome" "City"
## [10] "StateorProvince" "Country" "ProductFamily"
## [13] "ProductDepartment" "ProductCategory" "UnitsSold"
## [16] "Revenue"
library(DT)
variable_description <- data.frame(
Variable = c("Unnamed", "PurchaseDate", "CustomerID", "Gender", "MaritalStatus", "Homeowner",
"Children", "AnnualIncome", "City", "StateorProvince", "Country",
"ProductFamily", "ProductDepartment", "ProductCategory", "UnitsSold", "Revenue"),
Description = c("Số thứ tự",
"Ngày mua hàng",
"ID của khách hàng",
"Giới tính của khách hàng (F: nữ, M: nam)",
"Tình trạng hôn nhân của khách hàng (S: độc thân, M: đã kết hôn)",
"Sở hữu nhà (Y: có, N: không)",
"Số con trong gia đình",
"Thu nhập hàng năm (theo nhóm)",
"Thành phố đang sinh sống",
"Bang / tỉnh",
"Quốc gia",
"Nhóm sản phẩm chính",
"Phòng ban sản phẩm",
"Danh mục sản phẩm",
"Sản lượng sản phẩm đã bán",
"Doanh thu (USD)"
)
)
datatable(variable_description,
colnames = c("Tên biến", "Mô tả"),
options = list(pageLength = 5, autoWidth = TRUE))
Bộ Dữ liệu Supermarket Transactions bao gồm tổng cộng 14.059 quan sát và 16 biến khác nhau. Mỗi quan sát trong bộ dữ liệu tương ứng với một giao dịch mua hàng riêng biệt tại siêu thị. Qua đó, mỗi bản ghi thể hiện chi tiết về một lần mua sắm cụ thể, được mô tả đầy đủ bởi 16 yếu tố khác nhau như thông tin khách hàng, sản phẩm, địa điểm và các đặc điểm liên quan. Điều này giúp phân tích sâu sắc hơn về hành vi mua sắm và các yếu tố ảnh hưởng trong từng giao dịch.
str(data)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "12/18/2007" "12/20/2007" "12/21/2007" "12/21/2007" ...
## $ 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 ...
Với bảng dữ liệu trên ta có thể mô tả như sau: lấy ngầy nhiên quan sát thứ 10 ta có được thông tin vào ngày 25/12/2007, khách hàng có iD 7938 là nam hiện đang độc thân, không sở hữu nhà, có 1 con, thu nhập trong khoảng từ 50k-70K USD. Anh này sinh sống ở San Diego bang CA thuộc Hoa Kỳ mua 2 sản phẩm Pain Relievers thuộc nhóm Non-Consumable, siêu thị thu được 8.96USD.
library(DT)
library(htmltools)
# Hàm thống kê mô tả biến định tính có bảng phân trang
summary_categorical_DT <- function(data, var_name, label_map = NULL) {
if (!(var_name %in% names(data))) {
cat("Biến", var_name, "không tồn tại trong data!\n")
return(NULL)
}
freq <- table(data[[var_name]])
percent <- prop.table(freq) * 100
values <- names(freq)
if (!is.null(label_map)) {
labels <- sapply(values, function(x) ifelse(x %in% names(label_map), label_map[[x]], x))
} else {
labels <- values
}
df <- data.frame(
Giá_trị = values,
Nhãn = labels,
Số_lượng = as.vector(freq),
Phần_trăm = round(as.vector(percent), 2)
)
DT::datatable(df,
caption = paste("Thống kê biến:", var_name),
options = list(pageLength = 5, lengthMenu = c(5,10,20), searching = TRUE))
}
# Các biến định tính muốn thống kê
categorical_vars <- c("Gender", "MaritalStatus", "Homeowner", "AnnualIncome",
"City", "StateorProvince", "Country", "ProductFamily",
"ProductDepartment", "ProductCategory")
# Map nhãn cho một số biến mẫu (bạn thêm nếu muốn)
label_maps <- list(
Gender = list(M = "Nam", F = "Nữ"),
MaritalStatus = list(S = "Độc thân", M = "Đã kết hôn"),
Homeowner = list(Y = "Có nhà", N = "Không có nhà")
)
# Gọi hàm cho nhiều biến và gom kết quả để hiển thị khi knit
widgets <- lapply(categorical_vars, function(var) {
map <- label_maps[[var]]
summary_categorical_DT(data, var, map)
})
browsable(tagList(widgets))
Nhận xét: Tác giả đưa ra một vài nhận xét tổng quát như sau:
🔹 Biến Gender: Biến Gender thể hiện giới tính của khách hàng, gồm hai nhóm: nữ (F) và nam (M). Trong tổng số 14.059 quan sát, tỷ lệ nữ chiếm 51% (7.170 người), trong khi nam chiếm 49% (6.889 người). Phân phối giới tính giữa hai nhóm khá cân bằng, cho thấy mẫu dữ liệu không bị lệch quá nhiều về một giới cụ thể.
🔹 Biến MaritalStatus: Biến MaritalStatus phản ánh tình trạng hôn nhân, được chia thành hai nhóm: độc thân (S) và đã kết hôn (M). Có 7.193 người độc thân (chiếm 51.16%) và 6.866 người đã kết hôn (chiếm 48.84%). Tỷ lệ này cho thấy phân phối gần như đồng đều, tuy nhiên nhóm độc thân vẫn chiếm ưu thế nhẹ trong tập dữ liệu.
🔹 Biến Homeowner: Biến Homeowner thể hiện tình trạng sở hữu nhà ở. Trong dữ liệu, 8.444 người (60.06%) có nhà và 5.615 người (39.94%) không có nhà. Tỷ lệ cao hơn ở nhóm có nhà cho thấy phần lớn khách hàng trong mẫu thuộc nhóm có điều kiện kinh tế tương đối ổn định.
🔹 Biến AnnualIncome: Biến AnnualIncome phản ánh thu nhập hằng năm và được chia thành nhiều nhóm. Hai nhóm chiếm tỷ trọng lớn nhất là $30K–$50K (32.73%) và $10K–$30K (21.98%), cho thấy phần lớn khách hàng có thu nhập trung bình thấp. Các nhóm có thu nhập cao hơn như $110K–$130K, $130K–$150K, và $150K+ có tỷ lệ thấp hơn nhiều, lần lượt là 4.57%, 5.41%, và 1.94%. Phân phối này cho thấy sự chênh lệch đáng kể về thu nhập, với phần lớn khách hàng tập trung ở phân khúc thu nhập trung bình.
🔹 Biến City: Biến City thể hiện tên thành phố mà khách hàng sinh sống. Trong số 23 thành phố, một số thành phố có số lượng khách hàng cao đáng kể như Bremerton (5.93%), Beverly Hills (5.77%), và Camacho (3.22%). Sự phân bố khách hàng giữa các thành phố là khá đa dạng, cho phép phân tích hành vi theo khu vực địa lý cụ thể.
🔹 Biến StateorProvince: Biến StateorProvince cho biết tên bang hoặc tỉnh. Các khu vực có số lượng khách hàng cao bao gồm California (CA) với 19.44% và Distrito Federal (DF) với 5.8%. Trong khi đó, các tỉnh khác như Jalisco hay Guerrero chỉ chiếm dưới 1% đến hơn 2%, cho thấy sự tập trung dân cư không đồng đều giữa các khu vực.
🔹 Biến Country: Biến Country phân loại quốc gia nơi khách hàng cư trú. Hoa Kỳ (USA) chiếm tỷ lệ lớn nhất với 68.01%, tiếp theo là Mexico (26.23%) và Canada (5.75%). Dữ liệu bị nghiêng về phía khách hàng từ Mỹ, điều này cần lưu ý khi phân tích để tránh sai lệch kết luận.
🔹 Biến ProductFamily: Biến ProductFamily chia các sản phẩm thành 3 nhóm chính. Food chiếm tỷ trọng cao nhất với 72.22%, cho thấy đây là nhóm sản phẩm được tiêu thụ phổ biến nhất. Tiếp theo là Non-Consumable (18.89%) và Drink (8.89%). Kết quả này gợi ý rằng nhóm hàng thực phẩm là yếu tố chính trong doanh thu.
🔹 Biến ProductDepartment: Biến này cung cấp thông tin chi tiết hơn về loại sản phẩm trong từng bộ phận. Một số bộ phận có số lượng lớn như Baking Goods (7.63%) và Beverages (4.84%). Tuy nhiên, phần lớn các bộ phận còn lại đều chiếm tỷ trọng khá nhỏ, cho thấy thị trường phân tán theo nhiều danh mục hàng hóa nhỏ.
🔹 Biến ProductCategory: Tương tự như trên, ProductCategory chia nhỏ hơn nữa các nhóm hàng. Một số danh mục tiêu biểu như Baking Goods (3.44%), Bread (3.02%) và Beer and Wine (2.53%) là các nhóm có tỷ lệ cao hơn. Dù tỷ trọng không lớn, nhưng sự đa dạng về danh mục cho thấy cơ cấu sản phẩm phong phú.
library(dplyr)
##
## 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(moments)
library(knitr)
library(kableExtra)
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
# Hàm mô tả định lượng cho từng biến
describe_numeric <- function(data, var_name) {
x <- data[[var_name]]
x <- x[!is.na(x)]
df <- data.frame(
Biến = var_name,
Số_lượng = length(x),
Giá_trị_nhỏ_nhất = min(x),
Q1 = quantile(x, 0.25),
Trung_vị = median(x),
Trung_bình = mean(x),
Q3 = quantile(x, 0.75),
Giá_trị_lớn_nhất = max(x),
Độ_lệch_chuẩn = sd(x),
Độ_lệch = skewness(x),
Độ_nhọn = kurtosis(x)
)
kable(df, caption = paste("Thống kê mô tả biến:", var_name)) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "left")
}
# Gọi hàm cho từng biến
describe_numeric(data, "Revenue")
Biến | Số_lượng | Giá_trị_nhỏ_nhất | Q1 | Trung_vị | Trung_bình | Q3 | Giá_trị_lớn_nhất | Độ_lệch_chuẩn | Độ_lệch | Độ_nhọn | |
---|---|---|---|---|---|---|---|---|---|---|---|
25% | Revenue | 14059 | 0.53 | 6.84 | 11.25 | 13.00451 | 17.37 | 56.7 | 8.215543 | 1.13478 | 4.391438 |
describe_numeric(data, "Children")
Biến | Số_lượng | Giá_trị_nhỏ_nhất | Q1 | Trung_vị | Trung_bình | Q3 | Giá_trị_lớn_nhất | Độ_lệch_chuẩn | Độ_lệch | Độ_nhọn | |
---|---|---|---|---|---|---|---|---|---|---|---|
25% | Children | 14059 | 0 | 1 | 3 | 2.530336 | 4 | 5 | 1.491852 | -0.0212586 | 1.968741 |
describe_numeric(data, "UnitsSold")
Biến | Số_lượng | Giá_trị_nhỏ_nhất | Q1 | Trung_vị | Trung_bình | Q3 | Giá_trị_lớn_nhất | Độ_lệch_chuẩn | Độ_lệch | Độ_nhọn | |
---|---|---|---|---|---|---|---|---|---|---|---|
25% | UnitsSold | 14059 | 1 | 3 | 4 | 4.080589 | 5 | 8 | 1.174421 | 0.0124658 | 2.5622 |
Nhận xét:
🔹 Biến Revenue: Biến Revenue có 14.059 quan sát với giá trị nhỏ nhất là 0.53 và lớn nhất lên đến 56.7, cho thấy sự chênh lệch đáng kể giữa các quan sát. Giá trị trung bình của biến là 13.00, cao hơn trung vị (11.25), cho thấy phân phối của biến có xu hướng lệch phải. Điều này được củng cố bởi hệ số lệch (Skewness) là 1.13. Độ lệch chuẩn ở mức 8.22, phản ánh sự phân tán khá lớn trong dữ liệu. Ngoài ra, độ nhọn (Kurtosis) là 4.39, cao hơn 3, cho thấy phân phối có đỉnh cao hơn so với phân phối chuẩn, tức là tồn tại nhiều giá trị ngoại lệ hoặc giá trị cực trị.
🔹 Biến Children: Biến Children cũng có 14.059 quan sát, với giá trị nhỏ nhất là 0 và lớn nhất là 5. Giá trị trung bình là 2.53, thấp hơn một chút so với trung vị là 3, trong khi đó phân vị thứ nhất (Q1) và thứ ba (Q3) lần lượt là 1 và 4. Hệ số lệch là -0.02 gần bằng 0, cho thấy phân phối của biến khá đối xứng. Độ lệch chuẩn là 1.49, cho thấy mức độ phân tán vừa phải. Độ nhọn là 1.97, nhỏ hơn 3, cho thấy phân phối của biến hơi bẹt so với phân phối chuẩn, ít có giá trị cực trị.
🔹 Biến UnitsSold: Với 14.059 quan sát, biến UnitsSold có giá trị nhỏ nhất là 1 và lớn nhất là 8. Trung bình của biến là 4.08, gần sát với trung vị là 4, cho thấy phân phối tương đối cân đối. Q1 là 3 và Q3 là 5. Hệ số lệch là 0.01 gần bằng 0, cho thấy phân phối xấp xỉ đối xứng. Độ lệch chuẩn là 1.17, thể hiện mức độ phân tán không lớn. Độ nhọn là 2.56, thấp hơn một chút so với 3, cho thấy phân phối có phần bẹt hơn phân phối chuẩn, và ít có các giá trị ngoại lệ.
library(ggplot2)
# Hàm vẽ histogram cho 1 biến định lượng
plot_histogram <- function(data, var_name) {
ggplot(data, aes_string(x = var_name)) +
geom_histogram(fill = "#00BFC4", color = "black", bins = 30) +
labs(
title = paste("Biểu đồ Histogram của biến:", var_name),
x = var_name,
y = "Tần suất"
) +
theme_minimal()
}
# Vẽ biểu đồ cho từng biến
plot_histogram(data, "Revenue")
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
plot_histogram(data, "Children")
plot_histogram(data, "UnitsSold")
# Cài đặt và nạp các gói cần thiết
library(tidyr)
library(dplyr)
# Chuyển đổi dữ liệu từ dạng rộng sang dạng dài
data_long <- data %>%
pivot_longer(
cols = c(Revenue, Children, UnitsSold),
names_to = "Biến",
values_to = "Giá trị"
)
# Cài đặt và nạp ggplot2 nếu chưa có
library(ggplot2)
# Vẽ boxplot cho từng biến
ggplot(data_long, aes(x = "", y = `Giá trị`, fill = `Biến`)) +
geom_boxplot() +
facet_wrap(~ `Biến`, scales = "free") +
labs(
title = "Biểu đồ Boxplot cho từng biến định lượng",
x = "",
y = "Giá trị"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)