1 LỜI CẢM ƠN

Nhóm xin chân thành cảm ơn Thầy ThS. Trần Mạnh Tường đã luôn tận tình hướng dẫn và chỉ bảo trong suốt quá trình thực hiện bài luận này. Sự đồng hành của Thầy đã giúp nhóm không chỉ nắm vững những kiến thức lý thuyết quan trọng mà còn hiểu rõ hơn về cách áp dụng các phương pháp phân tích dữ liệu vào thực tế. Thầy đã cung cấp những định hướng quý báu, giúp nhóm vượt qua những khó khăn trong quá trình nghiên cứu, đồng thời truyền cảm hứng cho nhóm trong việc phát triển và hoàn thiện bài luận.

Bên cạnh đó, nhóm cũng xin gửi lời cảm ơn đến các bạn đồng môn và những người đã đồng hành và hỗ trợ nhóm trong suốt thời gian thực hiện bài luận. Những buổi thảo luận, trao đổi ý tưởng và góp ý từ các bạn đã tạo ra một môi trường học tập và làm việc hiệu quả, giúp nhóm hoàn thiện bài luận một cách tốt nhất. Chúng em sẽ luôn trân trọng và vận dụng những kiến thức, kỹ năng học được trong quá trình thực hiện bài luận này vào công việc và nghiên cứu trong tương lai.

2 LỜI CAM ĐOAN

Chúng em xin cam đoan rằng toàn bộ nội dung bài luận này là kết quả nghiên cứu và phân tích độc lập của nhóm, không sao chép hay vi phạm bản quyền từ bất kỳ nguồn tài liệu nào. Tất cả các số liệu, bảng biểu và kết quả phân tích trong bài luận đều được thu thập, xử lý và trình bày một cách trung thực, khách quan, có sự tham khảo đầy đủ từ các nguồn tài liệu đáng tin cậy và được trích dẫn rõ ràng trong bài.

Chúng em cam kết rằng không sử dụng bất kỳ hình thức sao chép nào từ các công trình nghiên cứu của người khác mà không ghi rõ nguồn, và bài luận này là sản phẩm hoàn toàn của nhóm, được thực hiện một cách nghiêm túc, tuân thủ quy định về đạo đức học thuật. Chúng em hoàn toàn chịu trách nhiệm về tính chính xác và hợp pháp của tất cả các số liệu, kết quả phân tích và nội dung bài luận.

Ngoài ra, chúng em cũng cam kết sẽ tiếp tục áp dụng những kiến thức và kỹ năng đã học được trong quá trình thực hiện bài luận này vào công việc và nghiên cứu trong tương lai, đồng thời giữ gìn và phát triển đạo đức nghề nghiệp trong suốt quá trình học tập và làm việc.

1. library(ggplot2)
2. library(dplyr)
3. library(rmarkdown)
4. library(ggridges)
5. library(scales)

Đoạn mã sử dụng các hàm từ các thư viện dplyr, tidyr, ggplot2, scales và ggrepel để xử lý và trực quan hóa dữ liệu.

3 CHƯƠNG 1: PHÂN TÍCH HÀNH VI MUA SẮM TRỰC TUYẾN CỦA KHÁCH HÀNG

3.1 GIỚI THIỆU BỘ DỮ LIỆU

3.1.1 Giới thiệu chung về bộ dữ liệu

Bộ dữ liệu ghi nhận hành vi mua sắm của người dùng trên nền tảng bán lẻ trực tuyến, bao gồm thông tin người mua (UserID, độ tuổi, giới tính, quốc gia), sản phẩm (ProductID, tên, ngành hàng, giá cả), tín hiệu hành vi giao dịch (thời điểm mua, số lượng, chiết khấu, tổng số tiền), và tín hiệu trải nghiệm khách hàng (thời gian phiên, thiết bị, nguồn giới thiệu). Dữ liệu cũng ghi nhận phản hồi khách hàng qua điểm đánh giá (ReviewScore) và văn bản đánh giá (ReviewText). Cấu trúc này hỗ trợ phân tích động lực doanh thu, hiệu quả khuyến mãi, hành vi mua sắm đa kênh và cảm nhận khách hàng.

3.1.2 Lí do lựa chọn bộ dữ liệu

Bộ dữ liệu này được lựa chọn vì tính toàn diện và đa dạng, cung cấp thông tin quan trọng giúp phân tích hành vi mua sắm từ nhiều góc độ. Các biến như TotalAmount, DiscountRate, ReviewScore, ReferralSource và ReviewText giúp phân tích động lực tài chính và sự hài lòng của khách hàng. Sự kết hợp giữa các yếu tố giao dịch (giá trị đơn hàng, chiết khấu, sản phẩm) và trải nghiệm người dùng (thiết bị, thời gian phiên, nguồn giới thiệu) tạo cơ hội đánh giá hiệu quả chiến lược tiếp thị và khuyến mãi.

Ngoài ra, bộ dữ liệu còn hỗ trợ phân tích thời gian, ví dụ như theo tháng, quý, ngày trong tuần, hoặc giờ trong ngày, giúp xác định xu hướng mua sắm và tối ưu hóa chiến lược bán hàng.

3.1.3 Phạm vi và nguồn dữ liệu

Bộ dữ liệu này được thu thập từ nền tảng Kaggle, cung cấp thông tin chi tiết về hành vi mua sắm trên nền tảng bán lẻ trực tuyến trong một khoảng thời gian dài, với sự đa dạng về người dùng, sản phẩm và các yếu tố giao dịch. Dữ liệu bao gồm các ngành hàng như quần áo, điện tử, phụ kiện và đồ gia dụng, giúp đưa ra những phân tích toàn diện về hành vi người tiêu dùng.

Bộ dữ liệu cho phép nghiên cứu về xu hướng mua sắm, hiệu quả khuyến mãi và đánh giá khách hàng, hỗ trợ quyết định kinh doanh chính xác hơn cho nền tảng bán lẻ. Dữ liệu đã được chuẩn hóa và làm sạch, thuận tiện cho phân tích và trực quan hóa.

3.1.3.1 Thống kê kích thước

Đoạn mã này sử dụng hàm read.csv() từ thư viện readr để đọc tệp CSV và lưu trữ dữ liệu vào một đối tượng trong R.

1. library(readr)
  • Hàm library(readr) trong R được dùng để nạp (kích hoạt) gói readr, chuyên để đọc và ghi dữ liệu (import/export) nhanh, gọn và nhất quán.
1. dataecommerce <- read.csv("D:/Rdata/ecommerce_synthetic_dataset.csv",
2.                           stringsAsFactors = FALSE)
3. dim(dataecommerce)
## [1] 100000     21

Giải thích kỹ thuật

Dòng lệnh (1) và (2) dùng để thực hiện các việc sau đây:

  • Lệnh này đọc tệp CSV có đường dẫn “D:/Rdata/ecommerce_synthetic_dataset.csv” và lưu nó vào biến dataecommerce.

  • Tham số stringsAsFactors = FALSE được sử dụng để đảm bảo rằng các chuỗi văn bản (strings) trong dữ liệu sẽ không bị chuyển đổi thành các yếu tố (factors).

Dòng lệnh (3): trả về kích thước của bộ dữ liệu, tức là số lượng hàng và cột.

  • Trong trường hợp này, nó sẽ trả về một mảng với hai phần tử: số lượng bản ghi (hàng) và số lượng biến (cột). Câu lệnh này giúp người dùng biết được bộ dữ liệu có bao nhiêu dòng và bao nhiêu cột.

Kết quả

Từ kết quả ta thấy được, bộ dữ liệu dataecommerce chứa 100,000 bản ghi (hàng) và 21 biến (cột).

3.1.3.2 Danh mục biến

1. colnames(dataecommerce)
##  [1] "UserID"             "UserName"           "Age"               
##  [4] "Gender"             "Country"            "SignUpDate"        
##  [7] "ProductID"          "ProductName"        "Category"          
## [10] "Price"              "PurchaseDate"       "Quantity"          
## [13] "TotalAmount"        "HasDiscountApplied" "DiscountRate"      
## [16] "ReviewScore"        "ReviewText"         "LastLogin"         
## [19] "SessionDuration"    "DeviceType"         "ReferralSource"

Giải thích kỹ thuật:

colnames(): là hàm cơ bản trong R giúp liệt kê tất cả các tên biến (cột) của bộ dữ liệu.

Ý nghĩa:

Các tên cột này cung cấp thông tin chi tiết về bộ dữ liệu, bao gồm các biến như UserID, Age, Gender, ProductName, TotalAmount, DiscountRate, ReviewScore, v.v.

3.1.3.3 Kiểu dữ liệu từng biến

Khi làm việc với dữ liệu, một trong những bước quan trọng là kiểm tra cấu trúc của bộ dữ liệu để hiểu rõ về các loại biến và kiểu dữ liệu của chúng.

1. str(dataecommerce)
## 'data.frame':    100000 obs. of  21 variables:
##  $ UserID            : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ UserName          : chr  "User_1" "User_2" "User_3" "User_4" ...
##  $ Age               : int  39 25 43 44 23 54 64 59 50 47 ...
##  $ Gender            : chr  "Male" "Female" "Male" "Male" ...
##  $ Country           : chr  "UK" "Canada" "Canada" "Germany" ...
##  $ SignUpDate        : chr  "2021-02-01" "2020-12-04" "2022-07-08" "2021-06-07" ...
##  $ ProductID         : int  8190 9527 3299 8795 1389 1524 4981 1847 3054 4719 ...
##  $ ProductName       : chr  "Shoes" "T-shirt" "Headphones" "T-shirt" ...
##  $ Category          : chr  "Books" "Accessories" "Apparel" "Apparel" ...
##  $ Price             : num  532.4 848.8 64.9 465.1 331.8 ...
##  $ PurchaseDate      : chr  "2021-02-25" "2021-09-22" "2021-11-30" "2021-10-14" ...
##  $ Quantity          : int  1 1 2 2 1 1 2 4 1 1 ...
##  $ TotalAmount       : num  532 849 130 930 332 ...
##  $ HasDiscountApplied: chr  "False" "True" "False" "False" ...
##  $ DiscountRate      : num  0.02 0.29 0.03 0.23 0.02 0.21 0.06 0.34 0.48 0.25 ...
##  $ ReviewScore       : num  5.1 5.1 3.2 4.3 5.1 4.6 3.7 3.6 4.8 5.2 ...
##  $ ReviewText        : chr  "Excellent" "Excellent" "Good" "Good" ...
##  $ LastLogin         : chr  "2024-05-03 04:04:27.591583" "2024-08-31 04:04:27.591606" "2024-07-28 04:04:27.591611" "2024-03-11 04:04:27.591615" ...
##  $ SessionDuration   : num  45 13.8 59.1 55.4 15 ...
##  $ DeviceType        : chr  "Mobile" "Mobile" "Tablet" "Desktop" ...
##  $ ReferralSource    : chr  "Social Media" "Social Media" "Organic Search" "Email Marketing" ...

Giải thích kỹ thuật:

str() là hàm cơ bản trong R dùng để hiển thị cấu trúc của đối tượng dữ liệu. Nó cho biết: Tên từng biến và kiểu dữ liệu của biến (numeric, character, date, logical, factor, …)

Ý nghĩa:

Kiểu dữ liệu: Các cột trong bộ dữ liệu có các kiểu dữ liệu khác nhau, bao gồm:

  • chr (8 biến): chứa thông tin định tính như tên, giới tính, quốc gia, loại thiết bị, nội dung đánh giá.

  • dbl (9 biến): là các biến số như tuổi, giá, số lượng, tổng tiền, điểm đánh giá, thời lượng phiên.

  • lgl (1 biến): biến nhị phân HasDiscountApplied, cho biết giao dịch có áp dụng giảm giá hay không.

  • dttm (1 biến): biến thời gian chi tiết LastLogin, ghi lại thời điểm đăng nhập gần nhất.

  • date (2 biến): SignUpDate và PurchaseDate, thể hiện ngày đăng ký tài khoản và ngày mua hàng.

=> Kết quả này giúp ta hiểu rõ hơn về các biến trong bộ dữ liệu và kiểu dữ liệu của chúng, từ đó có thể xác định các bước xử lý dữ liệu tiếp theo (chẳng hạn như chuyển đổi kiểu dữ liệu hoặc xử lý dữ liệu thiếu).

3.2 XỬ LÝ, CHỌN LỌC DỮ LIỆU

3.2.1 Kiểm tra dữ liệu thiếu

Khi làm việc với dữ liệu thực tế, rất có thể bạn sẽ gặp phải các giá trị thiếu (missing values) trong các cột. Các giá trị thiếu có thể làm ảnh hưởng đến kết quả phân tích, vì vậy việc phát hiện và xử lý các giá trị thiếu là một bước quan trọng trong quá trình chuẩn bị dữ liệu.

1. colSums(is.na(dataecommerce))
##             UserID           UserName                Age             Gender 
##                  0                  0                  0                  0 
##            Country         SignUpDate          ProductID        ProductName 
##                  0                  0                  0                  0 
##           Category              Price       PurchaseDate           Quantity 
##                  0                  0                  0                  0 
##        TotalAmount HasDiscountApplied       DiscountRate        ReviewScore 
##                  0                  0                  0                  0 
##         ReviewText          LastLogin    SessionDuration         DeviceType 
##                  0                  0                  0                  0 
##     ReferralSource 
##                  0

Giải thích kỹ thuật Hàm is.na() xác định các giá trị bị thiếu trong từng cột, còn colSums() tính tổng số giá trị NA của mỗi biến.

Kết quả Kết quả cho thấy không có giá trị bị thiếu (NA) trong toàn bộ bộ dữ liệu dataecommerce.

3.2.2 Kiểm tra dữ liệu trùng lặp

1. sum(duplicated(dataecommerce))
## [1] 0

Giải thích kỹ thuật

Lệnh sum(duplicated(dataecommerce)) dùng để kiểm tra số lượng bản ghi trùng lặp trong bộ dữ liệu dataecommerce.

duplicated(dataecommerce): Hàm duplicated() sẽ trả về một vector logic (TRUE/FALSE) cho biết mỗi hàng trong bộ dữ liệu có bị trùng lặp với hàng trước đó hay không.

sum(): Hàm sum() tính tổng số lượng giá trị TRUE (số bản ghi trùng lặp) trong vector.

Giải thích kết quả

Kết quả 0 có nghĩa là không có bản ghi nào trong bộ dữ liệu dataecommerce bị trùng lặp.

3.2.3 Kiểm tra giá trị bất thường

1. summary(dataecommerce[, c("Age", "TotalAmount", "DiscountRate")])
##       Age         TotalAmount       DiscountRate   
##  Min.   :18.00   Min.   :  10.02   Min.   :0.0000  
##  1st Qu.:31.00   1st Qu.: 494.68   1st Qu.:0.1300  
##  Median :43.00   Median : 966.08   Median :0.2500  
##  Mean   :43.46   Mean   :1260.85   Mean   :0.2498  
##  3rd Qu.:56.00   3rd Qu.:1850.33   3rd Qu.:0.3700  
##  Max.   :69.00   Max.   :3999.72   Max.   :0.5000

Giải thích kỹ thuật

Lệnh summary(dataecommerce[, c(“Age”, “TotalAmount”, “DiscountRate”)]) được sử dụng để cung cấp tóm tắt thống kê mô tả cho ba biến: Age, TotalAmount, và DiscountRate trong bộ dữ liệu dataecommerce. Hàm summary() sẽ tính toán các chỉ số thống kê cơ bản như:

  • Min.: Giá trị nhỏ nhất.
  • 1st Qu.: Phân vị 25% (giá trị dưới 25% số liệu).
  • Median: Trung vị (giá trị giữa trong tập hợp dữ liệu).
  • Mean: Giá trị trung bình.
  • 3rd Qu.: Phân vị 75% (giá trị dưới 75% số liệu).
  • Max.: Giá trị lớn nhất.

Giải thích kết quả

Kết quả summary() cho thấy các thông tin thống kê cơ bản của ba biến:

Age (Tuổi):

  • Tuổi khách hàng dao động từ 18 đến 69.
  • Tuổi trung bình là 43.46 và trung vị là 43, cho thấy phân bố tuổi khá đồng đều.

TotalAmount (Tổng số tiền):

  • Khoảng giá trị từ 10.02 đến 3999.72, cho thấy có những giao dịch rất nhỏ và rất lớn.
  • Giá trị trung bình là 1260.85, nhưng trung vị chỉ là 966.08, cho thấy có một số giao dịch có giá trị rất lớn kéo giá trị trung bình lên cao.

DiscountRate (Mức giảm giá):

  • Mức giảm giá dao động từ 0 đến 0.5.
  • Trung vị và trung bình gần giống nhau, đều xung quanh 0.25, cho thấy mức giảm giá phổ biến rơi vào khoảng 25%.

3.2.4 Kiểm tra tính ràng buộc logic

Đoạn mã dưới đây thực hiện hai kiểm tra quan trọng để đảm bảo tính hợp lý và nhất quán giữa các biến, bao gồm kiểm tra sự liên quan giữa các biến và tuân theo các quy tắc nhất định.

1. check_amount <- dataecommerce %>%
2.   mutate(ExpectedAmount = Price * Quantity * (1 - DiscountRate),
3.          Sai_so = TotalAmount - ExpectedAmount)
4. summary(check_amount$Sai_so)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   71.49  198.41  314.88  443.26 1999.00

Giải thích kỹ thuật

Đoạn mã sử dụng hàm mutate() để tạo ra một cột mới gọi là ExpectedAmount, tính toán theo công thức:

  • ExpectedAmount=Price×Quantity×(1−DiscountRate)
  • Sau đó, sai số giữa TotalAmount thực tế và ExpectedAmount được tính và lưu vào cột Sai_số. Phép tính này giúp kiểm tra xem dữ liệu có hợp lý không.

Giải thích kết quả

Kết quả của dòng lệnh 4 cho thấy:

  • Min. = 0.00: Không có sai số ở một số giao dịch.
  • Mean = 314.88 và Median = 198.41: Trung bình sai số khá lớn, cho thấy có một số giao dịch có sự chênh lệch đáng kể giữa TotalAmount và ExpectedAmount.
  • Max= 1999.00: Sai số lớn nhất lên tới 1999, cho thấy có những giao dịch mà sai số giữa TotalAmount và ExpectedAmount rất lớn.
1. table(dataecommerce$HasDiscountApplied, dataecommerce$DiscountRate > 0)
##        
##         FALSE  TRUE
##   False   486 49735
##   True    529 49250
  • Hàm table() được sử dụng để tạo một bảng chéo kiểm tra sự nhất quán giữa hai cột: HasDiscountApplied và điều kiện DiscountRate > 0.

Kết quả

  • FALSE & TRUE: Khi HasDiscountApplied là “False”, có 486 giao dịch với DiscountRate > 0, điều này có thể cho thấy có sự không nhất quán trong dữ liệu (giao dịch không áp dụng giảm giá nhưng lại có mức giảm giá).

  • TRUE & TRUE: Khi HasDiscountApplied là “True”, có 49250 giao dịch với DiscountRate > 0, điều này hợp lý vì giảm giá phải có mức giảm giá lớn hơn 0.

  • FALSE & FALSE: Khi HasDiscountApplied là “False”, có 49735 giao dịch với DiscountRate = 0, điều này hoàn toàn hợp lý.

Kết quả kiểm tra giữa TotalAmount và ExpectedAmount cho thấy sự sai lệch lớn, có thể do nhập liệu sai hoặc cách tính toán khác nhau. Cần làm sạch dữ liệu thêm.

Kiểm tra tính nhất quán giữa HasDiscountApplied và DiscountRate > 0 cho thấy một số giao dịch không áp dụng giảm giá nhưng lại có mức giảm giá lớn hơn 0, cần kiểm tra lại để đảm bảo tính nhất quán.

3.2.5 Làm sạch dữ liệu

3.2.5.1 Xử lý không ăn khớp giữa các biến

3.2.5.1.1 Xử lý không ăn khớp giữa ProductName và Category

Khi dữ liệu không khớp, ví dụ giữa ProductName và Category, ta có thể sử dụng bảng ánh xạ để sửa lỗi. Đoạn mã dưới đây sử dụng left_join để thay thế giá trị sai trong cột Category bằng giá trị chính xác từ bảng ánh xạ.

1. category_map <- data.frame(
2.   ProductName = c("Laptop", "Smartphone", "Headphones", "Shoes", "T-shirt", "Book", "Watch"),
3.   CorrectCategory = c("Electronics", "Electronics", "Electronics", "Apparel", "Apparel", "Books", "Accessories"))
4. dataecommerce <- dataecommerce %>%
5.   left_join(category_map, by = "ProductName") %>%
6.   mutate(Category = CorrectCategory) %>%
7.   select(-CorrectCategory)
8. head(dataecommerce, 10) 

Giải thích kỹ thuật

Dòng lệnh (1), (2) và (3) có mục đích là Tạo bảng ánh xạ: Đầu tiên, một bảng ánh xạ category_map được tạo ra, trong đó mỗi tên sản phẩm (ví dụ: “Laptop”, “Smartphone”) được ánh xạ với danh mục đúng của nó (ví dụ: “Electronics”, “Apparel”).

Dòng lệnh (5): Kết hợp bảng ánh xạ với dữ liệu gốc: Hàm left_join() được sử dụng để kết hợp dữ liệu từ bảng category_map với dataecommerce dựa trên cột ProductName. Cột CorrectCategory trong bảng ánh xạ sẽ được thêm vào dataecommerce.

Dòng lệnh (6): dùng để thay thế giá trị trong cột Category: Cột Category trong dataecommerce được thay thế bằng giá trị từ cột CorrectCategory trong bảng ánh xạ, đảm bảo rằng mỗi sản phẩm có đúng danh mục của nó.

Dòng lệnh (7): đểloại bỏ cột phụ CorrectCategory: Cột CorrectCategory được xóa đi sau khi thay thế giá trị trong cột Category.

Giải thích kết quả

head(dataecommerce, 10): Hiển thị 10 dòng đầu tiên của dữ liệu để kiểm tra kết quả sau khi thay thế danh mục.

3.2.5.1.2 Xử lý không ăn khớp giữa ReviewScore và ReviewText

Đoạn mã dưới đây xử lý sự không nhất quán giữa ReviewScore và ReviewText bằng cách phân loại lại ReviewText theo mức cảm xúc tương ứng với ReviewScore như “Poor”, “Average”, “Good” hoặc “Excellent”.

1. dataecommerce <- dataecommerce %>%
2.   mutate(
3.     ReviewText = case_when(
4.       ReviewScore < 4 ~ "Poor",
5.       ReviewScore >= 4 & ReviewScore < 7 ~ "Average",
6.       ReviewScore >= 7 & ReviewScore < 9 ~ "Good",
7.       ReviewScore >= 9 ~ "Excellent",
8.       TRUE ~ "Unknown"))
9. table(dataecommerce$ReviewText)
## 
## Average    Good    Poor 
##   52145     159   47696
1. summary(dataecommerce$ReviewScore)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  -0.600   3.300   4.000   4.006   4.700   8.600

Giải thích kết quả

Dòng lệnh 1-8 dùng để chuẩn hóa ReviewText:

Sử dụng hàm mutate() để thay đổi giá trị trong cột ReviewText dựa trên giá trị của ReviewScore. Hàm case_when() được sử dụng để tạo ra các phân loại cảm xúc như sau:

  • Nếu ReviewScore < 4, ReviewText sẽ là “Poor”.

  • Nếu ReviewScore từ 4 đến dưới 7, ReviewText sẽ là “Average”.

  • Nếu ReviewScore từ 7 đến dưới 9, ReviewText sẽ là “Good”.

  • Nếu ReviewScore từ 9 trở lên, ReviewText sẽ là “Excellent”.

  • Nếu không có giá trị hợp lệ, sẽ gán “Unknown”.

Kiểm tra kết quả:

  • Dòng lệnh (9) sẽ cho thấy số lượng các mức ReviewText sau khi phân loại.

  • Hàm summary(dataecommerce$ReviewScore) sẽ cung cấp thống kê mô tả về ReviewScore để đảm bảo rằng giá trị điểm đánh giá đã được phân bổ hợp lý.

Giải thích kết quả

Kết quả từ quá trình phân loại ReviewText và thống kê ReviewScore cho thấy:

Kết quả phân loại ReviewText (table(dataecommerce$ReviewText)):

  • Average: 52,145 bản ghi có đánh giá trung bình.

  • Good: 159 bản ghi có đánh giá tốt.

  • Poor: 47,696 bản ghi có đánh giá tệ.

-> Sự phân bố này cho thấy số lượng đánh giá “Poor” (tệ) và “Average” (trung bình) là rất lớn, trong khi số lượng đánh giá “Good” (tốt) lại rất ít.

Thống kê ReviewScore (summary(dataecommerce$ReviewScore)):

  • Min = -0.600 và Max = 8.600: Phù hợp bộ dữ liệu

  • 1st Qu = 3.300, Median = 4.000, Mean = 4.006: Hầu hết các giá trị điểm đánh giá đều nằm trong khoảng từ 3 đến 4, cho thấy phần lớn các đánh giá rơi vào mức trung bình hoặc tệ.

Nhận xét:

  • Phân bố ReviewText cho thấy phần lớn các đánh giá rơi vào mức “Poor” và “Average”, với ít đánh giá “Good”, có thể cần xem xét lại chất lượng dịch vụ/sản phẩm hoặc các yếu tố ảnh hưởng đến sự hài lòng của người dùng.

3.2.6 Chuẩn hóa ràng buộc logic

Đoạn mã dưới đây thực hiện ba nhiệm vụ chính trong việc xử lý sai lệch giữa giá trị lý thuyết và thực tế: tính toán lại tổng tiền lý thuyết, tạo cờ cho các giao dịch có sai lệch lớn hơn 2%, và chuẩn hóa lại biến HasDiscountApplied để đảm bảo tính nhất quán.

1. dataecommerce <- dataecommerce %>%
2.   mutate(ExpectedAmount = Price * Quantity * (1 - DiscountRate),
3.          Difference = TotalAmount - ExpectedAmount)
4. dataecommerce <- dataecommerce %>%
5.   mutate(LogicFlag = ifelse(abs(Difference) / ExpectedAmount > 0.02, 1, 0))
6. dataecommerce <- dataecommerce %>%
7.   mutate(HasDiscountApplied = ifelse(DiscountRate > 0, 1, 0))
8. summary(dataecommerce$Difference)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   71.49  198.41  314.88  443.26 1999.00
1. table(dataecommerce$LogicFlag)
## 
##     0     1 
##  3011 96989
1. table(dataecommerce$HasDiscountApplied)
## 
##     0     1 
##  1015 98985

Giải thích kỹ thuật

Đoạn lệnh (1) đến (3) được dùng để tính lại tổng tiền lý thuyết và sai lệch:

  • Dòng (2) để tính lại ExpectedAmount theo công thức: ExpectedAmount=Price×Quantity×(1−DiscountRate)

  • Sau đó, dòng (3) tính Difference giữa TotalAmount và ExpectedAmount. Cột này giúp phát hiện các sai lệch giữa giá trị thực tế và lý thuyết.

Đoạn lệnh (4) và (5) dùng để tạo cờ sai lệch: Dựa trên sai lệch, đoạn mã sử dụng mutate() để tạo cột LogicFlag, đánh dấu các giao dịch có sai lệch lớn hơn 2% so với tổng tiền lý thuyết. Nếu sai lệch lớn hơn 2%, cột LogicFlag sẽ có giá trị 1 (sai lệch), nếu không sẽ là 0 (không sai lệch).

Đoạn lệnh (6) và (7) chuẩn hóa lại biến HasDiscountApplied: Biến HasDiscountApplied được chuẩn hóa lại với mutate(). Cột này sẽ có giá trị 1 nếu DiscountRate > 0 (giảm giá được áp dụng), ngược lại giá trị là 0 (không áp dụng giảm giá).

Giải thích kết quả

Kết quả từ summary(dataecommerce$Difference) của đoạn lệnh (1) đến (3) cho thấy:

  • Min = 0.00: Không có sai lệch trong một số giao dịch.

  • Mean = 314.88 và Median = 198.41: Sai lệch trung bình khá lớn, cho thấy có sự khác biệt đáng kể giữa giá trị thực tế và lý thuyết trong một số giao dịch.

  • Max = 1999.00: Sai lệch lớn nhất lên đến 1999, có thể cần kiểm tra các giao dịch này vì có sự sai lệch quá lớn.

Kết quả table(dataecommerce$LogicFlag) của đoạn lệnh (4) và (5):

  • 0: 3,011 giao dịch không có sai lệch lớn hơn 2%.

  • 1: 96,989 giao dịch có sai lệch lớn hơn 2% so với tổng tiền lý thuyết. Điều này cho thấy số lượng giao dịch có sai lệch lớn rất cao, cần kiểm tra kỹ hơn.

Kết quả table(dataecommerce$HasDiscountApplied) của đoạn lệnh (6) và (7):

  • 0: 1,015 giao dịch không có giảm giá.

  • 1: 98,985 giao dịch có giảm giá. Điều này cho thấy phần lớn các giao dịch đều áp dụng giảm giá, và việc chuẩn hóa cột HasDiscountApplied đã được thực hiện đúng.

1. dataecommerce <- dataecommerce %>%
2.   mutate(TotalAmount = Price * Quantity * (1 - DiscountRate))
3. dataecommerce <- dataecommerce %>%
4.   mutate(HasDiscountApplied = ifelse(DiscountRate > 0, TRUE, FALSE))
5. summary(dataecommerce$TotalAmount)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##    5.228  356.311  730.275  945.968 1378.670 3977.000
1. table(dataecommerce$HasDiscountApplied)
## 
## FALSE  TRUE 
##  1015 98985

Giải thích kỹ thuật

Dòng lệnh (1) và (2): Sử dụng hàm mutate() để tính lại TotalAmount bằng công thức:

TotalAmount=Price×Quantity×(1−DiscountRate)

Dòng lệnh (3) và (4): Cập nhật lại biến HasDiscountApplied về dạng logic TRUE/FALSE:

  • Dùng mutate() kết hợp với hàm ifelse() để cập nhật HasDiscountApplied thành TRUE nếu DiscountRate > 0 (tức là có áp dụng giảm giá), ngược lại sẽ là FALSE.

Kiểm tra lại kết quả:

  • Sử dụng summary(dataecommerce$TotalAmount) để kiểm tra lại thống kê mô tả cho TotalAmount sau khi tính lại.

  • Sử dụng table(dataecommerce$HasDiscountApplied) để kiểm tra phân bố của biến HasDiscountApplied (TRUE/FALSE) sau khi chuẩn hóa.

Giải thích kết quả

*Kiểm tra lại TotalAmount: Kết quả từ summary(dataecommerce$TotalAmount) cho thấy:

Min = 5.228: Giá trị thấp nhất của TotalAmount là 5.228.

Mean = 945.968 và Median = 730.275: Giá trị trung bình của TotalAmount là 945.968, trong khi giá trị trung vị là 730.275, cho thấy một sự phân bố lệch về phía các giao dịch có tổng tiền cao hơn.

Max = 3977.000: Giá trị cao nhất là 3977.000, cho thấy một số giao dịch có tổng tiền rất lớn.

*Kiểm tra lại HasDiscountApplied: Kết quả từ table(dataecommerce$HasDiscountApplied) sẽ cho bạn số lượng giao dịch có và không có giảm giá:

TRUE: Giao dịch có áp dụng giảm giá.

FALSE: Giao dịch không có giảm giá.

Nhận xét:

Việc tính lại TotalAmount giúp đảm bảo tính chính xác trong dữ liệu và loại bỏ các sai sót có thể có.

HasDiscountApplied đã được chuẩn hóa đúng với các giá trị logic TRUE/FALSE, giúp phân tích dữ liệu dễ dàng hơn.

3.2.7 Lựa chọn dữ liệu biến chính để phân tích

Khi xử lý dữ liệu, việc lựa chọn các biến quan trọng từ bộ dữ liệu gốc để phục vụ cho các phân tích hoặc mô hình là một bước quan trọng.

1. newdata <- dataecommerce %>%
2.   select(UserID, Age, PurchaseDate, TotalAmount, HasDiscountApplied, DiscountRate, ReviewScore, ReviewText, ReferralSource)
3. head(newdata)
1. dim(newdata)
## [1] 100000      9

Giải thích kỹ thuật

Dòng lệnh (1), (2) và (3) này sử dụng hàm select() để chọn các biến cần thiết từ bộ dữ liệu dataecommerce. Cụ thể:

  • select(): Hàm này dùng để chọn các cột từ bộ dữ liệu. Sau khi sử dụng select(), bộ dữ liệu mới chỉ chứa các biến này và sẽ giúp giảm độ phức tạp của dữ liệu, đồng thời tạo ra một bảng nhỏ gọn hơn cho các phân tích sau.

  • head(newdata): Dùng để kiểm tra 6 dòng đầu tiên của bộ dữ liệu mới, giúp xác nhận các cột đã được chọn chính xác và dữ liệu có đầy đủ.

dim(newdata): Dùng để kiểm tra số lượng dòng và số lượng cột trong bộ dữ liệu mới, từ đó xác nhận kích thước của bộ dữ liệu đã được rút gọn đúng cách.

Giải thích kết quả

Kết quả trả về sẽ là 1 bản dữ liệu mới bao gồm:

UserID: Mã người dùng, để nhận diện các khách hàng.

Age: Tuổi của khách hàng.

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

TotalAmount: Tổng số tiền chi tiêu trong mỗi giao dịch.

HasDiscountApplied: Biến chỉ ra liệu giao dịch có áp dụng giảm giá không.

DiscountRate: Mức giảm giá áp dụng.

ReviewScore: Điểm đánh giá của khách hàng đối với sản phẩm.

ReviewText: Nội dung văn bản đánh giá của khách hàng.

ReferralSource: Nguồn giới thiệu của khách hàng (ví dụ: tìm thấy qua quảng cáo, tìm kiếm tự nhiên, v.v.).

3.2.8 Kiểm tra bộ dữ liệu mới

Sau khi tạo 1 bộ dữ liệu mới, ta cũng cần kiểm tra biến thiếu và trùng lặp

3.2.8.1 Kiểm tra biến thiếu

1. sum(is.na(newdata))
## [1] 0

Giải thích kỹ thuật

Đoạn mã này dùng hàm is.na() kết hợp với sum() để kiểm tra và tính tổng số lượng giá trị thiếu trong bộ dữ liệu:

  • is.na(newdata): Hàm is.na() kiểm tra xem mỗi giá trị trong bộ dữ liệu có phải là giá trị thiếu (NA) hay không.

  • sum(is.na(newdata)): Hàm sum() tính tổng số lượng giá trị TRUE (tức là số lượng giá trị thiếu) trong bộ dữ liệu.

Giải thích kết quả

Kết quả cho thấy bộ dữ liệu newdata không chứa bất kỳ giá trị thiếu nào, cho thấy dữ liệu đã được chuẩn bị sẵn sàng để tiến hành các phân tích tiếp theo mà không cần phải xử lý giá trị thiếu.

3.2.8.2 Kiểm tra trùng lặp

1. sum(duplicated(newdata))
## [1] 0

Đoạn mã này sử dụng hàm duplicated() kết hợp với sum() để kiểm tra số lượng bản ghi trùng lặp trong bộ dữ liệu:

  • duplicated(newdata): Hàm duplicated() kiểm tra mỗi bản ghi trong bộ dữ liệu có bị trùng lặp với bản ghi trước đó hay không.

  • sum(duplicated(newdata)): Hàm sum() tính tổng số lượng giá trị TRUE trong vector trả về từ duplicated(), tức là tổng số bản ghi trùng lặp trong bộ dữ liệu.

Giải thích kết quả

Kết quả cho thấy trong bộ dữ liệu newdata, không có bản ghi nào bị trùng lặp. Tất cả các bản ghi trong bộ dữ liệu là duy nhất, điều này giúp đảm bảo tính chính xác và đầy đủ của dữ liệu trong quá trình phân tích tiếp theo.

3.3 THỰC HIỆN CÁC THỐNG KÊ MÔ TẢ

3.3.1 Phân tổ dữ liệu

3.3.1.1 Phân tổ theo Age

Trong phân tích dữ liệu, việc phân tổ các biến liên quan đến người dùng như độ tuổi giúp dễ dàng xác định các nhóm người dùng và phân tích hành vi của họ theo từng nhóm. Đoạn mã dưới đây thực hiện phân tổ biến Age thành 3 nhóm độ tuổi: Dưới 25 tuổi, từ 25 đến 40 tuổi, và trên 40 tuổi.

1. newdata <- newdata %>%
2.   mutate(AgeGroup = case_when(
3.     Age < 25 ~ "Dưới 25 tuổi",
4.     Age >= 25 & Age <= 40 ~ "25-40 tuổi",
5.     Age > 40 ~ "Trên 40 tuổi",
6.     TRUE ~ "Không xác định"))
7. table(newdata$AgeGroup)
## 
##   25-40 tuổi Dưới 25 tuổi Trên 40 tuổi 
##        30804        13492        55704

Giải thích kỹ thuật

Đoạn mã từ (1) đến (6) thực hiện các việc sau:

mutate(): Tạo một cột mới AgeGroup trong bộ dữ liệu newdata dựa trên các điều kiện được xác định.

case_when(): Kiểm tra các điều kiện của biến Age:

-Nếu Age < 25, gán giá trị “Dưới 25 tuổi”.

-Nếu Age từ 25 đến 40, gán giá trị “25-40 tuổi”.

-Nếu Age > 40, gán giá trị “Trên 40 tuổi”.

-Nếu không thuộc các điều kiện trên, gán giá trị “Không xác định” (mặc dù trong trường hợp này, tất cả giá trị độ tuổi hợp lệ sẽ được phân vào 3 nhóm đã xác định).

Dòng lệnh (7) giúp kiểm tra phân bố của các nhóm độ tuổi trong bộ dữ liệu, tức là số lượng người dùng thuộc vào từng nhóm độ tuổi.

Giải thích kết quả

Kết quả từ lệnh (7) sẽ cho ta biết số lượng người dùng trong từng nhóm độ tuổi:

  • Dưới 25 tuổi: Có 30,804 người dùng trong nhóm này.

  • 25-40 tuổi: Có 13,492 người dùng trong nhóm này.

  • Trên 40 tuổi: Có 55,704 người dùng trong nhóm này.

Kết quả cho thấy đa phần người dùng thuộc nhóm Trên 40 tuổi, tiếp theo là nhóm Dưới 25 tuổi, và ít nhất là nhóm 25-40 tuổi.

3.3.1.2 Phân tổ biến TotalAmount thành 3 nhóm

Việc phân tổ các giá trị liên quan đến chi tiêu của người dùng giúp đánh giá mức độ chi tiêu của từng nhóm người dùng. Đoạn mã dưới đây thực hiện phân tổ biến TotalAmount thành 3 nhóm chi tiêu: dưới 500 USD, từ 500 đến 1000 USD, và trên 1000 USD.

1. newdata <- newdata %>%
2.   mutate(SpendingGroup = case_when(
3.     TotalAmount < 500 ~ "< 500 USD",
4.     TotalAmount >= 500 & TotalAmount <= 1000 ~ "500 – 1000 USD",
5.     TotalAmount > 1000 ~ "> 1000 USD",
6.     TRUE ~ "Không xác định"))
7. table(newdata$SpendingGroup)
## 
##      < 500 USD     > 1000 USD 500 – 1000 USD 
##          35365          37745          26890

Giải thích kỹ thuật

Đoạn mã từ (1) đến (6) thực hiện các việc sau:

mutate(): Hàm này dùng để tạo một cột mới SpendingGroup trong bộ dữ liệu newdata dựa trên các điều kiện xác định.

case_when(): Hàm này được sử dụng để kiểm tra các điều kiện của biến TotalAmount:

  • Nếu TotalAmount < 500, nhóm sẽ là “< 500 USD”.

  • Nếu TotalAmount từ 500 đến 1000, nhóm sẽ là “500 – 1000 USD”.

  • Nếu TotalAmount > 1000, nhóm sẽ là “> 1000 USD”.

  • Nếu không thuộc các điều kiện trên, giá trị mặc định sẽ là “Không xác định”.

Lệnh (7) dùng để kiểm tra phân bố của các nhóm chi tiêu trong bộ dữ liệu, tức là số lượng người dùng trong mỗi nhóm chi tiêu.

Giải thích kết quả

Kết quả từ lệnh (7) sẽ cho ta biết số lượng người dùng trong từng nhóm chi tiêu:

  • Nhóm < 500 USD: Có 35,365 người dùng trong nhóm chi tiêu dưới 500 USD.

  • Nhóm 500 – 1000 USD: Có 26,890 người dùng trong nhóm chi tiêu từ 500 đến 1000 USD.

  • Nhóm > 1000 USD: Có 37,745 người dùng trong nhóm chi tiêu trên 1000 USD.

Kết quả này cho thấy nhóm người dùng chi tiêu từ > 1000 USD là lớn nhất, tiếp theo là nhóm < 500 USD, và nhóm 500 – 1000 USD có ít người dùng nhất.

3.3.1.3 Phân tổ biến DiscountRate thành 3 nhóm

Phân tích tỷ lệ giảm giá là một bước quan trọng để hiểu được mức độ ưu đãi mà người dùng nhận được trong các giao dịch. Đoạn mã dưới đây thực hiện phân tổ biến DiscountRate thành 3 nhóm: dưới 10%, từ 10% đến 30%, và trên 30%.

1. newdata <- newdata %>%
2.   mutate(DiscountGroup = case_when(
3.     DiscountRate < 0.10 ~ "< 10%",
4.     DiscountRate >= 0.10 & DiscountRate <= 0.30 ~ "10% – 30%",
5.     DiscountRate > 0.30 ~ "> 30%",
6.     TRUE ~ "Không xác định"))
7. table(newdata$DiscountGroup)
## 
##     < 10%     > 30% 10% – 30% 
##     18995     39053     41952

Giải thích kỹ thuật

Đoạn mã từ (1) đến (6) thực hiện các việc sau:

mutate(): Dùng để tạo cột mới DiscountGroup trong bộ dữ liệu newdata dựa trên các điều kiện đã được xác định, case_when(): Dùng để kiểm tra các điều kiện của biến DiscountRate:

  • Nếu DiscountRate < 0.10, nhóm sẽ là “< 10%”.

  • Nếu DiscountRate từ 0.10 đến 0.30, nhóm sẽ là “10% – 30%”.

  • Nếu DiscountRate > 0.30, nhóm sẽ là “> 30%”.

  • Nếu không thuộc các điều kiện trên, giá trị mặc định là “Không xác định” (mặc dù trong trường hợp này, tất cả giá trị DiscountRate đều sẽ thuộc một trong ba nhóm đã xác định).

Dòng lệnh (7) giúp kiểm tra phân bố của các nhóm tỷ lệ giảm giá trong bộ dữ liệu, tức là số lượng người dùng trong mỗi nhóm tỷ lệ giảm giá.

Giải thích kết quả

-Nhóm < 10%: Có 18,995 người dùng trong nhóm giảm giá dưới 10%.

-Nhóm 10% – 30%: Có 41,952 người dùng trong nhóm giảm giá từ 10% đến 30%.

-Nhóm > 30%: Có 39,053 người dùng trong nhóm giảm giá trên 30%.

Kết quả này cho thấy phần lớn người dùng nhận được giảm giá trong khoảng 10% – 30%, tiếp theo là nhóm > 30%, và nhóm < 10% có ít người dùng nhất.

3.3.2 Phân tích đơn biến

3.3.2.1 Biến Age

Phân tích thống kê mô tả giúp cung cấp cái nhìn tổng quan về phân phối của một biến trong bộ dữ liệu. Đối với biến Age, thống kê mô tả sẽ giúp đánh giá các đặc điểm cơ bản của độ tuổi người dùng, như giá trị trung bình, trung vị, phạm vi tuổi (từ nhỏ nhất đến lớn nhất), và độ lệch chuẩn.

1. age_summary <- newdata %>%
2.   summarise(
3.     Mean = mean(Age, na.rm = TRUE),
4.     Min = min(Age, na.rm = TRUE),
5.     Max = max(Age, na.rm = TRUE),
6.     SD = sd(Age, na.rm = TRUE))
7. age_summary

Giải thích kỹ thuật

Đoạn mã từ (1) đến (6) được dùng để tính toán các chỉ số thống kê mô tả cho biến Age trong bộ dữ liệu newdata:

  • Dòng lệnh (3): Tính giá trị trung bình (mean) của độ tuổi, bỏ qua các giá trị thiếu (NA).

  • Dòng lệnh (4): Tính giá trị nhỏ nhất (min) của độ tuổi.

  • Dòng lệnh (5): Tính giá trị lớn nhất (max) của độ tuổi.

  • Dòng lệnh (6): Tính độ lệch chuẩn (standard deviation) của độ tuổi.

Giải thích kết quả Dòng lệnh (7) được dùng để xuất kết quả của việc tính toán

Mean (Trung bình): Trung bình độ tuổi của người dùng là 43.46, có nghĩa là độ tuổi trung bình của người dùng trong bộ dữ liệu gần 43 tuổi.

Median (Trung vị): Giá trị trung vị của độ tuổi là 43, cho thấy có một sự phân bố cân bằng giữa các độ tuổi thấp và cao.

Min (Giá trị nhỏ nhất): Tuổi nhỏ nhất trong bộ dữ liệu là 18 tuổi.

Max (Giá trị lớn nhất): Tuổi lớn nhất trong bộ dữ liệu là 69 tuổi.

SD (Độ lệch chuẩn): Độ lệch chuẩn là 14.98, cho thấy độ tuổi có sự phân tán vừa phải xung quanh giá trị trung bình.

Nhận xét

Dữ liệu có sự phân phối khá đồng đều về độ tuổi, với độ lệch chuẩn vừa phải (14.98), cho thấy có nhiều người dùng ở các độ tuổi khác nhau.

Phần lớn người dùng có độ tuổi xung quanh trung bình 43, nhưng cũng có sự hiện diện của người dùng trẻ (18 tuổi) và người dùng lớn tuổi (69 tuổi).

3.3.2.2 Biến TotalAmount

Phân tích thống kê mô tả cho biến TotalAmount giúp cung cấp cái nhìn tổng quan về tổng chi tiêu của người dùng trong bộ dữ liệu. Các chỉ số như giá trị trung bình, độ lệch chuẩn, giá trị nhỏ nhất và lớn nhất sẽ giúp đánh giá mức độ phân tán và các xu hướng chi tiêu của người dùng.

1. totalamount_summary <- newdata %>%
2.   summarise(
3.     Mean = mean(TotalAmount, na.rm = TRUE),
4.     SD = sd(TotalAmount, na.rm = TRUE),
5.     Min = min(TotalAmount, na.rm = TRUE),
6.     Max = max(TotalAmount, na.rm = TRUE))
7. totalamount_summary

Giải thích kết quả Dòng lệnh (7) được dùng để xuất kết quả của việc tính toán:

Mean (Trung bình): Trung bình tổng chi tiêu của người dùng là 945.97 USD, cho thấy rằng người dùng trong bộ dữ liệu có xu hướng chi tiêu khoảng 946 USD.

SD (Độ lệch chuẩn): Độ lệch chuẩn là 758.65 USD, cho thấy sự phân tán khá lớn của tổng chi tiêu xung quanh giá trị trung bình.

Min (Giá trị nhỏ nhất): Tổng chi tiêu thấp nhất trong bộ dữ liệu là 5.23 USD, cho thấy có người dùng chi tiêu rất ít.

Max (Giá trị lớn nhất): Tổng chi tiêu cao nhất là 3977 USD, cho thấy có người dùng chi tiêu một khoản lớn.

Nhận xét

TotalAmount có sự phân tán rộng (SD = 758.65), cho thấy rằng mặc dù phần lớn người dùng chi tiêu ở mức vừa phải (khoảng 946 USD), nhưng cũng có những người chi tiêu rất ít hoặc rất nhiều.

Sự phân bố này có thể chỉ ra rằng một số người dùng chi tiêu thấp hoặc chỉ mua một sản phẩm duy nhất, trong khi những người khác có thể mua nhiều sản phẩm hoặc chi tiêu với mức độ cao.

3.3.2.3 Biến ReviewScore

Thống kê mô tả cho biến ReviewScore giúp cung cấp cái nhìn tổng quan về mức độ hài lòng của người dùng đối với sản phẩm. Các chỉ số thống kê như giá trị trung bình, độ lệch chuẩn, giá trị nhỏ nhất và lớn nhất giúp đánh giá sự phân bố điểm đánh giá trong bộ dữ liệu và mức độ hài lòng của người dùng.

1. reviewscore_summary <- newdata %>%
2.   summarise(
3.     Mean = mean(ReviewScore, na.rm = TRUE),
4.     SD = sd(ReviewScore, na.rm = TRUE),
5.     Min = min(ReviewScore, na.rm = TRUE),
6.     Max = max(ReviewScore, na.rm = TRUE))
7. reviewscore_summary

Giải thích kết quả Dòng lệnh (7) được dùng để xuất kết quả của việc tính toán:

Mean (Trung bình): Trung bình điểm đánh giá của người dùng là 4.01, cho thấy điểm đánh giá trung bình của người dùng khá cao (gần mức tốt, thường điểm đánh giá nằm trong khoảng từ 1 đến 5 hoặc 1 đến 10 tùy theo hệ thống).

SD (Độ lệch chuẩn): Độ lệch chuẩn là 0.9988, cho thấy sự phân tán của điểm đánh giá xung quanh giá trị trung bình là khá thấp, nghĩa là các đánh giá không có sự chênh lệch quá lớn.

Min (Giá trị nhỏ nhất): Giá trị nhỏ nhất là -0.6, đây là một giá trị không hợp lý, có thể do dữ liệu bị lỗi hoặc người dùng nhập điểm đánh giá sai. Đây là điểm cần xem xét và xử lý.

Max (Giá trị lớn nhất): Giá trị lớn nhất là 8.6, có thể là mức đánh giá cao trong bộ dữ liệu, tuy nhiên, vẫn chưa đủ lớn để chỉ ra sự không hợp lý, nhưng cần xem xét nếu có bất kỳ quy tắc đánh giá nào.

Nhận xét

ReviewScore có trung bình là 4.01, cho thấy rằng phần lớn người dùng đánh giá sản phẩm khá tốt.

Tuy nhiên, giá trị Min = -0.6 là những đánh giá ở mức tệ. Có thể là do trải nghiệm khách hàng không được đúng với mong đợi.

Độ lệch chuẩn 0.9988 cho thấy sự phân tán của điểm đánh giá không quá lớn, và điểm đánh giá chủ yếu tập trung quanh giá trị trung bình.

3.3.3 Phân tích đa biến

3.3.3.1 Phân tích mối quan hệ giữa Age và TotalAmount

Phân tích mối quan hệ giữa độ tuổi và tổng chi tiêu là một bước quan trọng để hiểu hành vi chi tiêu của người dùng trong các nhóm độ tuổi khác nhau.

1. Age_vs_TotalAmount <- newdata %>%
2.   group_by(AgeGroup) %>% 
3.   summarise(
4.     Soluong = n(),
5.     Mean_TotalAmount = mean(TotalAmount, na.rm = TRUE), 
6.     SD_TotalAmount = sd(TotalAmount, na.rm = TRUE),  
7.     Min_TotalAmount = min(TotalAmount, na.rm = TRUE), 
8.     Max_TotalAmount = max(TotalAmount, na.rm = TRUE)) %>%
9.   arrange(AgeGroup)  
10. Age_vs_TotalAmount

Giải thích kỹ thuật

Đoạn mã từ (1) đến (9) dùng để nhóm bộ dữ liệu newdata theo biến AgeGroup (nhóm độ tuổi) và tính toán các chỉ số thống kê mô tả cho biến TotalAmount (tổng chi tiêu) trong từng nhóm độ tuổi:

group_by(AgeGroup): Nhóm bộ dữ liệu theo AgeGroup, tức là phân chia người dùng thành các nhóm độ tuổi: “Dưới 25 tuổi”, “25-40 tuổi”, và “Trên 40 tuổi”.

  • Dòng lệnh (3): Tính toán các chỉ số thống kê cho TotalAmount trong từng nhóm độ tuổi:

  • Dòng lệnh (4): Số lượng người dùng trong mỗi nhóm.

  • Dòng lệnh (5): Trung bình tổng chi tiêu trong mỗi nhóm.

  • Dòng lệnh (6): Độ lệch chuẩn của tổng chi tiêu trong mỗi nhóm.

  • Dòng lệnh (7): Tổng chi tiêu thấp nhất trong mỗi nhóm.

  • Dòng lệnh (8): Tổng chi tiêu cao nhất trong mỗi nhóm.

  • Dòng lệnh (9): Sắp xếp kết quả theo nhóm độ tuổi.

Dòng lệnh (10) được dùng để xem bảng kết quả các phép tính

Giải thích kết quả

  • 25-40 tuổi: Nhóm này có 30,804 người dùng với Mean_TotalAmount = 946.73 USD, độ lệch chuẩn là 760.10, tổng chi tiêu thấp nhất là 6.20 USD, và cao nhất là 3957.70 USD.

  • Dưới 25 tuổi: Nhóm này có 13,492 người dùng với Mean_TotalAmount = 942.49 USD, độ lệch chuẩn là 756.01, tổng chi tiêu thấp nhất là 7.10 USD, và cao nhất là 3920.28 USD.

  • Trên 40 tuổi: Nhóm này có 55,704 người dùng với Mean_TotalAmount = 946.39 USD, độ lệch chuẩn là 758.51, tổng chi tiêu thấp nhất là 5.23 USD, và cao nhất là 3977.00 USD.

Nhận xét

Các nhóm độ tuổi 25-40 và Dưới 25 tuổi có mức chi tiêu trung bình khá tương đương (946.73 USD và 942.49 USD), trong khi nhóm Trên 40 tuổi có mức chi tiêu trung bình rất gần (946.39 USD).

Mặc dù các nhóm có mức chi tiêu trung bình tương đương, nhưng Trên 40 tuổi có số lượng người dùng lớn nhất (55,704 người), dẫn đến sự phân tán lớn trong tổng chi tiêu (độ lệch chuẩn cao, 758.51 USD).

Các nhóm có tổng chi tiêu thấp nhất khá gần nhau, với các giá trị thấp nhất từ 5.23 USD đến 7.10 USD.

Nhóm 25-40 tuổi có mức chi tiêu tối đa cao nhất (3957.70 USD) so với các nhóm còn lại, cho thấy nhóm này có khả năng chi tiêu lớn hơn trong một số trường hợp.

Phân tích này cho thấy sự phân bổ chi tiêu giữa các nhóm độ tuổi có sự tương đồng về mặt trung bình, nhưng sự phân tán trong nhóm Trên 40 tuổi có thể phản ánh sự đa dạng trong hành vi chi tiêu của người dùng lớn tuổi.

3.3.3.2 Phân tích mối quan hệ giữa DiscountRate và TotalAmount

Phân tích mối quan hệ giữa tỷ lệ giảm giá (DiscountRate) và tổng chi tiêu (TotalAmount) của người dùng giúp đánh giá ảnh hưởng của việc giảm giá đến hành vi chi tiêu.

1. DiscountRate_vs_TotalAmount <- newdata %>%
2.   group_by(DiscountGroup) %>%  
3.   summarise(
4.     Soluong = n(),
5.     Mean_TotalAmount = mean(TotalAmount, na.rm = TRUE), 
6.     SD_TotalAmount = sd(TotalAmount, na.rm = TRUE), 
7.     Min_TotalAmount = min(TotalAmount, na.rm = TRUE),
8.     Max_TotalAmount = max(TotalAmount, na.rm = TRUE)) %>%
9.   arrange(DiscountGroup) 
10. DiscountRate_vs_TotalAmount

Giải thích kỹ thuật

Đoạn mã từ (1) đến (9) dùng để nhóm bộ dữ liệu newdata theo DiscountGroup (nhóm tỷ lệ giảm giá), và tính toán các chỉ số thống kê mô tả cho biến TotalAmount trong từng nhóm giảm giá:

  • Dòng lệnh (2): Nhóm bộ dữ liệu theo DiscountGroup (Nhóm tỷ lệ giảm giá), tức là phân chia người dùng thành ba nhóm giảm giá: “< 10%”, “10% – 30%”, và “> 30%”.

  • Dòng lệnh (3): Tính toán các chỉ số thống kê cho TotalAmount trong từng nhóm:

  • Dòng lệnh (4): Số lượng bản ghi (giao dịch) trong từng nhóm.

  • Dòng lệnh (5): Trung bình tổng chi tiêu trong từng nhóm.

  • Dòng lệnh (6): Độ lệch chuẩn của tổng chi tiêu trong từng nhóm.

  • Dòng lệnh (7): Tổng chi tiêu thấp nhất trong từng nhóm.

  • Dòng lệnh (8): Tổng chi tiêu cao nhất trong từng nhóm.

  • Dòng lệnh (9): Sắp xếp kết quả theo nhóm tỷ lệ giảm giá.

Dòng lệnh (10) được dùng để xem bảng kết quả các phép tính

Giải thích kết quả: từ bảng kết quả, ta có thế thấy được

Nhóm 10% – 30%:

  • Có 41,952 giao dịch trong nhóm này.

  • Trung bình tổng chi tiêu là 1008.41 USD, với độ lệch chuẩn là 780.93 USD, cho thấy sự phân tán lớn giữa các giao dịch trong nhóm này.

  • Tổng chi tiêu thấp nhất là 7.50 USD, và cao nhất là 3589.13 USD.

Nhóm < 10%:

  • Có 18,995 giao dịch trong nhóm này.

  • Trung bình tổng chi tiêu là 1204.58 USD, với độ lệch chuẩn 913.90 USD.

  • Tổng chi tiêu thấp nhất là 9.18 USD, và cao nhất là 3977.00 USD.

Nhóm > 30%:

  • Có 39,053 giao dịch trong nhóm này.

  • Trung bình tổng chi tiêu là 753.10 USD, với độ lệch chuẩn 581.84 USD.

  • Tổng chi tiêu thấp nhất là 5.23 USD, và cao nhất là 2746.83 USD.

Nhận xét

Nhóm < 10% có tổng chi tiêu trung bình cao nhất (1204.58 USD) so với các nhóm khác, cho thấy rằng khi tỷ lệ giảm giá thấp, người dùng có xu hướng chi tiêu nhiều hơn.

Nhóm 10% – 30% có tổng chi tiêu trung bình là 1008.41 USD, thấp hơn so với nhóm < 10%, nhưng độ lệch chuẩn khá lớn, cho thấy sự phân tán rộng về mức chi tiêu.

Nhóm > 30% có tổng chi tiêu trung bình thấp nhất (753.10 USD), với độ lệch chuẩn là 581.84 USD, cho thấy khi giảm giá lớn hơn 30%, người dùng có xu hướng chi tiêu ít hơn và có sự phân tán lớn trong mức chi tiêu.

Kết quả này cho thấy rằng mức độ giảm giá có ảnh hưởng đến hành vi chi tiêu của người dùng, và mức giảm giá thấp (< 10%) có thể kích thích người dùng chi tiêu nhiều hơn so với khi giảm giá cao (> 30%).

3.3.3.3 Phân tích mối quan hệ giữa ReviewScore và TotalAmount

Mối quan hệ này có thể cung cấp thông tin quan trọng cho việc tối ưu hóa các chiến lược marketing, cải thiện chất lượng sản phẩm, và nâng cao sự hài lòng của khách hàng.

1. ReviewScore_vs_TotalAmount <- newdata %>%
2.   group_by(ReviewScore) %>%  
3.   summarise(
4.     Soluong = n(),
5.     Mean_TotalAmount = mean(TotalAmount, na.rm = TRUE),  
6.     Min_TotalAmount = min(TotalAmount, na.rm = TRUE),  
7.     Max_TotalAmount = max(TotalAmount, na.rm = TRUE)) %>%
8.   arrange(ReviewScore)  
9. ReviewScore_vs_TotalAmount

Giải thích kỹ thuật

  • Đoạn mã từ (1) đến (9) dùng để nhóm bộ dữ liệu newdata theo ReviewScore (điểm đánh giá) và tính toán các chỉ số thống kê mô tả cho TotalAmount (tổng chi tiêu):

  • Dòng lệnh thứ (10) được dùng để xem bảng kết quả các phép tính

Kết quả

ReviewScore và TotalAmount có sự thay đổi lớn giữa các nhóm điểm đánh giá.:

  • Các điểm đánh giá thấp, chẳng hạn -0.6, -0.5, có tổng chi tiêu rất cao (2156.98 USD, 1289.56 USD), có thể là do chất lượng của sản phẩm không xứng với giá tiền nên ảnh hưởng tiêu cực đến đánh giá của khách hàng.

  • Các giá trị ReviewScore < 0 thể hiện đánh giá tiêu cực hợp lệ; nhóm này chi tiêu cao nhưng số lượng ít, một phân khúc khách hàng chi tiêu lớn nhưng không hài lòng.

  • ReviewScore từ 0.2 đến 8.6 có xu hướng có tổng chi tiêu trung bình dao động từ khoảng 900 USD đến 1000 USD, với một số nhóm điểm đánh giá có độ lệch chuẩn khá cao, cho thấy sự phân tán lớn trong tổng chi tiêu.

  • Nhóm có điểm đánh giá cao hơn như 3.0, 3.5 cho thấy tổng chi tiêu trung bình vào khoảng 960 USD - 980 USD, với độ lệch chuẩn cũng ở mức khá cao, thể hiện sự phân tán đáng kể về mức chi tiêu trong các nhóm điểm đánh giá cao.

Nhận xét tổng quan:

Tổng chi tiêu có xu hướng tăng hoặc dao động ở mức cao trong các nhóm có điểm đánh giá từ 0,2 đến 8,6. Sự phân tán của TotalAmount trong từng nhóm ReviewScore cho thấy người dùng có hành vi chi tiêu rất khác nhau ngay cả khi đánh giá sản phẩm ở mức tương đương.

Kết quả này cho thấy rằng có một sự phân tán lớn giữa các điểm đánh giá và tổng chi tiêu, tuy nhiên, các nhóm có điểm đánh giá thấp và cực cao cần được xem xét kỹ càng vì có thể chứa lỗi dữ liệu.

3.4 TRỰC QUAN HÓA DỮ LIỆU

3.4.1 Mối quan hệ giữa Age và TotalAmount

Phân tích mối quan hệ giữa các yếu tố trong dữ liệu là bước quan trọng trong việc hiểu hành vi của khách hàng. Biểu đồ phân tán là công cụ hiệu quả để kiểm tra mối quan hệ giữa hai biến định lượng, như giữa độ tuổi và tổng chi tiêu của khách hàng.

1. plot1 <- ggplot(newdata, aes(x = Age, y = TotalAmount)) +
2.   geom_point(color = "steelblue", alpha = 0.6) +  
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") + 
4.   geom_rug(sides = "b", color = "gray") +  
5.   scale_x_continuous(breaks = seq(0, 100, by = 10)) +  
6.   labs(title = "Mối quan hệ giữa Age và TotalAmount", x = "Độ tuổi", y = "Tổng chi tiêu (USD)") +  
7.   theme_minimal()
8. plot1

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng thư viện ggplot2 trong R để tạo biểu đồ phân tán giữa độ tuổi và tổng chi tiêu của khách hàng.

  • Dòng lệnh (1): Khởi tạo biểu đồ phân tán, với trục x là độ tuổi (Age) và trục y là tổng chi tiêu (TotalAmount).

  • Dòng lệnh (2): Vẽ các điểm dữ liệu trên biểu đồ với màu sắc là “steelblue” và độ mờ (alpha) là 0.6, giúp các điểm không bị chồng lên nhau quá nhiều.

  • Dòng lệnh (3): Thêm một đường xu hướng tuyến tính (linear regression) vào biểu đồ để chỉ ra mối quan hệ giữa độ tuổi và tổng chi tiêu. Đường này được vẽ màu đỏ và kiểu đường chấm (dashed).

  • Dòng lệnh (4): Thêm các dấu “rug” ở phía dưới của biểu đồ để chỉ ra sự phân bố của các điểm dữ liệu, giúp người xem nhận diện rõ ràng hơn về mật độ các giá trị.

  • Dòng lệnh (5): Điều chỉnh các mức độ chia của trục x (độ tuổi), với các mức giá trị từ 0 đến 100, chia theo bước nhảy 10.

  • Dòng lệnh (6): Thêm tiêu đề và nhãn cho các trục x và y.

  • Dòng lệnh (7): Sử dụng một theme đơn giản để biểu đồ trông sạch sẽ và dễ đọc hơn.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot1 ra màn hình.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa tỷ lệ giảm giá (DiscountRate) và tổng chi tiêu (TotalAmount) của khách hàng. Quan sát cho thấy khi tỷ lệ giảm giá tăng lên, tổng chi tiêu trung bình của khách hàng có xu hướng giảm dần. Đường hồi quy tuyến tính màu đỏ nét đứt đi xuống minh họa rõ mối quan hệ nghịch biến này, cho thấy các giao dịch có mức giảm giá cao thường gắn với giá trị đơn hàng thấp hơn.

Các điểm xanh lá cây đại diện cho từng giao dịch riêng lẻ, phân bố dọc theo các mức giảm giá và cho thấy sự phân tán lớn giữa các khách hàng. Dù cùng một tỷ lệ chiết khấu, giá trị chi tiêu vẫn rất khác nhau, phản ánh sự đa dạng trong hành vi mua sắm. Các điểm xanh đậm hình thoi biểu thị giá trị trung bình của tổng chi tiêu tại mỗi mức giảm giá, nằm gần đường hồi quy, khẳng định tính ổn định của xu hướng giảm.

Nhìn chung, biểu đồ cho thấy mối quan hệ nghịch biến giữa tỷ lệ giảm giá và tổng chi tiêu: khi giảm giá mạnh, khách hàng không nhất thiết chi tiêu nhiều hơn. Điều này gợi ý rằng các chương trình khuyến mãi quá sâu chủ yếu thu hút các đơn hàng có giá trị nhỏ, thay vì làm tăng doanh thu trung bình trên mỗi giao dịch.

3.4.2 Mối quan hệ giữa AgeGroup và TotalAmount

Chúng ta sử dụng biểu đồ hộp để phân tích tổng chi tiêu của khách hàng theo nhóm độ tuổi, giúp nhận diện sự biến động trong chi tiêu giữa các nhóm.

1. plot2 <- ggplot(newdata, aes(x = AgeGroup, y = TotalAmount)) +
2.   geom_boxplot(fill = "lightblue", color = "darkblue", alpha = 0.7) +  
3.   geom_jitter(width = 0.2, color = "#FFCC66", alpha = 0.5) +  
4.   geom_hline(yintercept = mean(newdata$TotalAmount), color = "green", linetype = "dashed") +  
5.   scale_y_continuous(labels = scales::comma) +  
6.   labs(title = "Phân phối tổng chi tiêu theo nhóm tuổi", x = "Độ tuổi", y = "Tổng chi tiêu (USD)") +  
7.   theme_minimal()
8. plot2

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng thư viện ggplot2 trong R để tạo ra biểu đồ hộp kết hợp với các lớp thông tin bổ sung:

  • Dòng lệnh (2): Vẽ biểu đồ hộp (boxplot) với màu nền là xanh nhạt và đường viền màu xanh đậm, với độ trong suốt (alpha) là 0.7.

  • Dòng lệnh (3): Thêm các điểm jitter (nhiễu) vào biểu đồ để thể hiện sự phân bố của các điểm dữ liệu, với màu vàng nhạt và độ mờ 0.5.

  • Dòng lệnh (4): Thêm một đường ngang (horizontal line) biểu thị giá trị trung bình của tổng chi tiêu, giúp người xem nhận diện rõ hơn về mức chi tiêu trung bình.

  • Dòng lệnh (5): Điều chỉnh nhãn trục y để hiển thị giá trị với dấu phẩy, giúp dễ đọc các giá trị tiền tệ.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot2 ra màn hình.

Giải thích kết quả

Biểu đồ trên thể hiện phân phối tổng chi tiêu (TotalAmount) của khách hàng theo ba nhóm tuổi: dưới 25 tuổi, từ 25–40 tuổi và trên 40 tuổi. Mỗi cột gồm phần hộp biểu diễn tứ phân vị và điểm trung vị, cùng các điểm vàng phân tán thể hiện từng giao dịch cá nhân.

Quan sát cho thấy cả ba nhóm tuổi có mức chi tiêu khá tương đồng, với trung vị nằm quanh mức 800–1000 USD. Tuy nhiên, nhóm khách hàng từ 25–40 tuổi có độ phân tán cao hơn, tức là khoảng biến động giữa các cá nhân trong nhóm này lớn hơn so với hai nhóm còn lại. Đường xanh lá biểu diễn giá trị trung bình tổng thể, cho thấy phần lớn các nhóm tuổi có mức chi tiêu trung bình xấp xỉ nhau.

Nhìn chung, biểu đồ cho thấy độ tuổi không tạo ra sự khác biệt đáng kể về tổng chi tiêu trung bình. Tuy vậy, nhóm trung niên (25–40 tuổi) có hành vi chi tiêu đa dạng hơn, với một số khách hàng chi tiêu cao vượt trội, trong khi nhóm trẻ và nhóm lớn tuổi có xu hướng chi tiêu tập trung quanh mức trung bình.

3.4.3 Mối quan hệ giữa DiscountRate và TotalAmount

Biểu đồ phân tán giúp chúng ta dễ dàng kiểm tra mối quan hệ giữa hai biến định lượng, chẳng hạn như tỷ lệ giảm giá và tổng chi tiêu.

1. plot3 <- ggplot(newdata, aes(x = DiscountRate, y = TotalAmount)) +
2.   geom_point(color = "green", alpha = 0.6) +  
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +  
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") +  
5.   scale_x_continuous(labels = scales::percent) + 
6.   labs(title = "Mối quan hệ giữa tỷ lệ giảm giá và tổng chi tiêu", x = "Tỷ lệ giảm giá", y = "Tổng chi tiêu (USD)") +
7.   theme_minimal()
8. plot3

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ phân tán và phân tích mối quan hệ giữa tỷ lệ giảm giá và tổng chi tiêu:

  • Dòng lệnh (2): Vẽ các điểm phân tán với màu xanh lá và độ mờ 0.6, thể hiện sự phân bố của các dữ liệu.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính (linear regression) màu đỏ và kiểu đường chấm, giúp thể hiện mối quan hệ giữa tỷ lệ giảm giá và tổng chi tiêu.

  • Dòng lệnh (4): Thêm điểm trung bình vào biểu đồ để chỉ ra giá trị trung bình của tổng chi tiêu đối với mỗi tỷ lệ giảm giá.

  • Dòng lệnh (5): Điều chỉnh trục x để hiển thị tỷ lệ phần trăm, giúp dễ hiểu hơn về tỷ lệ giảm giá.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot3 ra màn hình.

Kết quả

Biểu đồ thể hiện mối quan hệ giữa tỷ lệ giảm giá (DiscountRate) và tổng chi tiêu (TotalAmount) của khách hàng. Có thể thấy khi tỷ lệ giảm giá tăng, tổng chi tiêu trung bình của khách hàng có xu hướng giảm dần rõ rệt. Đường hồi quy tuyến tính màu đỏ nét đứt cho thấy mối quan hệ nghịch biến giữa hai biến, nghĩa là mức chiết khấu càng cao thì giá trị đơn hàng thường càng thấp.

Các điểm màu xanh lá biểu thị từng giao dịch riêng lẻ, thể hiện mức chi tiêu của khách hàng ở mỗi mức giảm giá, phân bố dọc thành các cột thẳng cho thấy số lượng giao dịch lớn ở nhiều mức chiết khấu khác nhau. Các điểm màu xanh dương hình thoi đại diện cho giá trị trung bình của tổng chi tiêu tại từng mức chiết khấu, nằm khá sát đường hồi quy, phản ánh tính ổn định của xu hướng giảm.

Nhìn chung, biểu đồ cho thấy các chương trình khuyến mãi với tỷ lệ giảm giá cao có thể không giúp tăng giá trị chi tiêu trung bình trên mỗi đơn hàng. Khách hàng có xu hướng mua các đơn hàng nhỏ hơn khi được giảm giá nhiều, trong khi các đơn hàng có giá trị cao thường đi kèm với mức chiết khấu thấp hơn.

3.4.4 DiscountGroup vs TotalAmount

Khi kết hợp với các yếu tố khác như jitter và đường trung bình, biểu đồ hộp không chỉ giúp ta hiểu rõ sự phân tán của dữ liệu mà còn làm nổi bật các đặc điểm quan trọng, chẳng hạn như mức chi tiêu trung bình theo các nhóm tỷ lệ giảm giá.

1. plot4 <- ggplot(newdata, aes(x = DiscountGroup, y = TotalAmount)) +
2.   geom_boxplot(fill = "yellow", color = "orange", alpha = 0.7) +  
3.   geom_jitter(width = 0.2, color = "blue", alpha = 0.5) + 
4.   geom_hline(yintercept = mean(newdata$TotalAmount), color = "green", linetype = "dashed") +  
5.   scale_y_continuous(labels = scales::comma) +  
6.   labs(title = "Phân phối tổng chi tiêu theo nhóm tỷ lệ giảm giá", x = "Tỷ lệ giảm giá", y = "Tổng chi tiêu (USD)") +  
7.   theme_minimal()
8. plot4

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ hộp và phân tích tổng chi tiêu của khách hàng theo các nhóm tỷ lệ giảm giá:

  • Dòng lệnh (1): Khởi tạo biểu đồ với nhóm tỷ lệ giảm giá (DiscountGroup) trên trục x và tổng chi tiêu (TotalAmount) trên trục y.

  • Dòng lệnh (2): Vẽ biểu đồ hộp với màu nền vàng và đường viền cam, giúp thể hiện sự phân bố tổng chi tiêu theo các nhóm tỷ lệ giảm giá.

  • Dòng lệnh (3): Thêm các điểm jitter (nhiễu) màu xanh dương vào biểu đồ, giúp thể hiện phân bố chi tiết của các điểm dữ liệu.

  • Dòng lệnh (4): Thêm một đường ngang màu xanh lá thể hiện giá trị trung bình của tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh nhãn trục y để hiển thị giá trị theo dạng có dấu phẩy, giúp dễ đọc các giá trị tiền tệ.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot4 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối tổng chi tiêu (TotalAmount) của khách hàng theo ba nhóm tỷ lệ giảm giá: dưới 10%, từ 10–30%, và trên 30%. Mỗi cột biểu đồ gồm các điểm xanh biểu diễn giá trị chi tiêu của từng giao dịch và phần hộp màu vàng thể hiện phân bố tứ phân vị cùng trung vị của từng nhóm.

Quan sát cho thấy nhóm khách hàng được giảm giá dưới 10% có mức chi tiêu cao và phân tán hơn so với hai nhóm còn lại. Trung vị của nhóm này cao hơn, cho thấy phần lớn khách hàng trong nhóm này có tổng chi tiêu lớn hơn so với các nhóm được giảm giá nhiều hơn. Ngược lại, hai nhóm có mức giảm giá từ 10–30% và trên 30% có tổng chi tiêu thấp hơn và tập trung quanh giá trị trung bình, thể hiện qua hộp nhỏ và vị trí trung vị thấp hơn.

Kết quả này củng cố nhận định rằng khi mức giảm giá tăng, giá trị trung bình của mỗi đơn hàng có xu hướng giảm. Điều này có thể do khách hàng tận dụng giảm giá để mua các sản phẩm giá thấp hoặc số lượng nhỏ, thay vì tăng tổng chi tiêu. Như vậy, các chương trình giảm giá cao chưa chắc đã giúp gia tăng doanh thu trên mỗi giao dịch.

3.4.5 ReviewScore vs TotalAmount

Biểu đồ phân tán giúp quan sát mối quan hệ giữa điểm đánh giá và tổng chi tiêu. Thêm đường hồi quy và điểm trung bình giúp làm rõ xu hướng và phát hiện các hành vi chi tiêu đặc trưng.

1. plot5 <- ggplot(newdata, aes(x = ReviewScore, y = TotalAmount)) +
2.   geom_point(color = "DeepSkyBlue1", alpha = 0.6) +   
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +  
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") + 
5.   scale_x_continuous(breaks = seq(0, 10, by = 1)) +  
6.   labs(title = "Mối quan hệ giữa ReviewScore và TotalAmount", x = "Điểm đánh giá", y = "Tổng chi tiêu (USD)") +  
7.   theme_minimal()
8. plot5

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ phân tán giữa điểm đánh giá và tổng chi tiêu:

  • Dòng lệnh (2): Vẽ các điểm phân tán màu tím với độ mờ 0.6, thể hiện sự phân bố của dữ liệu.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính (linear regression) màu đỏ và kiểu đường chấm để thể hiện mối quan hệ giữa điểm đánh giá và tổng chi tiêu.

  • Dòng lệnh (4): Thêm điểm trung bình (mean) vào biểu đồ để thể hiện giá trị trung bình của tổng chi tiêu theo các điểm đánh giá.

  • Dòng lệnh (5): Điều chỉnh trục x để có các mức điểm đánh giá từ 0 đến 10, chia theo bước nhảy 1.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot5 ra màn hình.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa điểm đánh giá (ReviewScore) và tổng chi tiêu (TotalAmount) của khách hàng. Mỗi điểm xanh biểu thị một giao dịch cụ thể, còn các điểm hình thoi xanh đậm thể hiện giá trị trung bình của tổng chi tiêu tại từng mức điểm đánh giá.

Quan sát cho thấy tổng chi tiêu của khách hàng phân bố khá đồng đều theo các mức điểm đánh giá, không xuất hiện xu hướng tăng hoặc giảm rõ rệt. Đường hồi quy màu đỏ nét đứt gần như nằm ngang, chứng tỏ giữa ReviewScore và TotalAmount không tồn tại mối quan hệ tuyến tính đáng kể. Dù có một số điểm ngoại lệ với giá trị chi tiêu rất cao, nhưng chúng chỉ chiếm tỷ trọng nhỏ và không ảnh hưởng nhiều đến xu hướng chung.

Kết quả này cho thấy mức độ hài lòng (thể hiện qua điểm đánh giá) không ảnh hưởng trực tiếp đến giá trị đơn hàng. Nói cách khác, khách hàng chi tiêu cao chưa chắc đã đánh giá cao hơn, và ngược lại — những người đánh giá thấp không nhất thiết chi tiêu ít hơn. Điều này phản ánh rằng các yếu tố khác như trải nghiệm mua sắm, chất lượng dịch vụ, hoặc kỳ vọng cá nhân có thể tác động mạnh hơn đến điểm đánh giá so với giá trị chi tiêu thực tế.

3.4.6 ReviewScore vs TotalAmount

1. plot6 <- ggplot(newdata, aes(x = DiscountGroup, y = TotalAmount, fill = DiscountGroup)) +
2.   geom_violin(color = "#1F77B4", alpha = 0.4) +        
3.   geom_boxplot(width = 0.15, color = "#1F77B4", alpha = 0.6, outlier.shape = NA) + 
4.   geom_jitter(width = 0.15, alpha = 0.25, size = 1, color = "#555555") +  
5.   stat_summary(fun = mean, geom = "point", shape = 23, size = 3, fill = "#FF0000") + 
6.   geom_hline(yintercept = mean(newdata$TotalAmount, na.rm = TRUE),
7.              color = "#FF0000", linetype = "dashed") +                     
8.   labs(title = "Phân phối TotalAmount theo DiscountGroup",
9.        x = "Nhóm giảm giá", y = "Tổng chi tiêu (USD)") +
10.   theme_minimal(base_size = 12)
11. plot6

Giải thích kỹ thuật Đoạn lệnh từ (1) đến (8) sử dụng ggplot2 trong R để tạo biểu đồ kết hợp violin, boxplot và jitter, giúp minh họa phân phối tổng chi tiêu (TotalAmount) theo từng nhóm giảm giá (DiscountGroup):

  • Dòng lệnh (2): Vẽ biểu đồ violin thể hiện hình dạng phân phối của tổng chi tiêu trong mỗi nhóm, với viền màu xanh dương và độ mờ 0.4.

  • Dòng lệnh (3): Chồng thêm boxplot để hiển thị giá trị trung vị và tứ phân vị, giúp dễ dàng quan sát sự biến động trong từng nhóm.

  • Dòng lệnh (4): Thêm các điểm dữ liệu rải ngẫu nhiên (jitter) để biểu diễn từng giao dịch riêng lẻ, tránh chồng lấn dữ liệu.

  • Dòng lệnh (5): Thêm dấu chấm màu đỏ để thể hiện giá trị trung bình của TotalAmount trong mỗi nhóm giảm giá.

  • Dòng lệnh (6) và (7): Thêm đường gạch ngang màu đỏ thể hiện mức trung bình tổng thể của toàn bộ khách hàng.

Dòng lệnh (11): Dùng để hiển thị biểu đồ đã được lưu trong biến plot6 ra màn hình.

Kết quả

Biểu đồ trên mô tả phân phối tổng chi tiêu (TotalAmount) của khách hàng theo ba nhóm tỷ lệ giảm giá: dưới 10%, từ 10–30%, và trên 30%. Mỗi nhóm được biểu diễn bằng đồ thị violin, thể hiện mật độ phân bố giá trị chi tiêu; các chấm đen là từng giao dịch, trong khi các điểm hình thoi đỏ đại diện cho giá trị trung bình của từng nhóm.

Quan sát cho thấy nhóm khách hàng có mức giảm giá dưới 10% có tổng chi tiêu trung bình cao hơn so với hai nhóm còn lại. Hai nhóm có mức giảm giá cao hơn (10–30% và trên 30%) đều có tổng chi tiêu trung bình thấp hơn, thể hiện xu hướng giảm dần khi tỷ lệ chiết khấu tăng. Ngoài ra, phân bố của nhóm dưới 10% cũng trải rộng hơn, cho thấy sự đa dạng trong giá trị đơn hàng, trong khi hai nhóm còn lại tập trung quanh mức thấp hơn và ít biến động hơn.

Tóm lại, biểu đồ phản ánh mối quan hệ nghịch biến giữa tỷ lệ giảm giá và tổng chi tiêu: khi khách hàng được giảm giá nhiều, họ có xu hướng mua các đơn hàng nhỏ hơn. Điều này cho thấy việc tăng chiết khấu không nhất thiết làm tăng doanh thu bình quân trên mỗi giao dịch mà chủ yếu khuyến khích các giao dịch giá trị thấp.

3.4.7 ReviewScore phân phối

Ta sử dụng biểu đồ histogram để thể hiện sự phân bố của điểm đánh giá, cùng với đồ thị mật độ để làm mịn và hiểu rõ hơn về xu hướng của dữ liệu.

1. plot7 <- ggplot(newdata, aes(x = ReviewScore)) +
2.   geom_histogram(aes(y = ..density..), binwidth = 0.5, fill = "orange", color = "black", alpha = 0.7) +
3.   geom_density(color = "blue", linewidth = 1) +
4.   geom_vline(aes(xintercept = mean(ReviewScore, na.rm = TRUE)), color = "red", linetype = "dashed") +
5.   scale_x_continuous(breaks = seq(0, 10, by = 1)) +
6.   labs(title = "Phân phối điểm đánh giá", x = "Điểm đánh giá", y = "Mật độ") +
7.   theme_minimal()
8. plot7

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ histogram và đồ thị mật độ cho điểm đánh giá:

  • Dòng lệnh (2): Vẽ biểu đồ histogram với các thanh có độ rộng 0.5, màu nền cam và đường viền đen, độ mờ 0.7. Mật độ (density) được tính thay vì tần suất (count).

  • Dòng lệnh (3): Thêm đồ thị mật độ màu xanh dương, giúp mượt mà hóa phân phối của điểm đánh giá.

  • Dòng lệnh (4): Thêm một đường dọc màu đỏ tại giá trị trung bình của điểm đánh giá để làm nổi bật giá trị trung bình của phân phối.

  • Dòng lệnh (5): Điều chỉnh các mức giá trị của trục x từ 0 đến 10, chia theo bước nhảy 1.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot7 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối điểm đánh giá (ReviewScore) của khách hàng. Dạng histogram màu cam mô tả tần suất xuất hiện của các mức điểm, trong khi đường cong màu xanh biểu diễn đường mật độ (density curve) cho thấy xu hướng phân phối tổng thể. Đường thẳng đỏ nét đứt ở giữa biểu thị giá trị trung bình của điểm đánh giá.

Quan sát cho thấy phân phối điểm đánh giá có dạng chuông đối xứng, gần với phân phối chuẩn, tập trung chủ yếu quanh giá trị trung bình khoảng 4 điểm. Điều này cho thấy phần lớn khách hàng có xu hướng đưa ra mức đánh giá trung bình đến khá, trong khi các điểm cực thấp hoặc cực cao (dưới 2 hoặc trên 6) xuất hiện rất ít.

Kết quả phản ánh rằng trải nghiệm tổng thể của khách hàng với sản phẩm hoặc dịch vụ là khá ổn định, không có sự phân cực mạnh giữa nhóm đánh giá tích cực và tiêu cực. Do đó, chất lượng sản phẩm/dịch vụ được nhìn nhận tương đối đồng đều và nhất quán trong nhóm khách hàng khảo sát.

3.4.8 Age phân phối

Biểu đồ histogram được sử dụng để thể hiện phân phối độ tuổi của khách hàng, đồng thời thêm đồ thị mật độ để làm mượt và nhận diện các xu hướng rõ ràng hơn trong phân phối độ tuổi.

1. plot8 <- ggplot(newdata, aes(x = Age)) +
2.   geom_histogram(binwidth = 5, fill = "lightblue", color = "black", alpha = 0.7) +  
3.   geom_vline(aes(xintercept = mean(Age, na.rm = TRUE)), color = "red", linetype = "dashed") + 
4.   geom_density(fill = "green", alpha = 0.3) + 
5.   scale_x_continuous(breaks = seq(0, 100, by = 10)) +  
6.   labs(title = "Phân phối độ tuổi", x = "Độ tuổi", y = "Số lượng") + 
7.   theme_minimal()
8. plot8

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ Phân phối độ tuổi

  • Dòng lệnh (2): Vẽ biểu đồ histogram với các thanh có độ rộng 5, màu nền xanh nhạt và đường viền đen, độ mờ 0.7. Histogram sẽ thể hiện sự phân phối của độ tuổi.

  • Dòng lệnh (3): Thêm đường dọc màu đỏ tại giá trị trung bình của độ tuổi, giúp nhận diện mức độ tuổi trung bình trong bộ dữ liệu.

  • Dòng lệnh (4): Thêm đồ thị mật độ màu xanh lá, độ mờ 0.3, giúp mượt mà hóa phân phối độ tuổi và nhận diện xu hướng phân phối dễ dàng hơn.

  • Dòng lệnh (5): Điều chỉnh các mức độ của trục x từ 0 đến 100, chia theo bước nhảy 10 để hiển thị các độ tuổi.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot8 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối độ tuổi của khách hàng trong tập dữ liệu. Mỗi cột của histogram biểu diễn số lượng khách hàng thuộc một khoảng tuổi nhất định, trong khi đường đỏ nét đứt thể hiện giá trị trung bình của độ tuổi.

Quan sát cho thấy độ tuổi của khách hàng phân bố khá đồng đều trong khoảng từ 18 đến 65 tuổi, không có sự chênh lệch rõ rệt giữa các nhóm tuổi. Tuy nhiên, từ 65 tuổi trở lên, số lượng khách hàng giảm mạnh, cho thấy nhóm người lớn tuổi chiếm tỷ trọng thấp hơn trong tập dữ liệu, có thể phản ánh xu hướng ít tham gia các hoạt động mua sắm trực tuyến của nhóm khách hàng cao tuổi, do hạn chế về công nghệ hoặc thói quen tiêu dùng truyền thống..

Kết quả này cho thấy cơ sở khách hàng có độ tuổi đa dạng, tập trung chủ yếu ở nhóm trung niên (25–65 tuổi) – nhóm tuổi có khả năng chi tiêu và mua sắm trực tuyến cao. Điều này phản ánh đặc điểm điển hình của các nền tảng thương mại điện tử, nơi nhóm khách hàng trong độ tuổi lao động chiếm ưu thế.

3.4.9 TotalAmount phân phối

Chúng ta sử dụng biểu đồ histogram để thể hiện phân phối của tổng chi tiêu, đồng thời thêm đồ thị mật độ để làm mịn và nhận diện các xu hướng rõ ràng hơn trong dữ liệu.

1. plot9 <- ggplot(newdata, aes(x = TotalAmount)) +
2.   geom_histogram(binwidth = 50, fill = "red", color = "black", alpha = 0.7) + 
3.   geom_vline(aes(xintercept = mean(TotalAmount, na.rm = TRUE)), color = "red", linetype = "dashed") +  
4.   geom_density(color = "blue", linewidth = 1) + 
5.   scale_x_continuous(labels = scales::comma) +  
6.   labs(title = "Phân phối tổng chi tiêu", x = "Tổng chi tiêu (USD)", y = "Số lượng") +  
7.   theme_minimal()
8. plot9

Giải thích kỹ thuật

Đoạn lệnh từ (1) đến (7) sử dụng ggplot2 trong R để tạo biểu đồ histogram và đồ thị mật độ cho tổng chi tiêu:

  • Dòng lệnh (2): Vẽ biểu đồ histogram với các thanh có độ rộng 50, màu nền đỏ và đường viền đen, độ mờ 0.7.

  • Dòng lệnh (3): Thêm đường dọc màu đỏ tại giá trị trung bình của tổng chi tiêu.

  • Dòng lệnh (4): Thêm đồ thị mật độ (density plot) màu xanh dương, giúp mượt mà hóa phân phối tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh nhãn trục x để hiển thị giá trị có dấu phẩy, giúp dễ đọc các giá trị tiền tệ.

Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot9 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối tổng chi tiêu (TotalAmount) của khách hàng trong toàn bộ tập dữ liệu. Các cột màu đỏ biểu diễn tần suất số lượng khách hàng tương ứng với từng mức chi tiêu, còn đường thẳng đỏ nét đứt cho biết giá trị trung bình của tổng chi tiêu.

Quan sát cho thấy phân phối có dạng lệch phải rõ rệt (right-skewed), tức phần lớn khách hàng có mức chi tiêu thấp, trong khi chỉ một tỷ lệ nhỏ khách hàng chi tiêu rất cao. Phần lớn các giá trị tập trung quanh mức dưới 1.000 USD, trong khi một số ít khách hàng có chi tiêu vượt xa mức trung bình, kéo dài phần đuôi bên phải của biểu đồ.

Kết quả này cho thấy hành vi chi tiêu của khách hàng mang tính phân hóa mạnh, với đa số người tiêu dùng thực hiện các giao dịch nhỏ và ít khách hàng tạo ra doanh thu lớn. Điều này hàm ý rằng một nhóm nhỏ “khách hàng giá trị cao” (high-value customers) có thể đóng vai trò quan trọng trong tổng doanh thu của doanh nghiệp, đồng thời gợi ý rằng các chiến lược tiếp thị nên tập trung vào việc giữ chân và gia tăng giá trị ở nhóm này.

3.4.10 ReviewScore phân phối

Đồ thị mật độ được sử dụng để thể hiện phân phối điểm đánh giá của khách hàng.

1. plot10 <- ggplot(newdata, aes(x = ReviewScore)) +
2.   geom_density(fill = "blue", alpha = 0.5) +   
3.   geom_vline(aes(xintercept = mean(ReviewScore, na.rm = TRUE)), color = "red", linetype = "dashed") +   
4.   scale_x_continuous(breaks = seq(0, 10, by = 1)) +  
5.   labs(title = "Phân phối mật độ điểm đánh giá", x = "Điểm đánh giá", y = "Mật độ") +   
6.   theme_minimal()
7. plot10

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ đồ thị mật độ với màu xanh dương và độ mờ 0.5. Đồ thị này giúp mượt mà hóa phân phối của điểm đánh giá.

  • Dòng lệnh (3): Thêm một đường dọc màu đỏ tại giá trị trung bình của điểm đánh giá để giúp nhận diện trung vị của phân phối.

  • Dòng lệnh (4): Điều chỉnh trục x để có các mức điểm đánh giá từ 0 đến 10, chia theo bước nhảy 1.

  • Dòng lệnh (5): Thêm tiêu đề và nhãn cho trục x và y để làm rõ thông tin.

  • Dòng lệnh (7): dùng để hiển thị biểu đồ đã được lưu trong biến plot10 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối mật độ của điểm đánh giá (ReviewScore) từ khách hàng. Đường cong màu xanh biểu diễn mật độ xác suất, cho thấy tần suất tương đối của các mức điểm, trong khi đường thẳng đỏ nét đứt thể hiện giá trị trung bình của toàn bộ phân phối.

Quan sát cho thấy phân phối có dạng chuông đối xứng, tương tự phân phối chuẩn, với đỉnh tập trung quanh mức điểm 4. Điều này cho thấy phần lớn khách hàng có xu hướng đưa ra đánh giá ở mức trung bình đến khá, trong khi các điểm đánh giá quá thấp hoặc quá cao ít xuất hiện hơn. Mật độ giảm dần đều ở hai phía, phản ánh sự ổn định trong cảm nhận của khách hàng.

Kết quả này cho thấy trải nghiệm tổng thể của người dùng là tích cực và ổn định, không có hiện tượng phân cực mạnh giữa nhóm đánh giá cao và nhóm đánh giá thấp. Nói cách khác, phần lớn khách hàng cảm thấy hài lòng ở mức tương đối, thể hiện sự đồng nhất trong chất lượng dịch vụ hoặc sản phẩm mà họ nhận được.

3.4.11 DiscountRate phân phối

Đồ thị này được sử dụng để phân tích tỷ lệ giảm giá (DiscountRate), cho phép chúng ta nhận diện mức độ phân tán và xu hướng chung của dữ liệu.

1. plot11 <- ggplot(newdata, aes(x = DiscountRate)) +
2.   geom_density(fill = "green", alpha = 0.5) +  # Lớp 1: Biểu đồ density
3.   geom_vline(aes(xintercept = mean(DiscountRate, na.rm = TRUE)), 
4.              color = "red", linetype = "dashed", size = 1) +  # Lớp 2: Đường trung bình
5.   geom_vline(aes(xintercept = median(DiscountRate, na.rm = TRUE)), 
6.              color = "blue", linetype = "dotted", size = 1) +  # Lớp 3: Đường trung vị
7.   annotate("text", x = mean(newdata$DiscountRate, na.rm = TRUE) + 0.02, 
8.            y = 4, label = "Mean", color = "red", size = 4, fontface = "bold") +  # Lớp 4: Ghi chú chú thích giá trị mean
9.   scale_x_continuous(labels = percent) +  # Lớp 5: Chuyển trục x sang dạng phần trăm
10.   labs(title = "Phân phối mật độ tỷ lệ giảm giá", 
11.        x = "Tỷ lệ giảm giá", y = "Mật độ") +
12.   theme_minimal()
13. plot11

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ đồ thị mật độ với màu xanh lá, độ mờ 0.5 để làm mượt phân phối của tỷ lệ giảm giá.

  • Dòng lệnh (3): Thêm đường dọc màu đỏ tại giá trị trung bình của tỷ lệ giảm giá.

  • Dòng lệnh (4): Thêm đường dọc màu xanh lam tại giá trị trung vị, giúp so sánh vị trí trung tâm của phân phối so với trung bình.

  • Dòng lệnh (5): Ghi chú chữ “Mean” ngay trên vị trí trung bình để biểu đồ dễ đọc hơn.

  • Dòng lệnh (6): Điều chỉnh trục x để hiển thị tỷ lệ phần trăm thay vì số thập phân.

  • Dòng lệnh (9): dùng để hiển thị biểu đồ đã được lưu trong biến plot11 ra màn hình.

Kết quả

Biểu đồ trên mô tả phân phối mật độ của tỷ lệ giảm giá (DiscountRate) trong tập dữ liệu. Diện tích màu xanh lá thể hiện mật độ xác suất của các mức chiết khấu, còn đường thẳng nét đứt màu xanh – đỏ đánh dấu giá trị trung bình của tỷ lệ giảm giá.

Quan sát cho thấy phân phối gần như phẳng và đồng đều, trải đều từ 0% đến 50%. Điều này cho thấy các mức giảm giá được áp dụng tương đối cân bằng, không tập trung vào một khoảng cụ thể nào. Nói cách khác, khách hàng có khả năng nhận được chiết khấu ở nhiều mức khác nhau với tần suất gần như ngang nhau.

Giá trị trung bình nằm khoảng giữa (xấp xỉ 25%), cho thấy các chương trình khuyến mãi được thiết kế khá đa dạng, từ mức thấp đến cao, giúp doanh nghiệp tiếp cận được nhiều nhóm khách hàng với nhu cầu và hành vi chi tiêu khác nhau. Phân bố đồng đều này phản ánh chính sách ưu đãi có tính linh hoạt và bao phủ rộng trong toàn bộ hệ thống.

3.4.12 Age phân phối

Đồ thị này sẽ minh họa sự phân phối của độ tuổi (Age), giúp hiểu rõ hơn về cấu trúc độ tuổi trong tập dữ liệu.

1. plot12 <- ggplot(newdata, aes(x = Age)) +
2.   geom_density(fill = "red", alpha = 0.5) +   
3.   geom_vline(aes(xintercept = mean(Age, na.rm = TRUE)), 
4.              color = "blue", linetype = "dashed", size = 1) +  
5.   geom_vline(aes(xintercept = median(Age, na.rm = TRUE)), 
6.              color = "green", linetype = "dotted", size = 1) +   
7.   scale_x_continuous(breaks = seq(0, 100, by = 10)) +   
8.   annotate("text", x = mean(newdata$Age, na.rm = TRUE) + 2, y = 0.015, 
9.            label = "Mean", color = "blue", size = 4, fontface = "bold") +  
10.   labs(title = "Phân phối mật độ độ tuổi", x = "Độ tuổi", y = "Mật độ") +
11.   theme_minimal()
12. plot12

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ đồ thị mật độ với màu đỏ, độ mờ 0.5, giúp mượt mà hóa phân phối độ tuổi và dễ nhận thấy vùng tập trung của dữ liệu.

  • Dòng lệnh (3) và (4): Thêm đường dọc màu xanh dương tại giá trị trung bình của độ tuổi, cho biết vị trí trung tâm của phân phối.

  • Dòng lệnh (5) và (6): Thêm đường dọc màu xanh lá biểu diễn giá trị trung vị, giúp so sánh độ lệch giữa trung bình và trung vị để đánh giá tính đối xứng của phân phối độ tuổi.

  • Dòng lệnh (7): Điều chỉnh trục x để hiển thị các mức độ tuổi từ 0 đến 100, chia theo bước nhảy 10.

  • Dòng lệnh (8) và (9): Ghi chú chữ “Mean” tại vị trí trung bình để biểu đồ trực quan, người xem dễ nhận biết điểm trung tâm của phân phối.

  • Dòng lệnh (12): dùng để hiển thị biểu đồ đã được lưu trong biến plot12 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối mật độ của độ tuổi khách hàng trong tập dữ liệu. Diện tích màu đỏ biểu diễn mật độ xác suất theo từng độ tuổi, trong khi đường thẳng nét đứt màu xanh lá và xanh dương đánh dấu giá trị trung bình (Mean) của toàn bộ mẫu.

Quan sát cho thấy phân phối độ tuổi khá đều và phẳng trong khoảng từ 18 đến khoảng 65 tuổi, không có đỉnh nổi bật nào. Điều này chứng tỏ dữ liệu được phân bố gần như đồng đều giữa các nhóm tuổi, không tập trung vào một độ tuổi cụ thể. Ở hai đầu biên (dưới 20 và trên 65 tuổi), mật độ có xu hướng giảm nhẹ, phản ánh số lượng khách hàng ở nhóm tuổi rất trẻ hoặc lớn tuổi ít hơn.

Kết quả cho thấy cơ cấu khách hàng của tập dữ liệu có sự đa dạng cao về độ tuổi, với phần lớn người dùng thuộc nhóm từ 25–55 tuổi – nhóm tuổi có hoạt động mua sắm mạnh nhất. Sự phân bố tương đối cân bằng này giúp cho các phân tích về hành vi chi tiêu theo độ tuổi có độ tin cậy cao và ít bị lệch do mất cân đối mẫu.

3.4.13 Age vs TotalAmount

Đồ thị này sẽ thể hiện mối quan hệ giữa độ tuổi (Age) và tổng chi tiêu (TotalAmount), đồng thời sử dụng màu sắc để phân nhóm theo điểm đánh giá (ReviewScore).

1. plot13 <- ggplot(newdata, aes(x = Age, y = TotalAmount, color = ReviewScore)) +
2.   geom_point(alpha = 0.6) +   
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") +   
5.   scale_x_continuous(breaks = seq(0, 100, by = 10)) +   
6.   labs(title = "Mối quan hệ giữa độ tuổi và tổng chi tiêu", x = "Độ tuổi", y = "Tổng chi tiêu (USD)") +   
7.   theme_minimal()
8. plot13

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ các điểm phân tán giữa độ tuổi và tổng chi tiêu với độ mờ 0.6.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính để thể hiện mối quan hệ giữa độ tuổi và tổng chi tiêu.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh các mức giá trị của trục x từ 0 đến 100, chia theo bước nhảy 10.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot13 ra màn hình.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa độ tuổi của khách hàng và tổng chi tiêu (TotalAmount), đồng thời sử dụng sắc độ màu xanh để biểu thị điểm đánh giá (ReviewScore). Mỗi điểm tròn đại diện cho một giao dịch, còn các hình thoi xanh đậm thể hiện giá trị trung bình của tổng chi tiêu theo từng độ tuổi.

Quan sát cho thấy tổng chi tiêu của khách hàng không thay đổi đáng kể theo độ tuổi, thể hiện qua dải trung bình khá ổn định quanh mức 1.000 USD. Không có xu hướng tăng hay giảm rõ rệt giữa các nhóm tuổi, cho thấy độ tuổi không phải là yếu tố chi phối mạnh đến hành vi chi tiêu. Tuy nhiên, sự phân tán khá lớn của các điểm dữ liệu cho thấy mức chi tiêu trong cùng một nhóm tuổi có thể rất khác nhau — phản ánh sự đa dạng về thu nhập, nhu cầu và hành vi mua sắm.

Về sắc độ màu, các tông màu xanh đậm và nhạt phân bố đồng đều, cho thấy điểm đánh giá của khách hàng cũng không bị ảnh hưởng rõ rệt bởi độ tuổi hay mức chi tiêu. Nói cách khác, cả mức độ chi tiêu và sự hài lòng của khách hàng đều phân bố khá đồng nhất trên toàn bộ dải độ tuổi, phản ánh cơ cấu khách hàng cân bằng và ổn định.

3.4.14 Tương quan giữa DiscountRate và ReviewScore theo AgeGroup

Đồ thị phân tán giữa tỷ lệ giảm giá (DiscountRate) và tổng chi tiêu (TotalAmount) giúp chúng ta hiểu mối quan hệ giữa các yếu tố này, đồng thời phân nhóm theo độ tuổi (AgeGroup).

1. plot14 <- ggplot(newdata, aes(x = DiscountRate, y = ReviewScore, color = AgeGroup)) +
2.   geom_point(alpha = 0.5) +   
3.   geom_smooth(method = "lm", se = FALSE, linetype = "dashed", size = 1) +   
4.   facet_wrap(~ AgeGroup) +   
5.   scale_x_continuous(labels = percent) +  
6.   labs(title = "Mối quan hệ giữa tỷ lệ giảm giá và điểm đánh giá theo nhóm tuổi", 
7.        x = "Tỷ lệ giảm giá", y = "Điểm đánh giá sản phẩm") +   
8.   theme_minimal()
9. plot14

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ các điểm dữ liệu phân tán giữa tỷ lệ giảm giá và điểm đánh giá, với độ mờ 0.5 giúp giảm chồng lấn và dễ quan sát.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính cho từng nhóm tuổi, biểu diễn xu hướng mối quan hệ giữa mức giảm giá và điểm đánh giá, giúp nhận diện chiều hướng tăng hay giảm.

  • Dòng lệnh (4): Chia biểu đồ thành nhiều ô (facet) tương ứng với từng nhóm độ tuổi, cho phép so sánh trực quan xu hướng giữa các thế hệ khác nhau.

  • Dòng lệnh (5): Định dạng trục x hiển thị theo phần trăm (%), giúp người xem dễ nhận biết tỷ lệ giảm giá.

  • Dòng lệnh (9): dùng để hiển thị biểu đồ đã được lưu trong biến plot14 ra màn hình.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa tỷ lệ giảm giá (DiscountRate)điểm đánh giá sản phẩm (ReviewScore), được tách theo ba nhóm tuổi: dưới 25, từ 25–40 và trên 40 tuổi. Mỗi điểm trên đồ thị đại diện cho một đánh giá của khách hàng, với màu sắc phân biệt cho từng nhóm tuổi.

Quan sát cho thấy, trong cả ba nhóm, các điểm đánh giá phân bố khá đồng đều quanh mức trung bình từ 4 đến 6 điểm, không có xu hướng rõ rệt theo tỷ lệ giảm giá. Điều này cho thấy mức giảm giá dường như không ảnh hưởng đáng kể đến mức độ hài lòng của khách hàng. Dù được hưởng ưu đãi cao hay thấp, người tiêu dùng vẫn đưa ra đánh giá tương đối ổn định.

Nhóm 25–40 tuổi có mật độ đánh giá dày đặc nhất, phản ánh đây là nhóm khách hàng năng động, tham gia nhiều hoạt động mua sắm trực tuyến hơn. Trong khi đó, nhóm dưới 25 tuổitrên 40 tuổi có phân bố thưa hơn nhưng vẫn duy trì mức đánh giá tương tự, cho thấy mức độ hài lòng không chênh lệch lớn giữa các độ tuổi. Tổng thể, biểu đồ phản ánh rằng yếu tố giảm giá không phải là động lực chính quyết định trải nghiệm hay đánh giá sản phẩm của người tiêu dùng.

3.4.15 ReviewScore vs TotalAmount

Biểu đồ phân tán này giúp ta phân tích mối quan hệ giữa điểm đánh giá (ReviewScore) và tổng chi tiêu (TotalAmount), đồng thời phân nhóm theo tỷ lệ giảm giá (DiscountGroup).

1. plot15 <- ggplot(newdata, aes(x = ReviewScore, y = TotalAmount, color = DiscountGroup)) +
2.   geom_point(alpha = 0.6) +   
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") +   
5.   scale_x_continuous(breaks = seq(0, 10, by = 1)) +   
6.   labs(title = "Mối quan hệ giữa điểm đánh giá và tổng chi tiêu", x = "Điểm đánh giá", y = "Tổng chi tiêu (USD)") +   
7.   theme_minimal()
8. plot15

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ các điểm phân tán giữa điểm đánh giá và tổng chi tiêu với độ mờ 0.6.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính để nhận diện mối quan hệ giữa điểm đánh giá và tổng chi tiêu.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh trục x để hiển thị các mức giá trị điểm đánh giá từ 0 đến 10, chia theo bước nhảy 1.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot15 ra màn hình.

Kết quả

Biểu đồ trên mô tả mối quan hệ giữa điểm đánh giá sản phẩm và tổng chi tiêu, đồng thời phân biệt theo ba nhóm tỷ lệ giảm giá (<10%, 10–30%, >30%). Mỗi chấm tròn thể hiện một giao dịch, còn các điểm hình thoi xanh đậm biểu thị giá trị chi tiêu trung bình tương ứng với từng mức điểm.

Quan sát cho thấy các điểm dữ liệu phân bố dày nhất trong khoảng điểm đánh giá từ 3 đến 6, với tổng chi tiêu trung bình quanh 1.000 USD. Dù mức chi tiêu tăng hay giảm, điểm đánh giá vẫn dao động ổn định quanh giá trị trung bình, cho thấy mối quan hệ giữa hai biến này là khá yếu.

Các nhóm giảm giá khác nhau không tạo ra chênh lệch đáng kể về xu hướng. Nhóm có giảm giá thấp (<10%) xuất hiện nhiều hơn, phản ánh nhóm khách hàng này mua sắm thường xuyên và có xu hướng chi tiêu cao hơn. Nhìn chung, mức giảm giá không phải là yếu tố chính ảnh hưởng đến cách khách hàng đánh giá sản phẩm; thay vào đó, chất lượng và trải nghiệm mua hàng có thể đóng vai trò quan trọng hơn.

3.4.16 Scatter plot (Age vs TotalAmount)

Đồ thị phân tán giữa độ tuổi (Age) và tổng chi tiêu (TotalAmount) giúp nhận diện mối quan hệ giữa hai biến này, đồng thời phân nhóm theo độ tuổi.

1. plot16 <- ggplot(newdata, aes(x = Age, y = TotalAmount)) +
2.   geom_point(aes(color = AgeGroup), alpha = 0.6) +   
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") + 
5.   scale_x_continuous(breaks = seq(0, 100, by = 10)) +  # Lớp 4: Điều chỉnh trục x
6.   labs(title = "Phân tích mối quan hệ giữa độ tuổi và tổng chi tiêu", x = "Độ tuổi", y = "Tổng chi tiêu (USD)") +   
7.   theme_minimal()
8. plot16

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ các điểm phân tán với màu sắc theo nhóm độ tuổi.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính để thể hiện mối quan hệ giữa độ tuổi và tổng chi tiêu.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh các mức giá trị trục x từ 0 đến 100, chia theo bước nhảy 10.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot16 ra màn hình.

Kết quả

Biểu đồ mô tả mối quan hệ giữa độ tuổi khách hàng và tổng chi tiêu, được phân chia theo ba nhóm tuổi: dưới 25 tuổi (màu xanh lá), 25–40 tuổi (màu đỏ) và trên 40 tuổi (màu xanh dương). Các chấm tròn thể hiện chi tiêu của từng cá nhân, trong khi hình thoi xanh đậm biểu thị mức chi tiêu trung bình của mỗi nhóm tuổi.

Quan sát cho thấy tổng chi tiêu trung bình ở cả ba nhóm khá tương đồng, dao động quanh mức 1.000 USD. Tuy nhiên, nhóm trên 40 tuổi có xu hướng chi tiêu cao hơn một chút so với hai nhóm còn lại, thể hiện qua mật độ điểm ở vùng giá trị cao (trên 3.000 USD) dày đặc hơn.

Nhóm 25–40 tuổi chiếm tỷ trọng lớn nhất trong mẫu, phản ánh nhóm khách hàng chính của nền tảng thương mại điện tử. Nhóm dưới 25 tuổi tuy ít chi tiêu hơn nhưng vẫn duy trì hoạt động mua sắm đều đặn. Nhìn chung, tuổi tác không tạo ra khác biệt rõ rệt trong tổng chi tiêu, song nhóm trung niên trở lên có khuynh hướng chi tiêu nhiều hơn, có thể do thu nhập ổn định và hành vi tiêu dùng bền vững hơn.

3.4.17 TotalAmount vs DiscountRate

Đồ thị phân tán này giúp chúng ta phân tích mối quan hệ giữa tổng chi tiêu (TotalAmount) và tỷ lệ giảm giá (DiscountRate), đồng thời phân nhóm theo nhóm giảm giá (DiscountGroup).

1. plot17 <- ggplot(newdata, aes(x = TotalAmount, y = DiscountRate)) +
2.   geom_point(aes(color = DiscountGroup), alpha = 0.6) +   
3.   geom_smooth(method = "lm", color = "red", linetype = "dashed") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "#99FFFF") +   
5.   scale_x_continuous(labels = scales::comma) +   
6.   labs(title = "Tổng chi tiêu và tỷ lệ giảm giá", x = "Tổng chi tiêu (USD)", y = "Tỷ lệ giảm giá") +   
7.   theme_minimal()
8. plot17

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ các điểm phân tán với màu sắc theo nhóm giảm giá.

  • Dòng lệnh (3): Thêm đường hồi quy tuyến tính giúp phân tích mối quan hệ giữa tổng chi tiêu và tỷ lệ giảm giá.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh nhãn trục x để hiển thị giá trị tiền tệ.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot17 ra màn hình.

Kết quả Mối quan hệ nghịch chiều rõ rệt:

Biểu đồ thể hiện mối quan hệ giữa tổng chi tiêu (TotalAmount) và tỷ lệ giảm giá (DiscountRate), trong đó các điểm dữ liệu được tô màu theo nhóm giảm giá. Đường xu hướng màu đỏ biểu diễn mối quan hệ tuyến tính giữa hai biến.

Quan sát cho thấy có xu hướng nghịch đảo rõ rệt: khi tỷ lệ giảm giá tăng, tổng chi tiêu có xu hướng giảm dần. Điều này phản ánh rằng khách hàng nhận được ưu đãi cao thường chi tiêu ít hơn, có thể vì họ tận dụng giảm giá để mua các sản phẩm giá trị nhỏ hoặc chỉ mua khi có khuyến mãi hấp dẫn.

Tuy nhiên, phần lớn dữ liệu tập trung dày đặc ở vùng giảm giá thấp (<30%), cho thấy phần lớn giao dịch không phụ thuộc mạnh vào khuyến mãi mà vẫn duy trì mức chi tiêu ổn định. Điều này hàm ý rằng chính sách giá chỉ là một yếu tố phụ, còn hành vi chi tiêu của khách hàng chủ yếu chịu ảnh hưởng bởi nhu cầu thực tế và trải nghiệm mua sắm tổng thể.

3.4.18 Phân phối điểm đánh giá theo nhóm giảm giá

Đồ thị này giúp chúng ta phân tích mối quan hệ giữa điểm đánh giá của khách hàng và nhóm giảm giá mà họ được áp dụng. Nó sẽ cho thấy sự phân bố của điểm đánh giá trong mỗi nhóm giảm giá khác nhau.

1. plot18 <- ggplot(newdata, aes(x = ReviewScore, fill = DiscountGroup)) +
2.   geom_bar(position = "dodge") +
3.   geom_vline(aes(xintercept = mean(ReviewScore, na.rm = TRUE)), 
4.              color = "red", linetype = "dashed") +
5.   scale_x_continuous(breaks = seq(0, 10, by = 1)) +
6.   labs(title = "Phân phối điểm đánh giá theo nhóm giảm giá",
7.        x = "Điểm đánh giá", y = "Số lượng") +
8.   theme_minimal()
9. plot18

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo biểu đồ với điểm đánh giá (ReviewScore) trên trục x và màu sắc theo nhóm giảm giá (DiscountGroup).

  • Dòng lệnh (2): Vẽ biểu đồ cột với các nhóm giảm giá được phân tách (dodge) để dễ dàng so sánh.

  • Dòng lệnh (3) và (4): Thêm một đường dọc màu đỏ tại giá trị trung bình của điểm đánh giá.

  • Dòng lệnh (5): Điều chỉnh các mức giá trị của trục x từ 0 đến 10, chia theo bước nhảy 1.

  • Dòng lệnh (9): dùng để hiển thị biểu đồ đã được lưu trong biến plot18 ra màn hình.

Kết quả

Biểu đồ trên thể hiện phân phối điểm đánh giá sản phẩm theo ba nhóm tỷ lệ giảm giá (<10%, 10–30%, >30%). Mỗi màu biểu thị một nhóm giảm giá khác nhau, và đường kẻ đỏ dọc đánh dấu vị trí trung bình của toàn bộ điểm đánh giá.

Quan sát cho thấy, các đường phân phối của ba nhóm giảm giá đều có hình dạng gần như chuẩn đối xứng, tập trung chủ yếu quanh điểm trung bình khoảng 4. Điều này cho thấy mức độ hài lòng của khách hàng nhìn chung ổn định và ít bị ảnh hưởng bởi tỷ lệ giảm giá.

Ngoài ra, nhóm giảm giá trên 30% (màu xanh lá) có phân phối hơi rộng hơn, tức là mức độ đánh giá của nhóm này đa dạng hơn — có thể có cả người rất hài lòng lẫn không hài lòng. Trong khi đó, nhóm giảm giá thấp (<10%) có phân phối hẹp, phản ánh trải nghiệm mua hàng tương đối nhất quán. Như vậy, giảm giá không làm thay đổi rõ rệt mức độ hài lòng, nhưng có thể làm gia tăng sự khác biệt trong cảm nhận của khách hàng.

3.4.19 Tổng chi tiêu theo nhóm giảm giá

Đồ thị này sẽ giúp ta phân tích tổng chi tiêu trung bình trong các nhóm giảm giá. Mỗi cột thể hiện tổng chi tiêu trung bình của khách hàng trong mỗi nhóm giảm giá, giúp dễ dàng so sánh.

1. plot19 <- ggplot(newdata, aes(x = DiscountGroup, y = TotalAmount)) +
2.   geom_bar(stat = "summary", fun = "mean", fill = "purple", color = "black", alpha = 0.7) +   
3.   geom_errorbar(stat = "summary", fun.data = "mean_cl_boot", color = "blue") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") +   
5.   scale_x_discrete() +   
6.   labs(title = "Tổng chi tiêu trung bình theo nhóm giảm giá", x = "Nhóm giảm giá", y = "Tổng chi tiêu (USD)") +   
7.   theme_minimal()
8. plot19

Giải thích kỹ thuật

  • Dòng lệnh (2): Vẽ biểu đồ cột với màu tím cho tổng chi tiêu trung bình trong mỗi nhóm giảm giá.

  • Dòng lệnh (3): Thêm thanh lỗi màu xanh dương để thể hiện khoảng tin cậy cho tổng chi tiêu trung bình.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh nhãn trục x để hiển thị các nhóm giảm giá.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot19 ra màn hình.

Kết quả

Biểu đồ thể hiện tổng chi tiêu trung bình của khách hàng theo ba nhóm tỷ lệ giảm giá: dưới 10%, từ 10–30% và trên 30%. Các cột màu tím biểu thị giá trị trung bình, trong khi các điểm xanh trên đỉnh cột giúp xác định vị trí trung bình một cách trực quan.

Kết quả cho thấy nhóm khách hàng được giảm giá dưới 10% có tổng chi tiêu trung bình cao nhất, đạt khoảng 1.200 USD. Trong khi đó, nhóm giảm giá mạnh trên 30% lại có mức chi tiêu trung bình thấp nhất, chỉ khoảng 750 USD. Nhóm 10–30% nằm ở mức giữa, khoảng 1.000 USD.

Điều này gợi ý rằng mức giảm giá cao không nhất thiết làm tăng tổng chi tiêu, thậm chí có thể thu hút những khách hàng có xu hướng chi tiêu ít hơn. Ngược lại, nhóm khách hàng ít quan tâm đến khuyến mãi (giảm giá thấp) lại có hành vi chi tiêu mạnh hơn, thể hiện khả năng chi trả và giá trị khách hàng cao hơn.

3.4.20 Phân phối tổng chi tiêu theo độ tuổi

Đồ thị này sẽ giúp ta hiểu rõ tổng chi tiêu trung bình của khách hàng trong các nhóm độ tuổi khác nhau. Đây là một cách để nhận diện các nhóm độ tuổi có mức chi tiêu cao hơn hoặc thấp hơn.

1. plot20 <- ggplot(newdata, aes(x = AgeGroup, y = TotalAmount)) +
2.   geom_bar(stat = "summary", fun = "mean", fill = "pink", color = "black", alpha = 0.7) +   
3.   geom_errorbar(stat = "summary", fun.data = "mean_cl_boot", color = "blue") +   
4.   stat_summary(fun = "mean", geom = "point", shape = 18, size = 4, color = "blue") +   
5.   scale_x_discrete() +   
6.   labs(title = "Tổng chi tiêu trung bình theo độ tuổi", x = "Độ tuổi", y = "Tổng chi tiêu (USD)") +  
7.   theme_minimal()
8. plot20

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo biểu đồ với nhóm độ tuổi (AgeGroup) trên trục x và tổng chi tiêu (TotalAmount) trên trục y.

  • Dòng lệnh (2): Vẽ biểu đồ cột với màu hồng cho tổng chi tiêu trung bình trong mỗi nhóm độ tuổi.

  • Dòng lệnh (3): Thêm thanh lỗi màu xanh dương để thể hiện khoảng tin cậy cho tổng chi tiêu trung bình.

  • Dòng lệnh (4): Thêm điểm trung bình cho tổng chi tiêu.

  • Dòng lệnh (5): Điều chỉnh nhãn trục x để hiển thị các nhóm độ tuổi.

  • Dòng lệnh (6): Thêm tiêu đề và nhãn cho các trục x và y.

  • Dòng lệnh (7): Sử dụng theme đơn giản để làm biểu đồ dễ hiểu.

  • Dòng lệnh (8): dùng để hiển thị biểu đồ đã được lưu trong biến plot20 ra màn hình.

Kết quả

Biểu đồ cho thấy tổng chi tiêu trung bình của ba nhóm tuổi: dưới 25 tuổi, từ 25–40 tuổi và trên 40 tuổi. Mỗi cột biểu diễn mức chi tiêu trung bình của nhóm, trong đó điểm xanh phía trên thể hiện giá trị trung bình chính xác.

Kết quả chỉ ra rằng ba nhóm tuổi có mức chi tiêu trung bình gần như tương đương nhau, dao động quanh 950–970 USD. Nhóm khách hàng trên 40 tuổi có xu hướng chi tiêu nhỉnh hơn một chút, trong khi nhóm dưới 25 tuổi có mức chi tiêu thấp nhất nhưng chênh lệch không đáng kể.

Điều này cho thấy độ tuổi không phải là yếu tố quyết định rõ rệt đến tổng chi tiêu, phản ánh rằng hành vi mua sắm trong tập dữ liệu tương đối đồng đều giữa các thế hệ. Các yếu tố khác như mức giảm giá, sản phẩm hoặc trải nghiệm mua sắm có thể đóng vai trò chi phối mạnh hơn trong quyết định chi tiêu.

4 CHƯƠNG 2: PHÂN TÍCH NGÂN HÀNG THƯƠNG MẠI CỔ PHẦN NGOẠI THƯƠNG VIỆT NAM

4.1 GIỚI THIỆU BỘ DỮ LIỆU NGÂN HÀNG VCB

4.1.1 Giới thiệu chung về Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank – VCB)

Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank) được thành lập ngày 01/04/1963, tách ra từ Sở Quản lý Ngoại hối thuộc Ngân hàng Nhà nước Việt Nam. Ban đầu là ngân hàng chuyên doanh đối ngoại, Vietcombank từng bước mở rộng sang lĩnh vực bán lẻ và đầu tư, trở thành ngân hàng thương mại đa năng hàng đầu Việt Nam.

Tính đến giữa năm 2025, Vietcombank có tổng tài sản hợp nhất khoảng 2,2 triệu tỷ đồng, dư nợ tín dụng gần 1,6 triệu tỷ đồng, tỷ lệ an toàn vốn (CAR) 11,8%. Ngân hàng sở hữu hơn 600 chi nhánh, 24.000 nhân viên, cùng mạng lưới 3.000 ATM và 120.000 điểm chấp nhận thẻ trên toàn quốc. Với vốn hóa thị trường khoảng 20 tỷ USD, Vietcombank nằm trong nhóm 100 ngân hàng niêm yết lớn nhất thế giới và nhiều năm liền được vinh danh là “Ngân hàng tốt nhất Việt Nam”, đồng thời được các tổ chức xếp hạng tín nhiệm quốc tế như Moody’s, S&P và Fitch đánh giá cao.

4.1.2 Lý do lựa chọn Vietcombank để phân tích

Có nhiều lý do thuyết phục để lựa chọn Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank) làm đối tượng nghiên cứu và phân tích tài chính. Trước hết, Vietcombank là ngân hàng dẫn đầu hệ thống với nền tảng tài chính vững mạnh, hiệu quả hoạt động cao và khả năng sinh lời vượt trội. Theo Vietnam Report, Vietcombank đã 9 năm liên tiếp đứng đầu bảng xếp hạng “Top 10 ngân hàng thương mại Việt Nam uy tín”, khẳng định vị thế và uy tín thương hiệu trên thị trường tài chính trong nước.

Về kết quả kinh doanh, Vietcombank liên tục ghi nhận lợi nhuận trước thuế cao nhất hệ thống, đạt hơn 1,5 tỷ USD năm 2024, phản ánh năng lực quản trị và khai thác thị trường hiệu quả. Báo cáo tài chính của ngân hàng có độ minh bạch và tin cậy cao, được kiểm toán độc lập và công bố công khai, tuân thủ các chuẩn mực quốc tế. Các tổ chức xếp hạng tín nhiệm như S&P, Fitch Ratings và Moody’s đều duy trì mức đánh giá cao nhất cho Vietcombank, thể hiện sức khỏe tài chính và khả năng quản trị rủi ro bền vững.

Bên cạnh đó, với quy mô tài sản lớn, thị phần thanh toán quốc tế hàng đầu và vai trò ngân hàng đối ngoại chủ lực của nền kinh tế, Vietcombank là đối tượng nghiên cứu lý tưởng, giúp phản ánh bức tranh toàn diện về hoạt động tài chính – ngân hàng Việt Nam, đồng thời mang giá trị tham chiếu quan trọng cho nhà đầu tư và các nhà hoạch định chính sách.

4.1.3 Phạm vi và nguồn dữ liệu

Phân tích trong đề tài được thực hiện dựa trên dữ liệu thu thập từ các báo cáo tài chính hợp nhất của Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank) trong giai đoạn 2015–2024. Ba báo cáo trọng yếu được sử dụng gồm: Bảng Cân đối Kế toán (CĐKT), Báo cáo Kết quả Hoạt động Kinh doanh (KQHĐKD) và Báo cáo Lưu chuyển Tiền tệ (LCTT). Việc kết hợp đồng thời ba báo cáo giúp phản ánh toàn diện tình hình tài chính của ngân hàng trên ba khía cạnh: cơ cấu tài sản – nguồn vốn, hiệu quả kinh doanh và khả năng tạo dòng tiền.

Toàn bộ số liệu được trích xuất trực tiếp từ các báo cáo tài chính thường niên đã được kiểm toán độc lập và công bố công khai, đảm bảo tính chính xác, khách quan và minh bạch cho nghiên cứu. Sau khi chọn lọc, chuẩn hóa và loại bỏ dữ liệu không đồng nhất giữa các năm, nhóm nghiên cứu đã tổng hợp các biến tài chính quan trọng từ ba báo cáo nói trên. Các biến này được mã hóa bằng ký hiệu viết tắt (không dấu) để thuận tiện cho việc xử lý dữ liệu và lập trình trong các phần mềm phân tích tài chính.

Nguồn dữ liệu: Các báo cáo tài chính hợp nhất giai đoạn 2015–2024 do Vietcombank công bố chính thức trên trang thông tin điện tử của ngân hàng.

Đoạn code này dùng để đọc file Excel, xem nhanh cấu trúc dữ liệu và kiểm tra tên các cột. Mục tiêu là bảo đảm dữ liệu đã nạp đúng, biết được có bao nhiêu dòng – bao nhiêu cột và các cột đang bao phủ những nhóm thông tin nào (tài sản, nợ, vốn chủ, KQKD, LCTT…), từ đó chuẩn bị cho các bước làm sạch và phân tích tiếp theo.

1. library(readxl)
2. VCBCHUONG2 <- read_excel("D:/ngon ngu lap trinh/VCBCHUONG2.xlsx")
3. names(VCBCHUONG2)
##   [1] "Năm"                                                                                                           
##   [2] "TỔNG TÀI SẢN"                                                                                                  
##   [3] "Tiền mặt"                                                                                                      
##   [4] "Tiền gửi ngân hàng"                                                                                            
##   [5] "Tiền gửi tại các TCTD khác và cho vay các TCTD khác"                                                           
##   [6] "Chứng khoán kinh doanh"                                                                                        
##   [7] "Dự phòng giảm giá chứng khoán kinh doanh"                                                                      
##   [8] "Các công cụ tài chính phái sinh và các tài sản tài chính khác"                                                 
##   [9] "Cho vay khách hàng"                                                                                            
##  [10] "Dự phòng rủi ro cho vay khách hàng"                                                                            
##  [11] "Chứng khoán đầu tư"                                                                                            
##  [12] "Chứng khoán đầu tư sẵn sàng để bán"                                                                            
##  [13] "Chứng khoán đầu tư giữ đến ngày đáo hạn"                                                                       
##  [14] "Dự phòng giảm giá chứng khoán đầu tư"                                                                          
##  [15] "Góp vốn, đầu tư dài hạn"                                                                                       
##  [16] "Đầu tư vào công ty con"                                                                                        
##  [17] "Đầu tư vào công ty liên doanh"                                                                                 
##  [18] "Đầu tư dài hạn khác"                                                                                           
##  [19] "Dự phòng giảm giá đầu tư dài hạn"                                                                              
##  [20] "TSCD"                                                                                                          
##  [21] "TSCDHH"                                                                                                        
##  [22] "Tài sản cố định thuê tài chính"                                                                                
##  [23] "TSCDVH"                                                                                                        
##  [24] "Tài sản khác"                                                                                                  
##  [25] "NỢ PHẢI TRẢ VÀ VỐN CHỦ SỞ HỮU"                                                                                 
##  [26] "Tổng nợ phải trả"                                                                                              
##  [27] "Các khoản nợ chính phủ và NHNN Việt Nam"                                                                       
##  [28] "Tiền gửi và vay các Tổ chức tín dụng khác"                                                                     
##  [29] "Tiền gửi của khách hàng"                                                                                       
##  [30] "Các công cụ tài chính phái sinh và các khoản nợ tài chính khác"                                                
##  [31] "Vốn tài trợ, uỷ thác đầu tư của Chính phủ và các tổ chức tín dụng khác"                                        
##  [32] "Phát hành giấy tờ có giá"                                                                                      
##  [33] "Các khoản nợ khác"                                                                                             
##  [34] "VỐN CHỦ SỞ HỮU"                                                                                                
##  [35] "Vốn của tổ chức tín dụng"                                                                                      
##  [36] "Vốn điều lệ"                                                                                                   
##  [37] "Vốn đầu tư XDCB"                                                                                               
##  [38] "Thặng dư vốn cổ phần"                                                                                          
##  [39] "Cổ phiếu Quỹ"                                                                                                  
##  [40] "Cổ phiếu ưu đãi"                                                                                               
##  [41] "Vốn khác"                                                                                                      
##  [42] "Quỹ của tổ chức tín dụng"                                                                                      
##  [43] "Chênh lệch tỷ giá hối đoái"                                                                                    
##  [44] "Chênh lệch đánh giá lại tài sản"                                                                               
##  [45] "Lợi nhuận chưa phân phối"                                                                                      
##  [46] "Thu nhập lãi và các khoản thu nhập tương tự"                                                                   
##  [47] "Chi phí lãi và các chi phí tương tự"                                                                           
##  [48] "Thu nhập lãi thuần"                                                                                            
##  [49] "Thu nhập từ hoạt động dịch vụ"                                                                                 
##  [50] "chi phí hoạt động dịch vụ"                                                                                     
##  [51] "Lãi thuần từ hoạt động dịch vụ"                                                                                
##  [52] "Lãi/(lỗ) thuần từ hoạy động kinh doanh ngoại hối và vàng"                                                      
##  [53] "Lãi/(lỗ) thuần từ mua bán chứng khoán kinh doanh"                                                              
##  [54] "Lãi/(lỗ) thuần từ mua bán chứng khoán đầu tư"                                                                  
##  [55] "Thu nhập từ hoạt động khác"                                                                                    
##  [56] "Chi phí hoạt động khác"                                                                                        
##  [57] "Lãi/(lỗ) thuần từ hoạt động khác"                                                                              
##  [58] "Thu nhập từ góp vốn, mua cổ phần"                                                                              
##  [59] "Tổng thu nhập hoạt động"                                                                                       
##  [60] "Chi phí hoạt động"                                                                                             
##  [61] "LN thuần từ hoạt động kinh doanh trước CF dự phòng rủi ro tín dụng"                                            
##  [62] "Chi phí dự phòng rủi ro tín dụng"                                                                              
##  [63] "Tổng lợi nhuận trước thuế"                                                                                     
##  [64] "Chi phí thuế TNDN hiện hành"                                                                                   
##  [65] "Chi phí thuế TNDN hoãn lại"                                                                                    
##  [66] "Chi phí thuế thu nhập doanh nghiệp"                                                                            
##  [67] "Lợi nhuận sau thuế"                                                                                            
##  [68] "Lợi ích của cổ đông thiểu số"                                                                                  
##  [69] "Cổ đông của Công ty mẹ"                                                                                        
##  [70] "Lãi cơ bản trên cổ phiếu"                                                                                      
##  [71] "Lưu chuyển tiền thuần từ các hoạt động sản xuất kinh doanh"                                                    
##  [72] "Lưu chuyển tiền thuần từ hoạt động kinh doanh trước thuế thu nhập DN"                                          
##  [73] "Lãi/lỗ trước những thay đổi vốn lưu động"                                                                      
##  [74] "Thu nhập lãi và các khoản tương đương"                                                                         
##  [75] "Chi phí lãi và các khoản tương đương"                                                                          
##  [76] "Thu nhập từ hoạt động dịch vụ nhận được"                                                                       
##  [77] "Thu nhập từ hoạt động kinh doanh chứng khoán"                                                                  
##  [78] "Thu nhập khác"                                                                                                 
##  [79] "Tiền thu các khoản nợ đã được xử lý, xóa, bù đắp bằng nguồn rủi ro"                                            
##  [80] "Thanh toán cho nhân viên và nhà cung cấp"                                                                      
##  [81] "Tiền chi nộp thuế thu nhập doanh nghiệp"                                                                       
##  [82] "(Tăng)/Giảm các khoản tiền gửi và cho vay các tổ chức tín dụng khác"                                           
##  [83] "(Tăng)/giảm các khoản về kinh doanh chứng khoán"                                                               
##  [84] "(Tăng)/Giảm các công cụ tài chính phái sinh và các tài sản tài chính khác"                                     
##  [85] "(Tăng)/Giảm các khoản cho vay khách hàng"                                                                      
##  [86] "(Tăng)/Giảm lãi, phí phải thu"                                                                                 
##  [87] "Tăng/(Giảm) nguồn dự phòng để bù đắp tổn thất các khoản"                                                       
##  [88] "(Tăng)/Giảm khác về tài sản hoạt động"                                                                         
##  [89] "Tăng/(Giảm) các khoản nợ chính phủ và NHNN"                                                                    
##  [90] "Tăng/(Giảm) các khoản tiền gửi và vay các TCTD khác"                                                           
##  [91] "Tăng/(Giảm) tiền gửi của khách hàng"                                                                           
##  [92] "Tăng/(Giảm) các công cụ tài chính phái sinh và các khoản nợ tài chính khác"                                    
##  [93] "Tăng/(Giảm) vốn tài trợ, uỷ thác đầu tư của chính phủ và các TCTD khác"                                        
##  [94] "Tăng/(Giảm) phát hành giấy tờ có giá"                                                                          
##  [95] "Tăng/(Giảm) lãi, phí phải trả"                                                                                 
##  [96] "Tăng/(Giảm) khác về công nợ hoạt động"                                                                         
##  [97] "Thuế thu nhập doanh nghiệp đã trả"                                                                             
##  [98] "Chi từ các quỹ của TCTD"                                                                                       
##  [99] "Thu được từ nợ khó đòi"                                                                                        
## [100] "Lưu chuyển tiền thuần từ hoạt động đầu tư"                                                                     
## [101] "Tiền mua tài sản cố định và các tài sản dài hạn khác"                                                          
## [102] "Tiền thu được từ thanh lý tài sản cố định"                                                                     
## [103] "Tiền chi từ thanh lý, nhượng bán TSCĐ"                                                                         
## [104] "Mua sắm Bất động sản đầu tư"                                                                                   
## [105] "Tiền thu từ bán, thanh lý bất động sản đầu tư"                                                                 
## [106] "Tiền chi ra do bán, thanh lý bất động sản đầu tư"                                                              
## [107] "Đầu tư vào các doanh nghiệp khác"                                                                              
## [108] "Tiền thu từ việc bán các khoản đầu tư vào các doanh nghiệp khác"                                               
## [109] "Cổ tức và tiền lãi nhận được"                                                                                  
## [110] "Lưu chuyển tiền từ hoạt động tài chính"                                                                        
## [111] "Tiền thu từ phát hành cổ phiếu và vốn góp"                                                                     
## [112] "Tiền thu từ phát hành giấy tờ có giá dài hạn đủ điều kiện tính vào vốn tự có và các khoản vốn vay dài hạn khác"
## [113] "Tiền chi thanh toán giấy tờ có giá dài hạn đủ điều kiện tính vào vốn tự có và các khoản vốn vay dài hạn khác"  
## [114] "Cổ tức đã trả"                                                                                                 
## [115] "Tiền chi ra mua cổ phiếu quỹ"                                                                                  
## [116] "Tiền thu được do bán cổ phiếu quỹ"                                                                             
## [117] "Lưu chuyển tiền thuần trong kỳ"                                                                                
## [118] "Tiền và tương đương tiền đầu kỳ"                                                                               
## [119] "Ảnh hưởng của chênh lệch tỷ giá"                                                                               
## [120] "Tiền và tương đương tiền cuối kỳ"
1. dim(VCBCHUONG2)
## [1]  10 120

Giải thích ý nghĩa

  • Dòng lệnh (1): nạp gói readxl để R có thể đọc file Excel (.xlsx) trực tiếp, không cần cài Excel trên máy.

  • Dòng lệnh (1): đọc dữ liệu từ đường dẫn đã cho và lưu vào data frame/tibble tên VCBCHUONG2.

  • Dòng lệnh (1): xem tên các cột trong bảng dữ liệu. Nói ngắn gọn: dữ liệu có 120 cột, bao gồm các nhóm lớn như: Năm, Bảng cân đối, Nợ và vốn chủ, Kết quả kinh doanh…

  • Dòng lệnh (1): trả về kích thước của bảng dữ liệu theo dạng (số_dòng, số_cột). Kết quả bạn nhận được là [1] 10 120, nghĩa là 10 dòng và 120 cột.

Kết quả

Kết quả dim cho thấy bộ dữ liệu hiện có 10 quan sát (nhiều khả năng là 10 năm) và 120 biến, bao trùm đầy đủ ba báo cáo tài chính lớn (Cân đối kế toán, Kết quả kinh doanh, Lưu chuyển tiền tệ) cùng các mục chi tiết (dự phòng, phái sinh, phát hành giấy tờ có giá…). Việc có nhiều cột như vậy là thuận lợi để phân tích sâu (đòn bẩy, chất lượng tài sản, cơ cấu vốn, biên LN, dòng tiền…)

4.1.4 Phụ lục viết tắt của các biến

1. library(readxl)
2. library(dplyr)
3. library(knitr)
4. library(kableExtra)
5. library(stringi)
6. VCBCHUONG2 <- read_excel("D:/ngon ngu lap trinh/VCBCHUONG2.xlsx")
7. VCBCHUONG2bctc <- VCBCHUONG2 %>%
8.   rename_with(~ stri_trans_general(., "Latin-ASCII"))
9. head(VCBCHUONG2bctc)

Giải thích kĩ thuật

  • Dòng lệnh (1) đến (5): được dùng để nạp các gói hỗ trợ xử lý và trình bày dữ liệu.

  • Dòng lệnh (6): Đọc dữ liệu từ file Excel và lưu vào đối tượng VCBCHUONG2. Đây là bảng dữ liệu gốc dùng cho các phân tích tài chính sau.

  • Dòng lệnh (7), (8): Đây là bước chính trong bỏ dấu tiếng Việt trong tất cả các tên cột.

  • Dòng lệnh (9): Hiển thị danh sách tên cột sau khi đã bỏ dấu, dùng để kiểm tra lại kết quả chuyển đổi.

Kết quả

Sau khi thực thi đoạn code, toàn bộ tên biến tiếng Việt đã được chuyển sang không dấu, đảm bảo dễ đọc và tương thích với cú pháp R

4.2 XỬ LÝ, CHỌN LỌC, ĐÁNH GIÁ DỮ LIỆU

4.2.1 Lựa chọn dữ liệu biến chính để phân tích Vietcombank

Lí do lựa chọn và đặt tên cho bộ mới

Trong bối cảnh kinh tế Việt Nam hội nhập sâu vào thị trường tài chính quốc tế, vai trò của các ngân hàng thương mại ngày càng quan trọng trong việc dẫn dắt dòng vốn và ổn định hệ thống tài chính. Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank) là một trong những ngân hàng lớn và có ảnh hưởng hàng đầu, nên việc phân tích tình hình tài chính của Vietcombank mang ý nghĩa thực tiễn và giá trị tham khảo cao.

Phân tích tài chính giúp đánh giá hiệu quả hoạt động, sức khỏe tài chính và là cơ sở để nhà đầu tư, nhà quản trị, cơ quan quản lý đưa ra quyết định phù hợp. Trong môi trường cạnh tranh và biến động hiện nay, việc xem xét các chỉ tiêu về thanh khoản, hiệu quả hoạt động, đòn bẩy tài chính và khả năng sinh lời là rất cần thiết.

Xuất phát từ đó, đề tài “Phân tích tình hình tài chính của Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank)” được thực hiện nhằm đánh giá toàn diện hiệu quả hoạt động, cơ cấu vốn và khả năng sinh lời của ngân hàng, đồng thời rút ra nhận định và khuyến nghị phục vụ công tác quản trị, hướng tới phát triển bền vững trong tương lai.

1. VCBbctc <- VCBCHUONG2bctc %>%
2.   select(
3.     Nam,                                          
4.     `Loi nhuan sau thue`,
5.     `Tong loi nhuan truoc thue`,
6.     `Thu nhap tu hoat dong dich vu`,
7.     `Thu nhap lai va cac khoan thu nhap tuong tu`,
8.     `Thu nhap lai thuan`,
9.     `Chi phi lai va cac chi phi tuong tu`,
10.     `Loi nhuan chua phan phoi`,
11.     `Von dieu le`,
12.     `VON CHU SO HUU`,
13.     `Cac khoan no khac`,
14.     `Tong no phai tra`,
15.     `Chung khoan dau tu san sang de ban`,
16.     `Cho vay khach hang`,
17.     `TONG TAI SAN`)
18. head(VCBbctc)

Giải thích kỹ thuật

Đoạn lệnh từ dòng (1) đến dòng (17): Lệnh này tạo ra một bảng dữ liệu mới tên là VCBbctc, được trích từ bảng VCBCHUONG2bctc (bộ dữ liệu sau khi đã bỏ dấu).

của gói dplyr được dùng để chọn ra các cột cần thiết theo thứ tự mong muốn.

  • Dòng lệnh (2): hiển thị danh sách tên các cột sau khi chọn, giúp kiểm tra xem có bị sai sót hoặc thiếu cột nào không.

  • Dòng lệnh (18): hiển thị 6 dòng đầu tiên của bảng dữ liệu mới, dùng để xem qua dữ liệu có được cắt chọn đúng và có giá trị hợp lý hay chưa

Kết quả

Kết quả cho thấy bảng VCBbctc giờ chỉ còn 15 cột đại diện cho những nhóm thông tin cốt lõi trong báo cáo tài chính của Vietcombank. Cấu trúc này giúp dễ dàng thực hiện các phép phân tích như:

  • Đánh giá hiệu quả hoạt động thông qua lợi nhuận và chi phí lãi.

  • Xem xét cơ cấu vốn giữa nợ và vốn chủ sở hữu.

  • Phân tích quy mô tài sản và cho vay khách hàng qua thời gian.

Đổi đơn vị

Trong quá trình xử lý dữ liệu tài chính của Ngân hàng Vietcombank, các chỉ tiêu được ghi nhận theo đơn vị VND với giá trị tuyệt đối rất lớn, gây khó khăn cho việc quan sát, so sánh và tính toán các tỷ suất tài chính. Do đó, Dữ liệu tài chính của Vietcombank được quy đổi từ đơn vị VND sang tỷ đồng nhằm chuẩn hóa và đơn giản hóa việc quan sát, so sánh và phân tích các chỉ tiêu tài chính.

1. VCBbctc <- VCBbctc %>%
2.   mutate(across(where(is.numeric) & !matches("^Nam$"), ~ .x / 1000000))
3. glimpse(VCBbctc)
## Rows: 10
## Columns: 15
## $ Nam                                           <chr> "2015", "2016", "2017", …
## $ `Loi nhuan sau thue`                          <dbl> 5332067, 6895047, 911058…
## $ `Tong loi nhuan truoc thue`                   <dbl> 6827457, 8578140, 113413…
## $ `Thu nhap tu hoat dong dich vu`               <dbl> 3557304, 4326483, 537817…
## $ `Thu nhap lai va cac khoan thu nhap tuong tu` <dbl> 31360729, 37718211, 4615…
## $ `Thu nhap lai thuan`                          <dbl> 15453032, 18532750, 2193…
## $ `Chi phi lai va cac chi phi tuong tu`         <dbl> -15907697, -19185461, -2…
## $ `Loi nhuan chua phan phoi`                    <dbl> 7475808, 5874992, 871525…
## $ `Von dieu le`                                 <dbl> 26650203, 35977686, 3597…
## $ `VON CHU SO HUU`                              <dbl> 45172342, 48145556, 5255…
## $ `Cac khoan no khac`                           <dbl> 11965744, 12661994, 1765…
## $ `Tong no phai tra`                            <dbl> 629222298, 739789532, 98…
## $ `Chung khoan dau tu san sang de ban`          <dbl> 42468041, 51931950, 3468…
## $ `Cho vay khach hang`                          <dbl> 379113059, 452721687, 53…
## $ `TONG TAI SAN`                                <dbl> 674394640, 787935088, 10…

Giải thích kĩ thuật

Dòng lệnh (1) và (2): Đây là dòng lệnh chính thực hiện chuẩn hóa toàn bộ dữ liệu số.

  • mutate(): dùng để tạo hoặc thay đổi cột trong bảng dữ liệu.

  • across(): áp dụng một thao tác cho nhiều cột cùng lúc.

  • where(is.numeric): chọn tất cả các cột có kiểu dữ liệu là số (numeric).

  • !matches(“^Nam$”): loại trừ cột “Nam” (vì đó là năm, không cần chia).

→ Kết quả: tất cả các biến tài chính (như “TONG TAI SAN”, “Loi nhuan sau thue”, “Von dieu le”, “Cho vay khach hang”…) được đổi đơn vị sang triệu đồng, trong khi cột “Nam” vẫn giữ nguyên.

Dòng lệnh (3): Lệnh này hiển thị tóm tắt cấu trúc của bảng dữ liệu, gồm: Tên cột, kiểu dữ liệu, một vài giá trị đầu tiên trong từng cột

4.2.2 Thêm biến vào bộ dữ liệu

Để đánh giá toàn diện tình hình tài chính và hiệu quả hoạt động của Ngân hàng TMCP Ngoại thương Việt Nam (Vietcombank), việc chỉ xem xét các chỉ tiêu kế toán cơ bản là chưa đủ. Do đó, ta tiến hành bổ sung một hệ thống 8 chỉ số tài chính tổng hợp, được tính toán dựa trên dữ liệu từ báo cáo tài chính giai đoạn 2015–2024.

Các chỉ số này giúp phản ánh rõ nét mức độ an toàn tài chính và đòn bẩy (CAR, D/E, Tỷ trọng vốn chủ sở hữu), khả năng thanh khoản (Tỷ lệ tiền mặt), tốc độ phát triển (Tăng trưởng tổng tài sản, Tăng trưởng lợi nhuận sau thuế).

Việc bổ sung các biến này giúp chuyển đổi dữ liệu tài chính thô thành các thước đo phân tích định lượng, qua đó hỗ trợ đánh giá hiệu quả hoạt động, khả năng tăng trưởng bền vững và sức khỏe tài chính của ngân hàng một cách khoa học và có hệ thống.

1. VCBbctc <- VCBbctc %>%
2.   mutate(
3.     Bien_LN_rong = `Loi nhuan sau thue` / `Thu nhap lai va cac khoan thu nhap tuong tu`,
4.     CAR = `VON CHU SO HUU` / `TONG TAI SAN`,
5.     DE = `Tong no phai tra` / `VON CHU SO HUU`,
6.     Tytrong_VCSH = `VON CHU SO HUU` / (`Tong no phai tra` + `VON CHU SO HUU`),
7.     NIM = `Thu nhap lai thuan` / `TONG TAI SAN`,
8.     Vongquay_CVKH = `Thu nhap lai va cac khoan thu nhap tuong tu` / `Cho vay khach hang`,
9.     Tangtruong_TS = (`TONG TAI SAN` - lag(`TONG TAI SAN`)) / lag(`TONG TAI SAN`),
10.     Tangtruong_LNST = (`Loi nhuan sau thue` - lag(`Loi nhuan sau thue`)) / lag(`Loi nhuan sau thue`))
11.   
12. colnames(VCBbctc)
##  [1] "Nam"                                        
##  [2] "Loi nhuan sau thue"                         
##  [3] "Tong loi nhuan truoc thue"                  
##  [4] "Thu nhap tu hoat dong dich vu"              
##  [5] "Thu nhap lai va cac khoan thu nhap tuong tu"
##  [6] "Thu nhap lai thuan"                         
##  [7] "Chi phi lai va cac chi phi tuong tu"        
##  [8] "Loi nhuan chua phan phoi"                   
##  [9] "Von dieu le"                                
## [10] "VON CHU SO HUU"                             
## [11] "Cac khoan no khac"                          
## [12] "Tong no phai tra"                           
## [13] "Chung khoan dau tu san sang de ban"         
## [14] "Cho vay khach hang"                         
## [15] "TONG TAI SAN"                               
## [16] "Bien_LN_rong"                               
## [17] "CAR"                                        
## [18] "DE"                                         
## [19] "Tytrong_VCSH"                               
## [20] "NIM"                                        
## [21] "Vongquay_CVKH"                              
## [22] "Tangtruong_TS"                              
## [23] "Tangtruong_LNST"

Giải thích kí thuật

  • Dòng lệnh (1): Tạo thêm các cột mới trong bảng VCBbctc, mỗi cột là một chỉ tiêu tài chính được tính toán dựa trên các biến sẵn có. Cụ thể:

-Bien_LN_rong = Loi nhuan sau thue / Thu nhap lai va cac khoan thu nhap tuong tu

-CAR = VON CHU SO HUU / TONG TAI SAN

-DE = Tong no phai tra / VON CHU SO HUU

-Tytrong_VCSH = VON CHU SO HUU / (Tong no phai tra + VON CHU SO HUU)

-NIM = Thu nhap lai thuan / TONG TAI SAN

-Vongquay_CVKH = Thu nhap lai va cac khoan thu nhap tuong tu / Cho vay khach hang

-Tangtruong_TS = (TONG TAI SAN - lag(TONG TAI SAN)) / lag(TONG TAI SAN)

-Tangtruong_LNST = (Loi nhuan sau thue - lag(Loi nhuan sau thue)) / lag(Loi nhuan sau thue)

-colnames(VCBbctc)

Ý nghĩa các biến thêm

Biên lợi nhuận ròng: phản ánh mức sinh lời cuối cùng của ngân hàng sau khi trừ chi phí và thuế. Giá trị cao cho thấy khả năng kiểm soát chi phí tốt và hiệu quả hoạt động cao.

Tỷ lệ an toàn vốn (CAR): thể hiện mức độ an toàn tài chính và khả năng tự chủ vốn. CAR cao nghĩa là ngân hàng ít phụ thuộc vào nguồn vay, có khả năng chống chịu rủi ro tốt.

Đòn bẩy tài chính (DE): cho biết ngân hàng sử dụng bao nhiêu nợ so với vốn chủ. DE cao giúp tăng lợi nhuận tiềm năng nhưng cũng làm tăng rủi ro tài chính.

Tỷ trọng vốn chủ sở hữu: phản ánh tỷ lệ vốn tự có trong tổng nguồn vốn. Giá trị cao cho thấy cơ cấu vốn ổn định và bền vững hơn.

Biên lãi ròng (NIM): đo lường hiệu quả sinh lời từ hoạt động cho vay. NIM cao cho thấy ngân hàng quản lý lãi suất đầu vào – đầu ra tốt và sử dụng tài sản hiệu quả.

Vòng quay cho vay khách hàng: thể hiện khả năng tạo thu nhập lãi từ danh mục cho vay. Chỉ số cao chứng tỏ hiệu quả sử dụng vốn cho vay tốt.

Tăng trưởng tổng tài sản: cho thấy tốc độ mở rộng quy mô hoạt động của ngân hàng qua thời gian. Giá trị dương lớn thể hiện xu hướng phát triển mạnh.

Tăng trưởng lợi nhuận sau thuế: phản ánh xu hướng cải thiện lợi nhuận ròng qua các năm. Tăng trưởng dương cho thấy hiệu quả kinh doanh được nâng cao.

4.2.3 Kiểm tra, đánh giá bộ dữ liệu

4.2.3.1 Kiểm tra biến thiếu

1. sum(is.na(VCBbctc))
## [1] 2

Giải thích kỹ thuật

is.na(VCBbctc) kiểm tra từng ô trong bảng dữ liệu và trả về giá trị TRUE nếu ô đó là NA (bị thiếu), hoặc FALSE nếu có giá trị hợp lệ.

sum(…) cộng tất cả các giá trị TRUE (vì trong R, TRUE = 1, FALSE = 0), do đó cho ra tổng số ô bị thiếu trong toàn bộ bảng.

Kết quả

Kết quả cho thấy bộ dữ liệu của VCB có 2 giá trị NA (của biến tăng trưởng tài sản và tăng trưởng lợi nhuận sau thuế), tuy nhiên nhóm tác giả chấp nhận biến thiếu này vì tăng trưởng của tài sản và tăng trưởng lợi nhuận sau thuế không thể tính năm 2015 do không có số liệu của 2014.

4.2.3.2 Kiểm tra biến trùng lặp

1. sum(duplicated(VCBbctc))
## [1] 0

Giải thích kỹ thuật

duplicated(VCBbctc): Hàm này kiểm tra từng dòng trong bảng dữ liệu và trả về:

TRUE nếu dòng đó trùng lặp hoàn toàn với một dòng trước đó,

FALSE nếu dòng là duy nhất.

sum(duplicated(VCBbctc)): Hàm sum() cộng tất cả các giá trị TRUE (vì TRUE = 1, FALSE = 0), kết quả là tổng số dòng bị trùng trong dữ liệu.

Kết quả cho thấy không có dòng trùng lặp trong bộ dữ liệu.

4.2.3.3 Làm sạch dữ liệu

Bởi vì dữ liệu có 2 biến na. Nên ta tiến hành loại bỏ giá trị thiếu. Trước hết, ta cần gọi gói library(tidyr) được dùng để “làm gọn” dữ liệu (tidy data).

1. library(tidyr)

Tiến hành làm sạch dữ liệu:

1. VCBbctc <- VCBbctc %>%
2.   mutate(
3.     Tangtruong_TS = replace_na(Tangtruong_TS, 0),
4.     Tangtruong_LNST = replace_na(Tangtruong_LNST, 0)
5.   )

Giải thích kỹ thuật

  • Dòng lệnh (3): Sử dụng hàm mutate() để thay đổi giá trị trong các cột được chỉ định.

Hai lệnh này thay thế các giá trị bị thiếu (NA) bằng số 0 trong hai biến:

  • Dòng lệnh (4): Tăng trưởng tổng tài sản so với năm trước.

  • Dòng lệnh (5): Tăng trưởng lợi nhuận sau thuế so với năm trước.

Kết quả

Sau khi chạy lệnh này, toàn bộ dữ liệu không còn giá trị NA, tức là đã được làm sạch hoàn toàn. Hai biến Tangtruong_TS và Tangtruong_LNST giờ có giá trị bằng 0 cho năm đầu tiên

4.3 THỰC HIỆN CÁC THỐNG KÊ MÔ TẢ

4.3.1 Phân tổ dữ liệu

4.3.1.1 Phân tổ theo tăng trưởng tổng tài sản (Tangtruong_TS)

Tổng tài sản (TTS) phản ánh quy mô và sức mạnh tài chính của ngân hàng. Phân tích theo quy mô TTS giúp so sánh hiệu quả và an toàn tài chính qua các chỉ tiêu như CAR, DE, Tytrong_VCSH, Bien_LN_rong và Tangtruong_LNST, qua đó đánh giá mối liên hệ giữa quy mô, sinh lời và an toàn vốn của Vietcombank.

1. VCBbctc <- VCBbctc %>%
2.   mutate(Nhom_Tangtruong_TS = cut(
3.     Tangtruong_TS,
4.     breaks = quantile(Tangtruong_TS, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE),
5.     include.lowest = TRUE,
6.     labels = c("Thấp", "TB", "Cao")))
7.   
8. table(VCBbctc$Nhom_Tangtruong_TS)
## 
## Thấp   TB  Cao 
##    4    3    3

Giải thích kĩ thuật

  • Dòng lệnh (2) đếm (6): tạo thêm biến Nhom_Tangtruong_TS để nhóm các giá trị tăng trưởng tài sản, cut() chia biến liên tục thành các khoảng (nhóm).

Ở đây, dữ liệu được chia thành 3 nhóm theo phân vị 1/3 và 2/3 của biến Tangtruong_TS, tương ứng với ba mức tăng trưởng:

  • Thấp: các năm có tốc độ tăng trưởng thấp nhất.

  • TB (Trung bình): các năm có mức tăng trưởng nằm giữa.

  • Cao: các năm có mức tăng trưởng mạnh nhất.

  • Trong đó dòng lệnh (5) được dùng để đảm bảo giá trị nhỏ nhất vẫn được tính trong nhóm đầu tiên.

  • Dòng lệnh (7): tạo bảng tần suất, đếm số năm thuộc mỗi nhóm.

Kết luận:

Kết quả cho thấy Vietcombank có 4 năm tăng trưởng tổng tài sản ở mức thấp, 3 năm ở mức trung bình và 3 năm ở mức cao, phản ánh rằng tốc độ mở rộng quy mô tài sản của ngân hàng không ổn định giữa các giai đoạn, có sự dao động rõ rệt.

Sự phân hóa này cung cấp cơ sở để tiếp tục phân tích xem mức tăng trưởng tài sản cao hay thấp có liên quan như thế nào đến khả năng sinh lời (Bien_LN_rong), an toàn vốn (CAR) và đòn bẩy tài chính (DE) của ngân hàng.

4.3.1.2 Phân tổ theo tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST)

Phân loại tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST) giúp nhận diện giai đoạn phát triển lợi nhuận của Vietcombank, từ đó đánh giá sự ổn định trong hiệu quả kinh doanh.

Cách phân tổ này hỗ trợ việc so sánh các chỉ tiêu tài chính như biên lợi nhuận ròng (Bien_LN_rong), tỷ lệ an toàn vốn (CAR) hay đòn bẩy tài chính (DE) giữa các mức tăng trưởng lợi nhuận khác nhau, qua đó hiểu rõ hơn mối quan hệ giữa khả năng sinh lời và mức độ tăng trưởng của ngân hàng.

1. VCBbctc <- VCBbctc %>%
2.   mutate(Nhom_Tangtruong_LNST = cut(
3.     Tangtruong_LNST,
4.     breaks = quantile(Tangtruong_LNST, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE),
5.     include.lowest = TRUE,
6.     labels = c("Thấp", "TB", "Cao")))
7.   
8. table(VCBbctc$Nhom_Tangtruong_LNST)
## 
## Thấp   TB  Cao 
##    4    3    3

Giải thích kĩ thuật

  • Dòng lệnh (2) đến (6) : được dùng để chia Tangtruong_LNST (tăng trưởng lợi nhuận sau thuế) thành ba nhóm theo phân vị 1/3 và 2/3:

“Thấp”: các năm có tốc độ tăng trưởng lợi nhuận thấp nhất.

“TB” (Trung bình): các năm có mức tăng trưởng trung gian.

“Cao”: các năm có tốc độ tăng trưởng lợi nhuận cao nhất.

  • Dòng lệnh (5): đảm bảo giá trị nhỏ nhất được tính vào nhóm đầu tiên.

  • Dòng lệnh (6): được dùng để đếm số lượng năm thuộc mỗi nhóm.

Kết quả

Kết quả cho thấy Vietcombank có 4 năm tăng trưởng lợi nhuận ở mức thấp, 3 năm trung bình và 3 năm cao.

Điều này cho thấy tốc độ tăng trưởng lợi nhuận của ngân hàng không ổn định, có sự dao động giữa các giai đoạn.

Những năm tăng mạnh có thể gắn với thời kỳ mở rộng tín dụng hoặc kiểm soát chi phí hiệu quả, trong khi những năm tăng thấp có thể chịu ảnh hưởng từ biến động kinh tế, lãi suất hoặc chi phí dự phòng rủi ro.

4.3.2 Phân tích đơn biến

4.3.2.1 Biến lợi nhuận ròng

Chỉ tiêu biên lợi nhuận ròng (Bien_LN_rong) là một trong những thước đo quan trọng phản ánh hiệu quả sinh lời thực tế của Vietcombank sau khi đã trừ toàn bộ chi phí và thuế.

Phân tích thống kê mô tả giúp hiểu rõ mức độ sinh lời trung bình, độ dao động qua các năm, và sự ổn định của hiệu quả kinh doanh trong giai đoạn nghiên cứu.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(Bien_LN_rong, na.rm = TRUE),
5.     Trung_vi = median(Bien_LN_rong, na.rm = TRUE),
6.     Lon_nhat = max(Bien_LN_rong, na.rm = TRUE),
7.     Nho_nhat = min(Bien_LN_rong, na.rm = TRUE),
8.     Do_lech_chuan = sd(Bien_LN_rong, na.rm = TRUE),
9.     Heso_Bien_thien = sd(Bien_LN_rong, na.rm = TRUE) / mean(Bien_LN_rong, na.rm = TRUE) * 100,
10.     Q1 = quantile(Bien_LN_rong, 0.25, na.rm = TRUE),
11.     Q3 = quantile(Bien_LN_rong, 0.75, na.rm = TRUE)
12.   )

Giải thích kĩ thuật

Đoạn mã trên sử dụng lệnh (2) để tính các đặc trưng thống kê cơ bản của biến Bien_LN_rong, bao gồm:

So_nam: tổng số năm quan sát trong bộ dữ liệu (10 năm).

Gia_tri_trung_binh: giá trị trung bình của biên lợi nhuận ròng.

Trung_vi:giá trị nằm giữa phân phối, phản ánh mức sinh lời điển hình nhất.

Lon_nhat và Nho_nhat: giới hạn trên – dưới của biến, thể hiện phạm vi dao động.

Do_lech_chuan: mức độ biến động xung quanh trung bình.

Heso_Bien_thien (Coefficient of Variation – CV): đo lường tương quan giữa độ lệch chuẩn và trung bình, thể hiện mức ổn định tương đối của chỉ tiêu.

Q1 và Q3: hai phân vị (25% và 75%), mô tả phạm vi biến thiên chính của dữ liệu.

Kết quả Kết quả cho thấy:

Biên lợi nhuận ròng của Vietcombank có giá trị trung bình 0.267, trung vị 0.271, cho thấy mức sinh lời khá ổn định và phân bố cân đối quanh giá trị điển hình.

Giá trị nhỏ nhất 0.170 và lớn nhất 0.361 thể hiện biên độ dao động vừa phải, không xuất hiện năm bất thường hoặc hiệu quả quá thấp.

Độ lệch chuẩn 0.0659 cùng hệ số biến thiên 24.67 cho thấy biến động lợi nhuận ở mức trung bình, phản ánh khả năng duy trì hiệu quả sinh lời ổn định qua các năm.

Nhìn chung, Vietcombank thể hiện năng lực kiểm soát chi phí và duy trì hiệu quả hoạt động tốt, đảm bảo lợi nhuận ròng ổn định trong suốt giai đoạn phân tích.

4.3.2.2 Biến Car

Tỷ lệ an toàn vốn (CAR) là chỉ tiêu quan trọng phản ánh mức độ an toàn tài chính và khả năng chống chịu rủi ro của ngân hàng. Chỉ tiêu này cho biết tỷ lệ giữa vốn chủ sở hữu và tổng tài sản, thể hiện khả năng ngân hàng tự tài trợ cho hoạt động mà không phụ thuộc quá nhiều vào nguồn vốn vay.

Phân tích thống kê mô tả giúp đánh giá mức độ ổn định, biến động và xu hướng an toàn vốn của Vietcombank qua các năm.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(CAR, na.rm = TRUE),
5.     Trung_vi = median(CAR, na.rm = TRUE),
6.     Lon_nhat = max(CAR, na.rm = TRUE),
7.     Nho_nhat = min(CAR, na.rm = TRUE),
8.     Do_lech_chuan = sd(CAR, na.rm = TRUE),
9.     Heso_Bien_thien = sd(CAR, na.rm = TRUE) / mean(CAR, na.rm = TRUE) * 100,
10.     Q1 = quantile(CAR, 0.25, na.rm = TRUE),
11.     Q3 = quantile(CAR, 0.75, na.rm = TRUE)
12.   )

Kết quả

Kết quả cho thấy tỷ lệ CAR trung bình của Vietcombank đạt 0.071, trung vị 0.069, thể hiện mức độ an toàn vốn ổn định và không có sự lệch đáng kể giữa các năm.

Giá trị thấp nhất 0.051 và cao nhất 0.094 cho thấy biên độ dao động nhỏ, phản ánh việc ngân hàng duy trì cơ cấu vốn vững vàng và kiểm soát rủi ro hiệu quả.

Độ lệch chuẩn 0.0135 và hệ số biến thiên 19.09 chứng tỏ mức biến động thấp, tức Vietcombank giữ ổn định chính sách vốn qua thời gian. Nhìn chung, ngân hàng duy trì tỷ lệ CAR quanh mức 0.07, đáp ứng tiêu chuẩn an toàn vốn và đảm bảo khả năng chống chịu tốt trước biến động thị trường.

4.3.2.3 Biến DE

Chỉ tiêu đòn bẩy tài chính (DE) phản ánh mức độ sử dụng nợ của ngân hàng so với vốn chủ sở hữu, là thước đo quan trọng để đánh giá rủi ro tài chính và khả năng tự chủ về vốn.

Việc phân tích các đặc trưng thống kê của DE giúp xem xét mức độ ổn định trong chính sách huy động vốn và khả năng cân đối giữa nợ và vốn chủ của Vietcombank qua các năm.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(DE, na.rm = TRUE),
5.     Trung_vi = median(DE, na.rm = TRUE),
6.     Lon_nhat = max(DE, na.rm = TRUE),
7.     Nho_nhat = min(DE, na.rm = TRUE),
8.     Do_lech_chuan = sd(DE, na.rm = TRUE),
9.     Heso_Bien_thien = sd(DE, na.rm = TRUE) / mean(DE, na.rm = TRUE) * 100,
10.     Q1 = quantile(DE, 0.25, na.rm = TRUE),
11.     Q3 = quantile(DE, 0.75, na.rm = TRUE)
12.   )

Kết quả

Tỷ lệ đòn bẩy tài chính (DE) của Vietcombank có giá trị trung bình 13.56, trung vị 13.51, cho thấy mức sử dụng nợ khá ổn định trong giai đoạn phân tích.

Giá trị nhỏ nhất 9.63 và lớn nhất 18.70 phản ánh sự dao động vừa phải trong cơ cấu nguồn vốn, cho thấy ngân hàng có sự linh hoạt trong việc sử dụng nợ để mở rộng hoạt động nhưng vẫn trong phạm vi kiểm soát.

Độ lệch chuẩn 2.76 và hệ số biến thiên 20.38 cho thấy mức biến động trung bình, nghĩa là ngân hàng có điều chỉnh nhẹ qua các năm nhưng không mang tính rủi ro.

Tổng thể, Vietcombank duy trì mức đòn bẩy hợp lý, sử dụng nợ hiệu quả để tăng quy mô tài sản nhưng vẫn đảm bảo an toàn tài chính và khả năng kiểm soát rủi ro vốn.

4.3.2.4 Biến Tỷ trọng VCSH

Chỉ tiêu tỷ trọng vốn chủ sở hữu (Tytrong_VCSH) thể hiện tỷ lệ vốn tự có trong tổng nguồn vốn của ngân hàng, phản ánh mức độ tự chủ tài chính và khả năng chống chịu rủi ro khi thị trường biến động.

Phân tích chỉ tiêu này giúp đánh giá sự ổn định của cấu trúc vốn và mức độ an toàn trong hoạt động của Vietcombank qua các năm.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(Tytrong_VCSH, na.rm = TRUE),
5.     Trung_vi = median(Tytrong_VCSH, na.rm = TRUE),
6.     Lon_nhat = max(Tytrong_VCSH, na.rm = TRUE),
7.     Nho_nhat = min(Tytrong_VCSH, na.rm = TRUE),
8.     Do_lech_chuan = sd(Tytrong_VCSH, na.rm = TRUE),
9.     Heso_Bien_thien = sd(Tytrong_VCSH, na.rm = TRUE) / mean(Tytrong_VCSH, na.rm = TRUE) * 100,
10.     Q1 = quantile(Tytrong_VCSH, 0.25, na.rm = TRUE),
11.     Q3 = quantile(Tytrong_VCSH, 0.75, na.rm = TRUE)
12.   )

Kết quả

Tỷ trọng vốn chủ sở hữu của Vietcombank có giá trị trung bình 0.071, trung vị 0.069, cho thấy mức độ tự chủ tài chính ổn định và khá cân đối giữa các năm.

Giá trị nhỏ nhất 0.051 và lớn nhất 0.094 phản ánh biên độ dao động hẹp, chứng tỏ ngân hàng duy trì cấu trúc vốn ổn định và an toàn.

Độ lệch chuẩn 0.0135 và hệ số biến thiên 19.09 thể hiện mức biến động thấp, nghĩa là Vietcombank ít thay đổi trong chính sách vốn, giữ được tỷ lệ vốn chủ sở hữu ổn định so với tổng nguồn vốn.

Tổng thể, ngân hàng duy trì tỷ trọng vốn chủ quanh mức 0.07 – thể hiện nền tảng tài chính vững chắc, khả năng chống chịu rủi ro tốt và mức an toàn vốn cao trong toàn giai đoạn nghiên cứu.

4.3.2.5 Biến Nim

Chỉ tiêu biên lãi ròng (NIM) thể hiện hiệu quả sinh lời từ hoạt động cho vay và đầu tư sinh lãi của ngân hàng.

Đây là một trong những chỉ tiêu quan trọng nhất trong hoạt động ngân hàng, phản ánh mức chênh lệch giữa thu nhập lãi và chi phí lãi trên tổng tài sản.

Phân tích NIM giúp đánh giá khả năng quản lý chi phí vốn và hiệu quả sử dụng tài sản của Vietcombank trong giai đoạn nghiên cứu.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(NIM, na.rm = TRUE),
5.     Trung_vi = median(NIM, na.rm = TRUE),
6.     Lon_nhat = max(NIM, na.rm = TRUE),
7.     Nho_nhat = min(NIM, na.rm = TRUE),
8.     Do_lech_chuan = sd(NIM, na.rm = TRUE),
9.     Heso_Bien_thien = sd(NIM, na.rm = TRUE) / mean(NIM, na.rm = TRUE) * 100,
10.     Q1 = quantile(NIM, 0.25, na.rm = TRUE),
11.     Q3 = quantile(NIM, 0.75, na.rm = TRUE)
12.   )

Kết quả

Giá trị NIM trung bình 0.0265 và trung vị 0.0270 cho thấy hiệu quả sinh lời trên tài sản ổn định, mức chênh lệch giữa lãi thu và chi phí lãi không biến động lớn.

Giá trị nhỏ nhất 0.021 và lớn nhất 0.030 phản ánh phạm vi dao động hẹp, chứng tỏ Vietcombank duy trì hoạt động sinh lãi hiệu quả và ổn định qua thời gian.

Độ lệch chuẩn 0.00299 và hệ số biến thiên 11.29 thể hiện mức biến động thấp, cho thấy ngân hàng quản lý tốt lãi suất huy động – cho vay, ít bị ảnh hưởng bởi biến động thị trường vốn.

Nhìn chung, NIM của Vietcombank duy trì ổn định quanh mức 0.026–0.027, phản ánh khả năng sinh lời vững vàng và kiểm soát hiệu quả chi phí vốn trong toàn giai đoạn phân tích.

4.3.2.6 Biến Vòng quay Cho vay Khách hàng

Chỉ tiêu vòng quay cho vay khách hàng (Vongquay_CVKH) phản ánh hiệu quả sử dụng danh mục cho vay của ngân hàng trong việc tạo ra thu nhập từ lãi.

Chỉ tiêu này càng cao cho thấy ngân hàng khai thác nguồn vốn cho vay hiệu quả hơn, quản lý dòng tín dụng tốt hơn và tối ưu hóa lợi nhuận từ hoạt động cho vay.

Phân tích đặc trưng thống kê của chỉ tiêu giúp đánh giá mức độ ổn định trong hiệu quả tín dụng của Vietcombank qua các năm.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(Vongquay_CVKH, na.rm = TRUE),
5.     Trung_vi = median(Vongquay_CVKH, na.rm = TRUE),
6.     Lon_nhat = max(Vongquay_CVKH, na.rm = TRUE),
7.     Nho_nhat = min(Vongquay_CVKH, na.rm = TRUE),
8.     Do_lech_chuan = sd(Vongquay_CVKH, na.rm = TRUE),
9.     Heso_Bien_thien = sd(Vongquay_CVKH, na.rm = TRUE) / mean(Vongquay_CVKH, na.rm = TRUE) * 100,
10.     Q1 = quantile(Vongquay_CVKH, 0.25, na.rm = TRUE),
11.     Q3 = quantile(Vongquay_CVKH, 0.75, na.rm = TRUE)
12.   )

Kết quả

Giá trị vòng quay cho vay khách hàng trung bình 0.0827, trung vị 0.0838, cho thấy mức hiệu quả sử dụng vốn cho vay ổn định qua các năm.

Khoảng dao động từ 0.0660 đến 0.0934 thể hiện biên độ tương đối hẹp, chứng tỏ Vietcombank duy trì hoạt động tín dụng hiệu quả, ít biến động giữa các giai đoạn.

Độ lệch chuẩn 0.0078 và hệ số biến thiên 9.41 cho thấy mức biến động thấp, phản ánh ngân hàng kiểm soát tốt chất lượng danh mục cho vay và khả năng sinh lãi từ tín dụng.

Tổng thể, Vietcombank thể hiện hiệu quả cho vay ổn định và bền vững, duy trì khả năng tạo thu nhập từ hoạt động tín dụng với rủi ro biến động thấp trong suốt giai đoạn nghiên cứu.

4.3.2.7 Biến Tăng trưởng Tài sản

Chỉ tiêu tăng trưởng tổng tài sản (Tangtruong_TS) thể hiện mức độ mở rộng quy mô hoạt động của ngân hàng qua từng năm.

Đây là thước đo phản ánh khả năng huy động vốn, mở rộng tín dụng và đầu tư tài sản, từ đó đánh giá chiến lược phát triển quy mô và tốc độ tăng trưởng của Vietcombank trong giai đoạn nghiên cứu.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(Tangtruong_TS, na.rm = TRUE),
5.     Trung_vi = median(Tangtruong_TS, na.rm = TRUE),
6.     Lon_nhat = max(Tangtruong_TS, na.rm = TRUE),
7.     Nho_nhat = min(Tangtruong_TS, na.rm = TRUE),
8.     Do_lech_chuan = sd(Tangtruong_TS, na.rm = TRUE),
9.     Heso_Bien_thien = sd(Tangtruong_TS, na.rm = TRUE) / mean(Tangtruong_TS, na.rm = TRUE) * 100,
10.     Q1 = quantile(Tangtruong_TS, 0.25, na.rm = TRUE),
11.     Q3 = quantile(Tangtruong_TS, 0.75, na.rm = TRUE)
12.   )

Kết quả

Tốc độ tăng trưởng tổng tài sản của Vietcombank có giá trị trung bình 0.124, trung vị 0.109, cho thấy ngân hàng duy trì được mức tăng trưởng khá ổn định trong dài hạn.

Giá trị nhỏ nhất bằng 0 và lớn nhất đạt 0.314 phản ánh sự chênh lệch giữa các năm — có giai đoạn tăng mạnh, nhưng cũng có năm gần như không tăng trưởng.

Độ lệch chuẩn 0.107 cùng hệ số biến thiên 86.30 cho thấy mức biến động khá cao, tức tốc độ tăng trưởng tài sản có sự thay đổi đáng kể giữa các năm.

Nhìn chung, Vietcombank vẫn giữ được xu hướng tăng trưởng tích cực về quy mô tài sản, nhưng tốc độ tăng chưa ổn định, phản ánh ảnh hưởng của chu kỳ tín dụng và chiến lược mở rộng từng giai đoạn.

4.3.2.8 Biến Tăng trưởng LNST

Chỉ tiêu tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST) phản ánh mức độ cải thiện kết quả kinh doanh của ngân hàng qua từng năm.

Đây là thước đo quan trọng để đánh giá hiệu quả hoạt động, khả năng kiểm soát chi phí và duy trì lợi nhuận bền vững của Vietcombank trong giai đoạn nghiên cứu.

1. VCBbctc %>%
2.   summarise(
3.     So_nam = n(),
4.     Gia_tri_trung_binh = mean(Tangtruong_LNST, na.rm = TRUE),
5.     Trung_vi = median(Tangtruong_LNST, na.rm = TRUE),
6.     Lon_nhat = max(Tangtruong_LNST, na.rm = TRUE),
7.     Nho_nhat = min(Tangtruong_LNST, na.rm = TRUE),
8.     Do_lech_chuan = sd(Tangtruong_LNST, na.rm = TRUE),
9.     Heso_Bien_thien = sd(Tangtruong_LNST, na.rm = TRUE) / mean(Tangtruong_LNST, na.rm = TRUE) * 100,
10.     Q1 = quantile(Tangtruong_LNST, 0.25, na.rm = TRUE),
11.     Q3 = quantile(Tangtruong_LNST, 0.75, na.rm = TRUE)
12.   )

Kết quả

Tốc độ tăng trưởng lợi nhuận sau thuế của Vietcombank đạt trung bình 0.216, trung vị 0.232, cho thấy hiệu quả kinh doanh nhìn chung duy trì ở mức tốt qua thời gian.

Giá trị lớn nhất 0.605 và nhỏ nhất -0.0067 cho thấy sự biến động rõ rệt, với một số năm lợi nhuận tăng mạnh, nhưng cũng có năm giảm nhẹ.

Độ lệch chuẩn 0.194 và hệ số biến thiên 89.52 phản ánh mức biến động cao, cho thấy lợi nhuận sau thuế chưa thực sự ổn định, chịu ảnh hưởng từ biến động kinh tế, chính sách tín dụng và chi phí dự phòng rủi ro.

Nhìn chung, Vietcombank có xu hướng tăng trưởng lợi nhuận tích cực, song tốc độ còn dao động mạnh qua các năm, thể hiện đặc trưng chu kỳ của hoạt động ngân hàng và tác động từ yếu tố thị trường.

4.3.3 Phân tích đa biến

4.3.3.1 Hiệu quả hoạt động theo nhóm tăng trưởng tổng tài sản

Phân tích theo nhóm tăng trưởng tổng tài sản (Nhom_Tangtruong_TS) giúp so sánh hiệu quả hoạt động, an toàn vốn và cơ cấu tài chính giữa các giai đoạn tăng trưởng khác nhau của Vietcombank.

Cách tiếp cận này làm rõ mối quan hệ giữa quy mô mở rộng tài sản và khả năng sinh lời, đồng thời cho thấy chiến lược cân bằng giữa tăng trưởng và an toàn vốn của ngân hàng.

1. Thongke_TS <- VCBbctc %>%
2.   group_by(Nhom_Tangtruong_TS) %>%
3.   summarise(
4.     Soluong = n(),
5.     BienLN_tb = mean(Bien_LN_rong, na.rm = TRUE),
6.     NIM_tb = mean(NIM, na.rm = TRUE),
7.     CAR_tb = mean(CAR, na.rm = TRUE),
8.     DE_tb = mean(DE, na.rm = TRUE),
9.     TytrongVCSH_tb = mean(Tytrong_VCSH, na.rm = TRUE),
10.     VongquayCVKH_tb = mean(Vongquay_CVKH, na.rm = TRUE)
11.   ) %>%
12.   arrange(Nhom_Tangtruong_TS)
13. Thongke_TS

Giải thích kỹ thuật

  • Dòng lệnh (2): chia dữ liệu thành ba nhóm tăng trưởng tổng tài sản — Thấp, Trung bình (TB), và Cao.

  • Dòng lệnh (3): tính trung bình các chỉ tiêu tài chính cho từng nhóm:

BienLN_tb: biên lợi nhuận ròng trung bình.

NIM_tb: biên lãi ròng trung bình.

CAR_tb: tỷ lệ an toàn vốn trung bình.

DE_tb: mức đòn bẩy tài chính trung bình.

TytrongVCSH_tb: tỷ trọng vốn chủ sở hữu trung bình.

VongquayCVKH_tb: hiệu quả sử dụng vốn cho vay trung bình.

  • Dòng lệnh (12): sắp xếp bảng kết quả theo thứ tự nhóm tăng trưởng từ thấp đến cao.

Kết quả

Kết quả cho thấy xu hướng đáng chú ý giữa tăng trưởng tài sản và hiệu quả tài chính:

-Nhóm tăng trưởng thấp có biên lợi nhuận ròng (0.262) và NIM (0.0271) ở mức khá ổn định, cùng tỷ lệ CAR (0.073) tương đối an toàn. Mức DE (13.08) cho thấy ngân hàng sử dụng nợ ở mức vừa phải. → Giai đoạn này Vietcombank hoạt động thận trọng, hiệu quả sinh lời tốt dù tăng trưởng chậm.

-Nhóm tăng trưởng trung bình đạt biên lợi nhuận ròng cao nhất (0.301) và CAR (0.077) cũng cao hơn, cho thấy hiệu quả hoạt động tối ưu và an toàn vốn cao nhất trong ba nhóm. → Đây là giai đoạn tăng trưởng cân bằng, vừa mở rộng quy mô vừa duy trì hiệu quả sinh lời.

-Nhóm tăng trưởng cao lại có biên lợi nhuận ròng (0.240) và CAR (0.062) thấp hơn rõ rệt, trong khi DE (15.48) tăng cao — biểu hiện rủi ro tài chính lớn hơn do phụ thuộc nhiều vào nợ. → Dù quy mô tài sản tăng nhanh, hiệu quả và an toàn vốn giảm, phản ánh áp lực mở rộng nhanh có thể làm giảm chất lượng lợi nhuận.

Tổng thể, Vietcombank đạt hiệu quả tốt nhất khi duy trì tăng trưởng tài sản ở mức trung bình, trong khi các giai đoạn tăng trưởng quá cao đi kèm rủi ro vốn và lợi nhuận thấp hơn.

4.3.3.2 Cấu trúc vốn theo nhóm tăng trưởng lợi nhuận sau thuế

Phân tích theo nhóm tăng trưởng lợi nhuận sau thuế (Nhom_Tangtruong_LNST) giúp làm rõ mối quan hệ giữa khả năng sinh lời và mức độ an toàn vốn của Vietcombank.

Việc so sánh các chỉ tiêu như CAR, DE, Tytrong_VCSH, NIM và Biên lợi nhuận ròng giữa các nhóm tăng trưởng khác nhau cho phép đánh giá hiệu quả hoạt động và cấu trúc tài chính trong từng giai đoạn lợi nhuận tăng mạnh, trung bình hoặc thấp.

1. Thongke_LNST <- VCBbctc %>%
2.   group_by(Nhom_Tangtruong_LNST) %>%
3.   summarise(
4.     Soluong = n(),
5.     CAR_tb = mean(CAR, na.rm = TRUE),
6.     DE_tb = mean(DE, na.rm = TRUE),
7.     TytrongVCSH_tb = mean(Tytrong_VCSH, na.rm = TRUE),
8.     NIM_tb = mean(NIM, na.rm = TRUE),
9.     BienLN_tb = mean(Bien_LN_rong, na.rm = TRUE)
10.   ) %>%
11.   arrange(Nhom_Tangtruong_LNST)
12. Thongke_LNST

Giải thích kỹ thuật

  • Dòng lệnh (2): chia dữ liệu thành ba nhóm theo mức tăng trưởng lợi nhuận — Thấp, Trung bình (TB), và Cao.

  • Dòng lệnh (3): tính trung bình cho các chỉ tiêu quan trọng trong từng nhóm, trong đó có:

BienLN_tb: biên lợi nhuận ròng trung bình.

  • Dòng lệnh (11): sắp xếp kết quả theo thứ tự tăng trưởng lợi nhuận từ thấp đến cao.

Kết quả

Khi phân tích theo nhóm tăng trưởng lợi nhuận, có thể thấy rõ sự thay đổi trong hiệu quả hoạt động và cấu trúc vốn của Vietcombank:

-Nhóm tăng trưởng thấp có CAR trung bình 0.080 và DE 11.70, cho thấy mức an toàn vốn cao và đòn bẩy thấp. Dù vậy, biên lợi nhuận ròng 0.276 vẫn ở mức tốt, phản ánh hiệu quả kinh doanh ổn định ngay cả khi lợi nhuận tăng chậm.

-Nhóm tăng trưởng trung bình có CAR giảm xuống 0.068 và DE tăng lên 13.81, cho thấy ngân hàng bắt đầu sử dụng nợ nhiều hơn để mở rộng hoạt động. Tuy nhiên, NIM 0.027 và biên lợi nhuận 0.256 vẫn giữ ở mức khả quan, thể hiện sự cân bằng giữa tăng trưởng và hiệu quả.

-Nhóm tăng trưởng cao có CAR giảm tiếp còn 0.061 và DE tăng lên 15.78, phản ánh rủi ro tài chính cao hơn do sử dụng nợ mạnh để thúc đẩy tăng trưởng. Mặc dù biên lợi nhuận ròng 0.266 vẫn tốt, hiệu quả sinh lời trên vốn có dấu hiệu giảm nhẹ do chi phí tài chính và rủi ro tín dụng tăng.

Tổng thể, Vietcombank đạt hiệu quả tối ưu khi duy trì mức tăng trưởng lợi nhuận trung bình, còn khi lợi nhuận tăng quá nhanh, ngân hàng phải đánh đổi an toàn vốn và gia tăng đòn bẩy, làm giảm tính bền vững trong dài hạn.

4.3.3.3 Tăng trưởng tổng tài sản và tốc độ quay vòng vốn

Phân tích theo nhóm tăng trưởng tổng tài sản (Nhom_Tangtruong_TS) kết hợp với các chỉ tiêu vòng quay cho vay khách hàng (Vongquay_CVKH), đòn bẩy tài chính (DE) và tỷ lệ an toàn vốn (CAR) giúp đánh giá mối quan hệ giữa tốc độ tăng quy mô tài sản, hiệu quả tín dụng và mức độ an toàn vốn của Vietcombank.

Qua đó có thể xác định ngân hàng duy trì hiệu quả tài chính ra sao trong từng giai đoạn tăng trưởng khác nhau.

1. Thongke_Von <- VCBbctc %>%
2.   group_by(Nhom_Tangtruong_TS) %>%
3.   summarise(
4.     Soluong = n(),
5.     VongquayCVKH_tb = mean(Vongquay_CVKH, na.rm = TRUE),
6.     DE_tb = mean(DE, na.rm = TRUE),
7.     CAR_tb = mean(CAR, na.rm = TRUE)
8.   ) %>%
9.   arrange(Nhom_Tangtruong_TS)
10. Thongke_Von

Giải thích kỹ thuật

  • Dòng lệnh (2): phân chia dữ liệu theo ba nhóm tăng trưởng tổng tài sản — Thấp, Trung bình (TB) và Cao.

  • Dòng lệnh (9): sắp xếp bảng kết quả theo thứ tự tăng trưởng tài sản để dễ so sánh.

Kết quả

Kết quả cho thấy mối quan hệ đáng chú ý giữa tăng trưởng tài sản, hiệu quả tín dụng và cấu trúc vốn của Vietcombank:

-Ở nhóm tăng trưởng thấp, ngân hàng có Vongquay_CVKH 0.0838, DE 13.08 và CAR 0.073. → Điều này cho thấy hoạt động tín dụng hiệu quả ổn định, sử dụng nợ ở mức hợp lý và duy trì an toàn vốn cao.

-Ở nhóm tăng trưởng trung bình, CAR đạt 0.077, cao nhất trong ba nhóm, trong khi DE 12.28 thấp nhất. → Đây là giai đoạn cân bằng tốt nhất giữa hiệu quả và an toàn tài chính, thể hiện cơ cấu vốn tối ưu.

-Ở nhóm tăng trưởng cao, DE tăng mạnh lên 15.48 và CAR giảm xuống còn 0.062, cho thấy rủi ro tài chính tăng do ngân hàng phụ thuộc nhiều hơn vào nợ để mở rộng quy mô. → Dù hiệu quả tín dụng (Vongquay_CVKH 0.0827) vẫn ổn định, nhưng an toàn vốn giảm, phản ánh áp lực tài chính lớn hơn trong giai đoạn tăng trưởng nhanh.

Tổng thể, Vietcombank đạt hiệu quả và an toàn tối ưu khi duy trì mức tăng trưởng tài sản trung bình, trong khi tăng trưởng quá cao kéo theo đòn bẩy lớn và giảm độ an toàn vốn.

4.4 TRỰC QUAN HÓA DỮ LIỆU

1. library(dplyr)
2. library(tidyr)
3. library(ggplot2)
4. library(scales)
5. library(ggrepel)

Đoạn mã sử dụng các hàm từ các thư viện dplyr, tidyr, ggplot2, scales và ggrepel để xử lý và trực quan hóa dữ liệu.

4.4.1 Line + points + smooth: xu hướng NIM & Biên lợi nhuận ròng theo năm

Biểu đồ trên thể hiện xu hướng của Biên lợi nhuận ròng (Bien_LN_rong) và Biên lãi ròng (NIM) của Vietcombank trong giai đoạn từ 2015 đến 2024.

Biên lợi nhuận ròng thể hiện mức độ sinh lời của ngân hàng sau khi trừ chi phí và thuế, cho thấy khả năng tạo ra lợi nhuận từ các hoạt động chính.

Biên lãi ròng (NIM) phản ánh hiệu quả sinh lời từ hoạt động tín dụng, cụ thể là mức chênh lệch giữa thu nhập lãi và chi phí lãi.

Biểu đồ này giúp chúng ta so sánh sự thay đổi trong hiệu quả sinh lời và quản lý tài chính của ngân hàng qua thời gian.

1. df_long <- VCBbctc %>%
2.   select(Nam, NIM, Bien_LN_rong) %>%
3.   pivot_longer(-Nam, names_to = "Chi_tieu", values_to = "Gia_tri")
4. ggplot(df_long, aes(x = Nam, y = Gia_tri, color = Chi_tieu, group = Chi_tieu)) +
5.   geom_line(linewidth = 1) +
6.   geom_point(size = 2.5) +
7.   geom_smooth(method = "loess", se = FALSE, linewidth = 0.8, linetype = "dashed") +
8.   scale_y_continuous(labels = percent_format(accuracy = 0.1)) +
9.   scale_color_brewer(palette = "Set1") +
10.   labs(title = "NIM và Biên lợi nhuận ròng theo năm",
11.        x = "Năm", y = "Tỷ lệ") +
12.   theme_minimal(base_size = 13) +
13.   theme(legend.title = element_blank())

Giải thích kỹ thuật

  • Dòng lệnh (1), (2) và (3) : Tạo bảng dữ liệu mới chỉ gồm ba cột Nam, NIM và Biên_LN_rong, sau đó chuyển dữ liệu từ dạng rộng sang dạng dài để thuận tiện cho việc vẽ nhiều chỉ tiêu trên cùng một biểu đồ.

  • Dòng lệnh (4): Khởi tạo biểu đồ ggplot với trục x là năm (Nam), trục y là giá trị phần trăm của chỉ tiêu (Gia_tri), và màu sắc phân biệt giữa các chỉ tiêu (NIM và Biên lợi nhuận ròng). Tham số group = Chi_tieu giúp nối các điểm cùng loại chỉ tiêu thành đường liên tục.

  • Dòng lệnh (5): Vẽ đường nối biểu diễn xu hướng thay đổi của từng chỉ tiêu theo năm. Độ dày đường (linewidth = 1) giúp biểu đồ rõ ràng, dễ phân biệt giữa các đường.

  • Dòng lệnh (6): Thêm các điểm dữ liệu tại từng năm để nhấn mạnh giá trị thực tế của từng chỉ tiêu. Kích thước điểm (size = 2.5) được chọn vừa đủ để nổi bật nhưng không gây rối.

  • Dòng lệnh (7): Thêm đường xu hướng mượt (loess smoothing) giúp người xem dễ nhận ra xu hướng biến động tổng thể theo thời gian. Tùy chọn se = FALSE tắt hiển thị vùng tin cậy, linetype = “dashed” tạo đường nét đứt để phân biệt với đường dữ liệu gốc.

  • Dòng lệnh (8): Định dạng trục tung hiển thị giá trị dưới dạng phần trăm (%), với độ chính xác 0.1%, giúp người xem dễ hiểu hơn so với dạng số thập phân.

  • Dòng lệnh (9): Áp dụng bảng màu “Set1” từ RColorBrewer, giúp hai đường biểu diễn có màu tươi sáng, chuyên nghiệp và dễ phân biệt.

  • Dòng lệnh (10) và (11): Thêm tiêu đề cho biểu đồ và nhãn cho trục x, trục y để biểu đồ có tính mô tả và dễ đọc hơn.

  • Dòng lệnh (12) và (13): Áp dụng giao diện tối giản (theme_minimal) giúp biểu đồ gọn gàng, dễ theo dõi. Tham số base_size = 13 tăng kích cỡ chữ toàn cục, còn legend.title = element_blank() ẩn tiêu đề chú thích để biểu đồ thanh thoát và hiện đại hơn.

Kết quả

Biểu đồ trên thể hiện xu hướng biến động của hai chỉ tiêu tài chính quan trọng của Vietcombank giai đoạn 2015–2024: NIM (Net Interest Margin – Biên lãi ròng)Biên lợi nhuận ròng (Bien_LN_rong).

Quan sát cho thấy, NIM duy trì ở mức tương đối ổn định quanh 3–4%, phản ánh hiệu quả khai thác tài sản sinh lãi của ngân hàng không biến động lớn qua thời gian. Trong khi đó, biên lợi nhuận ròng tăng mạnh và rõ rệt, từ khoảng 17% năm 2015 lên trên 30% vào năm 2024, cho thấy khả năng kiểm soát chi phí và tối ưu hóa hoạt động ngày càng tốt hơn.

Đặc biệt, giai đoạn 2018–2021 là bước ngoặt khi biên lợi nhuận ròng tăng nhanh, song song với NIM cải thiện nhẹ. Điều này hàm ý rằng Vietcombank không chỉ duy trì hiệu quả sinh lời từ hoạt động tín dụng mà còn nâng cao năng lực sinh lời tổng thể từ các hoạt động khác (phi tín dụng, quản lý chi phí, và đầu tư). Tổng thể, ngân hàng thể hiện xu hướng tăng trưởng lợi nhuận bền vững và cải thiện biên hiệu quả tài chính theo thời gian.

4.4.2 Boxplot + jitter + mean: CAR theo nhóm tăng trưởng TÀI SẢN

Biểu đồ boxplot trên cho thấy tỷ lệ an toàn vốn (CAR) của Vietcombank theo nhóm tăng trưởng tổng tài sản (TTS) trong ba nhóm: Thấp, Trung bình (TB) và Cao. Mục tiêu của biểu đồ này là so sánh mức độ an toàn vốn giữa các nhóm có tốc độ tăng trưởng tài sản khác nhau.

1. ggplot(VCBbctc, aes(x = Nhom_Tangtruong_TS, y = CAR, fill = Nhom_Tangtruong_TS)) +
2.   geom_boxplot(alpha = 0.7, outlier.shape = NA) +
3.   geom_jitter(width = 0.15, alpha = 0.6, size = 2, color = "grey30") +
4.   stat_summary(fun = mean, geom = "point", shape = 23, size = 3, fill = "white") +
5.   scale_y_continuous(labels = percent) +
6.   scale_fill_brewer(palette = "Blues") +
7.   labs(title = "CAR theo nhóm tăng trưởng tổng tài sản",
8.        x = "Nhóm tăng trưởng TTS", y = "CAR") +
9.   theme_minimal(base_size = 13) +
10.   theme(legend.position = "none")

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo biểu đồ ggplot với trục x là biến phân loại Nhom_Tangtruong_TS (nhóm tăng trưởng tổng tài sản), trục y là CAR (tỷ lệ an toàn vốn), và màu sắc cột được tô theo từng nhóm tăng trưởng.

  • Dòng lệnh (2): vẽ biểu đồ hộp nhằm thể hiện phân bố, trung vị và mức độ biến động của CAR trong từng nhóm. Tham số alpha = 0.7 giúp hộp có độ trong suốt vừa phải, còn outlier.shape = NA ẩn các điểm ngoại lai để biểu đồ gọn gàng hơn.

  • Dòng lệnh (3): hiển thị các điểm dữ liệu riêng lẻ, giúp quan sát rõ mật độ phân bố thực tế của CAR trong mỗi nhóm. Tham số width = 0.15 tạo độ lệch ngang nhẹ để tránh chồng lấn, alpha = 0.6 làm mờ nhẹ, và màu xám giúp điểm không lấn át phần hộp.

  • Dòng lệnh (4): vẽ điểm trung bình (mean) của CAR trong từng nhóm, biểu diễn bằng hình dạng shape = 23 (hình vuông rỗng), kích thước 3, màu nền trắng để nổi bật trên nền màu nhóm.

  • Dòng lệnh (5): để định dạng trục tung hiển thị theo tỷ lệ phần trăm, giúp dễ nhận biết và so sánh giữa các nhóm.

  • Dòng lệnh (6): để tạo dải màu xanh lam dịu, phù hợp với biểu đồ tài chính.

  • Dòng lệnh (7) và (8): Thêm tiêu đề và nhãn cho trục x, trục y bằng labs(), giúp biểu đồ rõ ràng, dễ hiểu. Tiêu đề “CAR theo nhóm tăng trưởng tổng tài sản” mô tả nội dung chính của biểu đồ.

  • Dòng lệnh (9) và (10): Sử dụng theme_minimal(base_size = 13) để biểu đồ gọn gàng và dễ đọc, đồng thời theme(legend.position = “none”) loại bỏ phần chú thích màu vì các nhóm đã được thể hiện rõ trên trục x.

Kết quả

Nhóm tăng trưởng thấp:

CAR dao động chủ yếu quanh mức 6–8%, trung vị (median) khoảng 7,2%.

Một số giá trị cao hơn 8% cho thấy có vài doanh nghiệp duy trì vốn an toàn tốt hơn mức trung bình.

Nhóm tăng trưởng trung bình:

CAR có xu hướng cao nhất trong ba nhóm, với trung vị khoảng 7,5–8%.

Độ phân tán không quá lớn, thể hiện sự ổn định về khả năng duy trì an toàn vốn.

Điểm trung bình (hình thoi trắng) cao hơn median một chút → có thể tồn tại một vài doanh nghiệp có CAR vượt trội.

Nhóm tăng trưởng cao:

CAR trung bình thấp nhất, khoảng 6–6,5%, cho thấy doanh nghiệp tăng trưởng nhanh thường chịu rủi ro về vốn cao hơn do mở rộng tài sản mạnh mẽ.

Phạm vi biến động rộng, có cả giá trị thấp gần 5% → phản ánh sự chênh lệch đáng kể trong quản lý vốn của nhóm này.

Kết luận:

Nhìn chung, khi tăng trưởng tổng tài sản tăng, CAR lại có xu hướng giảm, cho thấy doanh nghiệp phát triển nhanh thường ưu tiên tăng quy mô hơn là duy trì an toàn vốn cao.

Nhóm có tăng trưởng trung bình đạt hiệu quả cân bằng nhất: vừa duy trì được mức tăng trưởng hợp lý, vừa đảm bảo chỉ số an toàn vốn ổn định.

4.4.3 Violin + boxplot: DE theo nhóm tăng trưởng LỢI NHUẬN

Biểu đồ violon với boxplot kết hợp được sử dụng để trực quan hóa đòn bẩy tài chính (DE) của Vietcombank theo nhóm tăng trưởng lợi nhuận sau thuế (LNST).

Mục tiêu là so sánh mức độ sử dụng nợ (đòn bẩy tài chính) trong các nhóm có tốc độ tăng trưởng lợi nhuận khác nhau, giúp nhận diện sự khác biệt trong chiến lược tài chính của ngân hàng trong các giai đoạn lợi nhuận tăng mạnh, trung bình hoặc thấp.

1. ggplot(VCBbctc, aes(x = Nhom_Tangtruong_LNST, y = DE, fill = Nhom_Tangtruong_LNST)) +
2.   geom_violin(alpha = 0.6, color = "grey40", trim = TRUE) +
3.   geom_boxplot(width = 0.12, fill = "white", outlier.shape = NA) +
4.   stat_summary(fun = mean, geom = "point", size = 2.5, color = "red") +
5.   scale_fill_brewer(palette = "Pastel1") +
6.   labs(title = "(DE) theo nhóm tăng trưởng LNST",
7.        x = "Nhóm tăng trưởng LNST", y = "DE (lần)") +
8.   theme_minimal(base_size = 13) +
9.   theme(legend.position = "none")

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo biểu đồ ggplot với trục x là biến phân loại Nhom_Tangtruong_LNST (nhóm tăng trưởng lợi nhuận sau thuế), trục y là DE (tỷ lệ nợ trên vốn chủ sở hữu), và phần tô màu (fill) thể hiện từng nhóm tăng trưởng LNST.

  • Dòng lệnh (2): để vẽ biểu đồ violin nhằm thể hiện hình dạng phân phối của DE trong từng nhóm. Tham số alpha = 0.6 tạo độ trong suốt vừa phải, color = “grey40” viền màu xám nhẹ giúp tách biệt từng violin, và trim = TRUE cắt phần đuôi phân phối để biểu đồ gọn gàng hơn.

  • Dòng lệnh (3): Thêm geom_boxplot() bên trong violin để minh họa các thống kê mô tả cơ bản (trung vị, tứ phân vị, và độ trải dữ liệu). Tham số width = 0.12 làm hộp gọn lại, fill = “white” giúp hộp nổi bật trên nền violin, và outlier.shape = NA ẩn các điểm ngoại lai.

  • Dòng lệnh (4): để thêm điểm trung bình (mean) của DE cho từng nhóm. Điểm được hiển thị bằng chấm đỏ (color = "red") với kích thước size = 2.5, giúp người xem dễ nhận biết vị trí trung tâm của phân phối.

  • Dòng lệnh (8) : Sử dụng theme_minimal(base_size = 13) để tạo giao diện biểu đồ đơn giản, hiện đại, dễ đọc, đồng thời theme(legend.position = “none”) loại bỏ chú thích màu vì các nhóm đã được thể hiện rõ qua trục x.

Kết quả

Biểu đồ trên mô tả mức độ đòn bẩy tài chính (DE) của các ngân hàng được chia theo ba nhóm tăng trưởng lợi nhuận sau thuế (LNST): Thấp, Trung bình (TB) và Cao.

Dễ dàng nhận thấy rằng, nhóm có tăng trưởng LNST cao thường đi kèm với mức đòn bẩy tài chính lớn hơn so với hai nhóm còn lại. Cụ thể, giá trị trung vị của DE ở nhóm Cao nằm trên khoảng 15 lần, trong khi nhóm Thấp chỉ quanh mức 12 lần. Điều này cho thấy những ngân hàng đạt tốc độ tăng trưởng lợi nhuận mạnh thường tận dụng vốn vay nhiều hơn để khuếch đại hiệu quả sinh lời.

Đáng chú ý, độ biến động của DE ở nhóm Cao cũng rộng hơn, thể hiện qua hình dạng của hộp và độ mở của biểu đồ violin. Điều này ngụ ý rằng trong nhóm ngân hàng tăng trưởng nhanh, có sự khác biệt đáng kể trong chiến lược tài chính, một số ngân hàng sử dụng đòn bẩy rất cao, trong khi số khác vẫn duy trì mức an toàn tương đối.

Ngược lại, nhóm Thấp có phân phối DE hẹp hơn, thể hiện chính sách tài chính thận trọng và ít sử dụng nợ vay, song điều đó cũng có thể khiến khả năng mở rộng lợi nhuận bị hạn chế. Nhóm Trung bình nằm ở vị trí giữa hai cực, thể hiện sự cân bằng giữa rủi ro và lợi nhuận.

Tổng thể, biểu đồ phản ánh mối quan hệ thuận chiều giữa tăng trưởng lợi nhuận và mức độ đòn bẩy tài chính, đồng thời nhấn mạnh vai trò của việc quản trị nợ vay hợp lý trong việc tối ưu hóa hiệu quả kinh doanh của các ngân hàng.

4.4.4 Scatter+lm+nhãn năm (ggrepel): quan hệ DE – CAR

Biểu đồ này trực quan hóa mối quan hệ giữa Đòn bẩy tài chính (DE) và Tỷ lệ an toàn vốn (CAR) của Vietcombank. DE đo lường mức độ sử dụng nợ so với vốn chủ sở hữu (VCSH), thể hiện mức độ rủi ro tài chính của ngân hàng.

CAR là tỷ lệ giữa vốn chủ sở hữu và tổng tài sản, phản ánh khả năng chống chịu rủi ro và sức mạnh tài chính của ngân hàng. Biểu đồ này giúp chúng ta hiểu rõ hơn về mối quan hệ giữa việc sử dụng nợ và mức độ an toàn tài chính của ngân hàng.

1. p <- ggplot(VCBbctc, aes(x = DE, y = CAR)) +
2.   geom_point(size = 3, alpha = 0.8, color = "#2E86C1") +
3.   geom_smooth(method = "lm", se = TRUE, color = "red", linewidth = 0.8) +
4.   geom_text_repel(aes(label = Nam), size = 3, max.overlaps = 10) +
5.   scale_y_continuous(labels = percent) +
6.   labs(title = "Đòn bẩy (DE) và An toàn vốn (CAR)",
7.        x = "DE (Nợ/VCSH)", y = "CAR") +
8.   theme_minimal(base_size = 13)
9. p

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo biểu đồ ggplot với trục x là DE (tỷ lệ đòn bẩy tài chính – nợ trên vốn chủ sở hữu), trục y là CAR (tỷ lệ an toàn vốn).

  • Dòng lệnh (2): Sử dụng để vẽ các điểm dữ liệu, mỗi điểm đại diện cho một năm quan sát. Size = 3 tăng kích thước điểm giúp dễ nhận diện, alpha = 0.8 tạo độ trong suốt nhẹ để tránh chồng lấn.

  • Dòng lệnh (3): để vẽ đường hồi quy tuyến tính biểu diễn xu hướng tổng thể giữa DE và CAR.

  • Dòng lệnh (4): Dùng để thêm nhãn năm (Nam) cho từng điểm dữ liệu, giúp người xem biết giá trị thuộc năm nào. Hàm này có cơ chế “repel” (đẩy các nhãn ra xa nhau). Tham số size = 3 điều chỉnh kích cỡ chữ, max.overlaps = 10 giới hạn số nhãn hiển thị.

  • Dòng lệnh (5): Áp dụng để định dạng trục tung hiển thị theo phần trăm (%), phù hợp vì biến CAR thường được biểu diễn dưới dạng tỷ lệ.

  • Dòng lệnh (6) và (7): Thêm labs() để đặt tiêu đề “Đòn bẩy (DE) và An toàn vốn (CAR)” cùng nhãn cho hai trục x và y

  • Dòng lệnh (8) và (9) : Dùng theme_minimal(base_size = 13) để biểu đồ đơn giản, hiện đại, dễ đọc; đồng thời đảm bảo cỡ chữ lớn vừa đủ cho báo cáo.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa đòn bẩy tài chính (DE) và hệ số an toàn vốn (CAR) của các ngân hàng trong giai đoạn 2015–2024.

Nhìn chung, xu hướng đường hồi quy màu đỏ cho thấy mối quan hệ nghịch biến rõ rệt giữa hai biến này: khi DE tăng, CAR có xu hướng giảm. Điều này hoàn toàn phù hợp với lý thuyết tài chính, vì đòn bẩy tài chính càng cao (tức là tỷ lệ nợ trên vốn chủ sở hữu càng lớn) sẽ làm tăng rủi ro tài chính, dẫn đến giảm mức độ an toàn vốn của ngân hàng.

Cụ thể, ở những năm có DE thấp như 2023–2024, CAR đạt mức cao, khoảng trên 8%, cho thấy các ngân hàng duy trì được khả năng chống chịu rủi ro tốt. Ngược lại, giai đoạn 2016–2017 ghi nhận DE cao nhất, vượt 17 lần, thì CAR xuống mức thấp nhất, chỉ quanh 5%, phản ánh tình trạng sử dụng vốn vay lớn và tiềm ẩn rủi ro mất cân đối vốn.

Khoảng tin cậy (vùng xám) quanh đường hồi quy khá hẹp, chứng tỏ mối quan hệ nghịch biến giữa DE và CAR là ổn định và có ý nghĩa thống kê trong toàn bộ giai đoạn.

Tóm lại, biểu đồ cho thấy rằng việc gia tăng đòn bẩy tài chính sẽ làm suy giảm khả năng an toàn vốn, nhấn mạnh tầm quan trọng của việc duy trì mức DE hợp lý để đảm bảo sự ổn định tài chính và khả năng tuân thủ quy định an toàn vốn của các ngân hàng.

4.4.5 Heatmap tương quan giữa 8 biến định lượng

Đoạn code này tạo ra một ma trận tương quan giữa các chỉ tiêu tài chính của Vietcombank. Mục tiêu là kiểm tra mức độ liên quan giữa các chỉ số như Biên lợi nhuận ròng (Bien_LN_rong), Tỷ lệ an toàn vốn (CAR), Đòn bẩy tài chính (DE), Tỷ trọng vốn chủ sở hữu (Tytrong_VCSH), Biên lãi ròng (NIM), Vòng quay cho vay khách hàng (Vongquay_CVKH), Tăng trưởng tổng tài sản (Tangtruong_TS) và Tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST).

1. vars <- VCBbctc %>%
2.   select(Bien_LN_rong, CAR, DE, Tytrong_VCSH, NIM, Vongquay_CVKH, Tangtruong_TS, Tangtruong_LNST)
3. cor_mat <- round(cor(vars, use = "pairwise.complete.obs"), 2)
4. cor_df  <- as.data.frame(as.table(cor_mat))
5. names(cor_df) <- c("Var1", "Var2", "Corr")
6. ggplot(cor_df, aes(Var1, Var2, fill = Corr)) +
7.   geom_tile(color = "white") +
8.   geom_text(aes(label = Corr), color = "black", size = 3) +
9.   scale_fill_gradient2(low = "#4575b4", mid = "white", high = "#d73027", limits = c(-1,1)) +
10.   labs(title = "Ma trận tương quan các chỉ tiêu tài chính",
11.        x = NULL, y = NULL, fill = "r") +
12.   theme_minimal(base_size = 12) +
13.   theme(axis.text.x = element_text(angle = 45, hjust = 1))

Giải thích kỹ thuật

  • Dòng lệnh (1), (2): Sử dụng hàm select() để chọn ra các biến tài chính quan trọng từ bảng dữ liệu VCBbctc.

  • Dòng lệnh (3): Tính ma trận tương quan giữa các biến bằng hàm cor(), với tùy chọn use = “pairwise.complete.obs” để đảm bảo chỉ tính trên các cặp giá trị không bị thiếu (NA). Sau đó làm tròn kết quả đến hai chữ số thập phân bằng hàm round().

  • Dòng lệnh (4): Chuyển ma trận tương quan sang dạng bảng dài (long format) bằng as.table() rồi ép kiểu sang data frame để ggplot có thể xử lý.

  • Dòng lệnh (5): Đặt lại tên các cột của bảng tương quan thành “Var1”, “Var2” và “Corr” để dễ sử dụng trong ggplot.

  • Dòng lệnh (6): Khởi tạo biểu đồ ggplot với trục x là Var1, trục y là Var2 và màu sắc (fill) thể hiện giá trị tương quan Corr.

  • Dòng lệnh (7): Sử dụng geom_tile(color = “white”) để vẽ từng ô (tile) đại diện cho cặp biến, với đường viền màu trắng giúp phân tách rõ các ô.

  • Dòng lệnh (8): Dùng geom_text(aes(label = Corr)) để hiển thị trực tiếp giá trị hệ số tương quan trên mỗi ô, giúp người xem dễ đọc và so sánh.

  • Dòng lệnh (9): Áp dụng scale_fill_gradient2() để tạo thang màu đối xứng quanh 0, thể hiện rõ mối tương quan

  • Dòng lệnh (10) và (11): Thêm tiêu đề và nhãn bằng hàm labs(). Tiêu đề: “Ma trận tương quan các chỉ tiêu tài chính”.

  • Dòng lệnh (12) và (13): Dùng theme_minimal(base_size = 12) để làm biểu đồ đơn giản, dễ đọc, và theme(axis.text.x = element_text(angle = 45, hjust = 1)) để xoay nhãn trục x nghiêng 45 độ, tránh chồng chữ khi hiển thị nhiều biến.

Kết luận

Biểu đồ trên thể hiện ma trận tương quan giữa các chỉ tiêu tài chính của các ngân hàng, trong đó giá trị dao động từ -1 đến 1 cho biết mức độ và chiều hướng tương quan giữa các biến.

Trước hết, có thể nhận thấy các cặp biến CAR – DE và Tỷ trọng VCSH – DE có tương quan âm rất mạnh, lần lượt là -0.98, cho thấy khi đòn bẩy tài chính (DE) tăng thì hệ số an toàn vốn (CAR) và tỷ trọng vốn chủ sở hữu đều giảm đáng kể. Đây là mối quan hệ phản ánh đúng bản chất tài chính: sử dụng nợ nhiều làm suy giảm mức độ an toàn vốn.

Ngược lại, CAR, Tỷ trọng VCSH, và Biên lợi nhuận ròng (Biên_LN_rong) có mối tương quan dương rất cao (từ 0.74 đến 0.82), nghĩa là khi ngân hàng duy trì tỷ trọng vốn chủ cao thì hiệu quả sinh lời và an toàn vốn cùng được cải thiện.

NIM (biên lãi ròng) cũng có tương quan dương mạnh với CAR (0.62) và Biên_LN_rong (0.82), cho thấy việc duy trì biên lãi cao góp phần tăng lợi nhuận và củng cố an toàn vốn.

Trong khi đó, các biến Tăng trưởng LNST, Tăng trưởng tổng tài sản, và Vòng quay cho vay khách hàng có tương quan yếu hoặc trung bình với các chỉ tiêu khác, thể hiện rằng sự biến động tăng trưởng chưa có tác động mạnh hoặc ổn định đến cấu trúc tài chính và hiệu quả hoạt động.

Tóm lại, ma trận tương quan này làm nổi bật hai mối quan hệ chính:

Mối quan hệ nghịch biến rất mạnh giữa đòn bẩy tài chính (DE) với an toàn vốn (CAR) và vốn chủ sở hữu, cho thấy rủi ro khi tăng vay nợ.

Mối quan hệ đồng biến giữa NIM, CAR, và Biên_LN_rong, phản ánh vai trò của khả năng sinh lời trong việc củng cố an toàn và hiệu quả tài chính của ngân hàng.

4.4.6 ECDF (2 đường): phân phối tích lũy Tangtruong_TS vs Tangtruong_LNST

Đoạn mã này tạo ra một biểu đồ ECDF (Cumulative Distribution Function) để so sánh phân phối của tăng trưởng tổng tài sản (Tangtruong_TS) và tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST) của Vietcombank. Mục tiêu là hiểu cách các mức tăng trưởng này phân phối và có sự khác biệt như thế nào, đồng thời so sánh xác suất tích lũy của chúng.

1. df_ecdf <- VCBbctc %>%
2.   select(Tangtruong_TS, Tangtruong_LNST) %>%
3.   pivot_longer(everything(), names_to = "Bien", values_to = "Gia_tri")
4. ggplot(df_ecdf, aes(x = Gia_tri, color = Bien)) +
5.   stat_ecdf(geom = "step", linewidth = 1) +
6.   scale_x_continuous(labels = percent) +
7.   scale_color_brewer(palette = "Dark2") +
8.   labs(title = "Phân phối tăng trưởng TS và LNST",
9.        x = "Tăng trưởng", y = "Xác suất tích lũy", color = "Biến") +
10.   theme_minimal(base_size = 13)

Giải thích kỹ thuật

  • Dòng lệnh (1) và (2): Sử dụng select() để chọn hai biến cần so sánh là Tangtruong_TS (tăng trưởng tổng tài sản) và Tangtruong_LNST (tăng trưởng lợi nhuận sau thuế) từ bảng dữ liệu VCBbctc.

  • Dòng lệnh (3): Dùng pivot_longer(everything(), names_to = “Bien”, values_to = “Gia_tri”) để chuyển dữ liệu từ dạng rộng (wide) sang dạng dài (long format)

  • Dòng lệnh (4): Khởi tạo biểu đồ ggplot với trục x là Gia_tri (giá trị tăng trưởng) và màu sắc (color) thể hiện từng biến trong nhóm Bien.

  • Dòng lệnh (5): Sử dụng stat_ecdf(geom = “step”, linewidth = 1) để vẽ đường phân phối tích lũy thực nghiệm (ECDF) cho hai biến tăng trưởng.

  • Dòng lệnh (6): để hiển thị trục x dưới dạng phần trăm (%), phù hợp vì hai biến đều biểu diễn tốc độ tăng trưởng.

  • Dòng lệnh (7): để chọn bảng màu tương phản rõ, giúp hai đường ECDF dễ phân biệt.

Kết quả

Biểu đồ ECDF trên thể hiện so sánh phân phối tích lũy của tốc độ tăng trưởng tổng tài sản (Tangtruong_TS) và tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST).

Ta thấy đường màu cam (tăng trưởng tài sản) nằm phía trên đường màu xanh (tăng trưởng lợi nhuận) ở phần lớn các mức giá trị, điều này cho thấy phân phối tăng trưởng tài sản có xu hướng cao hơn, hoặc ổn định hơn so với tăng trưởng lợi nhuận. Nói cách khác, trong khi tài sản của các doanh nghiệp tăng tương đối đều, thì lợi nhuận sau thuế có mức biến động lớn hơn.

Sự khác biệt này phản ánh thực tế rằng tăng trưởng lợi nhuận chịu ảnh hưởng mạnh từ hiệu quả hoạt động kinh doanh và chi phí, trong khi tăng trưởng tài sản phần lớn phụ thuộc vào mở rộng quy mô đầu tư. Biểu đồ ECDF giúp minh họa rõ ràng sự khác biệt trong phân phối và mức độ ổn định giữa hai chỉ tiêu tài chính này.

4.4.7 Facet scatter: NIM ~ Vongquay_CVKH theo 2 phân tổ

Đoạn mã này tạo ra một biểu đồ scatter plot với đường hồi quy tuyến tính (linear regression) để so sánh biên lãi ròng (NIM) và vòng quay cho vay khách hàng (Vongquay_CVKH) của Vietcombank.

Mục tiêu của biểu đồ là đánh giá mối quan hệ giữa khả năng sinh lời từ tín dụng (NIM) và hiệu quả sử dụng vốn cho vay (Vongquay_CVKH) trong các giai đoạn tăng trưởng tài chính khác nhau.

1. ggplot(VCBbctc, aes(x = Vongquay_CVKH, y = NIM, color = Nhom_Tangtruong_TS)) +
2.   geom_point(size = 3, alpha = 0.8) +
3.   geom_smooth(method = "lm", se = FALSE) +
4.   facet_wrap(~ Nhom_Tangtruong_LNST) +
5.   scale_y_continuous(labels = percent) +
6.   labs(title = "NIM và Vòng quay cho vay theo 2 phân tổ TT",
7.        subtitle = "Màu: tăng trưởng TTS|Facet: nhóm tăng trưởng LNST",
8.        x = "Vòng quay cho vay KH", y = "NIM") +
9.   theme_minimal(base_size = 12) +
10.   theme(legend.position = "top")

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo ggplot với dữ liệu VCBbctc, trục x là Vongquay_CVKH, trục y là NIM, và color phân biệt theo nhóm tăng trưởng tổng tài sản. Thiết lập này cho phép quan sát mối tương quan giữa hiệu suất cho vay và biên lãi ròng theo từng nhóm TTS.

  • Dòng lệnh (2): vẽ đám mây điểm biểu diễn từng quan sát, kích thước vừa phải và độ trong suốt cao giúp giảm chồng lấn, đảm bảo dễ nhìn ngay cả khi dữ liệu dày.

  • Dòng lệnh (3): thêm đường hồi quy tuyến tính cho từng nhóm màu, mô tả xu hướng tuyến tính giữa NIM và Vòng quay cho vay; tắt se để loại bỏ dải tin cậy, giữ biểu đồ gọn.

  • Dòng lệnh (4): chia biểu đồ thành các ô con (facet) theo từng nhóm tăng trưởng lợi nhuận sau thuế (LNST), cho phép so sánh xu hướng giữa các nhóm.

  • Dòng lệnh (5): định dạng trục tung (NIM) theo phần trăm để người đọc dễ hiểu mức chênh lệch biên lãi.

Kết quả

Biểu đồ thể hiện mối quan hệ giữa NIM (biên lãi ròng)vòng quay cho vay khách hàng khi phân tổ theo hai chiều: nhóm tăng trưởng tổng tài sản (TTS) và nhóm tăng trưởng lợi nhuận sau thuế (LNST).

Quan sát cho thấy xu hướng khá rõ: trong mỗi nhóm LNST (Thấp – TB – Cao), các ngân hàng có vòng quay cho vay cao hơn thường đạt NIM lớn hơn, đặc biệt ở nhóm tăng trưởng LNST trung bình. Điều này cho thấy hiệu quả sử dụng vốn tín dụng có mối liên hệ thuận với biên lãi ròng – ngân hàng quay vòng vốn nhanh thường tối ưu hóa được lợi suất tài sản sinh lãi.

Tuy nhiên, khi xét giữa các nhóm LNST, ta thấy sự phân hóa: nhóm LNST cao có NIM biến động mạnh hơn (dao động khoảng 2.3–2.9%), phản ánh chiến lược tín dụng linh hoạt nhưng tiềm ẩn rủi ro biên lợi nhuận không ổn định. Trong khi đó, nhóm trung bình duy trì cân bằng giữa vòng quay và NIM, gợi ý một mô hình tăng trưởng bền vững hơn. Tổng thể, biểu đồ chỉ ra rằng tốc độ luân chuyển vốn và mức sinh lời trên tài sản có mối tương quan tích cực, song hiệu quả này phụ thuộc vào giai đoạn tăng trưởng lợi nhuận của ngân hàng.

4.4.8 Lollipop theo năm: DE (hoặc chỉ tiêu khác)

Biểu đồ Lollipop (biểu đồ que lollipop) này được sử dụng để trực quan hóa Đòn bẩy tài chính (DE) của Vietcombank qua các năm.

Biểu đồ lollipop là một biến thể của biểu đồ cột, nhưng thay vì dùng các cột, nó sử dụng đoạn thẳng với điểm đánh dấu ở cuối để thể hiện các giá trị.

1. df_lp <- VCBbctc %>% arrange(DE)
2. ggplot(df_lp, aes(x = reorder(as.factor(Nam), DE), y = DE)) +
3.   geom_segment(aes(xend = as.factor(Nam), y = 0, yend = DE), color = "grey70") +
4.   geom_point(size = 3, color = "#A04000") +
5.   coord_flip() +
6.   labs(title = "Lollipop – DE theo năm",
7.        x = "Năm", y = "DE (lần)") +
8.   theme_minimal(base_size = 13)

Giải thích kỹ thuật

  • Dòng lệnh (1): Sắp xếp bảng VCBbctc theo Đòn bẩy tài chính (DE), từ nhỏ đến lớn. Điều này đảm bảo rằng biểu đồ lollipop sẽ vẽ các đoạn từ thấp đến cao.

  • Dòng lệnh (2): Trục x đại diện cho năm (Nam), được sắp xếp lại theo giá trị DE từ thấp đến cao. Trục y là Đòn bẩy tài chính (DE).

  • Dòng lệnh (3): vẽ các đoạn thẳng từ y = 0 đến y = DE cho mỗi năm, giống như phần thân của một chiếc que lollipop, color = “grey70” tạo màu xám cho các đoạn thẳng để chúng không làm mất sự chú ý vào các điểm dữ liệu chính.

  • Dòng lệnh (4): vẽ các điểm ở cuối mỗi đoạn thẳng (lollipop), đại diện cho giá trị DE của mỗi năm, size = 3 điều chỉnh kích thước điểm và color = “#A04000” là màu sắc của điểm.

Kết quả

Biểu đồ trên thể hiện tỷ lệ nợ trên vốn chủ sở hữu (DE) của các ngân hàng qua các năm dưới dạng biểu đồ Lollipop (biểu đồ que kẹo).

Quan sát cho thấy DE có xu hướng giảm dần qua thời gian. Cụ thể, năm 2017 tỷ lệ DE đạt mức cao nhất (xấp xỉ 18 lần), sau đó giảm dần qua các năm và đến năm 2024 chỉ còn khoảng 10 lần. Xu hướng này phản ánh sự cải thiện trong cấu trúc tài chính của các ngân hàng, khi mức độ sử dụng đòn bẩy tài chính (nợ vay) ngày càng giảm so với vốn chủ sở hữu.

Điều này cho thấy các ngân hàng có thể đang tăng cường vốn tự có hoặc kiểm soát nợ vay tốt hơn, góp phần giảm rủi ro tài chính và tăng khả năng tự chủ vốn. Ngoài ra, xu hướng giảm liên tục cũng cho thấy chính sách quản trị rủi ro và tuân thủ quy định an toàn vốn (như Basel II, Basel III) được thực hiện nghiêm túc hơn trong giai đoạn gần đây.

Tóm lại, biểu đồ thể hiện một tín hiệu tích cực về an toàn tài chính, khi các ngân hàng dần chuyển dịch từ tăng trưởng dựa trên nợ sang phát triển bền vững dựa trên vốn chủ sở hữu.

4.4.9 Tacked 100%: cơ cấu nhóm tăng trưởng LNST trong từng nhóm tăng trưởng TS

Đoạn mã này tạo ra một biểu đồ stacked bar chart (biểu đồ cột chồng) để thể hiện tỷ trọng các nhóm tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST) trong từng nhóm tăng trưởng tổng tài sản (Tangtruong_TTS) của Vietcombank.

Mục tiêu là phân tích mối quan hệ giữa hai phân tổ tăng trưởng này, từ đó đánh giá sự phân bổ lợi nhuận trong các giai đoạn tăng trưởng tài sản khác nhau.

1. tab <- as.data.frame(table(VCBbctc$Nhom_Tangtruong_TS, VCBbctc$Nhom_Tangtruong_LNST))
2. names(tab) <- c("Nhom_TS", "Nhom_LNST", "n")
3. ggplot(tab, aes(x = Nhom_TS, y = n, fill = Nhom_LNST)) +
4.   geom_bar(stat = "identity", position = "fill") +
5.   scale_y_continuous(labels = percent) +
6.   scale_fill_brewer(palette = "Set2") +
7.   labs(title = "Tỷ trọng tăng trưởng LNST trong TTS",
8.        x = "Nhóm tăng trưởng TTS", y = "Tỷ trọng", fill = "Nhóm tăng trưởng LNST") +
9.   theme_minimal(base_size = 12)

Giải thích kỹ thuật

  • Dòng lệnh (1): Tạo bảng tần suất chéo giữa hai biến Nhom_Tangtruong_TS và Nhom_Tangtruong_LNST bằng hàm table(), sau đó chuyển kết quả sang dạng data.frame để có thể thao tác dễ dàng trong ggplot. Mỗi hàng của bảng biểu diễn một cặp nhóm tăng trưởng tổng tài sản và lợi nhuận sau thuế, cùng với tần suất xuất hiện tương ứng.

  • Dòng lệnh (2): Đặt lại tên ba cột của bảng là Nhom_TS, Nhom_LNST và n, tương ứng với nhóm tăng trưởng tổng tài sản, nhóm tăng trưởng lợi nhuận sau thuế, và số lượng quan sát trong từng cặp nhóm.

  • Dòng lệnh (3): Khởi tạo biểu đồ ggplot với trục x là Nhom_TS (các nhóm tăng trưởng TTS), trục y là n (số lượng), và fill thể hiện nhóm tăng trưởng LNST, nhằm so sánh tỷ trọng LNST trong từng nhóm TTS.

  • Dòng lệnh (4): vẽ biểu đồ cột chồng, chuẩn hóa tổng chiều cao mỗi cột bằng 1 (100%) để biểu diễn tỷ trọng phần trăm thay vì số lượng tuyệt đối.

  • Dòng lệnh (5): định dạng trục tung hiển thị dưới dạng phần trăm, giúp người xem dễ hiểu ý nghĩa “tỷ trọng” giữa các nhóm.

  • Dòng lệnh (6): sử dụng bảng màu “Set2” có tông màu nhẹ và phân biệt tốt, giúp nhận diện các nhóm LNST rõ ràng mà vẫn hài hòa.

Kết quả

Biểu đồ trên thể hiện tỷ trọng các nhóm tăng trưởng lợi nhuận sau thuế (LNST) trong từng nhóm tăng trưởng tổng tài sản (TTS), qua đó giúp so sánh mối quan hệ giữa hai khía cạnh tăng trưởng này.

Ta thấy rằng:

  • Ở nhóm tăng trưởng TTS thấp, phần lớn các ngân hàng thuộc nhóm LNST thấp và trung bình, trong khi tỷ trọng nhóm LNST cao còn hạn chế. Điều này cho thấy khi quy mô tài sản tăng chậm, khả năng sinh lời cũng thường bị hạn chế.

  • Ở nhóm tăng trưởng TTS trung bình, cơ cấu phân bố trở nên cân bằng hơn giữa ba nhóm LNST, phản ánh mức độ đa dạng trong hiệu quả hoạt động của các ngân hàng. Một số ngân hàng có thể vẫn duy trì tăng trưởng lợi nhuận khá dù tổng tài sản không tăng mạnh.

  • Ở nhóm tăng trưởng TTS cao, tỷ trọng nhóm LNST cao chiếm ưu thế nổi bật. Đây là dấu hiệu tích cực cho thấy mối quan hệ đồng biến giữa mở rộng quy mô tài sản và khả năng sinh lời, tức là những ngân hàng có tốc độ tăng trưởng tài sản nhanh cũng thường đạt được hiệu quả kinh doanh cao hơn.

Tổng thể, biểu đồ này cho thấy sự gắn kết giữa tăng trưởng quy mô và lợi nhuận, đồng thời gợi ý rằng các ngân hàng duy trì được tăng trưởng tổng tài sản ổn định và hiệu quả sử dụng vốn tốt sẽ có xác suất cao nằm trong nhóm lợi nhuận tăng trưởng mạnh.

4.4.10 Ridge/violin thay thế: phân bố NIM theo nhóm tăng trưởng LNST

Biểu đồ violin kết hợp với boxplot này giúp phân tích biên lãi ròng (NIM) theo các nhóm tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST) của Vietcombank.

Mục tiêu của biểu đồ là so sánh sự phân bố và mức độ sinh lời (NIM) của các nhóm tăng trưởng lợi nhuận, giúp hiểu rõ hơn về hiệu quả sử dụng vốn cho vay trong các giai đoạn tăng trưởng lợi nhuận khác nhau.

1. ggplot(VCBbctc, aes(x = Nhom_Tangtruong_LNST, y = NIM, fill = Nhom_Tangtruong_LNST)) +
2.   geom_violin(alpha = 0.6, color = "grey40", trim = TRUE) +
3.   geom_boxplot(width = 0.1, fill = "white", outlier.shape = NA) +
4.   stat_summary(fun = mean, geom = "point", size = 2.5, color = "red") +
5.   scale_y_continuous(labels = percent) +
6.   scale_fill_brewer(palette = "Pastel2") +
7.   labs(title = "Phân bố NIM theo nhóm tăng trưởng LNST",
8.        x = "Nhóm tăng trưởng LNST", y = "NIM") +
9.   theme_minimal(base_size = 13) +
10.   theme(legend.position = "none")

Giải thích kỹ thuật

  • Dòng lệnh (1): Dữ liệu được lấy từ VCBbctc, với trục x là nhóm tăng trưởng lợi nhuận sau thuế (Nhom_Tangtruong_LNST) và trục y là Biên lãi ròng (NIM), fill = Nhom_Tangtruong_LNST phân biệt các nhóm tăng trưởng lợi nhuận với các màu sắc khác nhau.

  • Dòng lệnh (2): Vẽ biểu đồ violin cho NIM trong từng nhóm tăng trưởng lợi nhuận. Biểu đồ violin thể hiện phân phối dữ liệu theo dạng đối xứng, giúp nhận diện dải giá trị của NIM trong các nhóm, alpha = 0.6 điều chỉnh độ trong suốt của hình violin, và color = “grey40” thêm viền màu xám cho các hình violin, trim = TRUE cắt phần dữ liệu ngoài phạm vi phân phối.

  • Dòng lệnh (3): thêm boxplot vào biểu đồ violin, width = 0.1 điều chỉnh độ rộng của boxplot, fill = “white” làm phần bên trong của boxplot trắng, và outlier.shape = NA loại bỏ các điểm ngoại lai khỏi boxplot.

  • Dòng lệnh (4): tính toán trung bình (mean) của NIM trong từng nhóm và vẽ một điểm màu đỏ ở vị trí trung bình trên boxplot, size = 2.5 điều chỉnh kích thước của điểm trung bình và color = “red” chỉ định màu sắc của điểm.

  • Dòng lệnh (5): Định dạng trục y dưới dạng tỷ lệ phần trăm để dễ dàng so sánh Biên lãi ròng (NIM) dưới dạng tỷ lệ phần trăm.

  • Dòng lệnh (6): Sử dụng bảng màu Pastel2 từ ColorBrewer để phân biệt các nhóm tăng trưởng lợi nhuận với các màu sắc dễ nhìn.

Kết quả

Biểu đồ trên thể hiện phân bố biên lợi nhuận lãi ròng (NIM) theo từng nhóm tăng trưởng lợi nhuận sau thuế (LNST), qua đó giúp đánh giá mối liên hệ giữa khả năng sinh lời từ hoạt động cho vay và mức tăng trưởng lợi nhuận của các ngân hàng.

Cụ thể:

Nhóm LNST thấp có phân bố NIM khá hẹp và tập trung quanh mức 2,6–2,8%, cho thấy các ngân hàng trong nhóm này có hiệu quả sinh lời từ lãi khá ổn định nhưng chưa nổi bật.

Nhóm LNST trung bình có trung vị NIM cao nhất, khoảng gần 2,9%, đồng thời độ biến thiên thấp, phản ánh rằng các ngân hàng có lợi nhuận tăng trưởng ổn định thường đạt hiệu quả sinh lời từ lãi cao và bền vững.

Nhóm LNST cao lại có NIM trung bình thấp hơn một chút, dù phạm vi phân bố khá hẹp. Điều này có thể do các ngân hàng trong nhóm này đạt tăng trưởng lợi nhuận cao nhờ các yếu tố khác như quy mô tín dụng, thu nhập ngoài lãi, hoặc kiểm soát chi phí hiệu quả, chứ không chỉ dựa vào biên lợi nhuận lãi.

Như vậy, biểu đồ cho thấy mối liên hệ giữa NIM và tăng trưởng LNST không hoàn toàn tuyến tính. Các ngân hàng có mức tăng trưởng lợi nhuận trung bình thường đạt hiệu quả sinh lời từ lãi tốt nhất, trong khi nhóm tăng trưởng cao có thể tận dụng các nguồn thu khác ngoài lãi để thúc đẩy lợi nhuận.

4.4.11 Density CAR theo nhóm tăng trưởng LNST + đường mean toàn mẫu

Đoạn mã này tạo ra một biểu đồ density plot (biểu đồ mật độ) để phân tích tỷ lệ an toàn vốn (CAR) của Vietcombank theo các nhóm tăng trưởng lợi nhuận sau thuế (Tangtruong_LNST).

Biểu đồ mật độ giúp bạn hiểu rõ hơn về phân bố của CAR trong các nhóm tăng trưởng lợi nhuận, từ đó phân tích mức độ an toàn tài chính của ngân hàng trong các giai đoạn tăng trưởng lợi nhuận khác nhau.

1. df_nv <- VCBbctc %>%
2.   transmute(Nam, Tytrong_VCSH, Tytrong_No = 1 - Tytrong_VCSH) %>%
3.   tidyr::pivot_longer(-Nam, names_to = "Thanh_phan", values_to = "Ty_trong")
4. ggplot(VCBbctc, aes(x = CAR, fill = Nhom_Tangtruong_LNST)) +
5.   geom_density(alpha = 0.5) +
6.   geom_vline(xintercept = mean(VCBbctc$CAR, na.rm = TRUE), color = "black", linetype = "dotted") +
7.   scale_x_continuous(labels = scales::percent) +
8.   labs(title = "Mật độ CAR theo nhóm tăng trưởng LNST", x = "CAR", fill = "Nhóm LNST") +
9.   theme_minimal(base_size = 12) +
10.   theme(legend.position = "top")

Giải thích kỹ thuật

  • Dòng lệnh (1): Dữ liệu từ VCBbctc được sử dụng để vẽ biểu đồ, với tỷ lệ an toàn vốn (CAR) trên trục x và màu sắc phân biệt theo nhóm tăng trưởng lợi nhuận (Nhom_Tangtruong_LNST).

  • Dòng lệnh (2): vẽ biểu đồ mật độ của CAR, giúp nhận diện phân bố mật độ của chỉ số này trong các nhóm.

  • Dòng lệnh (3): geom_vline() thêm một đường thẳng dọc tại trung bình của CAR, color = “black” làm đường thẳng có màu đen và linetype = “dotted” vẽ đường dưới dạng gạch chấm.

  • Dòng lệnh (4): Định dạng trục x dưới dạng tỷ lệ phần trăm (percent), giúp đọc và so sánh các giá trị CAR dễ dàng hơn.

  • Dòng lệnh (5): Thêm tiêu đề cho biểu đồ và nhãn cho các trục x và fill (chú giải màu sắc), giúp giải thích rõ ràng các yếu tố trong biểu đồ.

  • Dòng lệnh (7): Đặt chú giải (legend) ở phía trên của biểu đồ để dễ dàng phân biệt các nhóm tăng trưởng lợi nhuận.

Kết luận

Biểu đồ trên thể hiện phân bố mật độ của tỷ lệ an toàn vốn (CAR) theo từng nhóm tăng trưởng lợi nhuận sau thuế (LNST), qua đó phản ánh mối quan hệ giữa khả năng duy trì vốn tự có và tốc độ tăng trưởng lợi nhuận của các ngân hàng. Cụ thể:

  • Nhóm LNST thấp (màu đỏ) có CAR cao nhất, chủ yếu dao động trong khoảng 8–9%. Điều này cho thấy các ngân hàng có lợi nhuận tăng trưởng thấp thường duy trì tỷ lệ an toàn vốn cao hơn mức trung bình, phản ánh chiến lược thận trọng trong quản trị rủi ro và xu hướng hạn chế mở rộng tín dụng để bảo toàn vốn. Tuy nhiên, mức CAR cao cũng đồng nghĩa với việc khả năng sinh lời từ vốn chủ chưa được khai thác tối ưu.

  • Nhóm LNST trung bình (màu xanh lá) có phân bố CAR tập trung quanh mức 6,5–7,5%, với mật độ đỉnh cao nhất, thể hiện rằng phần lớn các ngân hàng trong nhóm này đạt được cân bằng hợp lý giữa an toàn vốn và hiệu quả sinh lời. Đây là nhóm có cấu trúc vốn tối ưu nhất, vừa duy trì an toàn tài chính, vừa hỗ trợ tăng trưởng lợi nhuận ổn định.

  • Ngược lại, nhóm LNST cao (màu xanh dương) có CAR trung bình thấp nhất, chủ yếu nằm trong khoảng 5,5–6,5%, cho thấy các ngân hàng đạt tăng trưởng lợi nhuận mạnh thường chấp nhận tỷ lệ an toàn vốn thấp hơn để mở rộng tín dụng và gia tăng lợi nhuận. Điều này phản ánh chiến lược tăng trưởng tích cực, dù tiềm ẩn rủi ro cao hơn về mặt an toàn vốn.

Như vậy, biểu đồ cho thấy mối quan hệ nghịch chiều giữa CAR và tăng trưởng LNST: các ngân hàng tăng trưởng lợi nhuận cao thường có CAR thấp hơn, trong khi các ngân hàng duy trì CAR cao lại có tốc độ tăng trưởng lợi nhuận khiêm tốn. Xu hướng này phù hợp với đặc điểm của ngành ngân hàng, nơi việc cân đối giữa an toàn vốn và hiệu quả sinh lời luôn là yếu tố trọng tâm trong chiến lược quản trị tài chính.

4.4.12 Stacked area cấu trúc nguồn vốn theo năm (VCSH vs NPT)

Đoạn mã tạo ra một stacked area chart để phân tích cấu trúc nguồn vốn của Vietcombank qua các năm, với tỷ trọng vốn chủ sở hữu (Tytrong_VCSH) và tỷ trọng nợ (Tytrong_No).

Mục tiêu của biểu đồ là so sánh sự thay đổi của tỷ trọng nợ và vốn chủ sở hữu trong tổng nguồn vốn qua các năm.

1. ggplot(df_nv, aes(Nam, Ty_trong, fill = Thanh_phan)) +
2.   geom_area(alpha = 0.85) +
3.   scale_y_continuous(labels = scales::percent) +
4.   scale_fill_brewer(palette = "Set2") +
5.   geom_point(aes(color = Thanh_phan),   
6.              position = position_stack(vjust = 0.98),
7.              size = 2) +
8.   scale_color_manual(values = c("Tytrong_VCSH" = "#FF5733",  # đỏ cam
9.                                 "Tytrong_No"   = "#6AAED6")) +  # xanh lam
10.   labs(title = "Cấu trúc nguồn vốn theo thời gian",
11.        x = "Năm", y = "Tỷ trọng") +
12.   theme_minimal(base_size = 12) +
13.   theme(axis.text.x = element_text(angle = 60, hjust = 1))

Giải thích kỹ thuật

-Dòng (1): Khởi tạo đối tượng ggplot từ dữ liệu df_nv, với trục hoành (x) là Nam, trục tung (y) là Ty_trong, và fill = Thanh_phan để tô màu vùng diện tích theo từng thành phần nguồn vốn (vốn chủ sở hữu hoặc nợ).

-Dòng (2): vẽ biểu đồ diện tích chồng (stacked area chart), trong đó alpha = 0.85 tạo độ trong suốt giúp phân biệt rõ các lớp chồng nhau.

-Dòng (3): định dạng trục tung hiển thị dưới dạng phần trăm, giúp so sánh dễ dàng tỷ trọng của từng thành phần.

-Dòng (4): áp dụng bảng màu “Set2” từ ColorBrewer để tô các vùng diện tích bằng màu sắc hài hòa và dễ nhận diện.

-Dòng (5), (6) và (7): thêm các điểm đánh dấu vào biểu đồ, mỗi điểm đại diện cho tỷ trọng tại từng năm; màu điểm được phân biệt theo Thanh_phan; position_stack(vjust = 0.98) đặt các điểm sát mép trên mỗi vùng để không bị che khuất.

-Dòng (8) và (9): tùy chỉnh màu của các điểm — Tytrong_VCSH là đỏ cam, Tytrong_No là xanh lam — tạo điểm nhấn trực quan rõ ràng giữa hai loại nguồn vốn.

Kết luận

Biểu đồ “Cấu trúc nguồn vốn theo thời gian” cho thấy tỷ trọng nợ phải trả (màu xanh)vốn chủ sở hữu (màu cam) trong tổng nguồn vốn duy trì tương đối ổn định qua giai đoạn 2015–2024. Tỷ trọng nợ luôn chiếm ưu thế áp đảo, dao động quanh mức gần 90–92%, trong khi vốn chủ sở hữu chỉ chiếm khoảng 8–10%.

Điều này phản ánh cơ cấu tài chính của ngân hàng vẫn dựa chủ yếu vào nguồn vốn huy động bên ngoài (nợ), còn vốn tự có tăng chậm và chiếm tỷ trọng nhỏ. Mặc dù xu hướng có cải thiện nhẹ ở giai đoạn cuối (2023–2024), nhưng mức thay đổi không đáng kể, cho thấy chính sách sử dụng đòn bẩy tài chính cao vẫn là đặc trưng trong giai đoạn này.

4.4.13 Slopegraph: NIM & DE (so sánh năm đầu–cuối)

Đoạn mã này tạo ra một slope graph (biểu đồ độ dốc) để phân tích biến động NIM và DE của Vietcombank từ năm đầu tiên đến năm cuối cùng trong dữ liệu.

Biểu đồ độ dốc này giúp trực quan hóa sự thay đổi của NIM (Biên lãi ròng) và DE (Đòn bẩy tài chính) qua thời gian, giúp bạn dễ dàng nhận diện mức độ thay đổi của các chỉ tiêu tài chính này trong suốt quá trình phân tích.

1. df_slope <- VCBbctc %>%
2.   slice(c(1, n())) %>%
3.   select(Nam, NIM, DE) %>%
4.   tidyr::pivot_longer(-Nam, names_to = "Bien", values_to = "Gia_tri")
5. ggplot(df_slope, aes(x = as.factor(Nam), y = Gia_tri, group = Bien, color = Bien)) +
6.   geom_point(size = 3) +
7.   geom_line(linewidth = 1.2) +
8.   geom_text(aes(label = scales::percent(Gia_tri, accuracy = 0.01)),
9.             vjust = -1, size = 3) +
10.   scale_y_continuous(labels = scales::percent) +
11.   labs(title = "Slopegraph: biến động NIM và DE (năm đầu ↔ năm cuối)",
12.        x = "Năm", y = "Giá trị") +
13.   theme_minimal(base_size = 12) +
14.   theme(legend.title = element_blank())

Giải thích kỹ thuật

  • Đoạn lệnh từ (1) đến (4): slice(c(1, n())): Lấy năm đầu tiên (dòng đầu) và năm cuối cùng (dòng cuối) từ dữ liệu, select(Nam, NIM, DE): Chỉ chọn các cột Nam, NIM, DE. Dòng lệnh (4) dùng để chuyển dữ liệu từ dạng rộng sang dạng dài, tạo hai cột mới: Bien (biến “NIM” hoặc “DE”) và Gia_tri .

  • Dòng lệnh (5): Dữ liệu từ df_slope được sử dụng để vẽ biểu đồ với trục x là Năm (Nam), trục y là giá trị (Gia_tri), và màu sắc phân biệt theo biến (NIM và DE).

  • Dòng lệnh (7): vẽ các điểm dữ liệu cho NIM và DE trong năm đầu và năm cuối, giúp nhận diện sự thay đổi của các giá trị này qua các năm và size = 3 điều chỉnh kích thước của các điểm.

  • Dòng lệnh (8): vẽ đường nối các điểm cho mỗi biến (NIM và DE) để thể hiện sự thay đổi qua các năm và điều chỉnh độ dày của đường nối.

  • Đoạn lệnh (9) và (10): thêm nhãn cho mỗi điểm trên đồ thị, thể hiện giá trị của NIM và DE dưới dạng tỷ lệ phần trăm (sử dụng scales::percent() để định dạng) và điều chỉnh vị trí của nhãn sao cho không bị che khuất bởi các điểm, và size = 3 điều chỉnh kích thước chữ của nhãn.

  • Dòng lệnh (11): Định dạng trục y dưới dạng tỷ lệ phần trăm, giúp dễ dàng đọc các giá trị NIM và DE dưới dạng tỷ lệ phần trăm.

Kết quả

Biểu đồ Slopegraph thể hiện biến động của hai chỉ tiêu tài chính quan trọng là tỷ lệ NIM (Net Interest Margin)hệ số nợ trên vốn chủ sở hữu (DE) trong giai đoạn 2015–2024. NIM cho thấy mức sinh lời từ tài sản sinh lãi, còn DE phản ánh mức độ sử dụng đòn bẩy tài chính trong cấu trúc nguồn vốn của ngân hàng.

Trong giai đoạn này, NIM tăng nhẹ từ 2,29% lên 2,66%, thể hiện sự cải thiện nhỏ trong hiệu quả sinh lời từ hoạt động cho vay và đầu tư tài chính. Mức tăng tuy không lớn, nhưng cho thấy ngân hàng đã duy trì được khả năng tạo lợi nhuận ổn định trong bối cảnh thị trường cạnh tranh và chi phí vốn có thể biến động.

Ngược lại, hệ số DE giảm mạnh từ 1.392,94% xuống còn 963,09%, cho thấy xu hướng giảm dần mức độ phụ thuộc vào nợ vay và tăng cường vốn chủ sở hữu. Đây là tín hiệu tích cực, phản ánh ngân hàng đang điều chỉnh cấu trúc tài chính theo hướng an toàn hơn, giảm rủi ro tài chính và củng cố năng lực vốn nhằm đảm bảo tính bền vững trong dài hạn.

4.4.14 Dot + errorbar: NIM theo nhóm tăng trưởng TTS (mean ± sd)

Đoạn mã này tạo ra một biểu đồ để phân tích NIM trung bình và độ lệch chuẩn của Vietcombank theo các nhóm tăng trưởng tổng tài sản (Nhom_Tangtruong_TS).

Biểu đồ này giúp chúng ta so sánh sự biến động trong biên lãi ròng (NIM) của các nhóm tăng trưởng tài sản khác nhau, đồng thời đánh giá mức độ rủi ro (được thể hiện qua độ lệch chuẩn) và hiệu quả tài chính của ngân hàng.

1. df_nim <- VCBbctc %>%
2.   group_by(Nhom_Tangtruong_TS) %>%
3.   summarise(meanNIM = mean(NIM, na.rm = TRUE),
4.             sdNIM = sd(NIM, na.rm = TRUE), .groups = "drop")
5. ggplot(df_nim, aes(x = Nhom_Tangtruong_TS, y = meanNIM)) +
6.   geom_errorbar(aes(ymin = meanNIM - sdNIM, ymax = meanNIM + sdNIM), width = 0.15) +
7.   geom_point(size = 3, color = "#A04000") +
8.   scale_y_continuous(labels = scales::percent) +
9.   labs(title = "NIM trung bình và độ lệch chuẩn theo TTS",
10.        x = "Nhóm TTS", y = "NIM") +
11.   theme_minimal(base_size = 12)

Giải thích kỹ thuật

  • Đoạn lệnh từ (1) đến (4):
  1. Nhóm dữ liệu theo Nhóm tăng trưởng tổng tài sản (Nhom_Tangtruong_TS).

  2. Tính toán NIM trung bình (meanNIM) và độ lệch chuẩn (sdNIM) của NIM trong mỗi nhóm.

  3. na.rm = TRUE giúp loại bỏ các giá trị thiếu (NA) trong khi tính toán.

  4. groups = “drop” loại bỏ thông tin nhóm sau khi tính toán.

  • Dòng lệnh (5): Dữ liệu từ df_nim được sử dụng để vẽ biểu đồ với trục x là nhóm tăng trưởng tài sản (Nhom_Tangtruong_TS) và trục y là NIM trung bình (meanNIM).

  • Dòng lệnh (6): vẽ các đoạn sai số cho mỗi nhóm, với độ lệch chuẩn được tính từ meanNIM ± sdNIM và điều chỉnh độ rộng của thanh sai số.

  • Dòng lệnh (7): geom_point() vẽ các điểm dữ liệu tại các NIM trung bình cho từng nhóm, với màu sắc #A04000 và kích thước 3.

Kết quả

Biểu đồ trên thể hiện giá trị trung bình và độ lệch chuẩn của NIM theo nhóm tăng trưởng tổng tài sản (TTS), giúp đánh giá mối quan hệ giữa hiệu quả sinh lời từ lãi và quy mô tăng trưởng.

Nhóm TTS trung bình có NIM cao nhất (~2,75%) và ổn định nhất, phản ánh sự cân bằng giữa mở rộng quy mô và quản lý chi phí vốn. Nhóm TTS thấp có NIM tương đương nhưng biến động lớn hơn, cho thấy hiệu quả sinh lời chưa đồng đều. Ngược lại, nhóm TTS cao có NIM thấp nhất (~2,5%) và dao động mạnh, cho thấy biên lãi kém ổn định do ưu tiên tăng trưởng nhanh.

Tổng thể, ngân hàng có tăng trưởng tài sản trung bình đạt hiệu quả sinh lời từ lãi cao và ổn định nhất, trong khi nhóm tăng trưởng cao hoặc thấp đều biến động nhiều hơn.

4.4.15 Scatter + contour mật độ: NIM ~ DE

Đoạn mã này tạo ra một biểu đồ scatter plot (biểu đồ phân tán) để phân tích mối quan hệ giữa NIM (Biên lãi ròng) và DE (Đòn bẩy tài chính) của Vietcombank. Biểu đồ này còn kết hợp với đường đồng mức mật độ (density contour) và đường hồi quy tuyến tính (linear regression line), giúp bạn nhận diện mối quan hệ giữa NIM và DE cũng như mức độ phân bố của các điểm dữ liệu.

1. ggplot(VCBbctc, aes(x = DE, y = NIM)) +
2.   geom_point(alpha = 0.7, color = "#1F78B4", size = 2.5) +
3.   stat_density2d(aes(fill = after_stat(level)), geom = "polygon", alpha = 0.3) +
4.   scale_fill_viridis_c() +
5.   geom_smooth(method = "lm", se = TRUE, color = "red", linewidth = 0.8) +
6.   scale_y_continuous(labels = scales::percent) +
7.   labs(title = "Quan hệ NIM và DE với đường đồng mức mật độ",
8.        x = "DE (lần)", y = "NIM") +
9.   theme_minimal(base_size = 12)

Giải thích kỹ thuật

  • Dòng lệnh (2): vẽ các điểm dữ liệu trên biểu đồ phân tán, mỗi điểm đại diện cho một cặp giá trị DE và NIM, alpha = 0.7 điều chỉnh độ trong suốt của các điểm, giúp bạn dễ dàng nhìn thấy các điểm phía sau.

  • Dòng lệnh (3): vẽ đường đồng mức mật độ (density contour) thể hiện sự phân bố mật độ của các điểm dữ liệu trong không gian DE và NIM, aes(fill = after_stat(level)) giúp tô màu các khu vực có mật độ điểm cao bằng các mức độ mật độ khác nhau, geom = “polygon” sử dụng các đa giác để vẽ các đường đồng mức mật độ,

  • Dòng lệnh (4): scale_fill_viridis_c() áp dụng bảng màu Viridis để tô màu các khu vực mật độ. Viridis là một bảng màu dễ đọc và phân biệt được giữa các mức độ mật độ.

  • Dòng lệnh (5): vẽ một đường hồi quy tuyến tính (linear regression line) để thể hiện mối quan hệ giữa DE và NIM, method = “lm” chỉ ra rằng phương pháp sử dụng là hồi quy tuyến tính, se = TRUE hiển thị vùng độ tin cậy của hồi quy (confidence interval) xung quanh đường hồi quy.

  • Dòng lệnh (6): Định dạng trục y dưới dạng tỷ lệ phần trăm (percent), giúp dễ dàng đọc và so sánh các giá trị NIM.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa biên lợi nhuận lãi ròng (NIM) và tỷ lệ nợ trên vốn chủ sở hữu (DE) của các ngân hàng, kèm theo đường đồng mức mật độ thể hiện vùng tập trung dữ liệu và đường hồi quy tuyến tính (màu đỏ) mô tả xu hướng chung.

Quan sát cho thấy, NIM có xu hướng giảm dần khi DE tăng, thể hiện mối quan hệ nghịch chiều giữa hai biến. Các ngân hàng có tỷ lệ nợ trên vốn chủ cao thường ghi nhận biên lợi nhuận lãi ròng thấp hơn, hàm ý rằng mức độ sử dụng đòn bẩy tài chính lớn có thể làm giảm hiệu quả sinh lời từ lãi. => Nguyên nhân có thể do chi phí lãi vay cao làm thu hẹp chênh lệch giữa lãi suất đầu ra và đầu vào, hoặc do áp lực duy trì an toàn vốn khiến biên lợi nhuận bị nén lại.

Khu vực mật độ màu xanh–vàng cho thấy phần lớn các quan sát tập trung quanh mức DE từ 11 đến 15 lần và NIM khoảng 2,6–2,9%, là vùng phản ánh mức cân bằng tương đối giữa đòn bẩy tài chính và khả năng sinh lời.

Như vậy, biểu đồ chỉ ra rằng việc gia tăng đòn bẩy tài chính không nhất thiết giúp cải thiện biên lợi nhuận lãi, mà ngược lại, có thể làm suy giảm hiệu quả sinh lời nếu không được quản lý phù hợp. Mối quan hệ âm giữa NIM và DE phản ánh sự đánh đổi giữa rủi ro tài chính và hiệu quả hoạt động, nhấn mạnh tầm quan trọng của việc tối ưu cấu trúc vốn trong ngành ngân hàng.

4.4.16 Heatmap “biến–năm”: z-score các chỉ tiêu chính

Đoạn mã này tạo ra một heatmap (biểu đồ nhiệt độ) để trực quan hóa z-score của các biến tài chính của Vietcombank qua các năm. Các biến được xem xét bao gồm Biên lãi ròng (Bien_LN_rong), NIM (Biên lãi ròng), CAR (Tỷ lệ an toàn vốn), DE (Đòn bẩy tài chính), Tytrong_VCSH (Tỷ trọng vốn chủ sở hữu) và Vongquay_CVKH (Vòng quay cho vay khách hàng).

Biểu đồ giúp bạn đánh giá sự thay đổi của các biến này qua các năm dưới dạng z-score, giúp nhận diện các biến động bất thường hoặc mức độ dao động của các chỉ tiêu tài chính.

1. vars <- c("Bien_LN_rong","NIM","CAR","DE","Tytrong_VCSH","Vongquay_CVKH")
2. df_z <- VCBbctc %>%
3.   select(Nam, all_of(vars)) %>%
4.   tidyr::pivot_longer(-Nam, names_to = "Bien", values_to = "Gia_tri") %>%
5.   group_by(Bien) %>% mutate(z = (Gia_tri - mean(Gia_tri, na.rm = TRUE))/sd(Gia_tri, na.rm = TRUE)) %>% ungroup()
6. ggplot(df_z, aes(x = as.factor(Nam), y = Bien, fill = z)) +
7.   geom_tile(color = "white") +
8.   scale_fill_gradient2(low = "#4575b4", mid = "white", high = "#d73027", limits = c(-2,2)) +
9.   labs(title = "Heatmap z-score theo năm và biến", x = "Năm", y = "Biến", fill = "z") +
10.   theme_minimal(base_size = 12) +
11.   theme(axis.text.x = element_text(angle = 45, hjust = 1))

Giải thích kỹ thuật

  • Dòng lệnh (1): Định nghĩa một danh sách các biến tài chính cần phân tích trong biểu đồ heatmap.

  • Đoạn lệnh từ (2) đến (4):

select(Nam, all_of(vars)): Chọn các cột năm và các biến tài chính được liệt kê trong vars.

pivot_longer(-Nam, names_to = “Bien”, values_to = “Gia_tri”): Chuyển đổi dữ liệu từ dạng rộng sang dạng dài để mỗi dòng đại diện cho một cặp giá trị Năm và Biến với Gia_tri là giá trị của các biến.

group_by(Bien): Nhóm dữ liệu theo các biến để tính toán z-score riêng cho từng biến.

mutate(z = (Gia_tri - mean(Gia_tri, na.rm = TRUE))/sd(Gia_tri, na.rm = TRUE)): Tính z-score cho mỗi biến bằng công thức (Giá trị - Trung bình) / Độ lệch chuẩn, giúp chuẩn hóa dữ liệu và so sánh giữa các biến.

ungroup(): Loại bỏ nhóm để tiếp tục xử lý dữ liệu.

  • Dòng lệnh (6): ggplot() khởi tạo biểu đồ với dữ liệu từ df_z, trong đó trục x là Năm, trục y là Biến và màu sắc fill biểu thị z-score của từng biến.

  • Dòng lệnh (7): vẽ các ô vuông trong heatmap, với màu sắc được phân biệt dựa trên giá trị z-score của từng biến.

  • Dòng lệnh (8): áp dụng bảng màu gradient với ba màu sắc:

+low = “#4575b4” cho các giá trị z-score thấp (màu xanh).

+mid = “white” cho giá trị trung bình (z = 0).

+high = “#d73027” cho các giá trị z-score cao (màu đỏ).

limits = c(-2, 2) thiết lập giới hạn cho z-score từ -2 đến 2, giúp hiển thị rõ ràng các vùng bất thường.

  • Dòng lệnh (11): axis.text.x = element_text(angle = 45, hjust = 1): Xoay nhãn trên trục x (Năm) 45 độ và căn chỉnh chúng cho dễ đọc.

Kết luận

Biểu đồ trên thể hiện heatmap của các giá trị z-score đối với các biến tài chính qua các năm, giúp nhận diện sự biến động tương đối của từng chỉ tiêu so với trung bình toàn kỳ. Màu đỏ thể hiện giá trị cao hơn trung bình, trong khi màu xanh thể hiện giá trị thấp hơn trung bình.

Quan sát chung cho thấy giai đoạn 2015–2017, hầu hết các biến như NIM, CAR và Biên_LN_ròng đều có giá trị z-score âm, phản ánh hiệu quả sinh lời và mức độ an toàn vốn của hệ thống ngân hàng ở mức thấp hơn trung bình. Ngược lại, tỷ lệ DE tăng mạnh trong năm 2017 (ô đỏ đậm), cho thấy mức đòn bẩy tài chính cao, phù hợp với xu hướng mở rộng tín dụng giai đoạn này.

Từ 2019 trở đi, các biến NIM, CAR và Biên_LN_ròng dần chuyển sang vùng đỏ, cho thấy sự cải thiện rõ rệt về khả năng sinh lời và an toàn vốn. Đặc biệt, Biên_LN_ròng tăng liên tục từ năm 2020 đến 2024, đạt mức cao nhất trong giai đoạn nghiên cứu, phản ánh sự phục hồi và tăng trưởng bền vững của ngành ngân hàng.

Ngược lại, DE có xu hướng giảm (chuyển dần sang vùng xanh), cho thấy mức độ sử dụng nợ vay giảm dần, đi kèm với sự tăng lên của tỷ trọng vốn chủ sở hữu (Tytrong_VCSH) – thể hiện xu hướng củng cố năng lực vốn và giảm rủi ro tài chính. Bên cạnh đó, vòng quay CVKH đạt giá trị cao trong các năm gần đây, gợi ý hiệu quả sử dụng vốn lưu động được cải thiện.

Nhìn chung, heatmap cho thấy sự chuyển dịch tích cực của các chỉ tiêu tài chính trong giai đoạn 2015–2024: hiệu quả sinh lời và khả năng an toàn vốn tăng lên, trong khi đòn bẩy tài chính giảm, phản ánh chiến lược tái cấu trúc tài chính bền vững và an toàn hơn của hệ thống ngân hàng.

4.4.17 Stacked 100%: tỷ trọng nhóm LNST theo năm

Biểu đồ Stacked 100% này được sử dụng để phân tích tỷ trọng nhóm tăng trưởng lợi nhuận sau thuế (Nhom_Tangtruong_LNST) của Vietcombank theo các năm.

Biểu đồ này giúp bạn so sánh tỷ trọng các nhóm trong tổng số mỗi năm và nhận diện xu hướng thay đổi trong cấu trúc nhóm lợi nhuận qua thời gian.

1. df_stack <- VCBbctc %>%
2.   count(Nam, Nhom_Tangtruong_LNST) %>%
3.   group_by(Nam) %>%
4.   mutate(tytrong = n / sum(n))
5. ggplot(df_stack, aes(x = as.factor(Nam), y = tytrong, fill = Nhom_Tangtruong_LNST)) +
6.   geom_col(position = "fill") +
7.   scale_y_continuous(labels = scales::percent) +
8.   scale_fill_brewer(palette = "Set3") +
9.   labs(title = "Tỷ trọng nhóm tăng trưởng LNST theo năm",
10.        x = "Năm", y = "Tỷ trọng", fill = "Nhóm LNST") +
11.   theme_minimal(base_size = 12)+
12.   theme(axis.text.x = element_text(angle = 45, hjust = 1))

Giải thích kỹ thuật

  • Đoạn lệnh từ (1) đến (4):
  1. Đếm số lượng các nhóm LNST theo từng năm (Nam).

  2. Nhóm dữ liệu theo năm để tính tỷ trọng cho mỗi năm.

  3. Tính tỷ trọng của mỗi nhóm LNST trong mỗi năm bằng cách chia số lượng của nhóm LNST cho tổng số của tất cả các nhóm trong năm đó.

  • Dòng lệnh (5): Dữ liệu từ df_stack được sử dụng để vẽ biểu đồ, với trục x là Năm (Nam), trục y là tỷ trọng (tytrong), và màu sắc phân biệt các nhóm LNST.

  • Dòng lệnh (6):vẽ các cột chồng cho mỗi năm sau đó chồng cột sao cho tổng của mỗi cột bằng 100%, tức là tỷ trọng của các nhóm trong năm đó sẽ được so sánh.

  • Dòng lệnh (7): Định dạng trục y dưới dạng tỷ lệ phần trăm, giúp dễ dàng so sánh tỷ trọng các nhóm trong mỗi năm.

Kết luận

Biểu đồ trên thể hiện sự thay đổi tỷ trọng các nhóm tăng trưởng lợi nhuận sau thuế (LNST) qua giai đoạn 2015–2024, nhằm phản ánh mức độ phân hóa về hiệu quả tăng trưởng giữa các ngân hàng trong từng năm. Quan sát cho thấy, cơ cấu nhóm tăng trưởng LNST có xu hướng luân chuyển rõ rệt qua các giai đoạn.

  • Trong giai đoạn đầu (2015–2016), nhóm LNST thấp chiếm tỷ trọng cao nhất, cho thấy phần lớn các ngân hàng có tốc độ tăng trưởng lợi nhuận còn khiêm tốn.

  • Sang giai đoạn 2017–2018, nhóm tăng trưởng cao chiếm ưu thế, phản ánh thời kỳ phục hồi mạnh mẽ của lợi nhuận ngân hàng, có thể nhờ tăng trưởng tín dụng và cải thiện biên lợi nhuận lãi.

  • Từ 2019 đến 2021, nhóm trung bình (TB) nổi lên với tỷ trọng lớn, cho thấy mức độ tăng trưởng lợi nhuận ổn định và bền vững hơn, ít biến động cực đoan.

  • Tuy nhiên, trong hai năm cuối (2023–2024), nhóm tăng trưởng thấp lại chiếm ưu thế trở lại, phản ánh sự chững lại của tăng trưởng lợi nhuận, có thể do áp lực chi phí vốn tăng và biên lợi nhuận thu hẹp.

Nhìn chung, biểu đồ cho thấy chu kỳ luân phiên giữa các nhóm tăng trưởng lợi nhuận, với giai đoạn đầu và cuối thiên về tăng trưởng thấp, xen giữa là thời kỳ tăng trưởng mạnh và ổn định. Điều này phản ánh tính chu kỳ của hoạt động ngân hàng, chịu ảnh hưởng từ điều kiện kinh tế vĩ mô, chính sách tiền tệ và khả năng quản trị vốn của từng giai đoạn.

4.4.18 Dumbbell: so sánh CAR vs Tytrong_VCSH theo năm

Đoạn mã này tạo ra một biểu đồ Dumbbell (biểu đồ kẹp) để so sánh CAR (Tỷ lệ an toàn vốn) và Tytrong_VCSH (Tỷ trọng vốn chủ sở hữu) của Vietcombank qua các năm.

Biểu đồ này rất hữu ích trong việc so sánh hai chỉ tiêu tài chính trong cùng một năm, giúp đánh giá mối quan hệ giữa an toàn vốn và vốn chủ sở hữu của ngân hàng.

1. df_db <- VCBbctc %>%
2.   select(Nam, CAR, Tytrong_VCSH) %>%
3.   tidyr::pivot_longer(-Nam, names_to = "Bien", values_to = "Gia_tri") %>%
4.   tidyr::pivot_wider(names_from = Bien, values_from = Gia_tri)
5. ggplot(df_db, aes(x = CAR, xend = Tytrong_VCSH, y = as.factor(Nam))) +
6.   geom_segment(aes(yend = as.factor(Nam)), color = "grey70", linewidth = 1) +
7.   geom_point(size = 3, color = "#1565C0") +
8.   geom_point(aes(x = Tytrong_VCSH), size = 3, color = "#C62828") +
9.   scale_x_continuous(labels = scales::percent) +
10.   labs(title = "Dumbbell: CAR vs Tỷ trọng VCSH theo năm",
11.        x = "Tỷ lệ", y = "Năm") +
12.   theme_minimal(base_size = 12)

Giải thích kỹ thuật

  • Đoạn lệnh từ (1) đến (4):
  1. Chọn các cột Năm, CAR và Tytrong_VCSH từ dữ liệu.

  2. Chuyển đổi dữ liệu từ dạng rộng sang dạng dài, trong đó cột Bien là tên các chỉ tiêu (CAR, Tytrong_VCSH) và Gia_tri là giá trị tương ứng.

  3. Chuyển dữ liệu lại về dạng rộng, giúp tạo các cột riêng biệt cho CAR và Tytrong_VCSH để dễ dàng so sánh.

  • Dòng lệnh (5): vẽ biểu đồ từ df_db với trục x là CAR và xend = Tytrong_VCSH giúp tạo đường nối từ CAR đến Tytrong_VCSH sau đó sử dụng Năm (Nam) làm trục y, với mỗi năm là một mức riêng biệt.

  • Dòng lệnh (6): vẽ các đoạn thẳng (segments) từ CAR đến Tytrong_VCSH cho mỗi năm sau đó tạo viền màu xám cho các đoạn thẳng, và linewidth = 1 điều chỉnh độ dày.

  • Dòng lệnh (7): vẽ các điểm dữ liệu cho CAR, với màu sắc xanh dương (#1565C0) và kích thước 3.

  • Dòng lệnh (8): vẽ các điểm dữ liệu cho Tytrong_VCSH, với màu sắc đỏ (#C62828) và kích thước 3.

  • Dòng lệnh (9): Định dạng trục x dưới dạng tỷ lệ phần trăm (percent), giúp dễ dàng đọc và so sánh các giá trị CAR và Tytrong_VCSH.

  • Dòng lệnh 10) và (11): Thêm tiêu đề cho biểu đồ và nhãn cho các trục x và y, giải thích rõ ràng các yếu tố trong biểu đồ.

Kết quả

Biểu đồ trên thể hiện mối quan hệ giữa tỷ lệ an toàn vốn (CAR) và tỷ trọng vốn chủ sở hữu (VCSH) của các ngân hàng qua các năm từ 2015 đến 2024, giúp đánh giá xu hướng thay đổi trong cấu trúc vốn và mức độ an toàn tài chính theo thời gian.

Quan sát cho thấy, cả CAR và tỷ trọng VCSH đều có xu hướng tăng dần rõ rệt trong giai đoạn nghiên cứu. Giai đoạn 2015–2017, hai chỉ tiêu này ở mức thấp (CAR quanh 5–6%, VCSH chiếm tỷ trọng nhỏ), phản ánh mức độ phụ thuộc vào nợ vay cao và nguồn vốn tự có còn hạn chế. Từ 2018 trở đi, các giá trị tăng đều, đạt đỉnh vào 2024 với CAR gần 9%, cho thấy các ngân hàng đã cải thiện đáng kể năng lực vốn và khả năng chống chịu rủi ro.

Xu hướng tăng song song của hai chỉ tiêu này thể hiện sự chuyển dịch tích cực trong cơ cấu tài chính, khi các ngân hàng giảm đòn bẩy tài chính và tăng cường vốn tự có, phù hợp với yêu cầu an toàn vốn theo chuẩn Basel II và Basel III. Điều này đồng thời cho thấy ngành ngân hàng đang hướng đến mô hình tài chính bền vững hơn, chú trọng vào khả năng tự chủ và quản trị rủi ro vốn.

Nhìn chung, biểu đồ Dumbbell cho thấy mối tương quan thuận giữa CAR và tỷ trọng vốn chủ, qua đó phản ánh xu hướng tăng cường an toàn tài chính và giảm phụ thuộc vào nguồn vốn vay trong giai đoạn 2015–2024.

4.4.19 Line plot: Xu hướng tăng trưởng tổng tài sản theo năm

Biểu đồ line plot này hiển thị xu hướng tăng trưởng tổng tài sản (Tăng trưởng TTS) của Vietcombank qua các năm. Biểu đồ sẽ giúp bạn đánh giá biến động tài sản của ngân hàng qua thời gian, xem xét các giai đoạn tăng trưởng mạnh mẽ hoặc giảm sút.

1. ggplot(VCBbctc, aes(x = Nam, y = Tangtruong_TS)) +
2.   geom_line(color = "#1F77B4", linewidth = 1.2) + 
3.   geom_point(size = 3, color = "#FF6347") +  
4.   scale_y_continuous(labels = scales::percent) +  
5.   labs(title = "Xu hướng tăng trưởng tổng tài sản theo năm",
6.        x = "Năm", y = "Tăng trưởng TTS") +  
7.   theme_minimal(base_size = 12)+
8.   theme(axis.text.x = element_text(angle = 45, hjust = 1))

Giải thích kỹ thuật

  • Dòng lệnh (1): lấy dữ liệu từ VCBbctc để vẽ biểu đồ trong đó: Trục x là Năm (Nam), và trục y là Tangtruong_TS (Tăng trưởng tổng tài sản).

  • Dòng lệnh (2): vẽ đường xu hướng thể hiện sự thay đổi của tăng trưởng tổng tài sản qua các năm, chọn màu xanh dương cho đường xu hướng, linewidth = 1.2 điều chỉnh độ dày của đường xu hướng để làm nổi bật sự thay đổi.

  • Dòng lệnh (3):vẽ các điểm dữ liệu trên đường xu hướng, thể hiện giá trị tăng trưởng tổng tài sản cho mỗi năm, size = 3 điều chỉnh kích thước của các điểm, chọn màu đỏ cam cho các điểm, giúp làm nổi bật các giá trị.

  • Dòng lệnh (4): định dạng trục y dưới dạng tỷ lệ phần trăm, giúp dễ dàng so sánh và đánh giá mức độ thay đổi của tăng trưởng tổng tài sản theo phần trăm.

Kết quả

Biểu đồ cho thấy tốc độ tăng trưởng tổng tài sản (TTS) của các ngân hàng trong giai đoạn 2015–2024 có sự biến động đáng kể theo chu kỳ.

Giai đoạn 2016–2017 ghi nhận mức tăng trưởng cao nhất, đặc biệt năm 2017 đạt hơn 30%, phản ánh xu hướng mở rộng mạnh về quy mô tài sản.

Tuy nhiên, giai đoạn 2018–2021 chứng kiến sự chững lại, khi tốc độ tăng giảm xuống chỉ còn khoảng 5–10%.

Năm 2022 là thời điểm phục hồi nổi bật với mức tăng gần 28%, song đến 2023–2024 tăng trưởng lại suy giảm.

Xu hướng này cho thấy chu kỳ tăng – điều chỉnh – phục hồi rõ rệt, phản ánh tác động của môi trường kinh tế và chính sách tín dụng đến chiến lược mở rộng quy mô tài sản của các ngân hàng.

4.4.20 Boxplot Phân phối NIM theo Năm: Trung bình, Trung vị và Biến động

Biểu đồ này sử dụng boxplot kết hợp với các điểm dữ liệu để phân tích phân phối NIM (Biên lãi ròng) của Vietcombank qua các năm. Mục tiêu của biểu đồ này là để hiểu rõ sự phân bố của NIM trong mỗi năm, đồng thời đánh giá các biến động và giá trị ngoại lai (outliers) của chỉ tiêu này.

1. ggplot(VCBbctc, aes(x = as.factor(Nam), y = NIM)) +
2.   geom_boxplot(fill = "#FF6347", color = "black", alpha = 0.6, outlier.shape = 16, outlier.colour = "blue", outlier.size = 2) + 
3.   geom_jitter(aes(color = Nhom_Tangtruong_TS), size = 2, width = 0.2, alpha = 0.5) +  
4.   geom_point(aes(y = mean(NIM, na.rm = TRUE)), shape = 23, size = 4, color = "black", fill = "white") + 
5.   stat_summary(fun = "median", geom = "point", size = 3, color = "green") + 
6.   labs(title = "Phân phối NIM theo năm", x = "Năm", y = "NIM") +  
7.   scale_y_continuous(labels = scales::percent) +  
8.   scale_color_brewer(palette = "Set1") + 
9.   theme_minimal(base_size = 12)+
10.   theme(axis.text.x = element_text(angle = 45, hjust = 1))

Giải thích kỹ thuật

  • Dòng lệnh (1): Khởi tạo ggplot với trục x là năm (as.factor(Nam)) và trục y là NIM nhằm thể hiện sự phân phối của biên lãi ròng theo từng năm, giúp quan sát biến động NIM theo thời gian.

  • Dòng lệnh (2): geom_boxplot() vẽ hộp số thể hiện trung vị, tứ phân vị và các giá trị ngoại lệ; phần hộp được tô đỏ cam với viền đen, còn các điểm ngoại lệ được đánh dấu bằng chấm tròn nhỏ màu xanh để dễ nhận biết.

  • Dòng lệnh (3): geom_jitter() bổ sung các điểm dữ liệu rải quanh hộp, được tô màu theo nhóm tăng trưởng tổng tài sản (TTS), giúp thấy rõ sự phân tán của từng quan sát trong mỗi năm.

  • Dòng lệnh (4): geom_point() thêm điểm hình thoi trắng viền đen biểu thị giá trị trung bình NIM của từng năm, giúp so sánh nhanh với trung vị trong hộp số.

  • Dòng lệnh (5): stat_summary() chèn điểm màu xanh tại trung vị để nhấn mạnh vị trí trung tâm của phân phối.

Kết quả Biểu đồ thể hiện phân phối biên lợi nhuận lãi ròng (NIM) của các ngân hàng theo từng năm, đồng thời so sánh giữa các nhóm tăng trưởng tổng tài sản (TTS). Trong giai đoạn 2015–2018, NIM duy trì ở mức thấp, dao động quanh 2,2–2,4%, phản ánh hiệu quả sinh lời từ hoạt động cho vay còn hạn chế. Từ 2019 trở đi, NIM tăng rõ rệt, đạt đỉnh khoảng 3% vào năm 2021, cho thấy khả năng cải thiện biên lãi thuần của các ngân hàng trong bối cảnh tín dụng tăng trưởng và chi phí vốn được kiểm soát. Giai đoạn 2022–2024, NIM có dấu hiệu ổn định quanh mức 2,9%, phản ánh mức sinh lời bền vững hơn. Nhìn chung, xu hướng tăng dần và ổn định của NIM cho thấy hiệu quả hoạt động cốt lõi của các ngân hàng được cải thiện, đặc biệt ở nhóm có tăng trưởng tài sản cao, vốn duy trì NIM ở mức trên trung bình qua hầu hết các năm.