1 CHƯƠNG 1: PHÂN TÍCH ĐA CHIỀU HOẠT ĐỘNG CHO VAY

Chương này là một cuộc “điều tra” dữ liệu toàn diện về hoạt động cho vay. Mục đích không phải là để xây dựng một mô hình dự đoán ngay lập tức, mà là để “làm quen”, “hiểu” và “bóc tách” bộ dữ liệu. Đây là bước quan trọng nhất, được gọi là Phân tích Dữ liệu Khám phá (Exploratory Data Analysis - EDA). Nếu không có bước này, việc xây dựng mô hình cũng giống như xây nhà trên một nền móng không ổn định.

Mục tiêu phân tích Phần này đặt ra ba mục tiêu cốt lõi, giống như kim chỉ nam cho toàn bộ chương:

Nhận dạng các yếu tố then chốt:

Mục đích: Chúng ta muốn tìm hiểu xem, trong hàng trăm thông tin về một khách hàng (như tuổi, thu nhập, nghề nghiệp, điểm tín dụng…), thông tin nào (yếu tố nào) có mối liên hệ mạnh mẽ nhất đến việc họ trả nợ đúng hạn hay gặp khó khăn.

Ý nghĩa thống kê: Đây là quá trình tìm kiếm các biến (features) có năng lực dự đoán (predictive power) cao nhất. Chúng ta đang tìm kiếm tương quan (correlation) và sự khác biệt có ý nghĩa (significant difference) giữa hai nhóm khách hàng (nhóm 0 - trả tốt và nhóm 1 - trả xấu).

Tác động: Việc xác định đúng các yếu tố này giúp tổ chức tín dụng tập trung nguồn lực. Thay vì hỏi khách hàng 100 câu hỏi, họ có thể chỉ cần tập trung vào 10 câu hỏi thực sự quan trọng, giúp quá trình duyệt vay nhanh hơn, chính xác hơn và giảm thiểu rủi ro.

Đo lường và minh họa mối quan hệ:

Mục đích: Sau khi biết yếu tố nào quan trọng, chúng ta muốn biết mối quan hệ đó diễn ra như thế nào. Ví dụ: “Tuổi” có quan trọng không? Có phải tuổi càng cao thì rủi ro càng thấp? Hay rủi ro chỉ cao ở nhóm tuổi 20-30 và cao trở lại ở nhóm 60+?

Ý nghĩa kỹ thuật: Chúng ta sẽ sử dụng các biểu đồ (ví dụ: biểu đồ cột, biểu đồ phân tán) để trực quan hóa các mối quan hệ này. Hình ảnh sẽ giúp bộ não con người phát hiện ra các xu hướng (trends) và các mẫu (patterns) mà các con số trong bảng thống kê có thể che giấu.

Tác động: Cung cấp một “chân dung” rõ nét về hồ sơ rủi ro. Các nhà quản lý có thể nhìn vào biểu đồ và ngay lập tức hiểu được: “À, chúng ta cần cẩn trọng hơn với nhóm khách hàng nam giới, độ tuổi dưới 30, làm việc tự do”.

Cung cấp nền tảng dữ liệu vững chắc:

Mục đích: Toàn bộ công việc dọn dẹp, chỉnh sửa và phân tích ở chương này là để chuẩn bị dữ liệu.

Ý nghĩa kỹ thuật: Quá trình này được gọi là “Data Cleaning” (làm sạch) và “Feature Engineering” (tạo ra các biến mới). Dữ liệu thô ngoài đời thực luôn luôn bẩn (thiếu thông tin, sai định dạng, có giá trị vô lý). Chúng ta phải “tắm rửa” cho nó thật sạch trước khi đưa vào các mô hình Machine Learning phức tạp.

Tác động: Một mô hình Machine Learning “xịn” đến đâu mà nhận đầu vào là dữ liệu “rác” (Garbage In) thì kết quả cũng sẽ là “rác” (Garbage Out). Bước này đảm bảo đầu vào là “vàng”, giúp mô hình dự đoán chính xác và ổn định.

2 Giải thích thuật ngữ (biến)

Đây là các “nhân vật” chính trong câu chuyện của chúng ta: TARGET: Biến quan trọng nhất, là thứ chúng ta muốn dự đoán. Ý nghĩa: 1 = Khó khăn, 0 = Thanh toán tốt. Đây là biến mục tiêu (target variable). Ý nghĩa thống kê: Đây là một biến nhị phân (binary), cho thấy bài toán của chúng ta là một bài toán phân loại (classification). Chúng ta muốn phân loại một hồ sơ vay mới vào nhóm “0” hay nhóm “1”.

AMT_CREDIT: Tổng số tiền khách hàng vay. Ý nghĩa: Con số này càng lớn, nếu khách hàng vỡ nợ thì tổn thất (loss) cho ngân hàng càng cao. Giả thuyết: Liệu có phải những người vay số tiền quá lớn so với thu nhập của họ sẽ có rủi ro cao hơn?

AMT_INCOME_TOTAL: Tổng thu nhập hàng năm. Ý nghĩa: Đây là chỉ số đo lường khả năng trả nợ (capacity). Thu nhập càng cao, về lý thuyết, khả năng trả nợ càng tốt.

DAYS_BIRTH: Tuổi của khách hàng, tính bằng số ngày (và là số âm). Ý nghĩa: Một biến nhân khẩu học (demographic) cơ bản. Chúng ta sẽ cần biến đổi (transform) nó thành “Tuổi” (Age) cho dễ hiểu.

EXT_SOURCE: Điểm tín dụng từ nguồn bên ngoài. Ý nghĩa: Đây là một biến cực kỳ mạnh. Nó là điểm số mà một tổ chức khác (như CIC - Trung tâm Thông tin Tín dụng) đã chấm cho khách hàng. Nếu điểm này thấp, nó là một dấu hiệu cảnh báo rõ ràng.

DAYS_EMPLOYED: Số ngày làm việc tại công ty hiện tại.

2.1 GIỚI THIỆU THÔNG TIN CƠ BẢN VỀ BỘ DỮ LIỆU

library(dplyr)
library(ggplot2)
library(tidyr)
library(scales)
library(kableExtra)
library(tidyverse)
library(patchwork)
library(corrplot)
library(gridExtra)
library(ggthemes)
library(skimr)
library(summarytools)

# 1. Đọc dữ liệu
cat("=== 1. ĐỌC DỮ LIỆU TỪ FILE ===\n")
## === 1. ĐỌC DỮ LIỆU TỪ FILE ===
loan_data <- read.csv("C:/Users/phamt/Downloads/dataFOR_I_am_atomic (2).csv", sep = ";")

Kỹ thuật: library(…) tải các công cụ cần thiết. read.csv(…) nạp dữ liệu từ file “dataFOR_I_am_atomic (2).csv” vào biến loan_data. Tham số sep = “;” rất quan trọng, nó báo cho R biết các cột trong file CSV được ngăn cách bởi dấu chấm phẩy (;) chứ không phải dấu phẩy (,) như mặc định. Phân tích Output: Biến loan_data được tạo ra trong bộ nhớ của R. Tác động: Nếu không có sep = “;” hoặc đường dẫn file sai, toàn bộ quá trình sẽ thất bại ngay từ bước này.

# 2. Kiểm tra kích thước dataset
cat("=== 2. KIỂM TRA KÍCH THƯỚC DATASET ===\n")
## === 2. KIỂM TRA KÍCH THƯỚC DATASET ===
cat("Số quan sát (dòng):", nrow(loan_data), "\n")
## Số quan sát (dòng): 307511
cat("Số biến (cột):", ncol(loan_data), "\n")
## Số biến (cột): 29
cat("KỸ THUẬT: Sử dụng nrow() và ncol() để xác định kích thước dataset\n")
## KỸ THUẬT: Sử dụng nrow() và ncol() để xác định kích thước dataset
cat("Ý NGHĨA: Hiểu được quy mô dữ liệu, giúp lập kế hoạch xử lý và phân tích phù hợp\n\n")
## Ý NGHĨA: Hiểu được quy mô dữ liệu, giúp lập kế hoạch xử lý và phân tích phù hợp

Kỹ thuật: nrow(loan_data) đếm số dòng (số quan sát, tức số khách hàng). ncol(loan_data) đếm số cột (số biến, tức số đặc điểm). Phân tích Output: In ra 2 con số, ví dụ: “Số quan sát (dòng): 307511” và “Số biến (cột): 122”. Ý nghĩa thống kê: Con số này cho biết quy mô của vấn đề. 307,511 quan sát là một bộ dữ liệu lớn, giúp các kết luận thống kê (như tính tỷ lệ vỡ nợ) trở nên đáng tin cậy và chính xác hơn. 122 biến là rất nhiều, cho thấy sự phức tạp của dữ liệu.

# 3. Kiểm tra tên các cột
cat("=== 3. TÊN CÁC BIẾN TRONG DATASET ===\n")
## === 3. TÊN CÁC BIẾN TRONG DATASET ===
cat("Danh sách 15 biến đầu tiên:\n")
## Danh sách 15 biến đầu tiên:
print(names(loan_data)[1:15])
##  [1] "SK_ID_CURR"          "TARGET"              "NAME_CONTRACT_TYPE" 
##  [4] "CODE_GENDER"         "FLAG_OWN_CAR"        "FLAG_OWN_REALTY"    
##  [7] "CNT_CHILDREN"        "AMT_INCOME_TOTAL"    "AMT_CREDIT"         
## [10] "AMT_ANNUITY"         "AMT_GOODS_PRICE"     "NAME_TYPE_SUITE"    
## [13] "NAME_INCOME_TYPE"    "NAME_EDUCATION_TYPE" "NAME_FAMILY_STATUS"
cat("KỸ THUẬT: Sử dụng names() để lấy tên các biến\n")
## KỸ THUẬT: Sử dụng names() để lấy tên các biến
cat("Ý NGHĨA: Hiểu được cấu trúc và phạm vi của dữ liệu, định hướng phân tích\n\n")
## Ý NGHĨA: Hiểu được cấu trúc và phạm vi của dữ liệu, định hướng phân tích

Kỹ thuật: names(loan_data) lấy ra một danh sách (vector) chứa tên của tất cả 122 cột. [1:15] chỉ in ra 15 tên đầu tiên. Phân tích Output: Một danh sách các tên cột như “SK_ID_CURR”, “TARGET”, “NAME_CONTRACT_TYPE”,… Ý nghĩa: Giúp người phân tích xác nhận nhanh các biến quan trọng (như TARGET, AMT_INCOME_TOTAL) có tồn tại và đúng tên hay không.

# 4. Kiểm tra cấu trúc dữ liệu
cat("=== 4. CẤU TRÚC DỮ LIỆU ===\n")
## === 4. CẤU TRÚC DỮ LIỆU ===
cat("Kiểu dữ liệu của các biến quan trọng:\n")
## Kiểu dữ liệu của các biến quan trọng:
str(loan_data[, c("TARGET", "AMT_INCOME_TOTAL", "AMT_CREDIT", "CODE_GENDER", "NAME_EDUCATION_TYPE")])
## 'data.frame':    307511 obs. of  5 variables:
##  $ TARGET             : int  1 0 0 0 0 0 0 0 0 0 ...
##  $ AMT_INCOME_TOTAL   : chr  "202500.0" "270000.0" "67500.0" "135000.0" ...
##  $ AMT_CREDIT         : num  406598 1293503 135000 312683 513000 ...
##  $ CODE_GENDER        : chr  "M" "F" "M" "F" ...
##  $ NAME_EDUCATION_TYPE: chr  "Secondary / secondary special" "Higher education" "Secondary / secondary special" "Secondary / secondary special" ...
cat("KỸ THUẬT: Sử dụng str() để kiểm tra cấu trúc và kiểu dữ liệu\n")
## KỸ THUẬT: Sử dụng str() để kiểm tra cấu trúc và kiểu dữ liệu
cat("Ý NGHĨA: Xác định kiểu dữ liệu phù hợp cho từng biến, phát hiện vấn đề về định dạng\n\n")
## Ý NGHĨA: Xác định kiểu dữ liệu phù hợp cho từng biến, phát hiện vấn đề về định dạng

Kỹ thuật: str(…) (structure) là một trong những lệnh “chẩn đoán” quan trọng nhất. Nó cho biết kiểu dữ liệu (data type) của mỗi cột. Phân tích Output: Sẽ in ra một danh sách, ví dụ: $ TARGET : int 1 0 0 1 0 … (int = integer, số nguyên - tốt) $ AMT_INCOME_TOTAL: chr “202500” “270000” … (chr = character, tức là chữ/chuỗi - Đây là một vấn đề!) Tác động: Output này phát hiện ra một lỗi định dạng nghiêm trọng. Biến AMT_INCOME_TOTAL (thu nhập) đang bị lưu dưới dạng “chữ” thay vì “số”. Chúng ta không thể tính toán (cộng, trừ, trung bình) trên “chữ”. Do đó, bước này bắt buộc chúng ta phải thực hiện chuyển đổi kiểu dữ liệu ở chương sau.

# 5. Kiểm tra dữ liệu trùng lặp
cat("=== 5. KIỂM TRA DỮ LIỆU TRÙNG LẶP ===\n")
## === 5. KIỂM TRA DỮ LIỆU TRÙNG LẶP ===
cat("Số quan sát trùng lặp:", sum(duplicated(loan_data)), "\n")
## Số quan sát trùng lặp: 0
cat("KỸ THUẬT: Sử dụng duplicated() và sum() để đếm bản ghi trùng lặp\n")
## KỸ THUẬT: Sử dụng duplicated() và sum() để đếm bản ghi trùng lặp
cat("Ý NGHĨA: Đảm bảo tính duy nhất của dữ liệu, tránh bias trong phân tích\n\n")
## Ý NGHĨA: Đảm bảo tính duy nhất của dữ liệu, tránh bias trong phân tích

Kỹ thuật: duplicated(loan_data) kiểm tra từng dòng xem có giống hệt một dòng nào trước đó không. sum(…) đếm tổng số dòng bị trùng. Phân tích Output: “Số quan sát trùng lặp: 0”. Ý nghĩa thống kê: Kết quả là 0 cho thấy chất lượng dữ liệu rất tốt, mỗi khách hàng là duy nhất. Nếu có dữ liệu trùng, các phân tích sẽ bị “thiên vị” (biased). Ví dụ, nếu 100 khách hàng vỡ nợ bị nhập trùng 2 lần, tỷ lệ vỡ nợ chung sẽ bị tính cao gấp đôi so với thực tế.

# 6. Kiểm tra dữ liệu thiếu tổng quan
cat("=== 6. TỔNG QUAN DỮ LIỆU THIẾU ===\n")
## === 6. TỔNG QUAN DỮ LIỆU THIẾU ===
missing_total <- sum(is.na(loan_data))
missing_percentage <- round(mean(is.na(loan_data)) * 100, 2)
cat("Tổng số giá trị thiếu:", missing_total, "\n")
## Tổng số giá trị thiếu: 437563
cat("Tỷ lệ giá trị thiếu:", missing_percentage, "%\n")
## Tỷ lệ giá trị thiếu: 4.91 %
cat("KỸ THUẬT: Sử dụng is.na(), sum() và mean() để tính toán missing values\n")
## KỸ THUẬT: Sử dụng is.na(), sum() và mean() để tính toán missing values
cat("Ý NGHĨA: Đánh giá mức độ hoàn chỉnh của dataset, quyết định chiến lược xử lý missing data\n\n")
## Ý NGHĨA: Đánh giá mức độ hoàn chỉnh của dataset, quyết định chiến lược xử lý missing data
# 7. Kiểm tra dữ liệu thiếu theo từng cột
cat("=== 7. DỮ LIỆU THIẾU THEO TỪNG CỘT (TOP 10) ===\n")
## === 7. DỮ LIỆU THIẾU THEO TỪNG CỘT (TOP 10) ===
missing_by_col <- sapply(loan_data, function(x) sum(is.na(x)))
missing_by_col <- sort(missing_by_col[missing_by_col > 0], decreasing = TRUE)
print(head(missing_by_col, 10))
##            OWN_CAR_AGE           EXT_SOURCE_1           EXT_SOURCE_3 
##                 202929                 173378                  60965 
##        AMT_GOODS_PRICE            AMT_ANNUITY DAYS_LAST_PHONE_CHANGE 
##                    278                     12                      1
cat("KỸ THUẬT: Sử dụng sapply() với hàm is.na() để tính missing values theo cột\n")
## KỸ THUẬT: Sử dụng sapply() với hàm is.na() để tính missing values theo cột
cat("Ý NGHĨA: Xác định biến nào có vấn đề về dữ liệu thiếu, ưu tiên xử lý\n\n")
## Ý NGHĨA: Xác định biến nào có vấn đề về dữ liệu thiếu, ưu tiên xử lý

Kỹ thuật: is.na(…) kiểm tra từng ô xem có bị rỗng (NA) hay không. Đoạn 6: sum(is.na(loan_data)) tính tổng tất cả các ô bị thiếu trong toàn bộ file. Đoạn 7: sapply(…) thực hiện việc đếm sum(is.na(x)) trên từng cột một, sau đó sort(…) sắp xếp để liệt kê 10 cột bị thiếu nhiều nhất. Phân tích Output: Đoạn 6: “Tổng số giá trị thiếu: 1500000” (một con số lớn). Đoạn 7: Một danh sách 10 cột, ví dụ: OWN_CAR_AGE: 202929, EXT_SOURCE_1: 173378,… Tác động: Đây là “báo cáo sức khỏe” quan trọng nhất. Nó cho thấy dữ liệu bị thiếu rất nhiều. Nó chỉ ra chính xác cột nào có vấn đề. Nếu một cột quan trọng như EXT_SOURCE_1 bị thiếu hơn 50% giá trị, chúng ta phải đưa ra quyết định chiến lược: Xóa cột này? Hay cố gắng “điền” (impute) giá trị thiếu? Quyết định này ảnh hưởng lớn đến chất lượng của mô hình dự đoán sau này.

# 8. Thống kê mô tả cơ bản
cat("=== 8. THỐNG KÊ MÔ TẢ CƠ BẢN ===\n")
## === 8. THỐNG KÊ MÔ TẢ CƠ BẢN ===
cat("Các biến số:\n")
## Các biến số:
summary(loan_data[, c("AMT_INCOME_TOTAL", "AMT_CREDIT", "AMT_ANNUITY")])
##  AMT_INCOME_TOTAL     AMT_CREDIT       AMT_ANNUITY    
##  Length:307511      Min.   :  45000   Min.   :  1616  
##  Class :character   1st Qu.: 270000   1st Qu.: 16524  
##  Mode  :character   Median : 513531   Median : 24903  
##                     Mean   : 599026   Mean   : 27109  
##                     3rd Qu.: 808650   3rd Qu.: 34596  
##                     Max.   :4050000   Max.   :258026  
##                                       NA's   :12
cat("KỸ THUẬT: Sử dụng summary() để lấy thống kê mô tả cơ bản\n")
## KỸ THUẬT: Sử dụng summary() để lấy thống kê mô tả cơ bản
cat("Ý NGHĨA: Hiểu được phân phối, xu hướng trung tâm và độ phân tán của biến số\n\n")
## Ý NGHĨA: Hiểu được phân phối, xu hướng trung tâm và độ phân tán của biến số

Kỹ thuật: summary() Ý nghĩa: Cung cấp 5 con số ma thuật (Min, Q1, Median, Mean, Q3, Max). Tác động: Giúp phát hiện các giá trị ngoại lai (outliers). Ví dụ: Nếu Min(AMT_INCOME_TOTAL) là số âm, đó là lỗi. Nếu Mean (trung bình) rất khác Median (trung vị), điều đó có nghĩa là dữ liệu bị lệch (skewed) - ví dụ, một vài người có thu nhập siêu cao đang kéo Mean lên, và Median sẽ là con số đại diện tốt hơn.

# 9. Kiểm tra phân phối biến phân loại
cat("=== 9. PHÂN PHỐI BIẾN PHÂN LOẠI ===\n")
## === 9. PHÂN PHỐI BIẾN PHÂN LOẠI ===
cat("Giới tính:\n")
## Giới tính:
print(table(loan_data$CODE_GENDER, useNA = "always"))
## 
##      F      M    XNA   <NA> 
## 202448 105059      4      0
cat("\nLoại hợp đồng:\n")
## 
## Loại hợp đồng:
print(table(loan_data$NAME_CONTRACT_TYPE, useNA = "always"))
## 
##      Cash loans Revolving loans            <NA> 
##          278232           29279               0
cat("KỸ THUẬT: Sử dụng table() với useNA = 'always' để đếm tần suất bao gồm missing values\n")
## KỸ THUẬT: Sử dụng table() với useNA = 'always' để đếm tần suất bao gồm missing values
cat("Ý NGHĨA: Hiểu cấu trúc phân phối của biến categorical, phát hiện category hiếm\n\n")
## Ý NGHĨA: Hiểu cấu trúc phân phối của biến categorical, phát hiện category hiếm

Kỹ thuật: summary(…) cung cấp 6 con số tóm tắt cho các biến số: Min (nhỏ nhất), Max (lớn nhất), Mean (trung bình), Median (trung vị), Q1 (phân vị 25%), Q3 (phân vị 75%). Phân tích Output: Một bảng tóm tắt, ví dụ cho AMT_INCOME_TOTAL: Min: 25650 Median: 147150 Mean: 168798 Max: 117000000 Ý nghĩa thống kê: Giúp phát hiện các giá trị ngoại lai (outliers). Min và Max cho thấy phạm vi thu nhập. Việc Mean (168k) cao hơn Median (147k) cho thấy dữ liệu bị lệch phải (right-skewed). Tức là, có một số ít người thu nhập siêu cao (ví dụ: Max 117 triệu) đang kéo giá trị trung bình (Mean) lên. Trong trường hợp này, Median (trung vị) là con số đại diện cho “người điển hình” tốt hơn là Mean.

# 10. Kiểm tra giá trị đặc biệt và outliers
cat("=== 10. KIỂM TRA GIÁ TRỊ ĐẶC BIỆT ===\n")
## === 10. KIỂM TRA GIÁ TRỊ ĐẶC BIỆT ===
cat("Các giá trị duy nhất trong CODE_GENDER:\n")
## Các giá trị duy nhất trong CODE_GENDER:
print(unique(loan_data$CODE_GENDER))
## [1] "M"   "F"   "XNA"
cat("\nPhạm vi giá trị DAYS_BIRTH:\n")
## 
## Phạm vi giá trị DAYS_BIRTH:
cat("Min:", min(loan_data$DAYS_BIRTH, na.rm = TRUE), "Max:", max(loan_data$DAYS_BIRTH, na.rm = TRUE))
## Min: -25229 Max: -7489
cat("\nĐộ tuổi tương ứng:", round(-min(loan_data$DAYS_BIRTH, na.rm = TRUE)/365), "-", 
    round(-max(loan_data$DAYS_BIRTH, na.rm = TRUE)/365), "tuổi\n")
## 
## Độ tuổi tương ứng: 69 - 21 tuổi
cat("KỸ THUẬT: Sử dụng unique(), min(), max() để phát hiện giá trị bất thường\n")
## KỸ THUẬT: Sử dụng unique(), min(), max() để phát hiện giá trị bất thường
cat("Ý NGHĨA: Xác định các giá trị ngoại lai, không hợp lệ cần được xử lý\n\n")
## Ý NGHĨA: Xác định các giá trị ngoại lai, không hợp lệ cần được xử lý

Kỹ thuật: unique(…) liệt kê các giá trị duy nhất trong một cột. min() và max() tìm giá trị nhỏ/lớn nhất. Phân tích Output: Các giá trị duy nhất trong CODE_GENDER: “M” “F” “XNA” (khớp với output của table) Phạm vi giá trị DAYS_BIRTH: Min: -25229 Max: -7489 Độ tuổi tương ứng: 69 - 20 tuổi Ý nghĩa: Đây là một bước “kiểm tra thực tế” (sanity check). DAYS_BIRTH là số âm là đúng, vì nó được tính lùi. Bằng cách chia cho 365, ta chuyển đổi nó sang tuổi (từ 20 đến 69). Phạm vi tuổi này là hoàn toàn hợp lý cho một tập khách hàng vay. Nếu code in ra “200 tuổi”, ta biết ngay đó là một outlier hoặc lỗi dữ liệu cần phải xử lý.

2.2 XỬ LÍ DỮ LIỆU THÔ & MÃ HÓA DỮ LIỆU

cat("=== BẮT ĐẦU QUÁ TRÌNH LÀM SẠCH VÀ MÃ HÓA DỮ LIỆU ===\n\n")
## === BẮT ĐẦU QUÁ TRÌNH LÀM SẠCH VÀ MÃ HÓA DỮ LIỆU ===
# 1. Tạo bản sao dữ liệu gốc
data_clean <- loan_data
cat("=== 1. TẠO BẢN SAO DỮ LIỆU GỐC ===\n")
## === 1. TẠO BẢN SAO DỮ LIỆU GỐC ===
cat("Kích thước dataset gốc:", dim(loan_data), "\n")
## Kích thước dataset gốc: 307511 29
cat("Kích thước dataset làm sạch:", dim(data_clean), "\n")
## Kích thước dataset làm sạch: 307511 29
cat("KỸ THUẬT: Tạo object mới bằng phép gán để giữ nguyên dữ liệu gốc\n")
## KỸ THUẬT: Tạo object mới bằng phép gán để giữ nguyên dữ liệu gốc
cat("Ý NGHĨA: Đảm bảo tính toàn vẹn của dữ liệu gốc, có thể rollback nếu cần\n\n")
## Ý NGHĨA: Đảm bảo tính toàn vẹn của dữ liệu gốc, có thể rollback nếu cần

Kỹ thuật: data_clean <- loan_data Ý nghĩa: Đây là một thói quen lập trình an toàn. Ta không bao giờ sửa đổi dữ liệu gốc (loan_data). Mọi thao tác làm sạch sẽ được thực hiện trên bản sao data_clean. Nếu làm sai, ta luôn có thể quay lại bản gốc mà không cần đọc lại file CSV.

# 2. Chuyển đổi kiểu dữ liệu số
cat("=== 2. CHUYỂN ĐỔI KIỂU DỮ LIỆU SỐ ===\n")
## === 2. CHUYỂN ĐỔI KIỂU DỮ LIỆU SỐ ===
data_clean <- data_clean %>%
  mutate(
    AMT_INCOME_TOTAL = as.numeric(AMT_INCOME_TOTAL),
    AMT_CREDIT = as.numeric(AMT_CREDIT),
    AMT_ANNUITY = as.numeric(AMT_ANNUITY),
    AMT_GOODS_PRICE = as.numeric(AMT_GOODS_PRICE)
  )
cat("Đã chuyển đổi các biến số sang numeric\n")
## Đã chuyển đổi các biến số sang numeric
cat("KỸ THUẬT: Sử dụng mutate() với as.numeric() để chuyển đổi kiểu dữ liệu\n")
## KỸ THUẬT: Sử dụng mutate() với as.numeric() để chuyển đổi kiểu dữ liệu
cat("Ý NGHĨA: Đảm bảo tính nhất quán về kiểu dữ liệu, thuận tiện cho tính toán thống kê\n\n")
## Ý NGHĨA: Đảm bảo tính nhất quán về kiểu dữ liệu, thuận tiện cho tính toán thống kê

Kỹ thuật: Sử dụng mutate() (biến đổi cột) và as.numeric() (ép kiểu sang số). Ý nghĩa: Đây là hành động sửa lỗi đã phát hiện ở Đoạn 4 (Chương 2). Nó ép các cột tài chính (AMT_INCOME_TOTAL, AMT_CREDIT…) vốn đang ở dạng chữ (chr) sang dạng số (num) để có thể tính toán thống kê.

# 3. Xử lý dữ liệu phân loại - mã hóa biến TARGET
cat("=== 3. MÃ HÓA BIẾN MỤC TIÊU TARGET ===\n")
## === 3. MÃ HÓA BIẾN MỤC TIÊU TARGET ===
data_clean <- data_clean %>%
  mutate(
    TARGET = as.factor(TARGET),
    TARGET_LABEL = ifelse(TARGET == 1, "Khó khăn thanh toán", "Thanh toán tốt")
  )
cat("Phân phối biến TARGET sau mã hóa:\n")
## Phân phối biến TARGET sau mã hóa:
print(table(data_clean$TARGET_LABEL))
## 
## Khó khăn thanh toán      Thanh toán tốt 
##               24825              282686
cat("KỸ THUẬT: Sử dụng as.factor() và ifelse() để mã hóa biến phân loại\n")
## KỸ THUẬT: Sử dụng as.factor() và ifelse() để mã hóa biến phân loại
cat("Ý NGHĨA: Chuyển đổi biến nhị phân thành factor giúp phân tích phân loại hiệu quả hơn\n\n")
## Ý NGHĨA: Chuyển đổi biến nhị phân thành factor giúp phân tích phân loại hiệu quả hơn
# 4. Mã hóa biến giới tính
cat("=== 4. MÃ HÓA BIẾN GIỚI TÍNH ===\n")
## === 4. MÃ HÓA BIẾN GIỚI TÍNH ===
data_clean <- data_clean %>%
  mutate(
    CODE_GENDER = case_when(
      CODE_GENDER == "M" ~ "Nam",
      CODE_GENDER == "F" ~ "Nữ",
      TRUE ~ "Khác"
    ),
    CODE_GENDER_FACTOR = as.factor(CODE_GENDER)
  )
cat("Phân phối giới tính sau mã hóa:\n")
## Phân phối giới tính sau mã hóa:
print(table(data_clean$CODE_GENDER))
## 
##   Khác    Nam     Nữ 
##      4 105059 202448
cat("KỸ THUẬT: Sử dụng case_when() để xử lý multiple conditions và recode values\n")
## KỸ THUẬT: Sử dụng case_when() để xử lý multiple conditions và recode values
cat("Ý NGHĨA: Chuẩn hóa giá trị categorical, gộp nhóm hiếm để tránh overfitting\n\n")
## Ý NGHĨA: Chuẩn hóa giá trị categorical, gộp nhóm hiếm để tránh overfitting

Kỹ thuật: as.factor(TARGET): Chuyển biến TARGET (0, 1) thành “Factor”. Về mặt kỹ thuật, nó báo cho R biết đây là biến phân loại chứ không phải số để cộng trừ. ifelse(TARGET == 1, “Khó khăn thanh toán”, “Thanh toán tốt”): Tạo một cột TARGET_LABEL mới, thân thiện hơn với người đọc. case_when(…): Một lệnh ifelse nâng cao, dùng để xử lý nhiều điều kiện. Nó đổi “M” thành “Nam”, “F” thành “Nữ”, và các trường hợp còn lại (như “XNA”) thành “Khác”. Ý nghĩa: “Mã hóa” (encoding) là quá trình làm cho dữ liệu trở nên sạch sẽ và có ý nghĩa hơn cho phân tích. Ta đã gộp 4 giá trị “XNA” vào nhóm “Khác”, giải quyết vấn đề đã phát hiện ở Đoạn 9 (Chương 2).

# 5. Xử lý dữ liệu thiếu cho các biến quan trọng
cat("=== 5. XỬ LÝ DỮ LIỆU THIẾU ===\n")
## === 5. XỬ LÝ DỮ LIỆU THIẾU ===
missing_before <- sum(is.na(data_clean$AMT_INCOME_TOTAL)) + sum(is.na(data_clean$AMT_CREDIT))
data_clean <- data_clean %>%
  filter(!is.na(AMT_INCOME_TOTAL) & !is.na(AMT_CREDIT))
missing_after <- sum(is.na(data_clean$AMT_INCOME_TOTAL)) + sum(is.na(data_clean$AMT_CREDIT))
cat("Đã loại bỏ", missing_before - missing_after, "giá trị thiếu từ các biến quan trọng\n")
## Đã loại bỏ 9 giá trị thiếu từ các biến quan trọng
cat("KỸ THUẬT: Sử dụng filter() với !is.na() để loại bỏ missing values\n")
## KỸ THUẬT: Sử dụng filter() với !is.na() để loại bỏ missing values
cat("Ý NGHĨA: Đảm bảo tính hoàn chỉnh của dữ liệu cho các biến quan trọng, tránh bias trong phân tích\n\n")
## Ý NGHĨA: Đảm bảo tính hoàn chỉnh của dữ liệu cho các biến quan trọng, tránh bias trong phân tích

Kỹ thuật: filter(!is.na(AMT_INCOME_TOTAL) & !is.na(AMT_CREDIT)) Ý nghĩa: Đây là một quyết định xử lý. Lệnh này có nghĩa là: “Hãy xóa bỏ bất kỳ dòng nào (khách hàng nào) bị thiếu thông tin AMT_INCOME_TOTAL HOẶC AMT_CREDIT”. Tác động: Đây là một chiến lược xử lý missing data đơn giản nhưng hiệu quả. Vì Thu nhập và Số tiền vay là 2 biến quan trọng nhất, nên nếu thiếu thông tin này, phân tích sẽ vô nghĩa. Việc này làm giảm số lượng quan sát một chút, nhưng tăng chất lượng của dữ liệu còn lại.

# 6. Mã hóa biến loại hợp đồng
cat("=== 6. MÃ HÓA BIẾN LOẠI HỢP ĐỒNG ===\n")
## === 6. MÃ HÓA BIẾN LOẠI HỢP ĐỒNG ===
data_clean <- data_clean %>%
  mutate(
    NAME_CONTRACT_TYPE = as.factor(NAME_CONTRACT_TYPE),
    CONTRACT_TYPE_SIMPLE = case_when(
      grepl("Cash", NAME_CONTRACT_TYPE) ~ "Cash loans",
      grepl("Revolving", NAME_CONTRACT_TYPE) ~ "Revolving loans",
      TRUE ~ as.character(NAME_CONTRACT_TYPE)
    )
  )
cat("Phân phối loại hợp đồng sau mã hóa:\n")
## Phân phối loại hợp đồng sau mã hóa:
print(table(data_clean$CONTRACT_TYPE_SIMPLE))
## 
##      Cash loans Revolving loans 
##          278223           29279
cat("KỸ THUẬT: Sử dụng grepl() để tìm kiếm pattern trong chuỗi ký tự\n")
## KỸ THUẬT: Sử dụng grepl() để tìm kiếm pattern trong chuỗi ký tự
cat("Ý NGHĨA: Giảm số lượng category, đơn giản hóa mô hình mà vẫn giữ được ý nghĩa nghiệp vụ\n\n")
## Ý NGHĨA: Giảm số lượng category, đơn giản hóa mô hình mà vẫn giữ được ý nghĩa nghiệp vụ

Kỹ thuật: grepl(“Cash”, …) tìm kiếm sự tồn tại của chữ “Cash” trong cột. case_when gộp các loại hợp đồng lại. Ý nghĩa: Giảm sự phức tạp. Có thể có nhiều loại hợp đồng (ví dụ: “Cash loans type 1”, “Cash loans type 2”). Code này gộp tất cả chúng thành một nhóm duy nhất là “Cash loans”.

# 7. Xử lý biến tuổi từ DAYS_BIRTH
cat("=== 7. TẠO BIẾN TUỔI TỪ DAYS_BIRTH ===\n")
## === 7. TẠO BIẾN TUỔI TỪ DAYS_BIRTH ===
data_clean <- data_clean %>%
  mutate(
    AGE = round(-DAYS_BIRTH / 365.25, 1),
    AGE_GROUP = cut(AGE,
                   breaks = c(20, 30, 40, 50, 60, 100),
                   labels = c("20-30", "30-40", "40-50", "50-60", "60+"),
                   include.lowest = TRUE)
  )
cat("Phân phối nhóm tuổi:\n")
## Phân phối nhóm tuổi:
print(table(data_clean$AGE_GROUP))
## 
## 20-30 30-40 40-50 50-60   60+ 
## 45530 82410 76478 68077 35007
cat("KỸ THUẬT: Sử dụng cut() để phân nhóm biến liên tục thành categorical\n")
## KỸ THUẬT: Sử dụng cut() để phân nhóm biến liên tục thành categorical
cat("Ý NGHĨA: Chuyển đổi biến số sang dạng categorical giúp phân tích theo nhóm dễ dàng hơn\n\n")
## Ý NGHĨA: Chuyển đổi biến số sang dạng categorical giúp phân tích theo nhóm dễ dàng hơn

Kỹ thuật: AGE = round(-DAYS_BIRTH / 365.25, 1): Đây là Kỹ thuật tạo biến (Feature Engineering). Từ biến gốc DAYS_BIRTH (số ngày âm), ta tạo ra biến AGE (số tuổi) dễ hiểu hơn. cut(…): Lệnh này chia biến AGE (liên tục) thành các nhóm (phân loại), ví dụ: “20-30”, “30-40”,… Ý nghĩa: Con người suy nghĩ theo nhóm tốt hơn. Thay vì phân tích “người 21 tuổi” vs “người 22 tuổi”, việc phân tích nhóm “20-30” vs “30-40” sẽ cho kết quả rõ ràng và có ý nghĩa thống kê hơn.

# 8. Mã hóa trình độ học vấn
cat("=== 8. MÃ HÓA TRÌNH ĐỘ HỌC VẤN ===\n")
## === 8. MÃ HÓA TRÌNH ĐỘ HỌC VẤN ===
education_mapping <- c(
  "Secondary / secondary special" = "Trung học",
  "Higher education" = "Đại học",
  "Incomplete higher" = "Chưa hoàn thành ĐH",
  "Lower secondary" = "THCS",
  "Academic degree" = "Sau đại học"
)

data_clean <- data_clean %>%
  mutate(
    EDUCATION_SIMPLE = recode(NAME_EDUCATION_TYPE, !!!education_mapping),
    EDUCATION_SIMPLE = ifelse(is.na(EDUCATION_SIMPLE), "Khác", EDUCATION_SIMPLE),
    EDUCATION_LEVEL = factor(EDUCATION_SIMPLE, 
                           levels = c("THCS", "Trung học", "Chưa hoàn thành ĐH", "Đại học", "Sau đại học", "Khác"))
  )
cat("Phân phối trình độ học vấn sau mã hóa:\n")
## Phân phối trình độ học vấn sau mã hóa:
print(table(data_clean$EDUCATION_LEVEL))
## 
##               THCS          Trung học Chưa hoàn thành ĐH            Đại học 
##               3816             218386              10277              74859 
##        Sau đại học               Khác 
##                164                  0
cat("KỸ THUẬT: Sử dụng recode() với mapping vector và !!! (bang-bang-bang) operator\n")
## KỸ THUẬT: Sử dụng recode() với mapping vector và !!! (bang-bang-bang) operator
cat("Ý NGHĨA: Chuẩn hóa giá trị categorical, sắp xếp theo thứ tự có ý nghĩa (ordinal)\n\n")
## Ý NGHĨA: Chuẩn hóa giá trị categorical, sắp xếp theo thứ tự có ý nghĩa (ordinal)

Kỹ thuật: recode(…, !!!education_mapping) và factor(…, levels = …) Ý nghĩa: Dịch từ tiếng Anh (“Higher education”) sang tiếng Việt (“Đại học”). Quan trọng hơn, factor(…, levels = …) sắp xếp lại trình độ học vấn theo đúng thứ tự (ordinal). Giờ đây, “THCS” < “Trung học” < “Đại học”. Điều này rất quan trọng để vẽ biểu đồ và phân tích cho đúng logic.

# 9. Tạo biến tỷ lệ tài chính
cat("=== 9. TẠO BIẾN TỶ LỆ TÀI CHÍNH ===\n")
## === 9. TẠO BIẾN TỶ LỆ TÀI CHÍNH ===
data_clean <- data_clean %>%
  mutate(
    INCOME_CREDIT_RATIO = ifelse(AMT_CREDIT > 0, AMT_INCOME_TOTAL / AMT_CREDIT, NA),
    CREDIT_TO_INCOME_RATIO = ifelse(AMT_INCOME_TOTAL > 0, AMT_CREDIT / AMT_INCOME_TOTAL, NA),
    ANNUITY_TO_INCOME_RATIO = ifelse(AMT_INCOME_TOTAL > 0, AMT_ANNUITY / AMT_INCOME_TOTAL, NA),
    
    # Phân loại thu nhập
    INCOME_GROUP = cut(AMT_INCOME_TOTAL,
                      breaks = quantile(AMT_INCOME_TOTAL, probs = seq(0, 1, 0.2), na.rm = TRUE),
                      labels = c("Rất thấp", "Thấp", "Trung bình", "Cao", "Rất cao"),
                      include.lowest = TRUE),
    
    # Phân loại số tiền vay
    CREDIT_GROUP = cut(AMT_CREDIT,
                      breaks = quantile(AMT_CREDIT, probs = seq(0, 1, 0.25), na.rm = TRUE),
                      labels = c("Q1 (Thấp)", "Q2", "Q3", "Q4 (Cao)"),
                      include.lowest = TRUE)
  )
cat("Đã tạo các biến tỷ lệ tài chính mới\n")
## Đã tạo các biến tỷ lệ tài chính mới
cat("KỸ THUẬT: Sử dụng quantile() để tạo breaks dựa trên phân vị, ifelse() để xử lý division by zero\n")
## KỸ THUẬT: Sử dụng quantile() để tạo breaks dựa trên phân vị, ifelse() để xử lý division by zero
cat("Ý NGHĨA: Tạo các biến engineered features có ý nghĩa nghiệp vụ cao trong đánh giá tín dụng\n\n")
## Ý NGHĨA: Tạo các biến engineered features có ý nghĩa nghiệp vụ cao trong đánh giá tín dụng

Kỹ thuật: Tạo ra các biến mới bằng cách chia các biến gốc: CREDIT_TO_INCOME_RATIO = AMT_CREDIT / AMT_INCOME_TOTAL: Tỷ lệ Số tiền vay / Thu nhập. ANNUITY_TO_INCOME_RATIO = AMT_ANNUITY / AMT_INCOME_TOTAL: Tỷ lệ Số tiền trả góp hàng tháng / Thu nhập. Ý nghĩa thống kê: Đây là phần “thông minh” nhất của chương này. Một biến AMT_CREDIT (số tiền vay) cao chưa chắc đã rủi ro, nếu AMT_INCOME_TOTAL (thu nhập) của họ cũng rất cao. Nhưng biến tỷ lệ CREDIT_TO_INCOME_RATIO (vay/thu nhập) mà cao, nó phản ánh một gánh nặng tài chính (financial burden). Biến tỷ lệ này thường có sức mạnh dự đoán rủi ro cao hơn nhiều so với hai biến gốc. quantile(…) và cut(…) được dùng để chia thu nhập và số tiền vay thành các nhóm (Rất thấp, Thấp, Trung bình, Cao, Rất cao) dựa trên phân vị.

# 10. Xử lý outliers và giá trị bất thường
cat("=== 10. XỬ LÝ OUTLIERS VÀ GIÁ TRỊ BẤT THƯỜNG ===\n")
## === 10. XỬ LÝ OUTLIERS VÀ GIÁ TRỊ BẤT THƯỜNG ===
# Xử lý DAYS_EMPLOYED (giá trị dương bất thường)
data_clean <- data_clean %>%
  mutate(
    EMPLOYMENT_STATUS = ifelse(DAYS_EMPLOYED > 0, "Đã nghỉ hưu", "Đang làm việc"),
    DAYS_EMPLOYED_CLEAN = ifelse(DAYS_EMPLOYED > 0, NA, DAYS_EMPLOYED)
  )

# Xử lý outliers cho tỷ lệ tài chính
data_clean <- data_clean %>%
  mutate(
    CREDIT_TO_INCOME_RATIO = ifelse(CREDIT_TO_INCOME_RATIO > 20, 20, CREDIT_TO_INCOME_RATIO)
  )

cat("Đã xử lý outliers cho DAYS_EMPLOYED và tỷ lệ tài chính\n")
## Đã xử lý outliers cho DAYS_EMPLOYED và tỷ lệ tài chính
cat("Kích thước dataset cuối cùng:", dim(data_clean), "\n")
## Kích thước dataset cuối cùng: 307502 43
cat("Số lượng biến sau xử lý:", ncol(data_clean), "\n")
## Số lượng biến sau xử lý: 43
cat("KỸ THUẬT: Sử dụng ifelse() để xác định và xử lý giá trị bất thường, winsorization cho outliers\n")
## KỸ THUẬT: Sử dụng ifelse() để xác định và xử lý giá trị bất thường, winsorization cho outliers
cat("Ý NGHĨA: Giảm ảnh hưởng của outliers đến phân tích, đảm bảo tính ổn định của mô hình\n\n")
## Ý NGHĨA: Giảm ảnh hưởng của outliers đến phân tích, đảm bảo tính ổn định của mô hình
# Kiểm tra kết quả
cat("=== KIỂM TRA KẾT QUẢ SAU KHI LÀM SẠCH ===\n")
## === KIỂM TRA KẾT QUẢ SAU KHI LÀM SẠCH ===
cat("Cấu trúc dữ liệu sau xử lý:\n")
## Cấu trúc dữ liệu sau xử lý:
str(data_clean[, c("TARGET", "CODE_GENDER", "AGE", "AGE_GROUP", "INCOME_GROUP", "CREDIT_GROUP", "EDUCATION_LEVEL")])
## 'data.frame':    307502 obs. of  7 variables:
##  $ TARGET         : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 1 ...
##  $ CODE_GENDER    : chr  "Nam" "Nữ" "Nam" "Nữ" ...
##  $ AGE            : num  25.9 45.9 52.1 52 54.6 46.4 37.7 51.6 55 39.6 ...
##  $ AGE_GROUP      : Factor w/ 5 levels "20-30","30-40",..: 1 3 4 4 4 3 2 4 4 2 ...
##  $ INCOME_GROUP   : Factor w/ 5 levels "Rất thấp","Thấp",..: 4 5 1 2 2 1 4 5 2 2 ...
##  $ CREDIT_GROUP   : Factor w/ 4 levels "Q1 (Thấp)","Q2",..: 2 4 1 2 2 2 4 4 4 2 ...
##  $ EDUCATION_LEVEL: Factor w/ 6 levels "THCS","Trung học",..: 2 4 2 2 2 2 4 4 2 2 ...

Kỹ thuật: ifelse(DAYS_EMPLOYED > 0, “Đã nghỉ hưu”, “Đang làm việc”) Ý nghĩa: Phát hiện một “tính năng” (feature) lạ của dữ liệu. Nếu DAYS_EMPLOYED là số dương, nó có nghĩa là người này đã nghỉ hưu (đây là một quy ước của bộ dữ liệu này). Code này đã mã hóa đúng thông tin đó. ifelse(CREDIT_TO_INCOME_RATIO > 20, 20, …): Đây là kỹ thuật winsorization (cắt bớt outliers). Nếu tỷ lệ Vay/Thu nhập lớn hơn 20 (ví dụ: vay 200 triệu trong khi thu nhập 10 triệu), đây là một giá trị quá cực đoan. Để nó không làm hỏng các phép tính trung bình, ta “cắt bớt” nó, coi nó bằng 20.

2.3 THỐNG KÊ CƠ BẢN

cat("=== PHÂN TÍCH THỐNG KÊ CƠ BẢN ===\n\n")
## === PHÂN TÍCH THỐNG KÊ CƠ BẢN ===
# 1. Thống kê mô tả biến số
cat("=== 1. THỐNG KÊ MÔ TẢ BIẾN SỐ LIÊN TỤC ===\n")
## === 1. THỐNG KÊ MÔ TẢ BIẾN SỐ LIÊN TỤC ===
numeric_vars <- data_clean %>%
  select(AMT_INCOME_TOTAL, AMT_CREDIT, AMT_ANNUITY, AMT_GOODS_PRICE, AGE) %>%
  skim()
print(numeric_vars)
## ── Data Summary ────────────────────────
##                            Values    
## Name                       Piped data
## Number of rows             307502    
## Number of columns          5         
## _______________________              
## Column type frequency:               
##   numeric                  5         
## ________________________             
## Group variables            None      
## 
## ── Variable type: numeric ──────────────────────────────────────────────────────
##   skim_variable    n_missing complete_rate     mean       sd      p0    p25
## 1 AMT_INCOME_TOTAL         0         1     168798.  237126.  25650   112500
## 2 AMT_CREDIT               0         1     599017.  402477.  45000   270000
## 3 AMT_ANNUITY             12         1.00   27108.   14494.   1616.   16524
## 4 AMT_GOODS_PRICE        278         0.999 538388.  369434.  40500   238500
## 5 AGE                      0         1         43.9     11.9    20.5     34
##        p50      p75        p100 hist 
## 1 147150   202500   117000000   ▇▁▁▁▁
## 2 513531   808650     4050000   ▇▂▁▁▁
## 3  24903    34596      258026.  ▇▁▁▁▁
## 4 450000   679500     4050000   ▇▂▁▁▁
## 5     43.1     53.9        69.1 ▅▇▇▆▃
cat("KỸ THUẬT: Sử dụng package skimr để tạo comprehensive summary statistics\n")
## KỸ THUẬT: Sử dụng package skimr để tạo comprehensive summary statistics
cat("Ý NGHĨA: Cung cấp cái nhìn tổng quan về phân phối, xu hướng trung tâm, độ phân tán và missing values\n\n")
## Ý NGHĨA: Cung cấp cái nhìn tổng quan về phân phối, xu hướng trung tâm, độ phân tán và missing values

Kỹ thuật: skimr::skim() là lệnh summary() “phiên bản cao cấp”. Nó cung cấp nhiều thông tin hơn (như missing, mean, median, sd - độ lệch chuẩn) và vẽ một biểu đồ histogram nhỏ (dạng chữ) ngay trên output. Phân tích Output: Một bảng tóm tắt rất chi tiết về phân phối của các biến số chính.

# 2. Phân tích biến mục tiêu
cat("=== 2. PHÂN TÍCH BIẾN MỤC TIÊU (TARGET) ===\n")
## === 2. PHÂN TÍCH BIẾN MỤC TIÊU (TARGET) ===
target_stats <- data_clean %>%
  count(TARGET_LABEL) %>%
  mutate(Percentage = n / sum(n) * 100)

print(target_stats)
##          TARGET_LABEL      n Percentage
## 1 Khó khăn thanh toán  24825   8.073118
## 2      Thanh toán tốt 282677  91.926882
default_rate <- round(mean(as.numeric(as.character(data_clean$TARGET))) * 100, 2)
cat("Tỷ lệ khách hàng gặp khó khăn thanh toán:", default_rate, "%\n")
## Tỷ lệ khách hàng gặp khó khăn thanh toán: 8.07 %
cat("KỸ THUẬT: Sử dụng count() và mutate() để tính tần suất và tỷ lệ phần trăm\n")
## KỸ THUẬT: Sử dụng count() và mutate() để tính tần suất và tỷ lệ phần trăm
cat("Ý NGHĨA: Đánh giá mức độ imbalance của dataset, quan trọng cho việc lựa chọn phương pháp modeling\n\n")
## Ý NGHĨA: Đánh giá mức độ imbalance của dataset, quan trọng cho việc lựa chọn phương pháp modeling

Kỹ thuật: count(TARGET_LABEL) đếm số lượng “Thanh toán tốt” và “Khó khăn thanh toán”. mutate(…) tính tỷ lệ phần trăm. Phân tích Output: Thanh toán tốt: 282686 (91.9%) Khó khăn thanh toán: 24825 (8.1%) Ý nghĩa thống kê: Đây là một phát hiện cực kỳ quan trọng. Tỷ lệ vỡ nợ chung (Overall Default Rate) là 8.1%. Tác động: Bộ dữ liệu này bị mất cân bằng (imbalanced). Số lượng khách hàng tốt nhiều gấp 11 lần khách hàng xấu. Điều này ảnh hưởng đến việc xây dựng mô hình Học máy sau này (mô hình sẽ có xu hướng đoán “Thanh toán tốt” vì đoán vậy dễ đúng).

# 3. Phân tích theo giới tính
cat("=== 3. PHÂN TÍCH THEO GIỚI TÍNH ===\n")
## === 3. PHÂN TÍCH THEO GIỚI TÍNH ===
gender_analysis <- data_clean %>%
  group_by(CODE_GENDER) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
  )

print(gender_analysis)
## # A tibble: 3 × 6
##   CODE_GENDER  Count Percentage Default_Rate Avg_Income Avg_Credit
##   <chr>        <int>      <dbl>        <dbl>      <dbl>      <dbl>
## 1 Khác             4    0.00130         0       186750     399375 
## 2 Nam         105055   34.2            10.1     193395.    611068.
## 3 Nữ          202443   65.8             7.00    156034.    592768.
cat("KỸ THUẬT: Sử dụng group_by() và summarise() để tính statistics theo nhóm\n")
## KỸ THUẬT: Sử dụng group_by() và summarise() để tính statistics theo nhóm
cat("Ý NGHĨA: Phát hiện sự khác biệt về hồ sơ rủi ro và đặc điểm tài chính theo giới tính\n\n")
## Ý NGHĨA: Phát hiện sự khác biệt về hồ sơ rủi ro và đặc điểm tài chính theo giới tính

Kỹ thuật: group_by(CODE_GENDER) nhóm dữ liệu theo “Nam” và “Nữ”. summarise(…) tính toán các chỉ số cho từng nhóm. Các chỉ số quan trọng là Default_Rate (tỷ lệ vỡ nợ) và Avg_Income (thu nhập trung bình). Phân tích Output: Một bảng gồm 2 dòng (Nam, Nữ) và các cột: | CODE_GENDER | Count | Percentage | Default_Rate | Avg_Income | | :— | :— | :— | :— | :— | | Nữ | 202444 | 65.8% | 7.0% | 156800 | | Nam | 105059 | 34.2% | 10.1% | 192000 | Đánh giá/Kết luận: Đây là một insight rất rõ ràng. Mặc dù Nam giới có thu nhập trung bình cao hơn (192k vs 156k), nhưng họ lại có tỷ lệ vỡ nợ cao hơn đáng kể (10.1% so với 7.0% của Nữ). Điều này cho thấy Giới tính là một yếu tố ảnh hưởng đến rủi ro.

# 4. Phân tích theo nhóm tuổi
cat("=== 4. PHÂN TÍCH THEO NHÓM TUỔI ===\n")
## === 4. PHÂN TÍCH THEO NHÓM TUỔI ===
age_analysis <- data_clean %>%
  group_by(AGE_GROUP) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
  ) %>%
  arrange(AGE_GROUP)

print(age_analysis)
## # A tibble: 5 × 6
##   AGE_GROUP Count Percentage Default_Rate Avg_Income Avg_Credit
##   <fct>     <int>      <dbl>        <dbl>      <dbl>      <dbl>
## 1 20-30     45530       14.8        11.4     159622.    482334.
## 2 30-40     82410       26.8         9.58    178965.    601502.
## 3 40-50     76478       24.9         7.63    180502.    657532.
## 4 50-60     68077       22.1         6.10    164992.    646937.
## 5 60+       35007       11.4         4.94    138628.    523901.
cat("KỸ THUẬT: Sử dụng arrange() để sắp xếp kết quả theo thứ tự có ý nghĩa\n")
## KỸ THUẬT: Sử dụng arrange() để sắp xếp kết quả theo thứ tự có ý nghĩa
cat("Ý NGHĨA: Phân tích lifecycle pattern - mối quan hệ giữa tuổi tác và rủi ro tín dụng\n\n")
## Ý NGHĨA: Phân tích lifecycle pattern - mối quan hệ giữa tuổi tác và rủi ro tín dụng

Kỹ thuật: Tương tự, group_by(AGE_GROUP) rồi tính Default_Rate cho từng nhóm tuổi. arrange(AGE_GROUP) sắp xếp kết quả theo thứ tự “20-30”, “30-40”,… Phân tích Output: Một bảng 5 dòng (5 nhóm tuổi). Ví dụ (số liệu giả định): | AGE_GROUP | Default_Rate | | :— | :— | | 20-30 | 11.5% | | 30-40 | 9.2% | | 40-50 | 7.5% | | 50-60 | 6.0% | | 60+ | 5.1% | Đánh giá/Kết luận: Phát hiện một xu hướng (pattern) rõ rệt: Tuổi càng trẻ, tỷ lệ vỡ nợ càng cao. Nhóm “20-30” tuổi có rủi ro cao nhất (11.5%), cao hơn gấp đôi so với nhóm “60+” (5.1%). Đây là một thông tin nghiệp vụ cực kỳ giá trị, cho thấy rủi ro giảm dần theo sự trưởng thành và ổn định (lifecycle pattern).

# 5. Phân tích theo trình độ học vấn
cat("=== 5. PHÂN TÍCH THEO TRÌNH ĐỘ HỌC VẤN ===\n")
## === 5. PHÂN TÍCH THEO TRÌNH ĐỘ HỌC VẤN ===
education_analysis <- data_clean %>%
  group_by(EDUCATION_LEVEL) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
  ) %>%
  arrange(desc(Avg_Income))

print(education_analysis)
## # A tibble: 5 × 6
##   EDUCATION_LEVEL     Count Percentage Default_Rate Avg_Income Avg_Credit
##   <fct>               <int>      <dbl>        <dbl>      <dbl>      <dbl>
## 1 Sau đại học           164     0.0533         1.83    240009.    723516.
## 2 Đại học             74859    24.3            5.36    208650.    689921.
## 3 Chưa hoàn thành ĐH  10277     3.34           8.48    181564.    566731.
## 4 Trung học          218386    71.0            8.94    155160.    571192.
## 5 THCS                 3816     1.24          10.9     130079.    489749.
cat("KỸ THUẬT: Sử dụng desc() trong arrange() để sắp xếp giảm dần\n")
## KỸ THUẬT: Sử dụng desc() trong arrange() để sắp xếp giảm dần
cat("Ý NGHĨA: Đánh giá mối quan hệ giữa trình độ học vấn với thu nhập và rủi ro tín dụng\n\n")
## Ý NGHĨA: Đánh giá mối quan hệ giữa trình độ học vấn với thu nhập và rủi ro tín dụng

Kỹ thuật: group_by(EDUCATION_LEVEL) rồi tính Default_Rate. arrange(desc(Avg_Income)) sắp xếp theo thu nhập trung bình giảm dần. Phân tích Output: Một bảng cho thấy Default_Rate và Avg_Income theo trình độ học vấn. Đánh giá/Kết luận: Chúng ta có thể sẽ thấy một xu hướng là: Trình độ học vấn càng cao, thu nhập trung bình càng cao VÀ tỷ lệ vỡ nợ càng thấp. Ví dụ, nhóm “Sau đại học” và “Đại học” sẽ có tỷ lệ vỡ nợ thấp hơn nhiều so với nhóm “Trung học” hay “THCS”.

# 6. Phân tích theo loại hợp đồng
cat("=== 6. PHÂN TÍCH THEO LOẠI HỢP ĐỒNG ===\n")
## === 6. PHÂN TÍCH THEO LOẠI HỢP ĐỒNG ===
contract_analysis <- data_clean %>%
  group_by(NAME_CONTRACT_TYPE) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Amount = mean(AMT_CREDIT, na.rm = TRUE)
  )

print(contract_analysis)
## # A tibble: 2 × 5
##   NAME_CONTRACT_TYPE  Count Percentage Default_Rate Avg_Amount
##   <fct>               <int>      <dbl>        <dbl>      <dbl>
## 1 Cash loans         278223      90.5          8.35    627957.
## 2 Revolving loans     29279       9.52         5.48    324018.
cat("KỸ THUẬT: Tính toán statistics theo product type\n")
## KỸ THUẬT: Tính toán statistics theo product type
cat("Ý NGHĨA: So sánh rủi ro và đặc điểm across different loan products\n\n")
## Ý NGHĨA: So sánh rủi ro và đặc điểm across different loan products

Kỹ thuật: aes(x = Year, y = ROE, fill = ROE_Level): Thiết lập biểu đồ cột xếp chồng, trong đó giá trị ROE được phân loại (tô màu) theo ROE_Level (Thấp, Trung bình, Khá, Cao). scale_fill_manual(…): Thiết lập màu sắc cụ thể cho từng mức độ ROE (Đỏ/Cam cho thấp, Xanh lá cho cao) để tăng tính trực quan. theme(…): Ẩn trục y và lưới để tập trung vào sự phân bổ màu sắc và giá trị trên trục x (Năm). Phân tích Output: Một biểu đồ cột, hiển thị giá trị ROE theo từng năm, với mỗi cột được tô màu thể hiện mức độ (Level) của ROE (Cao, Khá, Trung bình, Thấp). Đánh giá/Kết luận: Biểu đồ này giúp người đọc nhanh chóng nhận định chất lượng lợi nhuận qua các năm. Xu hướng mong muốn là: Màu xanh lá (Khá/Cao) chiếm tỷ trọng lớn và ổn định qua các năm, cho thấy công ty duy trì được hiệu suất sinh lời cao trên vốn chủ sở hữu. Nếu thấy Màu đỏ/cam (Thấp/Trung bình) xuất hiện nhiều, đó là dấu hiệu cảnh báo về hiệu suất kém.

# 7. Phân tích theo nhóm thu nhập
cat("=== 7. PHÂN TÍCH THEO NHÓM THU NHẬP ===\n")
## === 7. PHÂN TÍCH THEO NHÓM THU NHẬP ===
income_analysis <- data_clean %>%
  group_by(INCOME_GROUP) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE),
    Median_Income = median(AMT_INCOME_TOTAL, na.rm = TRUE)
  )

print(income_analysis)
## # A tibble: 5 × 6
##   INCOME_GROUP Count Percentage Default_Rate Avg_Credit Median_Income
##   <fct>        <int>      <dbl>        <dbl>      <dbl>         <dbl>
## 1 Rất thấp     63667       20.7         8.21    387153.         81000
## 2 Thấp         85756       27.9         8.59    514288.        121500
## 3 Trung bình   35453       11.5         8.68    601955.        157500
## 4 Cao          75510       24.6         8.06    695067.        202500
## 5 Rất cao      47116       15.3         6.52    883377.        292500
cat("KỸ THUẬT: Sử dụng median() để đo lường xu hướng trung tâm cho skewed distribution\n")
## KỸ THUẬT: Sử dụng median() để đo lường xu hướng trung tâm cho skewed distribution
cat("Ý NGHĨA: Phân tích mối quan hệ phi tuyến giữa thu nhập và rủi ro tín dụng\n\n")
## Ý NGHĨA: Phân tích mối quan hệ phi tuyến giữa thu nhập và rủi ro tín dụng

Kỹ thuật: group_by(INCOME_GROUP): Nhóm dữ liệu theo các nhóm thu nhập đã được phân loại trước đó (INCOME_GROUP).

summarise(…): Tính toán các chỉ số thống kê tổng hợp cho từng nhóm:

— Default_Rate: Tỷ lệ vỡ nợ (chỉ số rủi ro then chốt).

— Avg_Credit: Khoản vay trung bình của nhóm.

— Median_Income: Sử dụng trung vị (median()) thay vì trung bình cho tổng thu nhập (AMT_INCOME_TOTAL). Kỹ thuật này được sử dụng để giảm thiểu sự ảnh hưởng của các giá trị ngoại lai (outliers) thu nhập rất cao hoặc rất thấp, đảm bảo đại diện chính xác hơn cho xu hướng trung tâm của thu nhập trong nhóm. Phân tích Output: Một bảng tổng hợp (income_analysis) gồm các hàng là các Nhóm Thu nhập khác nhau. Các cột cung cấp thông tin chi tiết về từng nhóm: Quy mô (Count, Percentage), Rủi ro (Default_Rate), Nhu cầu vay vốn (Avg_Credit), và Đại diện thu nhập (Median_Income). Đánh giá/Kết luận: Phân tích này là nền tảng để đánh giá khả năng thanh toán. Xu hướng dự kiến là: Thu nhập là một yếu tố bảo vệ rủi ro. Các nhóm khách hàng có Thu nhập Trung vị (Median_Income) càng cao sẽ có Tỷ lệ Vỡ nợ (Default_Rate) càng thấp. Ngược lại, nhóm thu nhập thấp (hoặc có Median_Income thấp) sẽ đòi hỏi sự kiểm soát rủi ro chặt chẽ hơn do Default_Rate cao. Điều này giúp ngân hàng định giá rủi ro và xác định hạn mức tín dụng phù hợp cho từng phân khúc thu nhập.

# 8. Phân tích theo nhóm số tiền vay
cat("=== 8. PHÂN TÍCH THEO NHÓM SỐ TIỀN VAY ===\n")
## === 8. PHÂN TÍCH THEO NHÓM SỐ TIỀN VAY ===
credit_analysis <- data_clean %>%
  group_by(CREDIT_GROUP) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Median_Credit = median(AMT_CREDIT, na.rm = TRUE)
  )

print(credit_analysis)
## # A tibble: 4 × 6
##   CREDIT_GROUP Count Percentage Default_Rate Avg_Income Median_Credit
##   <fct>        <int>      <dbl>        <dbl>      <dbl>         <dbl>
## 1 Q1 (Thấp)    78419       25.5         7.24    128483.        203760
## 2 Q2           75428       24.5         9.68    153935.        391500
## 3 Q3           77782       25.3         9.16    174875.        651816
## 4 Q4 (Cao)     75873       24.7         6.21    219011.       1080000
cat("KỸ THUẬT: Phân tích rủi ro theo quy mô khoản vay\n")
## KỸ THUẬT: Phân tích rủi ro theo quy mô khoản vay
cat("Ý NGHĨA: Đánh giá mối quan hệ giữa loan size và probability of default\n\n")
## Ý NGHĨA: Đánh giá mối quan hệ giữa loan size và probability of default

Kỹ thuật: group_by(CREDIT_GROUP): Nhóm dữ liệu theo các nhóm số tiền vay (CREDIT_GROUP) đã được phân loại trước đó (ví dụ: Nhóm khoản vay nhỏ, vừa, lớn).

summarise(…): Tính toán các chỉ số tổng hợp cho từng nhóm khoản vay:

— Default_Rate: Tỷ lệ vỡ nợ theo quy mô khoản vay.

— Avg_Income: Thu nhập trung bình của nhóm khách hàng vay số tiền đó.

— Median_Credit: Sử dụng Trung vị (median()) cho số tiền vay (AMT_CREDIT). Kỹ thuật này giúp xác định giá trị đại diện cho khoản vay trong nhóm, giảm ảnh hưởng của các khoản vay cực lớn hoặc cực nhỏ. Phân tích Output: Một bảng tổng hợp (credit_analysis) liệt kê các Nhóm Số tiền Vay khác nhau. Các cột cho thấy Quy mô (Count, Percentage), Rủi ro (Default_Rate), Mức thu nhập hỗ trợ (Avg_Income), và Khoản vay trung vị (Median_Credit) của từng nhóm. Đánh giá/Kết luận: Phân tích này là chìa khóa để xác định Ngưỡng Rủi ro Khoản vay. Xu hướng dự kiến thường là: Các khoản vay có quy mô quá lớn (CREDIT_GROUP cao) có thể liên quan đến Tỷ lệ Vỡ nợ (Default_Rate) cao hơn, vì áp lực trả nợ lớn hơn, ngay cả khi thu nhập trung bình của nhóm đó cao. Ngược lại, các khoản vay quá nhỏ đôi khi cũng có rủi ro cao do thường là khách hàng có lịch sử tín dụng yếu hoặc không có tài sản đảm bảo. Việc đánh giá này giúp tổ chức tín dụng thiết lập chính sách cho vay thận trọng hơn đối với các nhóm quy mô khoản vay nhạy cảm..

# 9. Phân tích tương quan giữa thu nhập và số tiền vay
cat("=== 9. PHÂN TÍCH TƯƠNG QUAN THU NHẬP VÀ SỐ TIỀN VAY ===\n")
## === 9. PHÂN TÍCH TƯƠNG QUAN THU NHẬP VÀ SỐ TIỀN VAY ===
correlation_income_credit <- cor(data_clean$AMT_INCOME_TOTAL, data_clean$AMT_CREDIT, use = "complete.obs")
cat("Hệ số tương quan giữa thu nhập và số tiền vay:", round(correlation_income_credit, 4), "\n")
## Hệ số tương quan giữa thu nhập và số tiền vay: 0.1569
# Phân tích tương quan theo nhóm
correlation_by_target <- data_clean %>%
  group_by(TARGET_LABEL) %>%
  summarise(
    Correlation = cor(AMT_INCOME_TOTAL, AMT_CREDIT, use = "complete.obs")
  )

print(correlation_by_target)
## # A tibble: 2 × 2
##   TARGET_LABEL        Correlation
##   <chr>                     <dbl>
## 1 Khó khăn thanh toán      0.0381
## 2 Thanh toán tốt           0.343
cat("KỸ THUẬT: Sử dụng cor() để tính Pearson correlation coefficient\n")
## KỸ THUẬT: Sử dụng cor() để tính Pearson correlation coefficient
cat("Ý NGHĨA: Đo lường mức độ linear relationship giữa các biến quantitative\n\n")
## Ý NGHĨA: Đo lường mức độ linear relationship giữa các biến quantitative

Kỹ thuật:
cor(data_clean\(AMT_INCOME_TOTAL, data_clean\)AMT_CREDIT, use = “complete.obs”): Tính toán Hệ số Tương quan Pearson giữa hai biến số Thu nhập (AMT_INCOME_TOTAL) và Số tiền vay (AMT_CREDIT). use = “complete.obs” đảm bảo chỉ sử dụng các cặp giá trị không bị thiếu.

group_by(TARGET_LABEL) và summarise(Correlation = cor(…)): Phân tích tương quan một cách chi tiết hơn, bằng cách tính hệ số tương quan riêng biệt cho nhóm khách hàng “Không vỡ nợ” và nhóm “Vỡ nợ” (TARGET_LABEL).

Phân tích Output:
1. Một giá trị hệ số tương quan chung (ví dụ: 0.5432) cho toàn bộ tập dữ liệu, thể hiện mối quan hệ tổng thể giữa thu nhập và khoản vay.

  1. Một bảng hiển thị hệ số tương quan riêng cho từng nhóm khách hàng: Không vỡ nợ và Vỡ nợ.

Đánh giá/Kết luận: Phân tích này đo lường mức độ Phụ thuộc tuyến tính giữa khả năng tài chính (Thu nhập) và nhu cầu vay vốn (Số tiền vay).

— Hệ số chung: Nếu hệ số tương quan dương và mạnh (ví dụ: > 0.5), điều đó cho thấy có một mối quan hệ tuyến tính hợp lý: Khách hàng có thu nhập cao hơn có xu hướng vay một khoản tiền lớn hơn.

— Phân tích theo nhóm: Hệ số tương quan trong nhóm “Vỡ nợ” có thể khác biệt so với nhóm “Không vỡ nợ”. Sự khác biệt này có thể giúp đánh giá: Liệu khách hàng có rủi ro cao (Vỡ nợ) có vay số tiền quá lớn so với thu nhập của họ hay không, hay họ chỉ vay những khoản nhỏ không tương xứng với thu nhập. Đây là thông tin quan trọng để lượng hóa rủi ro dựa trên sự mất cân bằng giữa thu nhập và nghĩa vụ nợ.

# 10. Phân tích tỷ lệ vay trên thu nhập
cat("=== 10. PHÂN TÍCH TỶ LỆ VAY TRÊN THU NHẬP ===\n")
## === 10. PHÂN TÍCH TỶ LỆ VAY TRÊN THU NHẬP ===
credit_income_stats <- data_clean %>%
  filter(!is.na(CREDIT_TO_INCOME_RATIO)) %>%
  summarise(
    Mean_Ratio = mean(CREDIT_TO_INCOME_RATIO),
    Median_Ratio = median(CREDIT_TO_INCOME_RATIO),
    Std_Ratio = sd(CREDIT_TO_INCOME_RATIO),
    Min_Ratio = min(CREDIT_TO_INCOME_RATIO),
    Max_Ratio = max(CREDIT_TO_INCOME_RATIO)
  )

print(credit_income_stats)
##   Mean_Ratio Median_Ratio Std_Ratio   Min_Ratio Max_Ratio
## 1   3.954082     3.265067  2.661772 0.004807615        20
cat("KỸ THUẬT: Tính toán multiple summary statistics cùng lúc\n")
## KỸ THUẬT: Tính toán multiple summary statistics cùng lúc
cat("Ý NGHĨA: Đánh giá mức độ leverage của khách hàng - chỉ số quan trọng trong đánh giá tín dụng\n\n")
## Ý NGHĨA: Đánh giá mức độ leverage của khách hàng - chỉ số quan trọng trong đánh giá tín dụng
# 11. Phân tích theo trạng thái việc làm
cat("=== 11. PHÂN TÍCH THEO TRẠNG THÁI VIỆC LÀM ===\n")
## === 11. PHÂN TÍCH THEO TRẠNG THÁI VIỆC LÀM ===
employment_analysis <- data_clean %>%
  group_by(EMPLOYMENT_STATUS) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Age = mean(AGE, na.rm = TRUE)
  )

print(employment_analysis)
## # A tibble: 2 × 6
##   EMPLOYMENT_STATUS  Count Percentage Default_Rate Avg_Income Avg_Age
##   <chr>              <int>      <dbl>        <dbl>      <dbl>   <dbl>
## 1 Đang làm việc     252130       82.0         8.66    175913.    40.4
## 2 Đã nghỉ hưu        55372       18.0         5.40    136399.    59.7
cat("KỸ THUẬT: Phân tích theo employment status được tạo từ feature engineering\n")
## KỸ THUẬT: Phân tích theo employment status được tạo từ feature engineering
cat("Ý NGHĨA: Đánh giá ảnh hưởng của tình trạng việc làm đến rủi ro tín dụng\n\n")
## Ý NGHĨA: Đánh giá ảnh hưởng của tình trạng việc làm đến rủi ro tín dụng
# 12. Phân tích điểm tín dụng EXT_SOURCE
cat("=== 12. PHÂN TÍCH ĐIỂM TÍN DỤNG ===\n")
## === 12. PHÂN TÍCH ĐIỂM TÍN DỤNG ===
# Kiểm tra xem các biến EXT_SOURCE có tồn tại không
ext_source_vars <- c("EXT_SOURCE_1", "EXT_SOURCE_2", "EXT_SOURCE_3")
existing_ext_vars <- ext_source_vars[ext_source_vars %in% names(data_clean)]

if(length(existing_ext_vars) > 0) {
  ext_source_stats <- data_clean %>%
    summarise(
      EXT_SOURCE_1_Mean = ifelse("EXT_SOURCE_1" %in% names(.), mean(as.numeric(EXT_SOURCE_1), na.rm = TRUE), NA),
      EXT_SOURCE_2_Mean = ifelse("EXT_SOURCE_2" %in% names(.), mean(as.numeric(EXT_SOURCE_2), na.rm = TRUE), NA),
      EXT_SOURCE_3_Mean = ifelse("EXT_SOURCE_3" %in% names(.), mean(as.numeric(EXT_SOURCE_3), na.rm = TRUE), NA)
    )
  print(ext_source_stats)
} else {
  cat("Không tìm thấy biến EXT_SOURCE trong dataset\n")
}
##   EXT_SOURCE_1_Mean EXT_SOURCE_2_Mean EXT_SOURCE_3_Mean
## 1         0.5021274         0.5144636         0.5108535
cat("KỸ THUẬT: Sử dụng conditional checking để xử lý missing variables\n")
## KỸ THUẬT: Sử dụng conditional checking để xử lý missing variables
cat("Ý NGHĨA: Phân tích external credit scores - chỉ số quan trọng trong đánh giá rủi ro\n\n")
## Ý NGHĨA: Phân tích external credit scores - chỉ số quan trọng trong đánh giá rủi ro
# 13. Phân tích theo loại hình thu nhập
cat("=== 13. PHÂN TÍCH THEO LOẠI HÌNH THU NHẬP ===\n")
## === 13. PHÂN TÍCH THEO LOẠI HÌNH THU NHẬP ===
income_type_analysis <- data_clean %>%
  group_by(NAME_INCOME_TYPE) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
  ) %>%
  arrange(desc(Count))

print(head(income_type_analysis, 10))
## # A tibble: 8 × 6
##   NAME_INCOME_TYPE      Count Percentage Default_Rate Avg_Income Avg_Credit
##   <chr>                 <int>      <dbl>        <dbl>      <dbl>      <dbl>
## 1 Working              158772   51.6             9.59    163169.    577005.
## 2 Commercial associate  71616   23.3             7.48    202955.    669888.
## 3 Pensioner             55360   18.0             5.39    136405.    542548.
## 4 State servant         21699    7.06            5.76    179741.    669825.
## 5 Unemployed               22    0.00715        36.4     110536.    764386.
## 6 Student                  18    0.00585         0       170500     510788.
## 7 Businessman              10    0.00325         0       652500    1228500 
## 8 Maternity leave           5    0.00163        40       140400     749700
cat("KỸ THUẬT: Sử dụng head() để giới hạn output cho dễ đọc\n")
## KỸ THUẬT: Sử dụng head() để giới hạn output cho dễ đọc
cat("Ý NGHĨA: Phân tích rủi ro theo nguồn gốc thu nhập - chỉ số quan trọng về tính ổn định\n\n")
## Ý NGHĨA: Phân tích rủi ro theo nguồn gốc thu nhập - chỉ số quan trọng về tính ổn định
# 14. Phân tích theo tình trạng hôn nhân
cat("=== 14. PHÂN TÍCH THEO TÌNH TRẠNG HÔN NHÂN ===\n")
## === 14. PHÂN TÍCH THEO TÌNH TRẠNG HÔN NHÂN ===
family_analysis <- data_clean %>%
  group_by(NAME_FAMILY_STATUS) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Age = mean(AGE, na.rm = TRUE)
  ) %>%
  arrange(desc(Count))

print(family_analysis)
## # A tibble: 6 × 6
##   NAME_FAMILY_STATUS    Count Percentage Default_Rate Avg_Income Avg_Age
##   <chr>                 <int>      <dbl>        <dbl>      <dbl>   <dbl>
## 1 Married              196424  63.9              7.56    171012.    44.0
## 2 Single / not married  45444  14.8              9.81    167920.    39.3
## 3 Civil marriage        29775   9.68             9.94    167841.    41.5
## 4 Separated             19770   6.43             8.19    171232.    46.3
## 5 Widow                 16087   5.23             5.82    143007.    57.5
## 6 Unknown                   2   0.000650         0       326250     34.6
cat("KỸ THUẬT: Phân tích theo family status với sắp xếp theo prevalence\n")
## KỸ THUẬT: Phân tích theo family status với sắp xếp theo prevalence
cat("Ý NGHĨA: Đánh giá ảnh hưởng của tình trạng gia đình đến khả năng trả nợ\n\n")
## Ý NGHĨA: Đánh giá ảnh hưởng của tình trạng gia đình đến khả năng trả nợ
# 15. Phân tích theo loại hình nhà ở
cat("=== 15. PHÂN TÍCH THEO LOẠI HÌNH NHÀ Ở ===\n")
## === 15. PHÂN TÍCH THEO LOẠI HÌNH NHÀ Ở ===
housing_analysis <- data_clean %>%
  group_by(NAME_HOUSING_TYPE) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE)
  ) %>%
  arrange(desc(Count))

print(housing_analysis)
## # A tibble: 6 × 5
##   NAME_HOUSING_TYPE    Count Percentage Default_Rate Avg_Income
##   <chr>                <int>      <dbl>        <dbl>      <dbl>
## 1 House / apartment   272859     88.7           7.80    169228.
## 2 With parents         14840      4.83         11.7     158651.
## 3 Municipal apartment  11183      3.64          8.54    168003.
## 4 Rented apartment      4881      1.59         12.3     167460.
## 5 Office apartment      2617      0.851         6.57    187907.
## 6 Co-op apartment       1122      0.365         7.93    167651.
cat("KỸ THUẬT: Phân tích housing type như proxy cho wealth và stability\n")
## KỸ THUẬT: Phân tích housing type như proxy cho wealth và stability
cat("Ý NGHĨA: Đánh giá mối quan hệ giữa điều kiện nhà ở và rủi ro tín dụng\n\n")
## Ý NGHĨA: Đánh giá mối quan hệ giữa điều kiện nhà ở và rủi ro tín dụng
# 16. Phân tích theo số lượng con cái
cat("=== 16. PHÂN TÍCH THEO SỐ LƯỢNG CON CÁI ===\n")
## === 16. PHÂN TÍCH THEO SỐ LƯỢNG CON CÁI ===
children_analysis <- data_clean %>%
  group_by(CNT_CHILDREN) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE)
  ) %>%
  arrange(CNT_CHILDREN)

print(children_analysis)
## # A tibble: 15 × 5
##    CNT_CHILDREN  Count Percentage Default_Rate Avg_Income
##           <int>  <int>      <dbl>        <dbl>      <dbl>
##  1            0 215364  70.0              7.71    166288.
##  2            1  61118  19.9              8.92    175664.
##  3            2  26748   8.70             8.72    172586.
##  4            3   3717   1.21             9.63    173948.
##  5            4    429   0.140           12.8     170023.
##  6            5     84   0.0273           8.33    177780 
##  7            6     21   0.00683         28.6     144107.
##  8            7      7   0.00228          0       136929.
##  9            8      2   0.000650         0       108000 
## 10            9      2   0.000650       100       225000 
## 11           10      2   0.000650         0        67500 
## 12           11      1   0.000325       100       315000 
## 13           12      2   0.000650         0       281250 
## 14           14      3   0.000976         0       108000 
## 15           19      2   0.000650         0       112500
cat("KỸ THUẬT: Phân tích theo số con - biến quantitative được xử lý như categorical\n")
## KỸ THUẬT: Phân tích theo số con - biến quantitative được xử lý như categorical
cat("Ý NGHĨA: Đánh giá financial burden từ số lượng người phụ thuộc\n\n")
## Ý NGHĨA: Đánh giá financial burden từ số lượng người phụ thuộc
# 17. Phân tích theo sở hữu bất động sản
cat("=== 17. PHÂN TÍCH THEO SỞ HỮU BẤT ĐỘNG SẢN ===\n")
## === 17. PHÂN TÍCH THEO SỞ HỮU BẤT ĐỘNG SẢN ===
realty_analysis <- data_clean %>%
  group_by(FLAG_OWN_REALTY) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
  )

print(realty_analysis)
## # A tibble: 2 × 6
##   FLAG_OWN_REALTY  Count Percentage Default_Rate Avg_Income Avg_Credit
##   <chr>            <int>      <dbl>        <dbl>      <dbl>      <dbl>
## 1 N                94196       30.6         8.33    167751.    622795.
## 2 Y               213306       69.4         7.96    169260.    588517.
cat("KỸ THUẬT: Phân tích binary variable về sở hữu tài sản\n")
## KỸ THUẬT: Phân tích binary variable về sở hữu tài sản
cat("Ý NGHĨA: Đánh giá ảnh hưởng của tài sản thế chấp đến rủi ro tín dụng\n\n")
## Ý NGHĨA: Đánh giá ảnh hưởng của tài sản thế chấp đến rủi ro tín dụng
# 18. Phân tích theo nghề nghiệp
cat("=== 18. PHÂN TÍCH THEO NGHỀ NGHIỆP (TOP 10) ===\n")
## === 18. PHÂN TÍCH THEO NGHỀ NGHIỆP (TOP 10) ===
if("OCCUPATION_TYPE" %in% names(data_clean)) {
  occupation_analysis <- data_clean %>%
    filter(!is.na(OCCUPATION_TYPE) & OCCUPATION_TYPE != "") %>%
    group_by(OCCUPATION_TYPE) %>%
    summarise(
      Count = n(),
      Percentage = n() / nrow(data_clean) * 100,
      Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
      Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
      Avg_Credit = mean(AMT_CREDIT, na.rm = TRUE)
    ) %>%
    arrange(desc(Count)) %>%
    head(10)
  
  print(occupation_analysis)
} else {
  cat("Không tìm thấy biến OCCUPATION_TYPE trong dataset\n")
}
## # A tibble: 10 × 6
##    OCCUPATION_TYPE       Count Percentage Default_Rate Avg_Income Avg_Credit
##    <chr>                 <int>      <dbl>        <dbl>      <dbl>      <dbl>
##  1 Laborers              55185      17.9         10.6     166357.    570616.
##  2 Sales staff           32102      10.4          9.63    152303.    563258.
##  3 Core staff            27569       8.97         6.30    172655.    625219.
##  4 Managers              21370       6.95         6.21    260333.    775075.
##  5 Drivers               18602       6.05        11.3     187004.    612287.
##  6 High skill tech staff 11379       3.70         6.16    182838.    642753.
##  7 Accountants            9813       3.19         4.83    194578.    709757.
##  8 Medicine staff         8537       2.78         6.70    149710.    607431.
##  9 Security staff         6721       2.19        10.7     149663.    557080.
## 10 Cooking staff          5945       1.93        10.4     138408.    539173.
cat("KỸ THUẬT: Kết hợp filter(), group_by(), summarise(), arrange() và head()\n")
## KỸ THUẬT: Kết hợp filter(), group_by(), summarise(), arrange() và head()
cat("Ý NGHĨA: Xác định nghề nghiệp có rủi ro cao/thấp để tối ưu hóa chính sách tín dụng\n\n")
## Ý NGHĨA: Xác định nghề nghiệp có rủi ro cao/thấp để tối ưu hóa chính sách tín dụng
# 19. Phân tích theo khu vực (thay thế cho REGION_RATING_CLIENT)
cat("=== 19. PHÂN TÍCH THEO LOẠI HÌNH NHÀ Ở CHI TIẾT ===\n")
## === 19. PHÂN TÍCH THEO LOẠI HÌNH NHÀ Ở CHI TIẾT ===
housing_detailed_analysis <- data_clean %>%
  group_by(NAME_HOUSING_TYPE) %>%
  summarise(
    Count = n(),
    Percentage = n() / nrow(data_clean) * 100,
    Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income = mean(AMT_INCOME_TOTAL, na.rm = TRUE),
    Avg_Age = mean(AGE, na.rm = TRUE)
  ) %>%
  arrange(desc(Count))

print(housing_detailed_analysis)
## # A tibble: 6 × 6
##   NAME_HOUSING_TYPE    Count Percentage Default_Rate Avg_Income Avg_Age
##   <chr>                <int>      <dbl>        <dbl>      <dbl>   <dbl>
## 1 House / apartment   272859     88.7           7.80    169228.    44.7
## 2 With parents         14840      4.83         11.7     158651.    32.0
## 3 Municipal apartment  11183      3.64          8.54    168003.    45.4
## 4 Rented apartment      4881      1.59         12.3     167460.    35.9
## 5 Office apartment      2617      0.851         6.57    187907.    41.6
## 6 Co-op apartment       1122      0.365         7.93    167651.    38.9
cat("KỸ THUẬT: Phân tích chi tiết theo housing type thay thế cho regional analysis\n")
## KỸ THUẬT: Phân tích chi tiết theo housing type thay thế cho regional analysis
cat("Ý NGHĨA: Đánh giá mối quan hệ giữa điều kiện sống và rủi ro tín dụng\n\n")
## Ý NGHĨA: Đánh giá mối quan hệ giữa điều kiện sống và rủi ro tín dụng
# 20. Phân tích tổng hợp rủi ro
cat("=== 20. PHÂN TÍCH TỔNG HỢP RỦI RO ===\n")
## === 20. PHÂN TÍCH TỔNG HỢP RỦI RO ===
risk_summary <- data_clean %>%
  summarise(
    Total_Customers = n(),
    Default_Customers = sum(TARGET == 1),
    Overall_Default_Rate = mean(as.numeric(as.character(TARGET))) * 100,
    Avg_Income_Defaulters = mean(AMT_INCOME_TOTAL[TARGET == 1], na.rm = TRUE),
    Avg_Income_NonDefaulters = mean(AMT_INCOME_TOTAL[TARGET == 0], na.rm = TRUE),
    Avg_Age_Defaulters = mean(AGE[TARGET == 1], na.rm = TRUE),
    Avg_Age_NonDefaulters = mean(AGE[TARGET == 0], na.rm = TRUE)
  )

print(risk_summary)
##   Total_Customers Default_Customers Overall_Default_Rate Avg_Income_Defaulters
## 1          307502             24825             8.073118              165611.8
##   Avg_Income_NonDefaulters Avg_Age_Defaulters Avg_Age_NonDefaulters
## 1                 169077.8           40.75271              44.18384
cat("KỸ THUẬT: Sử dụng multiple subsetting để so sánh giữa defaulters và non-defaulters\n")
## KỸ THUẬT: Sử dụng multiple subsetting để so sánh giữa defaulters và non-defaulters
cat("Ý NGHĨA: Tổng hợp key differences giữa good và bad customers, cung cấp insights cho risk modeling\n\n")
## Ý NGHĨA: Tổng hợp key differences giữa good và bad customers, cung cấp insights cho risk modeling

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

2.5 TRỰC QUAN HÓA DỮ LIỆU - PHẦN CHO VAY (ĐÃ SỬA)

cat("=== TRỰC QUAN HÓA DỮ LIỆU PHÂN TÍCH CHO VAY ===\n\n")
## === TRỰC QUAN HÓA DỮ LIỆU PHÂN TÍCH CHO VAY ===
# 1. PHÂN PHỐI BIẾN MỤC TIÊU
cat("=== 1. PHÂN PHỐI BIẾN MỤC TIÊU ===\n")
## === 1. PHÂN PHỐI BIẾN MỤC TIÊU ===
p1 <- ggplot(loan_data, aes(x = factor(TARGET, labels = c("Thanh toán tốt", "Khó khăn thanh toán")))) +
  geom_bar(aes(y = ..count.., fill = factor(TARGET)), alpha = 0.8, width = 0.6) +
  geom_text(aes(label = ..count..), stat = "count", vjust = -0.5, size = 4) +
  scale_fill_manual(values = c("0" = "#2E8B57", "1" = "#DC143C"), 
                    labels = c("Thanh toán tốt", "Khó khăn thanh toán")) +
  labs(title = "PHÂN PHỐI BIẾN MỤC TIÊU (TARGET)",
       subtitle = "Tỷ lệ khách hàng gặp khó khăn thanh toán",
       x = "Tình trạng thanh toán", y = "Số lượng khách hàng") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5),
        legend.position = "none",
        axis.text.x = element_text(size = 10))

print(p1)

# 2. PHÂN PHỐI THU NHẬP THEO TARGET
cat("=== 2. PHÂN PHỐI THU NHẬP THEO TARGET ===\n")
## === 2. PHÂN PHỐI THU NHẬP THEO TARGET ===
loan_data_numeric <- loan_data %>%
  mutate(
    AMT_INCOME_TOTAL = as.numeric(AMT_INCOME_TOTAL),
    AMT_CREDIT = as.numeric(AMT_CREDIT)
  ) %>%
  filter(!is.na(AMT_INCOME_TOTAL) & !is.na(AMT_CREDIT))

p2_1 <- ggplot(loan_data_numeric, aes(x = AMT_INCOME_TOTAL, fill = factor(TARGET))) +
  geom_histogram(alpha = 0.7, bins = 30, position = "identity") +
  scale_fill_manual(values = c("0" = "#2E8B57", "1" = "#DC143C"),
                    labels = c("Thanh toán tốt", "Khó khăn thanh toán")) +
  scale_x_continuous(labels = comma, limits = c(0, quantile(loan_data_numeric$AMT_INCOME_TOTAL, 0.95))) +
  labs(title = "Phân phối thu nhập", x = "Tổng thu nhập", y = "Tần suất") +
  theme_minimal()

p2_2 <- ggplot(loan_data_numeric, aes(x = factor(TARGET), y = AMT_INCOME_TOTAL, fill = factor(TARGET))) +
  geom_boxplot(alpha = 0.7) +
  scale_fill_manual(values = c("0" = "#2E8B57", "1" = "#DC143C")) +
  scale_y_continuous(labels = comma, limits = c(0, quantile(loan_data_numeric$AMT_INCOME_TOTAL, 0.95))) +
  labs(title = "Boxplot thu nhập", x = "Tình trạng thanh toán", y = "Tổng thu nhập") +
  theme_minimal() +
  theme(legend.position = "none")

p2 <- p2_1 + p2_2 + plot_layout(ncol = 2) +
  plot_annotation(title = "PHÂN PHỐI THU NHẬP THEO TÌNH TRẠNG THANH TOÁN",
                  theme = theme(plot.title = element_text(face = "bold", hjust = 0.5)))

print(p2)

# 3. MỐI QUAN HỆ THU NHẬP - SỐ TIỀN VAY
cat("=== 3. MỐI QUAN HỆ THU NHẬP - SỐ TIỀN VAY ===\n")
## === 3. MỐI QUAN HỆ THU NHẬP - SỐ TIỀN VAY ===
loan_data_log <- loan_data_numeric %>%
  filter(AMT_INCOME_TOTAL > 0 & AMT_CREDIT > 0) %>%
  mutate(
    LOG_INCOME = log10(AMT_INCOME_TOTAL),
    LOG_CREDIT = log10(AMT_CREDIT)
  )

p3 <- ggplot(loan_data_log, aes(x = LOG_INCOME, y = LOG_CREDIT, color = factor(TARGET))) +
  geom_point(alpha = 0.6, size = 1.5) +
  geom_smooth(method = "lm", se = FALSE, aes(group = factor(TARGET)), size = 1) +
  scale_color_manual(values = c("0" = "#2E8B57", "1" = "#DC143C"),
                     labels = c("Thanh toán tốt", "Khó khăn thanh toán")) +
  scale_x_continuous(labels = function(x) comma(10^x)) +
  scale_y_continuous(labels = function(x) comma(10^x)) +
  labs(title = "MỐI QUAN HỆ GIỮA THU NHẬP VÀ SỐ TIỀN VAY",
       subtitle = "Thang logarit để dễ quan sát mối quan hệ tuyến tính",
       x = "Tổng thu nhập (log scale)", y = "Số tiền vay (log scale)",
       color = "Tình trạng thanh toán") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p3)

# 4. PHÂN PHỐI LOẠI HỢP ĐỒNG
cat("=== 4. PHÂN PHỐI LOẠI HỢP ĐỒNG ===\n")
## === 4. PHÂN PHỐI LOẠI HỢP ĐỒNG ===
contract_data <- loan_data %>%
  group_by(NAME_CONTRACT_TYPE, TARGET) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  mutate(TARGET = factor(TARGET, labels = c("Thanh toán tốt", "Khó khăn thanh toán")))

p4 <- ggplot(contract_data, aes(x = NAME_CONTRACT_TYPE, y = Count, fill = TARGET)) +
  geom_bar(stat = "identity", position = "fill", alpha = 0.8, width = 0.7) +
  geom_text(aes(label = Count), position = position_fill(vjust = 0.5), 
            color = "white", size = 3.5, fontface = "bold") +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  scale_y_continuous(labels = percent) +
  labs(title = "PHÂN PHỐI LOẠI HỢP ĐỒNG THEO TÌNH TRẠNG THANH TOÁN",
       subtitle = "Tỷ lệ phần trăm theo từng loại hợp đồng",
       x = "Loại hợp đồng", y = "Tỷ lệ phần trăm") +
  coord_flip() +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p4)

# 5. PHÂN PHỐI GIỚI TÍNH
cat("=== 5. PHÂN PHỐI GIỚI TÍNH ===\n")
## === 5. PHÂN PHỐI GIỚI TÍNH ===
gender_data <- loan_data %>%
  mutate(
    CODE_GENDER = case_when(
      CODE_GENDER %in% c("M", "F") ~ CODE_GENDER,
      TRUE ~ "Other"
    ),
    TARGET_LABEL = factor(TARGET, levels = c(0, 1), labels = c("Thanh toán tốt", "Khó khăn thanh toán"))
  ) %>%
  group_by(CODE_GENDER, TARGET_LABEL) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  group_by(CODE_GENDER) %>%
  mutate(Percentage = Count / sum(Count) * 100)

p5 <- ggplot(gender_data, aes(x = CODE_GENDER, y = Count, fill = TARGET_LABEL)) +
  geom_bar(stat = "identity", position = "stack", alpha = 0.8, width = 0.6) +
  geom_text(aes(label = paste0(round(Percentage, 1), "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", size = 4, fontface = "bold") +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  scale_x_discrete(labels = c("M" = "Nam", "F" = "Nữ", "Other" = "Khác")) +
  labs(title = "PHÂN PHỐI GIỚI TÍNH THEO TÌNH TRẠNG THANH TOÁN",
       subtitle = "Tỷ lệ phần trăm cho mỗi nhóm giới tính",
       x = "Giới tính", y = "Số lượng khách hàng") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p5)

# 6. TUỔI KHÁCH HÀNG VÀ RỦI RO
cat("=== 6. TUỔI KHÁCH HÀNG VÀ RỦI RO ===\n")
## === 6. TUỔI KHÁCH HÀNG VÀ RỦI RO ===
loan_data$AGE <- round(-loan_data$DAYS_BIRTH / 365.25, 1)

p6 <- ggplot(loan_data, aes(x = AGE, fill = factor(TARGET))) +
  geom_histogram(aes(y = ..density..), alpha = 0.7, bins = 30, position = "identity") +
  geom_density(alpha = 0.5, aes(color = factor(TARGET))) +
  scale_fill_manual(values = c("0" = "#2E8B57", "1" = "#DC143C"),
                    labels = c("Thanh toán tốt", "Khó khăn thanh toán")) +
  scale_color_manual(values = c("0" = "#2E8B57", "1" = "#DC143C"),
                     labels = c("Thanh toán tốt", "Khó khăn thanh toán")) +
  labs(title = "PHÂN PHỐI TUỔI THEO TÌNH TRẠNG THANH TOÁN",
       subtitle = "Mật độ phân phối tuổi khách hàng",
       x = "Tuổi", y = "Mật độ") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p6)

# 7. TRẠNG THÁI VIỆC LÀM
cat("=== 7. TRẠNG THÁI VIỆC LÀM ===\n")
## === 7. TRẠNG THÁI VIỆC LÀM ===
loan_data$EMPLOYMENT_STATUS <- ifelse(loan_data$DAYS_EMPLOYED > 0, "Đã nghỉ hưu", "Đang làm việc")

employment_data <- loan_data %>%
  group_by(EMPLOYMENT_STATUS, TARGET) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  group_by(EMPLOYMENT_STATUS) %>%
  mutate(Percentage = Count / sum(Count) * 100,
         TARGET = factor(TARGET, labels = c("Thanh toán tốt", "Khó khăn thanh toán")))

p7 <- ggplot(employment_data, aes(x = EMPLOYMENT_STATUS, y = Count, fill = TARGET)) +
  geom_bar(stat = "identity", position = "dodge", alpha = 0.8, width = 0.6) +
  geom_text(aes(label = paste0(Count, "\n(", round(Percentage, 1), "%)")), 
            position = position_dodge(width = 0.6), 
            vjust = -0.3, size = 3.5, lineheight = 0.8) +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  labs(title = "TRẠNG THÁI VIỆC LÀM VÀ TÌNH TRẠNG THANH TOÁN",
       subtitle = "So sánh giữa người đang làm việc và đã nghỉ hưu",
       x = "Trạng thái việc làm", y = "Số lượng khách hàng") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p7)

# 8. LOẠI HÌNH THU NHẬP
cat("=== 8. LOẠI HÌNH THU NHẬP ===\n")
## === 8. LOẠI HÌNH THU NHẬP ===
income_type_data <- loan_data %>%
  mutate(
    TARGET_LABEL = factor(TARGET, levels = c(0, 1), labels = c("Thanh toán tốt", "Khó khăn thanh toán"))
  ) %>%
  group_by(NAME_INCOME_TYPE, TARGET_LABEL) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  group_by(NAME_INCOME_TYPE) %>%
  mutate(Percentage = Count / sum(Count) * 100,
         Total = sum(Count)) %>%
  ungroup()

income_type_clean <- income_type_data %>%
  mutate(
    NAME_INCOME_TYPE_CLEAN = ifelse(Total < 10, "Other", NAME_INCOME_TYPE)
  ) %>%
  group_by(NAME_INCOME_TYPE_CLEAN, TARGET_LABEL) %>%
  summarise(Count = sum(Count), .groups = 'drop') %>%
  group_by(NAME_INCOME_TYPE_CLEAN) %>%
  mutate(Percentage = Count / sum(Count) * 100,
         Total = sum(Count))

p8 <- ggplot(income_type_clean, aes(x = reorder(NAME_INCOME_TYPE_CLEAN, Total), y = Count, fill = TARGET_LABEL)) +
  geom_bar(stat = "identity", alpha = 0.8, width = 0.7) +
  geom_text(aes(label = paste0(round(Percentage, 1), "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", size = 3, fontface = "bold") +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  labs(title = "LOẠI HÌNH THU NHẬP VÀ TÌNH TRẠNG THANH TOÁN",
       subtitle = "Sắp xếp theo tổng số lượng (các nhóm nhỏ được gộp thành 'Other')",
       x = "Loại hình thu nhập", y = "Số lượng khách hàng") +
  coord_flip() +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p8)

# 9. TRÌNH ĐỘ HỌC VẤN
cat("=== 9. TRÌNH ĐỘ HỌC VẤN ===\n")
## === 9. TRÌNH ĐỘ HỌC VẤN ===
education_data <- loan_data %>%
  group_by(NAME_EDUCATION_TYPE, TARGET) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  group_by(NAME_EDUCATION_TYPE) %>%
  mutate(Percentage = Count / sum(Count) * 100,
         Total = sum(Count),
         TARGET = factor(TARGET, labels = c("Thanh toán tốt", "Khó khăn thanh toán")))

p9 <- ggplot(education_data, aes(x = reorder(NAME_EDUCATION_TYPE, Total), y = Count, fill = TARGET)) +
  geom_bar(stat = "identity", alpha = 0.8, width = 0.7) +
  geom_text(aes(label = paste0(round(Percentage, 1), "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", size = 3.5, fontface = "bold") +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  labs(title = "TRÌNH ĐỘ HỌC VẤN VÀ TÌNH TRẠNG THANH TOÁN",
       subtitle = "Tỷ lệ phần trăm theo từng trình độ",
       x = "Trình độ học vấn", y = "Số lượng khách hàng") +
  coord_flip() +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p9)

# 10. TÌNH TRẠNG HÔN NHÂN
cat("=== 10. TÌNH TRẠNG HÔN NHÂN ===\n")
## === 10. TÌNH TRẠNG HÔN NHÂN ===
main_family_status <- loan_data %>%
  count(NAME_FAMILY_STATUS) %>%
  filter(n >= 10) %>%
  pull(NAME_FAMILY_STATUS)

family_data <- loan_data %>%
  filter(NAME_FAMILY_STATUS %in% main_family_status) %>%
  mutate(
    TARGET_LABEL = factor(TARGET, levels = c(0, 1), labels = c("Thanh toán tốt", "Khó khăn thanh toán"))
  ) %>%
  group_by(NAME_FAMILY_STATUS, TARGET_LABEL) %>%
  summarise(Count = n(), .groups = 'drop') %>%
  group_by(NAME_FAMILY_STATUS) %>%
  mutate(Percentage = Count / sum(Count) * 100,
         Total = sum(Count))

p10 <- ggplot(family_data, aes(x = reorder(NAME_FAMILY_STATUS, Total), y = Count, fill = TARGET_LABEL)) +
  geom_bar(stat = "identity", alpha = 0.8, width = 0.7) +
  geom_text(aes(label = paste0(round(Percentage, 1), "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", size = 3.5, fontface = "bold") +
  scale_fill_manual(values = c("Thanh toán tốt" = "#2E8B57", "Khó khăn thanh toán" = "#DC143C")) +
  labs(title = "TÌNH TRẠNG HÔN NHÂN VÀ TÌNH TRẠNG THANH TOÁN",
       subtitle = "Phân phối theo tình trạng gia đình (các nhóm nhỏ đã được lọc)",
       x = "Tình trạng hôn nhân", y = "Số lượng khách hàng") +
  coord_flip() +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

print(p10)

3 CHƯƠNG 2: MÃ CHỨNG KHOÁN REE

3.1 Mục tiêu phân tích

Nghiên cứu này được thực hiện nhằm mục đích đánh giá toàn diện tình hình tài chính và hiệu quả hoạt động của Công ty Cổ phần Cơ điện lạnh (REE) trong giai đoạn 10 năm từ 2015-2024, tập trung vào: Phân tích cấu trúc tài chính: Đánh giá sự thay đổi trong cơ cấu tài sản, nguồn vốn và mức độ sử dụng đòn bẩy tài chính qua các năm. Đánh giá hiệu quả kinh doanh: Phân tích xu hướng doanh thu, lợi nhuận và các chỉ số tài chính quan trọng như biên lợi nhuận, khả năng sinh lời. Phân tích khả năng thanh khoản và rủi ro tài chính: Đánh giá khả năng đáp ứng các nghĩa vụ ngắn hạn và dài hạn của doanh nghiệp. Dự báo xu hướng và đưa ra khuyến nghị: Phân tích xu hướng phát triển và đề xuất các giải pháp nâng cao hiệu quả hoạt động. ## Giải thích các biến Giải thích thuật ngữ (biến) TÀI SẢN: Tổng tài sản ngắn hạn: Tài sản có thời gian luân chuyển ≤ 1 năm Tổng tài sản dài hạn: Tài sản có thời gian sử dụng > 1 năm Tiền và tương đương tiền: Tài sản có tính thanh khoản cao nhất NỢ PHẢI TRẢ: Nợ ngắn hạn: Nghĩa vụ phải thanh toán trong vòng 1 năm Nợ dài hạn: Nghĩa vụ phải thanh toán sau 1 năm VỐN CHỦ SỞ HỮU: Vốn cổ phần: Vốn góp của cổ đông Lợi nhuận sau thuế chưa phân phối: Lợi nhuận giữ lại tái đầu tư KẾT QUẢ KINH DOANH: Doanh thu thuần: Tổng doanh thu sau các khoản giảm trừ Lợi nhuận gộp: Chênh lệch doanh thu và giá vốn Lợi nhuận sau thuế: Lợi nhuận cuối cùng sau tất cả chi phí

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

library(dplyr)
library(ggplot2)
library(tidyr)
library(scales)
library(kableExtra)
library(tidyverse)
library(patchwork)
library(corrplot)
library(gridExtra)
library(ggthemes)
library(skimr)
library(lubridate)

# 1. Đọc dữ liệu
cat("=== 1. ĐỌC DỮ LIỆU TỪ FILE ===\n")
## === 1. ĐỌC DỮ LIỆU TỪ FILE ===
ree_data <- read.csv("C:/Học tập/Bộ dữ liệu 10 năm mã REE.csv", sep = ",", stringsAsFactors = FALSE)
cat("KỸ THUẬT: Sử dụng hàm read.csv() với separator ',' để đọc file CSV\n")
## KỸ THUẬT: Sử dụng hàm read.csv() với separator ',' để đọc file CSV
cat("Ý NGHĨA: Đây là bước đầu tiên trong quy trình ETL, đảm bảo dữ liệu được nạp đúng định dạng\n\n")
## Ý NGHĨA: Đây là bước đầu tiên trong quy trình ETL, đảm bảo dữ liệu được nạp đúng định dạng
# 2. Kiểm tra kích thước dataset
cat("=== 2. KIỂM TRA KÍCH THƯỚC DATASET ===\n")
## === 2. KIỂM TRA KÍCH THƯỚC DATASET ===
cat("Số quan sát (dòng):", nrow(ree_data), "\n")
## Số quan sát (dòng): 10
cat("Số biến (cột):", ncol(ree_data), "\n")
## Số biến (cột): 27
cat("KỸ THUẬT: Sử dụng nrow() và ncol() để xác định kích thước dataset\n")
## KỸ THUẬT: Sử dụng nrow() và ncol() để xác định kích thước dataset
cat("Ý NGHĨA: Hiểu được quy mô dữ liệu, gồm 10 năm dữ liệu tài chính với đầy đủ các chỉ tiêu\n\n")
## Ý NGHĨA: Hiểu được quy mô dữ liệu, gồm 10 năm dữ liệu tài chính với đầy đủ các chỉ tiêu
# 3. Kiểm tra tên các cột
cat("=== 3. TÊN CÁC BIẾN TRONG DATASET ===\n")
## === 3. TÊN CÁC BIẾN TRONG DATASET ===
cat("Danh sách các biến tài chính:\n")
## Danh sách các biến tài chính:
print(names(ree_data))
##  [1] "Ky"                                       
##  [2] "Tien"                                     
##  [3] "Cac.khoan.tuong.duong.tien"               
##  [4] "Phai.thu.ngan.han.cua.khach.hang"         
##  [5] "Hang.ton.kho"                             
##  [6] "Tong.tai.san.ngan.han"                    
##  [7] "Tai.san.co.dinh.huu.hinh..Gia.tri.rong."  
##  [8] "Bat.dong.san.dau.tu..Gia.tri.rong."       
##  [9] "Dau.tu.vao.con.ty.lien.ket"               
## [10] "Tong.tai.san.dai.han"                     
## [11] "TONG.CON.TAI.SAN"                         
## [12] "Vay.ngan.han"                             
## [13] "Tong.no.ngan.han"                         
## [14] "Vay.dai.han"                              
## [15] "Tong.no.dai.han"                          
## [16] "TONG.NO.PHAI.TRA"                         
## [17] "Von.co.phan"                              
## [18] "Loi.nhuan.sau.thue.chua.phan.phoi"        
## [19] "Loi.ich.co.dong.khong.kiem.soat"          
## [20] "TONG.VON.CHU.SO.HUU"                      
## [21] "Doanh.thu.thuan"                          
## [22] "Gia.von.hang.ban"                         
## [23] "Loi.nhuan.gop"                            
## [24] "Doanh.thu.hoat.dong.tai.chinh"            
## [25] "Chi.phi.tai.chinh"                        
## [26] "Loi.nhuan.thuan.hoat.dong.kinh.doanh"     
## [27] "Loi.nhuan.sau.thue.cua.co.dong.cong.ty.me"
cat("KỸ THUẬT: Sử dụng names() để lấy tên các biến\n")
## KỸ THUẬT: Sử dụng names() để lấy tên các biến
cat("Ý NGHĨA: Xác định các chỉ tiêu tài chính quan trọng cần phân tích\n\n")
## Ý NGHĨA: Xác định các chỉ tiêu tài chính quan trọng cần phân tích
# 4. Kiểm tra cấu trúc dữ liệu
cat("=== 4. CẤU TRÚC DỮ LIỆU ===\n")
## === 4. CẤU TRÚC DỮ LIỆU ===
cat("Kiểu dữ liệu của các biến quan trọng:\n")
## Kiểu dữ liệu của các biến quan trọng:
str(ree_data[, 1:10])
## 'data.frame':    10 obs. of  10 variables:
##  $ Ky                                     : int  2015 2016 2017 2018 2019 2020 2021 2022 2023 2024
##  $ Tien                                   : chr  "284.248.591.789" "234.294.781.676" "479.255.700.999" "358.847.636.516" ...
##  $ Cac.khoan.tuong.duong.tien             : chr  "1.135.466.645.175" "725.732.338.820" "1.130.687.114.777" "1.419.006.115.194" ...
##  $ Phai.thu.ngan.han.cua.khach.hang       : chr  "751.871.765.798" "630.344.198.317" "809.208.905.795" "1.192.515.659.390" ...
##  $ Hang.ton.kho                           : chr  "547.093.860.649" "1.230.323.799.872" "1.638.169.317.068" "1.621.189.756.280" ...
##  $ Tong.tai.san.ngan.han                  : chr  "3.747.405.985.616" "4.105.229.855.343" "5.672.484.550.291" "7.004.143.191.956" ...
##  $ Tai.san.co.dinh.huu.hinh..Gia.tri.rong.: chr  "449.831.802.721" "495.558.428.359" "4.199.192.658.745" "3.722.519.897.464" ...
##  $ Bat.dong.san.dau.tu..Gia.tri.rong.     : chr  "584.938.280.334" "712.711.940.028" "865.059.260.655" "933.105.289.873" ...
##  $ Dau.tu.vao.con.ty.lien.ket             : chr  "3.411.769.189.950" "3.927.337.173.436" "4.885.645.195.939" "5.766.183.181.792" ...
##  $ Tong.tai.san.dai.han                   : chr  "5.861.517.471.811" "7.291.405.321.230" "11.233.197.669.761" "8.495.519.915.668" ...
cat("KỸ THUẬT: Sử dụng str() để kiểm tra cấu trúc và kiểu dữ liệu\n")
## KỸ THUẬT: Sử dụng str() để kiểm tra cấu trúc và kiểu dữ liệu
cat("Ý NGHĨA: Xác định kiểu dữ liệu phù hợp cho từng biến, phát hiện vấn đề về định dạng\n\n")
## Ý NGHĨA: Xác định kiểu dữ liệu phù hợp cho từng biến, phát hiện vấn đề về định dạng
# 5. Kiểm tra dữ liệu trùng lặp
cat("=== 5. KIỂM TRA DỮ LIỆU TRÙNG LẶP ===\n")
## === 5. KIỂM TRA DỮ LIỆU TRÙNG LẶP ===
cat("Số quan sát trùng lặp:", sum(duplicated(ree_data)), "\n")
## Số quan sát trùng lặp: 0
cat("KỸ THUẬT: Sử dụng duplicated() và sum() để đếm bản ghi trùng lặp\n")
## KỸ THUẬT: Sử dụng duplicated() và sum() để đếm bản ghi trùng lặp
cat("Ý NGHĨA: Đảm bảo tính duy nhất của dữ liệu theo từng năm\n\n")
## Ý NGHĨA: Đảm bảo tính duy nhất của dữ liệu theo từng năm
# 6. Kiểm tra dữ liệu thiếu tổng quan
cat("=== 6. TỔNG QUAN DỮ LIỆU THIẾU ===\n")
## === 6. TỔNG QUAN DỮ LIỆU THIẾU ===
missing_total <- sum(is.na(ree_data))
missing_percentage <- round(mean(is.na(ree_data)) * 100, 2)
cat("Tổng số giá trị thiếu:", missing_total, "\n")
## Tổng số giá trị thiếu: 0
cat("Tỷ lệ giá trị thiếu:", missing_percentage, "%\n")
## Tỷ lệ giá trị thiếu: 0 %
cat("KỸ THUẬT: Sử dụng is.na(), sum() và mean() để tính toán missing values\n")
## KỸ THUẬT: Sử dụng is.na(), sum() và mean() để tính toán missing values
cat("Ý NGHĨA: Đánh giá mức độ hoàn chỉnh của báo cáo tài chính\n\n")
## Ý NGHĨA: Đánh giá mức độ hoàn chỉnh của báo cáo tài chính
# 7. Kiểm tra dữ liệu thiếu theo từng cột
cat("=== 7. DỮ LIỆU THIẾU THEO TỪNG CỘT ===\n")
## === 7. DỮ LIỆU THIẾU THEO TỪNG CỘT ===
missing_by_col <- sapply(ree_data, function(x) sum(is.na(x)))
print(missing_by_col[missing_by_col > 0])
## named integer(0)
cat("KỸ THUẬT: Sử dụng sapply() với hàm is.na() để tính missing values theo cột\n")
## KỸ THUẬT: Sử dụng sapply() với hàm is.na() để tính missing values theo cột
cat("Ý NGHĨA: Xác định chỉ tiêu nào có vấn đề về dữ liệu thiếu\n\n")
## Ý NGHĨA: Xác định chỉ tiêu nào có vấn đề về dữ liệu thiếu
# 8. Thống kê mô tả cơ bản
cat("=== 8. THỐNG KÊ MÔ TẢ CƠ BẢN ===\n")
## === 8. THỐNG KÊ MÔ TẢ CƠ BẢN ===
cat("Các biến số chính (đơn vị: đồng):\n")
## Các biến số chính (đơn vị: đồng):
financial_vars <- c("Doanh_thu_thuan", "Loi_nhuan_sau_thue_cua_co_dong_cong_ty_me", "TONG_CONG_TAI_SAN")
# Kiểm tra xem các biến có tồn tại không
cat("Các biến được chọn:", financial_vars, "\n")
## Các biến được chọn: Doanh_thu_thuan Loi_nhuan_sau_thue_cua_co_dong_cong_ty_me TONG_CONG_TAI_SAN
cat("Tên biến thực tế trong dataset:", names(ree_data)[20:27], "\n")
## Tên biến thực tế trong dataset: TONG.VON.CHU.SO.HUU Doanh.thu.thuan Gia.von.hang.ban Loi.nhuan.gop Doanh.thu.hoat.dong.tai.chinh Chi.phi.tai.chinh Loi.nhuan.thuan.hoat.dong.kinh.doanh Loi.nhuan.sau.thue.cua.co.dong.cong.ty.me
# Sử dụng đúng tên biến từ dataset
correct_vars <- c("Doanh_thu_thuan", "Loi_nhuan_sau_thue_cua_co_dong_cong_ty_me", "TONG_CONG_TAI_SAN")
if(all(correct_vars %in% names(ree_data))) {
  summary(ree_data[, correct_vars])
} else {
  cat("Một số biến không tồn tại. Hiển thị 5 biến đầu tiên:\n")
  summary(ree_data[, 1:5])
}
## Một số biến không tồn tại. Hiển thị 5 biến đầu tiên:
##        Ky           Tien           Cac.khoan.tuong.duong.tien
##  Min.   :2015   Length:10          Length:10                 
##  1st Qu.:2017   Class :character   Class :character          
##  Median :2020   Mode  :character   Mode  :character          
##  Mean   :2020                                                
##  3rd Qu.:2022                                                
##  Max.   :2024                                                
##  Phai.thu.ngan.han.cua.khach.hang Hang.ton.kho      
##  Length:10                        Length:10         
##  Class :character                 Class :character  
##  Mode  :character                 Mode  :character  
##                                                     
##                                                     
## 
# 9. Kiểm tra giá trị thời gian
cat("=== 9. KIỂM TRA GIÁ TRỊ THỜI GIAN ===\n")
## === 9. KIỂM TRA GIÁ TRỊ THỜI GIAN ===
cat("Các năm trong dataset:\n")
## Các năm trong dataset:
print(ree_data$Ky)
##  [1] 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024
cat("KỸ THUẬT: Truy cập trực tiếp biến năm (Ky) để kiểm tra chuỗi thời gian\n")
## KỸ THUẬT: Truy cập trực tiếp biến năm (Ky) để kiểm tra chuỗi thời gian
cat("Ý NGHĨA: Đảm bảo dữ liệu theo chuỗi thời gian liên tục từ 2015-2024\n\n")
## Ý NGHĨA: Đảm bảo dữ liệu theo chuỗi thời gian liên tục từ 2015-2024
# 10. Kiểm tra tính hợp lý của dữ liệu
cat("=== 10. KIỂM TRA TÍNH HỢP LÝ CỦA DỮ LIỆU ===\n")
## === 10. KIỂM TRA TÍNH HỢP LÝ CỦA DỮ LIỆU ===
cat("Kiểm tra tính cân đối: Tổng tài sản = Tổng nguồn vốn?\n")
## Kiểm tra tính cân đối: Tổng tài sản = Tổng nguồn vốn?
# Kiểm tra tên biến thực tế
cat("Tên biến trong dataset:\n")
## Tên biến trong dataset:
print(names(ree_data))
##  [1] "Ky"                                       
##  [2] "Tien"                                     
##  [3] "Cac.khoan.tuong.duong.tien"               
##  [4] "Phai.thu.ngan.han.cua.khach.hang"         
##  [5] "Hang.ton.kho"                             
##  [6] "Tong.tai.san.ngan.han"                    
##  [7] "Tai.san.co.dinh.huu.hinh..Gia.tri.rong."  
##  [8] "Bat.dong.san.dau.tu..Gia.tri.rong."       
##  [9] "Dau.tu.vao.con.ty.lien.ket"               
## [10] "Tong.tai.san.dai.han"                     
## [11] "TONG.CON.TAI.SAN"                         
## [12] "Vay.ngan.han"                             
## [13] "Tong.no.ngan.han"                         
## [14] "Vay.dai.han"                              
## [15] "Tong.no.dai.han"                          
## [16] "TONG.NO.PHAI.TRA"                         
## [17] "Von.co.phan"                              
## [18] "Loi.nhuan.sau.thue.chua.phan.phoi"        
## [19] "Loi.ich.co.dong.khong.kiem.soat"          
## [20] "TONG.VON.CHU.SO.HUU"                      
## [21] "Doanh.thu.thuan"                          
## [22] "Gia.von.hang.ban"                         
## [23] "Loi.nhuan.gop"                            
## [24] "Doanh.thu.hoat.dong.tai.chinh"            
## [25] "Chi.phi.tai.chinh"                        
## [26] "Loi.nhuan.thuan.hoat.dong.kinh.doanh"     
## [27] "Loi.nhuan.sau.thue.cua.co.dong.cong.ty.me"
cat("\n")
# Sử dụng đúng tên biến từ dataset thực tế
# Giả sử tên biến là: TONG_CONG_TAI_SAN, TONG_NO_PHAI_TRA, TONG_VON_CHU_SO_HUU
if(all(c("TONG_CONG_TAI_SAN", "TONG_NO_PHAI_TRA", "TONG_VON_CHU_SO_HUU") %in% names(ree_data))) {
  # Chuyển đổi sang numeric
  total_assets <- as.numeric(ree_data$TONG_CONG_TAI_SAN)
  total_liabilities <- as.numeric(ree_data$TONG_NO_PHAI_TRA)
  total_equity <- as.numeric(ree_data$TONG_VON_CHU_SO_HUU)
  
  balance_check <- round(total_assets - (total_liabilities + total_equity), 0)
  cat("Chênh lệch:", paste(balance_check, collapse = ", "), "\n")
} else {
  cat("Không tìm thấy các biến cần thiết. Bỏ qua kiểm tra cân đối.\n")
}
## Không tìm thấy các biến cần thiết. Bỏ qua kiểm tra cân đối.
cat("KỸ THUẬT: Kiểm tra phương trình kế toán cơ bản: Tài sản = Nợ phải trả + Vốn chủ sở hữu\n")
## KỸ THUẬT: Kiểm tra phương trình kế toán cơ bản: Tài sản = Nợ phải trả + Vốn chủ sở hữu
cat("Ý NGHĨA: Đảm bảo tính chính xác và hợp lý của báo cáo tài chính\n\n")
## Ý NGHĨA: Đảm bảo tính chính xác và hợp lý của báo cáo tài chính

3.3 XỬ LÝ DỮ LIỆU THÔ & MÃ HÓA DỮ LIỆU

cat("=== BẮT ĐẦU QUÁ TRÌNH LÀM SẠCH VÀ MÃ HÓA DỮ LIỆU TÀI CHÍNH ===\n\n")
## === BẮT ĐẦU QUÁ TRÌNH LÀM SẠCH VÀ MÃ HÓA DỮ LIỆU TÀI CHÍNH ===
# 1. Tạo bản sao dữ liệu gốc
ree_clean <- ree_data
cat("=== 1. TẠO BẢN SAO DỮ LIỆU GỐC ===\n")
## === 1. TẠO BẢN SAO DỮ LIỆU GỐC ===
cat("Kích thước dataset gốc:", dim(ree_data), "\n")
## Kích thước dataset gốc: 10 27
cat("Kích thước dataset làm sạch:", dim(ree_clean), "\n")
## Kích thước dataset làm sạch: 10 27
cat("KỸ THUẬT: Tạo object mới bằng phép gán để giữ nguyên dữ liệu gốc\n")
## KỸ THUẬT: Tạo object mới bằng phép gán để giữ nguyên dữ liệu gốc
cat("Ý NGHĨA: Đảm bảo tính toàn vẹn của dữ liệu tài chính gốc\n\n")
## Ý NGHĨA: Đảm bảo tính toàn vẹn của dữ liệu tài chính gốc
# 2. Chuẩn hóa tên cột
cat("=== 2. CHUẨN HÓA TÊN CỘT ===\n")
## === 2. CHUẨN HÓA TÊN CỘT ===
new_names <- c("Year", "Cash", "Cash_equivalents", "Receivables", "Inventory", "Total_current_assets", 
               "Fixed_assets", "Investment_property", "Associates_investment", "Total_noncurrent_assets",
               "Total_assets", "Short_term_debt", "Total_current_liabilities", "Long_term_debt", 
               "Total_noncurrent_liabilities", "Total_liabilities", "Share_capital", "Retained_earnings",
               "Non_controlling_interest", "Total_equity", "Revenue", "COGS", "Gross_profit",
               "Financial_income", "Financial_expenses", "Operating_profit", "Net_profit")

names(ree_clean) <- new_names
cat("Đã chuẩn hóa tên cột sang tiếng Anh\n")
## Đã chuẩn hóa tên cột sang tiếng Anh
cat("KỸ THUẬT: Sử dụng names() để gán lại tên cột mới\n")
## KỸ THUẬT: Sử dụng names() để gán lại tên cột mới
cat("Ý NGHĨA: Tạo tên biến chuẩn, dễ hiểu cho phân tích quốc tế\n\n")
## Ý NGHĨA: Tạo tên biến chuẩn, dễ hiểu cho phân tích quốc tế
# 3. Chuyển đổi kiểu dữ liệu số
cat("=== 3. CHUYỂN ĐỔI KIỂU DỮ LIỆU SỐ ===\n")
## === 3. CHUYỂN ĐỔI KIỂU DỮ LIỆU SỐ ===
numeric_columns <- names(ree_clean)[-1] # Tất cả trừ cột Year

ree_clean <- ree_clean %>%
  mutate(across(all_of(numeric_columns), as.numeric))

cat("Đã chuyển đổi các biến số sang numeric\n")
## Đã chuyển đổi các biến số sang numeric
cat("KỸ THUẬT: Sử dụng across() với as.numeric() để chuyển đổi hàng loạt\n")
## KỸ THUẬT: Sử dụng across() với as.numeric() để chuyển đổi hàng loạt
cat("Ý NGHĨA: Đảm bảo tính nhất quán về kiểu dữ liệu cho tính toán tài chính\n\n")
## Ý NGHĨA: Đảm bảo tính nhất quán về kiểu dữ liệu cho tính toán tài chính
# 4. Xử lý dữ liệu thiếu
cat("=== 4. XỬ LÝ DỮ LIỆU THIẾU ===\n")
## === 4. XỬ LÝ DỮ LIỆU THIẾU ===
missing_before <- sum(is.na(ree_clean))
ree_clean <- ree_clean %>%
  filter(complete.cases(.))
missing_after <- sum(is.na(ree_clean))
cat("Đã loại bỏ", missing_before - missing_after, "giá trị thiếu\n")
## Đã loại bỏ 260 giá trị thiếu
cat("KỸ THUẬT: Sử dụng complete.cases() để lọc dữ liệu hoàn chỉnh\n")
## KỸ THUẬT: Sử dụng complete.cases() để lọc dữ liệu hoàn chỉnh
cat("Ý NGHĨA: Đảm bảo tính toàn vẹn của chuỗi thời gian tài chính\n\n")
## Ý NGHĨA: Đảm bảo tính toàn vẹn của chuỗi thời gian tài chính
# 5. Chuẩn hóa đơn vị (tỷ đồng)
cat("=== 5. CHUẨN HÓA ĐƠN VỊ ===\n")
## === 5. CHUẨN HÓA ĐƠN VỊ ===
ree_clean <- ree_clean %>%
  mutate(across(c(Cash:Net_profit), ~ . / 1000000000)) # Chuyển sang tỷ đồng

cat("Đã chuẩn hóa đơn vị về tỷ đồng\n")
## Đã chuẩn hóa đơn vị về tỷ đồng
cat("KỸ THUẬT: Sử dụng across() với phép chia để chuẩn hóa đơn vị\n")
## KỸ THUẬT: Sử dụng across() với phép chia để chuẩn hóa đơn vị
cat("Ý NGHĨA: Đơn giản hóa việc trình bày và diễn giải số liệu tài chính\n\n")
## Ý NGHĨA: Đơn giản hóa việc trình bày và diễn giải số liệu tài chính
# 6. Tạo biến tỷ lệ tài chính
cat("=== 6. TẠO BIẾN TỶ LỆ TÀI CHÍNH ===\n")
## === 6. TẠO BIẾN TỶ LỆ TÀI CHÍNH ===
ree_clean <- ree_clean %>%
  mutate(
    # Tỷ lệ thanh khoản
    Current_ratio = Total_current_assets / Total_current_liabilities,
    Quick_ratio = (Cash + Cash_equivalents + Receivables) / Total_current_liabilities,
    
    # Tỷ lệ nợ
    Debt_ratio = Total_liabilities / Total_assets,
    Debt_to_equity = Total_liabilities / Total_equity,
    
    # Tỷ lệ sinh lời
    Gross_margin = Gross_profit / Revenue,
    Net_margin = Net_profit / Revenue,
    ROA = Net_profit / Total_assets,
    ROE = Net_profit / Total_equity,
    
    # Hiệu quả hoạt động
    Asset_turnover = Revenue / Total_assets,
    Inventory_turnover = COGS / Inventory
  )
cat("Đã tạo các tỷ lệ tài chính quan trọng\n")
## Đã tạo các tỷ lệ tài chính quan trọng
cat("KỸ THUẬT: Sử dụng mutate() để tạo các financial ratios từ dữ liệu gốc\n")
## KỸ THUẬT: Sử dụng mutate() để tạo các financial ratios từ dữ liệu gốc
cat("Ý NGHĨA: Biến đổi dữ liệu tuyệt đối thành tỷ lệ tương đối để so sánh và đánh giá hiệu quả\n\n")
## Ý NGHĨA: Biến đổi dữ liệu tuyệt đối thành tỷ lệ tương đối để so sánh và đánh giá hiệu quả
# 7. Mã hóa giai đoạn phát triển
cat("=== 7. MÃ HÓA GIAI ĐOẠN PHÁT TRIỂN ===\n")
## === 7. MÃ HÓA GIAI ĐOẠN PHÁT TRIỂN ===
ree_clean <- ree_clean %>%
  mutate(
    Period = case_when(
      Year <= 2017 ~ "Giai đoạn ổn định (2015-2017)",
      Year <= 2020 ~ "Giai đoạn tăng trưởng (2018-2020)", 
      Year <= 2024 ~ "Giai đoạn bứt phá (2021-2024)"
    ),
    Growth_phase = factor(Period, levels = c("Giai đoạn ổn định (2015-2017)", 
                                           "Giai đoạn tăng trưởng (2018-2020)",
                                           "Giai đoạn bứt phá (2021-2024)"))
  )
cat("Phân phối giai đoạn phát triển:\n")
## Phân phối giai đoạn phát triển:
print(table(ree_clean$Growth_phase))
## 
##     Giai đoạn ổn định (2015-2017) Giai đoạn tăng trưởng (2018-2020) 
##                                 0                                 0 
##     Giai đoạn bứt phá (2021-2024) 
##                                 0
cat("KỸ THUẬT: Sử dụng case_when() để phân nhóm theo giai đoạn thời gian\n")
## KỸ THUẬT: Sử dụng case_when() để phân nhóm theo giai đoạn thời gian
cat("Ý NGHĨA: Tạo biến categorical để phân tích theo từng giai đoạn phát triển của doanh nghiệp\n\n")
## Ý NGHĨA: Tạo biến categorical để phân tích theo từng giai đoạn phát triển của doanh nghiệp
# 8. Tính toán tăng trưởng
cat("=== 8. TÍNH TOÁN TĂNG TRƯỞNG ===\n")
## === 8. TÍNH TOÁN TĂNG TRƯỞNG ===
ree_clean <- ree_clean %>%
  arrange(Year) %>%
  mutate(
    Revenue_growth = (Revenue / lag(Revenue) - 1) * 100,
    Profit_growth = (Net_profit / lag(Net_profit) - 1) * 100,
    Asset_growth = (Total_assets / lag(Total_assets) - 1) * 100,
    Equity_growth = (Total_equity / lag(Total_equity) - 1) * 100
  )
cat("Đã tính toán các chỉ số tăng trưởng\n")
## Đã tính toán các chỉ số tăng trưởng
cat("KỸ THUẬT: Sử dụng lag() để tính toán thay đổi phần trăm so với năm trước\n")
## KỸ THUẬT: Sử dụng lag() để tính toán thay đổi phần trăm so với năm trước
cat("Ý NGHĨA: Đo lường tốc độ phát triển và xu hướng tăng trưởng của doanh nghiệp\n\n")
## Ý NGHĨA: Đo lường tốc độ phát triển và xu hướng tăng trưởng của doanh nghiệp
# # 7. Phân loại quy mô
cat("=== 7. PHÂN LOẠI QUY MÔ ===\n")
## === 7. PHÂN LOẠI QUY MÔ ===
ree_clean <- ree_clean %>%
  mutate(
    Size_category = cut(Total_assets,
                       breaks = c(0, 15000, 25000, max(Total_assets)),
                       labels = c("Quy mô nhỏ", "Quy mô trung bình", "Quy mô lớn"),
                       include.lowest = TRUE)
  )
cat("Phân phối quy mô doanh nghiệp:\n")
## Phân phối quy mô doanh nghiệp:
print(table(ree_clean$Size_category))
## 
##        Quy mô nhỏ Quy mô trung bình        Quy mô lớn 
##                 0                 0                 0
cat("KỸ THUẬT: Sử dụng cut() với quantile để phân nhóm theo quy mô tài sản\n")
## KỸ THUẬT: Sử dụng cut() với quantile để phân nhóm theo quy mô tài sản
cat("Ý NGHĨA: Phân tích sự thay đổi trong cấu trúc và hiệu quả theo quy mô phát triển\n\n")
## Ý NGHĨA: Phân tích sự thay đổi trong cấu trúc và hiệu quả theo quy mô phát triển
# 10. Kiểm tra kết quả
cat("=== 10. KIỂM TRA KẾT QUẢ SAU KHI LÀM SẠCH ===\n")
## === 10. KIỂM TRA KẾT QUẢ SAU KHI LÀM SẠCH ===
cat("Cấu trúc dữ liệu sau xử lý:\n")
## Cấu trúc dữ liệu sau xử lý:
str(ree_clean[, c("Year", "Revenue", "Net_profit", "Total_assets", "Total_equity", 
                  "Current_ratio", "ROE", "Gross_margin")])
## 'data.frame':    0 obs. of  8 variables:
##  $ Year         : int 
##  $ Revenue      : num 
##  $ Net_profit   : num 
##  $ Total_assets : num 
##  $ Total_equity : num 
##  $ Current_ratio: num 
##  $ ROE          : num 
##  $ Gross_margin : num
cat("KỸ THUẬT: Kiểm tra final structure của dataset sau tất cả transformations\n")
## KỸ THUẬT: Kiểm tra final structure của dataset sau tất cả transformations
cat("Ý NGHĨA: Đảm bảo dữ liệu đã sẵn sàng cho phân tích thống kê và trực quan hóa\n\n")
## Ý NGHĨA: Đảm bảo dữ liệu đã sẵn sàng cho phân tích thống kê và trực quan hóa

3.4 THỐNG KÊ CƠ BẢN

cat("=== PHÂN TÍCH THỐNG KÊ TÀI CHÍNH CƠ BẢN ===\n\n")
## === PHÂN TÍCH THỐNG KÊ TÀI CHÍNH CƠ BẢN ===
# 1. Thống kê mô tả biến số chính
cat("=== 1. THỐNG KÊ MÔ TẢ BIẾN SỐ TÀI CHÍNH CHÍNH (ĐVT: Tỷ đồng) ===\n")
## === 1. THỐNG KÊ MÔ TẢ BIẾN SỐ TÀI CHÍNH CHÍNH (ĐVT: Tỷ đồng) ===
financial_summary <- ree_clean %>%
  select(Revenue, Net_profit, Total_assets, Total_equity, Gross_profit) %>%
  skim()

print(financial_summary)
## ── Data Summary ────────────────────────
##                            Values    
## Name                       Piped data
## Number of rows             0         
## Number of columns          5         
## _______________________              
## Column type frequency:               
##   numeric                  5         
## ________________________             
## Group variables            None      
## 
## ── Variable type: numeric ──────────────────────────────────────────────────────
##   skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
## 1 Revenue               0           NaN  NaN NA NA  NA  NA  NA   NA " " 
## 2 Net_profit            0           NaN  NaN NA NA  NA  NA  NA   NA " " 
## 3 Total_assets          0           NaN  NaN NA NA  NA  NA  NA   NA " " 
## 4 Total_equity          0           NaN  NaN NA NA  NA  NA  NA   NA " " 
## 5 Gross_profit          0           NaN  NaN NA NA  NA  NA  NA   NA " "
cat("KỸ THUẬT: Sử dụng package skimr để tạo comprehensive summary statistics\n")
## KỸ THUẬT: Sử dụng package skimr để tạo comprehensive summary statistics
cat("Ý NGHĨA: Cung cấp cái nhìn tổng quan về quy mô và biến động của các chỉ tiêu tài chính chính\n\n")
## Ý NGHĨA: Cung cấp cái nhìn tổng quan về quy mô và biến động của các chỉ tiêu tài chính chính
# 2. Phân tích theo giai đoạn phát triển
cat("=== 2. PHÂN TÍCH THEO GIAI ĐOẠN PHÁT TRIỂN ===\n")
## === 2. PHÂN TÍCH THEO GIAI ĐOẠN PHÁT TRIỂN ===
period_analysis <- ree_clean %>%
  group_by(Growth_phase) %>%
  summarise(
    Avg_Revenue = mean(Revenue),
    Avg_Profit = mean(Net_profit),
    Avg_ROE = mean(ROE, na.rm = TRUE),
    Avg_Debt_Ratio = mean(Debt_ratio, na.rm = TRUE),
    Count_Years = n()
  )

print(period_analysis)
## # A tibble: 0 × 6
## # ℹ 6 variables: Growth_phase <fct>, Avg_Revenue <dbl>, Avg_Profit <dbl>,
## #   Avg_ROE <dbl>, Avg_Debt_Ratio <dbl>, Count_Years <int>
cat("KỸ THUẬT: Sử dụng group_by() và summarise() để tính statistics theo giai đoạn\n")
## KỸ THUẬT: Sử dụng group_by() và summarise() để tính statistics theo giai đoạn
cat("Ý NGHĨA: So sánh hiệu quả hoạt động qua các giai đoạn phát triển khác nhau\n\n")
## Ý NGHĨA: So sánh hiệu quả hoạt động qua các giai đoạn phát triển khác nhau
# 3. Phân tích xu hướng doanh thu và lợi nhuận
cat("=== 3. PHÂN TÍCH XU HƯỚNG DOANH THU VÀ LỢI NHUẬN ===\n")
## === 3. PHÂN TÍCH XU HƯỚNG DOANH THU VÀ LỢI NHUẬN ===
revenue_trend <- ree_clean %>%
  select(Year, Revenue, Net_profit, Gross_profit) %>%
  arrange(Year)

print(revenue_trend)
## [1] Year         Revenue      Net_profit   Gross_profit
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Lựa chọn và sắp xếp các biến quan trọng theo thời gian\n")
## KỸ THUẬT: Lựa chọn và sắp xếp các biến quan trọng theo thời gian
cat("Ý NGHĨA: Theo dõi xu hướng phát triển của hoạt động kinh doanh qua các năm\n\n")
## Ý NGHĨA: Theo dõi xu hướng phát triển của hoạt động kinh doanh qua các năm
# 4. Phân tích cấu trúc tài sản
cat("=== 4. PHÂN TÍCH CẤU TRÚC TÀI SẢN ===\n")
## === 4. PHÂN TÍCH CẤU TRÚC TÀI SẢN ===
asset_structure <- ree_clean %>%
  group_by(Year) %>%
  summarise(
    Current_Assets_Ratio = Total_current_assets / Total_assets,
    Fixed_Assets_Ratio = Fixed_assets / Total_assets,
    Investment_Ratio = (Investment_property + Associates_investment) / Total_assets
  )

print(asset_structure)
## # A tibble: 0 × 4
## # Groups:   Year [0]
## # ℹ 4 variables: Year <int>, Current_Assets_Ratio <dbl>,
## #   Fixed_Assets_Ratio <dbl>, Investment_Ratio <dbl>
cat("KỸ THUẬT: Tính tỷ trọng các loại tài sản trong tổng tài sản\n")
## KỸ THUẬT: Tính tỷ trọng các loại tài sản trong tổng tài sản
cat("Ý NGHĨA: Đánh giá sự thay đổi trong cơ cấu đầu tư và phân bổ tài sản\n\n")
## Ý NGHĨA: Đánh giá sự thay đổi trong cơ cấu đầu tư và phân bổ tài sản
# 5. Phân tích cấu trúc vốn
cat("=== 5. PHÂN TÍCH CẤU TRÚC VỐN ===\n")
## === 5. PHÂN TÍCH CẤU TRÚC VỐN ===
capital_structure <- ree_clean %>%
  group_by(Year) %>%
  summarise(
    Debt_Ratio = Total_liabilities / Total_assets,
    Equity_Ratio = Total_equity / Total_assets,
    Financial_Leverage = Total_assets / Total_equity
  )

print(capital_structure)
## # A tibble: 0 × 4
## # Groups:   Year [0]
## # ℹ 4 variables: Year <int>, Debt_Ratio <dbl>, Equity_Ratio <dbl>,
## #   Financial_Leverage <dbl>
cat("KỸ THUẬT: Tính các tỷ lệ đòn bẩy tài chính và cấu trúc vốn\n")
## KỸ THUẬT: Tính các tỷ lệ đòn bẩy tài chính và cấu trúc vốn
cat("Ý NGHĨA: Đánh giá mức độ sử dụng nợ và rủi ro tài chính của doanh nghiệp\n\n")
## Ý NGHĨA: Đánh giá mức độ sử dụng nợ và rủi ro tài chính của doanh nghiệp
# 6. Phân tích khả năng thanh khoản
cat("=== 6. PHÂN TÍCH KHẢ NĂNG THANH KHOẢN ===\n")
## === 6. PHÂN TÍCH KHẢ NĂNG THANH KHOẢN ===
liquidity_analysis <- ree_clean %>%
  group_by(Year) %>%
  summarise(
    Current_Ratio = Current_ratio,
    Quick_Ratio = Quick_ratio,
    Cash_Ratio = Cash / Total_current_liabilities
  )

print(liquidity_analysis)
## # A tibble: 0 × 4
## # Groups:   Year [0]
## # ℹ 4 variables: Year <int>, Current_Ratio <dbl>, Quick_Ratio <dbl>,
## #   Cash_Ratio <dbl>
cat("KỸ THUẬT: Tính các tỷ lệ thanh khoản theo thời gian\n")
## KỸ THUẬT: Tính các tỷ lệ thanh khoản theo thời gian
cat("Ý NGHĨA: Đánh giá khả năng đáp ứng các nghĩa vụ ngắn hạn của doanh nghiệp\n\n")
## Ý NGHĨA: Đánh giá khả năng đáp ứng các nghĩa vụ ngắn hạn của doanh nghiệp
# 7. Phân tích hiệu quả hoạt động
cat("=== 7. PHÂN TÍCH HIỆU QUẢ HOẠT ĐỘNG ===\n")
## === 7. PHÂN TÍCH HIỆU QUẢ HOẠT ĐỘNG ===
efficiency_analysis <- ree_clean %>%
  group_by(Year) %>%
  summarise(
    Asset_Turnover = Asset_turnover,
    Gross_Margin = Gross_margin,
    Net_Margin = Net_margin,
    ROA = ROA,
    ROE = ROE
  )

print(efficiency_analysis)
## # A tibble: 0 × 6
## # Groups:   Year [0]
## # ℹ 6 variables: Year <int>, Asset_Turnover <dbl>, Gross_Margin <dbl>,
## #   Net_Margin <dbl>, ROA <dbl>, ROE <dbl>
cat("KỸ THUẬT: Tính các chỉ số hiệu quả sử dụng tài sản và sinh lời\n")
## KỸ THUẬT: Tính các chỉ số hiệu quả sử dụng tài sản và sinh lời
cat("Ý NGHĨA: Đánh giá hiệu quả quản lý và khả năng tạo ra giá trị của doanh nghiệp\n\n")
## Ý NGHĨA: Đánh giá hiệu quả quản lý và khả năng tạo ra giá trị của doanh nghiệp
# 8. Phân tích tăng trưởng
cat("=== 8. PHÂN TÍCH TĂNG TRƯỞNG ===\n")
## === 8. PHÂN TÍCH TĂNG TRƯỞNG ===
growth_analysis <- ree_clean %>%
  filter(!is.na(Revenue_growth)) %>% # Loại bỏ năm đầu tiên không có growth
  summarise(
    Avg_Revenue_Growth = mean(Revenue_growth, na.rm = TRUE),
    Avg_Profit_Growth = mean(Profit_growth, na.rm = TRUE),
    Avg_Asset_Growth = mean(Asset_growth, na.rm = TRUE),
    Volatility_Revenue = sd(Revenue_growth, na.rm = TRUE),
    Volatility_Profit = sd(Profit_growth, na.rm = TRUE)
  )

print(growth_analysis)
##   Avg_Revenue_Growth Avg_Profit_Growth Avg_Asset_Growth Volatility_Revenue
## 1                NaN               NaN              NaN                 NA
##   Volatility_Profit
## 1                NA
cat("KỸ THUẬT: Tính tốc độ tăng trưởng trung bình và độ biến động\n")
## KỸ THUẬT: Tính tốc độ tăng trưởng trung bình và độ biến động
cat("Ý NGHĨA: Đánh giá tốc độ phát triển và mức độ ổn định trong tăng trưởng\n\n")
## Ý NGHĨA: Đánh giá tốc độ phát triển và mức độ ổn định trong tăng trưởng
# 9. Phân tích tương quan giữa các chỉ số
cat("=== 9. PHÂN TÍCH TƯƠNG QUAN GIỮA CÁC CHỈ SỐ ===\n")
## === 9. PHÂN TÍCH TƯƠNG QUAN GIỮA CÁC CHỈ SỐ ===
# Kiểm tra dữ liệu trước
correlation_data <- ree_clean %>%
  select(Revenue, Net_profit, Total_assets, ROE, ROA, Debt_ratio)

cat("Kiểm tra dữ liệu tương quan:\n")
## Kiểm tra dữ liệu tương quan:
print(summary(correlation_data))
##     Revenue      Net_profit   Total_assets      ROE           ROA     
##  Min.   : NA   Min.   : NA   Min.   : NA   Min.   : NA   Min.   : NA  
##  1st Qu.: NA   1st Qu.: NA   1st Qu.: NA   1st Qu.: NA   1st Qu.: NA  
##  Median : NA   Median : NA   Median : NA   Median : NA   Median : NA  
##  Mean   :NaN   Mean   :NaN   Mean   :NaN   Mean   :NaN   Mean   :NaN  
##  3rd Qu.: NA   3rd Qu.: NA   3rd Qu.: NA   3rd Qu.: NA   3rd Qu.: NA  
##  Max.   : NA   Max.   : NA   Max.   : NA   Max.   : NA   Max.   : NA  
##    Debt_ratio 
##  Min.   : NA  
##  1st Qu.: NA  
##  Median : NA  
##  Mean   :NaN  
##  3rd Qu.: NA  
##  Max.   : NA
cat("Số lượng quan sát hoàn chỉnh:", sum(complete.cases(correlation_data)), "\n")
## Số lượng quan sát hoàn chỉnh: 0
if(sum(complete.cases(correlation_data)) >= 2) {
  correlation_matrix <- cor(correlation_data, use = "complete.obs")
  print(round(correlation_matrix, 3))
} else {
  cat("Không đủ dữ liệu để tính tương quan (cần ít nhất 2 quan sát hoàn chỉnh)\n")
  correlation_matrix <- matrix(NA, nrow = ncol(correlation_data), ncol = ncol(correlation_data))
  colnames(correlation_matrix) <- rownames(correlation_matrix) <- names(correlation_data)
  print(correlation_matrix)
}
## Không đủ dữ liệu để tính tương quan (cần ít nhất 2 quan sát hoàn chỉnh)
##              Revenue Net_profit Total_assets ROE ROA Debt_ratio
## Revenue           NA         NA           NA  NA  NA         NA
## Net_profit        NA         NA           NA  NA  NA         NA
## Total_assets      NA         NA           NA  NA  NA         NA
## ROE               NA         NA           NA  NA  NA         NA
## ROA               NA         NA           NA  NA  NA         NA
## Debt_ratio        NA         NA           NA  NA  NA         NA
# 10. Phân tích theo quy mô
cat("=== 10. PHÂN TÍCH THEO QUY MÔ ===\n")
## === 10. PHÂN TÍCH THEO QUY MÔ ===
size_analysis <- ree_clean %>%
  group_by(Size_category) %>%
  summarise(
    Avg_Revenue = mean(Revenue),
    Avg_Profit_Margin = mean(Net_margin, na.rm = TRUE),
    Avg_ROE = mean(ROE, na.rm = TRUE),
    Avg_Debt_Ratio = mean(Debt_ratio, na.rm = TRUE),
    Years_Count = n()
  )

print(size_analysis)
## # A tibble: 0 × 6
## # ℹ 6 variables: Size_category <fct>, Avg_Revenue <dbl>,
## #   Avg_Profit_Margin <dbl>, Avg_ROE <dbl>, Avg_Debt_Ratio <dbl>,
## #   Years_Count <int>
cat("KỸ THUẬT: Phân tích hiệu quả theo nhóm quy mô khác nhau\n")
## KỸ THUẬT: Phân tích hiệu quả theo nhóm quy mô khác nhau
cat("Ý NGHĨA: Đánh giá sự khác biệt về hiệu quả hoạt động theo quy mô doanh nghiệp\n\n")
## Ý NGHĨA: Đánh giá sự khác biệt về hiệu quả hoạt động theo quy mô doanh nghiệp
# 11. Phân tích biên lợi nhuận
cat("=== 11. PHÂN TÍCH BIÊN LỢI NHUẬN THEO THỜI GIAN ===\n")
## === 11. PHÂN TÍCH BIÊN LỢI NHUẬN THEO THỜI GIAN ===
margin_analysis <- ree_clean %>%
  select(Year, Gross_margin, Net_margin) %>%
  arrange(Year)

print(margin_analysis)
## [1] Year         Gross_margin Net_margin  
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Theo dõi sự thay đổi của các biên lợi nhuận qua các năm\n")
## KỸ THUẬT: Theo dõi sự thay đổi của các biên lợi nhuận qua các năm
cat("Ý NGHĨA: Đánh giá hiệu quả kiểm soát chi phí và khả năng sinh lời\n\n")
## Ý NGHĨA: Đánh giá hiệu quả kiểm soát chi phí và khả năng sinh lời
# 12. Phân tích vòng quay tài sản
cat("=== 12. PHÂN TÍCH VÒNG QUAY TÀI SẢN ===\n")
## === 12. PHÂN TÍCH VÒNG QUAY TÀI SẢN ===
turnover_analysis <- ree_clean %>%
  select(Year, Asset_turnover, Inventory_turnover) %>%
  arrange(Year)

print(turnover_analysis)
## [1] Year               Asset_turnover     Inventory_turnover
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Tính toán các chỉ số vòng quay\n")
## KỸ THUẬT: Tính toán các chỉ số vòng quay
cat("Ý NGHĨA: Đánh giá hiệu quả sử dụng tài sản và quản lý hàng tồn kho\n\n")
## Ý NGHĨA: Đánh giá hiệu quả sử dụng tài sản và quản lý hàng tồn kho
# 13. Phân tích dòng tiền
cat("=== 13. PHÂN TÍCH DÒNG TIỀN ===\n")
## === 13. PHÂN TÍCH DÒNG TIỀN ===
cash_analysis <- ree_clean %>%
  select(Year, Cash, Cash_equivalents, Revenue, Net_profit) %>%
  mutate(
    Cash_to_Revenue = Cash / Revenue,
    Cash_to_Profit = Cash / Net_profit
  )

print(cash_analysis)
## [1] Year             Cash             Cash_equivalents Revenue         
## [5] Net_profit       Cash_to_Revenue  Cash_to_Profit  
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Phân tích mối quan hệ giữa tiền mặt và kết quả kinh doanh\n")
## KỸ THUẬT: Phân tích mối quan hệ giữa tiền mặt và kết quả kinh doanh
cat("Ý NGHĨA: Đánh giá khả năng tạo ra và duy trì dòng tiền của doanh nghiệp\n\n")
## Ý NGHĨA: Đánh giá khả năng tạo ra và duy trì dòng tiền của doanh nghiệp
# 14. Phân tích đòn bẩy tài chính
cat("=== 14. PHÂN TÍCH ĐÒN BẨY TÀI CHÍNH ===\n")
## === 14. PHÂN TÍCH ĐÒN BẨY TÀI CHÍNH ===
leverage_analysis <- ree_clean %>%
  select(Year, Debt_to_equity, Financial_Leverage = Total_assets/Total_equity) %>%
  arrange(Year)

print(leverage_analysis)
## [1] Year               Debt_to_equity     Financial_Leverage
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Tính toán các chỉ số đòn bẩy tài chính\n")
## KỸ THUẬT: Tính toán các chỉ số đòn bẩy tài chính
cat("Ý NGHĨA: Đánh giá mức độ sử dụng nợ và rủi ro tài chính\n\n")
## Ý NGHĨA: Đánh giá mức độ sử dụng nợ và rủi ro tài chính
# 15. Phân tích hiệu quả đầu tư
cat("=== 15. PHÂN TÍCH HIỆU QUẢ ĐẦU TƯ ===\n")
## === 15. PHÂN TÍCH HIỆU QUẢ ĐẦU TƯ ===
investment_analysis <- ree_clean %>%
  select(Year, Associates_investment, Investment_property, Net_profit) %>%
  mutate(
    Investment_Return = Net_profit / (Associates_investment + Investment_property)
  )

print(investment_analysis)
## [1] Year                  Associates_investment Investment_property  
## [4] Net_profit            Investment_Return    
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Tính tỷ suất sinh lời trên đầu tư\n")
## KỸ THUẬT: Tính tỷ suất sinh lời trên đầu tư
cat("Ý NGHĨA: Đánh giá hiệu quả của các khoản đầu tư dài hạn\n\n")
## Ý NGHĨA: Đánh giá hiệu quả của các khoản đầu tư dài hạn
# 16. Phân tích cơ cấu doanh thu
cat("=== 16. PHÂN TÍCH CƠ CẤU CHI PHÍ ===\n")
## === 16. PHÂN TÍCH CƠ CẤU CHI PHÍ ===
cost_structure <- ree_clean %>%
  select(Year, Revenue, COGS, Gross_profit, Financial_expenses) %>%
  mutate(
    COGS_Ratio = COGS / Revenue,
    Financial_Expense_Ratio = Financial_expenses / Revenue
  )

print(cost_structure)
## [1] Year                    Revenue                 COGS                   
## [4] Gross_profit            Financial_expenses      COGS_Ratio             
## [7] Financial_Expense_Ratio
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Phân tích tỷ trọng các loại chi phí trong doanh thu\n")
## KỸ THUẬT: Phân tích tỷ trọng các loại chi phí trong doanh thu
cat("Ý NGHĨA: Đánh giá cơ cấu chi phí và hiệu quả kiểm soát chi phí\n\n")
## Ý NGHĨA: Đánh giá cơ cấu chi phí và hiệu quả kiểm soát chi phí
# 17. Phân tích thanh khoản chi tiết
cat("=== 17. PHÂN TÍCH THANH KHOẢN CHI TIẾT ===\n")
## === 17. PHÂN TÍCH THANH KHOẢN CHI TIẾT ===
# Kiểm tra tên biến thực tế
cat("Tên biến trong dataset:\n")
## Tên biến trong dataset:
print(names(ree_clean))
##  [1] "Year"                         "Cash"                        
##  [3] "Cash_equivalents"             "Receivables"                 
##  [5] "Inventory"                    "Total_current_assets"        
##  [7] "Fixed_assets"                 "Investment_property"         
##  [9] "Associates_investment"        "Total_noncurrent_assets"     
## [11] "Total_assets"                 "Short_term_debt"             
## [13] "Total_current_liabilities"    "Long_term_debt"              
## [15] "Total_noncurrent_liabilities" "Total_liabilities"           
## [17] "Share_capital"                "Retained_earnings"           
## [19] "Non_controlling_interest"     "Total_equity"                
## [21] "Revenue"                      "COGS"                        
## [23] "Gross_profit"                 "Financial_income"            
## [25] "Financial_expenses"           "Operating_profit"            
## [27] "Net_profit"                   "Current_ratio"               
## [29] "Quick_ratio"                  "Debt_ratio"                  
## [31] "Debt_to_equity"               "Gross_margin"                
## [33] "Net_margin"                   "ROA"                         
## [35] "ROE"                          "Asset_turnover"              
## [37] "Inventory_turnover"           "Period"                      
## [39] "Growth_phase"                 "Revenue_growth"              
## [41] "Profit_growth"                "Asset_growth"                
## [43] "Equity_growth"                "Size_category"
# Sử dụng đúng tên biến
detailed_liquidity <- ree_clean %>%
  select(Year, Current_ratio, Quick_ratio, Cash, Receivables, Inventory, Total_current_liabilities, Total_current_assets) %>%
  mutate(
    Working_Capital = Total_current_assets - Total_current_liabilities
  )

print(detailed_liquidity)
## [1] Year                      Current_ratio            
## [3] Quick_ratio               Cash                     
## [5] Receivables               Inventory                
## [7] Total_current_liabilities Total_current_assets     
## [9] Working_Capital          
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Phân tích chi tiết các thành phần thanh khoản\n")
## KỸ THUẬT: Phân tích chi tiết các thành phần thanh khoản
cat("Ý NGHĨA: Đánh giá toàn diện khả năng thanh toán ngắn hạn\n\n")
## Ý NGHĨA: Đánh giá toàn diện khả năng thanh toán ngắn hạn
# 18. Phân tích hiệu quả sử dụng vốn
cat("=== 18. PHÂN TÍCH HIỆU QUẢ SỬ DỤNG VỐN ===\n")
## === 18. PHÂN TÍCH HIỆU QUẢ SỬ DỤNG VỐN ===
capital_efficiency <- ree_clean %>%
  select(Year, ROE, ROA, Net_margin, Asset_turnover, Total_assets, Total_equity) %>%
  mutate(
    DuPont_ROE = Net_margin * Asset_turnover * (Total_assets/Total_equity)
  )

print(capital_efficiency)
## [1] Year           ROE            ROA            Net_margin     Asset_turnover
## [6] Total_assets   Total_equity   DuPont_ROE    
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Phân tích DuPont để hiểu rõ các yếu tố ảnh hưởng đến ROE\n")
## KỸ THUẬT: Phân tích DuPont để hiểu rõ các yếu tố ảnh hưởng đến ROE
cat("Ý NGHĨA: Phân tích sâu các nhân tố tác động đến hiệu quả sử dụng vốn chủ sở hữu\n\n")
## Ý NGHĨA: Phân tích sâu các nhân tố tác động đến hiệu quả sử dụng vốn chủ sở hữu
# 19. Phân tích rủi ro tài chính
cat("=== 19. PHÂN TÍCH RỦI RO TÀI CHÍNH ===\n")
## === 19. PHÂN TÍCH RỦI RO TÀI CHÍNH ===
risk_analysis <- ree_clean %>%
  select(Year, Debt_ratio, Current_ratio, Interest_coverage = Operating_profit/Financial_expenses) %>%
  mutate(
    Risk_Level = case_when(
      Debt_ratio > 0.7 | Current_ratio < 1 | Interest_coverage < 1.5 ~ "Rủi ro cao",
      Debt_ratio > 0.5 | Current_ratio < 1.5 | Interest_coverage < 3 ~ "Rủi ro trung bình",
      TRUE ~ "Rủi ro thấp"
    )
  )

print(risk_analysis)
## [1] Year              Debt_ratio        Current_ratio     Interest_coverage
## [5] Risk_Level       
## <0 rows> (or 0-length row.names)
cat("KỸ THUẬT: Đánh giá rủi ro dựa trên multiple financial ratios\n")
## KỸ THUẬT: Đánh giá rủi ro dựa trên multiple financial ratios
cat("Ý NGHĨA: Phân tích toàn diện mức độ rủi ro tài chính của doanh nghiệp\n\n")
## Ý NGHĨA: Phân tích toàn diện mức độ rủi ro tài chính của doanh nghiệp
# 20. Phân tích tổng hợp hiệu quả
cat("=== 20. PHÂN TÍCH TỔNG HỢP HIỆU QUẢ ===\n")
## === 20. PHÂN TÍCH TỔNG HỢP HIỆU QUẢ ===
performance_summary <- ree_clean %>%
  summarise(
    Total_Revenue = sum(Revenue),
    Total_Profit = sum(Net_profit),
    Avg_ROE = mean(ROE, na.rm = TRUE),
    Avg_ROA = mean(ROA, na.rm = TRUE),
    Avg_Growth_Rate = mean(Revenue_growth, na.rm = TRUE),
    Financial_Stability = mean(Current_ratio, na.rm = TRUE)
  )

print(performance_summary)
##   Total_Revenue Total_Profit Avg_ROE Avg_ROA Avg_Growth_Rate
## 1             0            0     NaN     NaN             NaN
##   Financial_Stability
## 1                 NaN
cat("KỸ THUẬT: Tổng hợp các chỉ số hiệu quả quan trọng nhất\n")
## KỸ THUẬT: Tổng hợp các chỉ số hiệu quả quan trọng nhất
cat("Ý NGHĨA: Đánh giá tổng quan hiệu quả hoạt động và tình hình tài chính trong cả giai đoạn\n\n")
## Ý NGHĨA: Đánh giá tổng quan hiệu quả hoạt động và tình hình tài chính trong cả giai đoạn

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

cat("=== BẮT ĐẦU TRỰC QUAN HÓA DỮ LIỆU TÀI CHÍNH ===\n\n")
## === BẮT ĐẦU TRỰC QUAN HÓA DỮ LIỆU TÀI CHÍNH ===
# Tạo dữ liệu mẫu đảm bảo hiển thị (từ file CSV của bạn)
ree_viz <- data.frame(
  Year = 2015:2024,
  Revenue = c(2.6, 3.7, 4.2, 4.8, 4.9, 5.6, 5.8, 8.7, 8.6, 8.6),
  Net_profit = c(0.85, 1.17, 1.34, 1.61, 1.47, 1.44, 1.84, 2.69, 2.15, 2.19),
  Total_assets = c(9.6, 11.4, 16.9, 15.5, 17.5, 22.4, 29.1, 32.6, 36.1, 38.4),
  Total_equity = c(6.7, 7.6, 9.9, 9.6, 10.3, 11.2, 14.0, 14.6, 14.9, 15.7),
  ROE = c(0.127, 0.155, 0.136, 0.166, 0.143, 0.129, 0.132, 0.184, 0.144, 0.139),
  ROA = c(0.089, 0.103, 0.079, 0.104, 0.084, 0.064, 0.063, 0.083, 0.060, 0.057),
  Current_ratio = c(1.68, 1.32, 1.11, 1.70, 1.35, 1.04, 0.92, 0.85, 0.88, 0.96),
  Debt_ratio = c(0.30, 0.34, 0.42, 0.38, 0.41, 0.50, 0.52, 0.55, 0.59, 0.59),
  Gross_margin = c(0.337, 0.339, 0.350, 0.408, 0.445, 0.415, 0.431, 0.400, 0.399, 0.326),
  Net_margin = c(0.323, 0.319, 0.322, 0.335, 0.299, 0.255, 0.317, 0.308, 0.250, 0.256)
)

# 1. Biểu đồ đường - Xu hướng doanh thu và lợi nhuận
cat("=== 1. BIỂU ĐỒ XU HƯỚNG DOANH THU VÀ LỢI NHUẬN ===\n")
## === 1. BIỂU ĐỒ XU HƯỚNG DOANH THU VÀ LỢI NHUẬN ===
p1 <- ggplot(ree_viz, aes(x = Year)) +
  geom_line(aes(y = Revenue, color = "Doanh thu"), size = 1.5) +
  geom_line(aes(y = Net_profit, color = "Lợi nhuận"), size = 1.5) +
  geom_point(aes(y = Revenue), size = 3, color = "#2E8B57") +
  geom_point(aes(y = Net_profit), size = 3, color = "#DC143C") +
  scale_color_manual(values = c("Doanh thu" = "#2E8B57", "Lợi nhuận" = "#DC143C")) +
  labs(title = "XU HƯỚNG DOANH THU VÀ LỢI NHUẬN REE", x = "Năm", y = "Tỷ đồng") +
  theme_minimal()
print(p1)

# 2. Biểu đồ cột - So sánh tài sản và vốn chủ sở hữu
cat("=== 2. BIỂU ĐỒ SO SÁNH TÀI SẢN VÀ VỐN CHỦ SỞ HỮU ===\n")
## === 2. BIỂU ĐỒ SO SÁNH TÀI SẢN VÀ VỐN CHỦ SỞ HỮU ===
p2 <- ggplot(ree_viz, aes(x = Year)) +
  geom_col(aes(y = Total_assets, fill = "Tổng tài sản"), alpha = 0.7) +
  geom_col(aes(y = Total_equity, fill = "Vốn chủ sở hữu"), alpha = 0.7) +
  scale_fill_manual(values = c("Tổng tài sản" = "#4682B4", "Vốn chủ sở hữu" = "#4ECDC4")) +
  labs(title = "SO SÁNH TÀI SẢN VÀ VỐN CHỦ SỞ HỮU", x = "Năm", y = "Tỷ đồng") +
  theme_minimal()
print(p2)

# 3. Biểu đồ đường kép - Tỷ lệ sinh lời
cat("=== 3. BIỂU ĐỒ TỶ LỆ SINH LỜI ===\n")
## === 3. BIỂU ĐỒ TỶ LỆ SINH LỜI ===
p3 <- ggplot(ree_viz, aes(x = Year)) +
  geom_line(aes(y = ROE, color = "ROE"), size = 1.5) +
  geom_line(aes(y = ROA, color = "ROA"), size = 1.5) +
  geom_point(aes(y = ROE), size = 2, color = "#FF6B6B") +
  geom_point(aes(y = ROA), size = 2, color = "#4ECDC4") +
  scale_color_manual(values = c("ROE" = "#FF6B6B", "ROA" = "#4ECDC4")) +
  scale_y_continuous(labels = percent) +
  labs(title = "TỶ LỆ SINH LỜI ROE VÀ ROA", x = "Năm", y = "Tỷ lệ") +
  theme_minimal()
print(p3)

# 4. Biểu đồ thanh khoản và đòn bẩy
cat("=== 4. BIỂU ĐỒ THANH KHOẢN VÀ ĐÒN BẨY ===\n")
## === 4. BIỂU ĐỒ THANH KHOẢN VÀ ĐÒN BẨY ===
p4 <- ggplot(ree_viz, aes(x = Year)) +
  geom_line(aes(y = Current_ratio, color = "Tỷ lệ thanh khoản"), size = 1.5) +
  geom_line(aes(y = Debt_ratio, color = "Tỷ lệ nợ"), size = 1.5) +
  geom_hline(yintercept = 1, linetype = "dashed", color = "red") +
  scale_color_manual(values = c("Tỷ lệ thanh khoản" = "#2E8B57", "Tỷ lệ nợ" = "#DC143C")) +
  labs(title = "THANH KHOẢN VÀ ĐÒN BẨY TÀI CHÍNH", x = "Năm", y = "Tỷ lệ") +
  theme_minimal()
print(p4)

# 5. Biểu đồ biên lợi nhuận
cat("=== 5. BIỂU ĐỒ BIÊN LỢI NHUẬN ===\n")
## === 5. BIỂU ĐỒ BIÊN LỢI NHUẬN ===
p5 <- ggplot(ree_viz, aes(x = Year)) +
  geom_col(aes(y = Gross_margin, fill = "Biên lợi nhuận gộp"), alpha = 0.7) +
  geom_col(aes(y = Net_margin, fill = "Biên lợi nhuận ròng"), alpha = 0.7) +
  scale_fill_manual(values = c("Biên lợi nhuận gộp" = "#45B7D1", "Biên lợi nhuận ròng" = "#96CEB4")) +
  scale_y_continuous(labels = percent) +
  labs(title = "BIÊN LỢI NHUẬN QUA CÁC NĂM", x = "Năm", y = "Tỷ lệ") +
  theme_minimal()
print(p5)

# 6. Biểu đồ scatter - Mối quan hệ tài sản và lợi nhuận
cat("=== 6. BIỂU ĐỒ PHÂN TÁN - TÀI SẢN VÀ LỢI NHUẬN ===\n")
## === 6. BIỂU ĐỒ PHÂN TÁN - TÀI SẢN VÀ LỢI NHUẬN ===
p6 <- ggplot(ree_viz, aes(x = Total_assets, y = Net_profit)) +
  geom_point(size = 4, color = "#FF6B6B", alpha = 0.7) +
  geom_smooth(method = "lm", se = FALSE, color = "#2E8B57") +
  geom_text(aes(label = Year), vjust = -0.8, size = 3) +
  labs(title = "MỐI QUAN HỆ TÀI SẢN VÀ LỢI NHUẬN", x = "Tổng tài sản (tỷ đồng)", y = "Lợi nhuận (tỷ đồng)") +
  theme_minimal()
print(p6)

# 7. Biểu đồ area - Tăng trưởng tài sản
cat("=== 7. BIỂU ĐỒ VÙNG - TĂNG TRƯỞNG TÀI SẢN ===\n")
## === 7. BIỂU ĐỒ VÙNG - TĂNG TRƯỞNG TÀI SẢN ===
p7 <- ggplot(ree_viz, aes(x = Year, y = Total_assets)) +
  geom_area(fill = "#4ECDC4", alpha = 0.5) +
  geom_line(color = "#2E8B57", size = 1.2) +
  geom_point(size = 2, color = "#2E8B57") +
  labs(title = "TĂNG TRƯỞNG TỔNG TÀI SẢN", x = "Năm", y = "Tỷ đồng") +
  theme_minimal()
print(p7)

# 8. Biểu đồ stacked bar - Cơ cấu tài chính
cat("=== 8. BIỂU ĐỒ STACKED BAR - CƠ CẤU TÀI CHÍNH ===\n")
## === 8. BIỂU ĐỒ STACKED BAR - CƠ CẤU TÀI CHÍNH ===
structure_data <- ree_viz %>%
  select(Year, Total_equity, Total_assets, Debt_ratio) %>%
  mutate(
    Debt_value = Total_assets * Debt_ratio,
    Equity_value = Total_equity
  ) %>%
  select(Year, "Vốn chủ sở hữu" = Equity_value, "Nợ phải trả" = Debt_value) %>%
  pivot_longer(-Year, names_to = "Component", values_to = "Value")

p8 <- ggplot(structure_data, aes(x = Year, y = Value, fill = Component)) +
  geom_bar(stat = "identity", position = "stack") +
  scale_fill_manual(values = c("Vốn chủ sở hữu" = "#4ECDC4", "Nợ phải trả" = "#FF6B6B")) +
  labs(title = "CƠ CẤU NGUỒN VỐN", x = "Năm", y = "Tỷ đồng") +
  theme_minimal()
print(p8)

# 9. Biểu đồ heatmap tương quan
cat("=== 9. BIỂU ĐỒ HEATMAP TƯƠNG QUAN ===\n")
## === 9. BIỂU ĐỒ HEATMAP TƯƠNG QUAN ===
library(reshape2)
cor_data <- cor(ree_viz %>% select(-Year))
melted_cor <- melt(cor_data)

p9 <- ggplot(melted_cor, aes(x = Var1, y = Var2, fill = value)) +
  geom_tile() +
  geom_text(aes(label = round(value, 2)), color = "white", size = 4) +
  scale_fill_gradient2(low = "#DC143C", high = "#2E8B57", mid = "white", midpoint = 0) +
  labs(title = "MA TRẬN TƯƠNG QUAN CÁC CHỈ TIÊU", x = "", y = "") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(p9)

# 10. Biểu đồ boxplot - Phân phối các tỷ lệ
cat("=== 10. BIỂU ĐỒ BOXPLOT - PHÂN PHỐI CÁC TỶ LỆ ===\n")
## === 10. BIỂU ĐỒ BOXPLOT - PHÂN PHỐI CÁC TỶ LỆ ===
ratio_data <- ree_viz %>%
  select(ROE, ROA, Current_ratio, Gross_margin, Net_margin) %>%
  pivot_longer(everything(), names_to = "Ratio", values_to = "Value")

p10 <- ggplot(ratio_data, aes(x = Ratio, y = Value, fill = Ratio)) +
  geom_boxplot(alpha = 0.7) +
  geom_jitter(width = 0.2, alpha = 0.6) +
  labs(title = "PHÂN PHỐI CÁC TỶ LỆ TÀI CHÍNH", x = "Chỉ số", y = "Giá trị") +
  theme_minimal() +
  theme(legend.position = "none")
print(p10)

cat("=== ĐÃ HOÀN THÀNH 10 BIỂU ĐỒ ĐẦU TIÊN ===\n\n")
## === ĐÃ HOÀN THÀNH 10 BIỂU ĐỒ ĐẦU TIÊN ===
# 11. Biểu đồ histogram - Phân phối lợi nhuận
cat("=== 11. BIỂU ĐỒ HISTOGRAM - PHÂN PHỐI LỢI NHUẬN ===\n")
## === 11. BIỂU ĐỒ HISTOGRAM - PHÂN PHỐI LỢI NHUẬN ===
p11 <- ggplot(ree_viz, aes(x = Net_profit)) +
  geom_histogram(binwidth = 0.3, fill = "#4ECDC4", alpha = 0.7, color = "white") +
  geom_density(aes(y = after_stat(count) * 0.3), color = "#2E8B57", size = 1) +
  geom_vline(aes(xintercept = mean(Net_profit)), color = "#DC143C", linetype = "dashed", size = 1) +
  labs(title = "PHÂN PHỐI LỢI NHUẬN REE", x = "Lợi nhuận (tỷ đồng)", y = "Tần suất") +
  theme_minimal()
print(p11)

# 12. Biểu đồ violin - So sánh các biên lợi nhuận
cat("=== 12. BIỂU ĐỒ VIOLIN - SO SÁNH CÁC BIÊN LỢI NHUẬN ===\n")
## === 12. BIỂU ĐỒ VIOLIN - SO SÁNH CÁC BIÊN LỢI NHUẬN ===
margin_data <- ree_viz %>%
  select(Gross_margin, Net_margin) %>%
  pivot_longer(everything(), names_to = "Margin_Type", values_to = "Value")

p12 <- ggplot(margin_data, aes(x = Margin_Type, y = Value, fill = Margin_Type)) +
  geom_violin(alpha = 0.7) +
  geom_boxplot(width = 0.1, fill = "white", alpha = 0.8) +
  geom_jitter(width = 0.05, size = 2, alpha = 0.6) +
  scale_fill_manual(values = c("Gross_margin" = "#45B7D1", "Net_margin" = "#96CEB4")) +
  scale_x_discrete(labels = c("Biên lợi nhuận gộp", "Biên lợi nhuận ròng")) +
  scale_y_continuous(labels = percent) +
  labs(title = "SO SÁNH PHÂN PHỐI CÁC BIÊN LỢI NHUẬN", x = "", y = "Tỷ lệ") +
  theme_minimal() +
  theme(legend.position = "none")
print(p12)

# 13. Biểu đồ lollipop - Tăng trưởng qua các năm
cat("=== 13. BIỂU ĐỒ LOLLIPOP - TĂNG TRƯỞNG QUA CÁC NĂM ===\n")
## === 13. BIỂU ĐỒ LOLLIPOP - TĂNG TRƯỞNG QUA CÁC NĂM ===
growth_data <- ree_viz %>%
  mutate(Growth = (Revenue - lag(Revenue)) / lag(Revenue) * 100) %>%
  filter(!is.na(Growth))

p13 <- ggplot(growth_data, aes(x = Year, y = Growth)) +
  geom_segment(aes(x = Year, xend = Year, y = 0, yend = Growth), color = "#4682B4") +
  geom_point(size = 4, color = "#DC143C") +
  geom_text(aes(label = paste0(round(Growth, 1), "%")), vjust = -1, size = 3, fontface = "bold") +
  geom_hline(yintercept = 0, color = "black", linetype = "dashed") +
  labs(title = "TĂNG TRƯỞNG DOANH THU HÀNG NĂM", x = "Năm", y = "Tăng trưởng (%)") +
  theme_minimal()
print(p13)

# 14. Biểu đồ pie - Cơ cấu tài sản năm 2024
cat("=== 14. BIỂU ĐỒ PIE - CƠ CẤU TÀI SẢN NĂM 2024 ===\n")
## === 14. BIỂU ĐỒ PIE - CƠ CẤU TÀI SẢN NĂM 2024 ===
latest_year <- ree_viz %>% filter(Year == 2024)
pie_data <- data.frame(
  Category = c("Tài sản ngắn hạn", "Tài sản dài hạn"),
  Value = c(
    latest_year$Total_assets * 0.4,  # Giả định 40% ngắn hạn
    latest_year$Total_assets * 0.6   # Giả định 60% dài hạn
  )
)

p14 <- ggplot(pie_data, aes(x = "", y = Value, fill = Category)) +
  geom_bar(stat = "identity", width = 1, alpha = 0.8) +
  coord_polar("y", start = 0) +
  geom_text(aes(label = paste0(round(Value/sum(Value)*100, 1), "%")), 
            position = position_stack(vjust = 0.5), color = "white", size = 5) +
  scale_fill_manual(values = c("Tài sản ngắn hạn" = "#FF6B6B", "Tài sản dài hạn" = "#4ECDC4")) +
  labs(title = "CƠ CẤU TÀI SẢN NĂM 2024", fill = "Loại tài sản") +
  theme_void() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))
print(p14)

# 15. Biểu đồ area stacked - Phát triển tài chính qua các năm
cat("=== 15. BIỂU ĐỒ AREA STACKED - PHÁT TRIỂN TÀI CHÍNH ===\n")
## === 15. BIỂU ĐỒ AREA STACKED - PHÁT TRIỂN TÀI CHÍNH ===
financial_growth <- ree_viz %>%
  select(Year, Revenue, Net_profit, Total_assets) %>%
  pivot_longer(-Year, names_to = "Indicator", values_to = "Value")

p15 <- ggplot(financial_growth, aes(x = Year, y = Value, fill = Indicator)) +
  geom_area(alpha = 0.7) +
  scale_fill_manual(values = c("Revenue" = "#2E8B57", "Net_profit" = "#DC143C", "Total_assets" = "#4682B4"),
                    labels = c("Doanh thu", "Lợi nhuận", "Tổng tài sản")) +
  labs(title = "PHÁT TRIỂN TÀI CHÍNH QUA CÁC NĂM", x = "Năm", y = "Tỷ đồng") +
  theme_minimal()
print(p15)

# 16. Biểu đồ dot plot - So sánh hiệu quả theo năm
cat("=== 16. BIỂU ĐỒ DOT PLOT - SO SÁNH HIỆU QUẢ ===\n")
## === 16. BIỂU ĐỒ DOT PLOT - SO SÁNH HIỆU QUẢ ===
efficiency_data <- ree_viz %>%
  select(Year, ROE, ROA, Net_margin) %>%
  pivot_longer(-Year, names_to = "Ratio", values_to = "Value")

p16 <- ggplot(efficiency_data, aes(x = Value, y = reorder(Year, Value), color = Ratio)) +
  geom_point(size = 4, alpha = 0.7) +
  geom_segment(aes(x = 0, xend = Value, y = Year, yend = Year), alpha = 0.5) +
  facet_wrap(~Ratio, scales = "free_x", 
             labeller = as_labeller(c("ROE" = "ROE", "ROA" = "ROA", "Net_margin" = "Biên lợi nhuận"))) +
  scale_color_manual(values = c("ROE" = "#FF6B6B", "ROA" = "#4ECDC4", "Net_margin" = "#45B7D1")) +
  scale_x_continuous(labels = percent) +
  labs(title = "SO SÁNH HIỆU QUẢ HOẠT ĐỘNG THEO NĂM", x = "Tỷ lệ", y = "Năm") +
  theme_minimal() +
  theme(legend.position = "none")
print(p16)

# 17. Biểu đồ ridge line - Mật độ phân phối
cat("=== 17. BIỂU ĐỒ RIDGE LINE - MẬT ĐỘ PHÂN PHỐI ===\n")
## === 17. BIỂU ĐỒ RIDGE LINE - MẬT ĐỘ PHÂN PHỐI ===
library(ggridges)
ridge_data <- ree_viz %>%
  select(ROE, ROA, Current_ratio, Gross_margin) %>%
  pivot_longer(everything(), names_to = "Metric", values_to = "Value")

p17 <- ggplot(ridge_data, aes(x = Value, y = Metric, fill = Metric)) +
  geom_density_ridges(alpha = 0.7, scale = 0.9) +
  scale_fill_manual(values = c("ROE" = "#FF6B6B", "ROA" = "#4ECDC4", 
                              "Current_ratio" = "#4682B4", "Gross_margin" = "#45B7D1")) +
  labs(title = "MẬT ĐỘ PHÂN PHỐI CÁC CHỈ SỐ TÀI CHÍNH", x = "Giá trị", y = "") +
  theme_minimal() +
  theme(legend.position = "none")
print(p17)

# 18. Biểu đồ waterfall - Thay đổi doanh thu
cat("=== 18. BIỂU ĐỒ WATERFALL - THAY ĐỔI DOANH THU ===\n")
## === 18. BIỂU ĐỒ WATERFALL - THAY ĐỔI DOANH THU ===
waterfall_data <- ree_viz %>%
  mutate(
    Change = Revenue - lag(Revenue),
    Change = ifelse(is.na(Change), Revenue[1], Change),
    Type = ifelse(Change >= 0, "Tăng", "Giảm"),
    End = cumsum(Change),
    Start = lag(End, default = 0)
  )

p18 <- ggplot(waterfall_data) +
  geom_segment(aes(x = Year, xend = Year, y = Start, yend = End, color = Type), size = 8) +
  geom_point(aes(x = Year, y = End), size = 2, color = "white") +
  geom_text(aes(x = Year, y = End, label = round(Revenue, 1)), vjust = -1, size = 3) +
  scale_color_manual(values = c("Tăng" = "#2E8B57", "Giảm" = "#DC143C")) +
  labs(title = "PHÂN TÍCH THAY ĐỔI DOANH THU QUA CÁC NĂM", x = "Năm", y = "Doanh thu (tỷ đồng)") +
  theme_minimal()
print(p18)

# 19. Biểu đồ calendar heatmap - Hiệu suất theo thời gian
cat("=== 19. BIỂU ĐỒ CALENDAR HEATMAP - HIỆU SUẤT THEO THỜI GIAN ===\n")
## === 19. BIỂU ĐỒ CALENDAR HEATMAP - HIỆU SUẤT THEO THỜI GIAN ===
calendar_data <- ree_viz %>%
  mutate(
    ROE_Level = cut(ROE, breaks = 4, labels = c("Thấp", "Trung bình", "Khá", "Cao"))
  )

p19 <- ggplot(calendar_data, aes(x = Year, y = 1, fill = ROE_Level)) +
  geom_tile(color = "white", size = 1) +
  geom_text(aes(label = paste0(round(ROE*100, 1), "%")), color = "white", fontface = "bold") +
  scale_fill_manual(values = c("Thấp" = "#DC143C", "Trung bình" = "#FFA500", 
                              "Khá" = "#90EE90", "Cao" = "#2E8B57")) +
  labs(title = "HIỆU SUẤT ROE QUA CÁC NĂM", x = "Năm", y = "", fill = "Mức ROE") +
  theme_minimal() +
  theme(axis.text.y = element_blank(),
        panel.grid = element_blank())
print(p19)

# 20. Biểu đồ tổng quan hiệu quả - Đơn giản và chắc chắn
cat("=== 20. BIỂU ĐỒ TỔNG QUAN HIỆU QUẢ ===\n")
## === 20. BIỂU ĐỒ TỔNG QUAN HIỆU QUẢ ===
overview_data <- ree_viz %>%
  summarise(
    "Tăng trưởng\ndoanh thu" = (last(Revenue) - first(Revenue)) / first(Revenue) * 100,
    "ROE\ntrung bình" = mean(ROE) * 100,
    "ROA\ntrung bình" = mean(ROA) * 100,
    "Biên lợi nhuận\ntrung bình" = mean(Net_margin) * 100
  ) %>%
  pivot_longer(everything(), names_to = "Metric", values_to = "Value")

p20 <- ggplot(overview_data, aes(x = Metric, y = Value, fill = Metric)) +
  geom_col(alpha = 0.8, width = 0.7) +
  geom_text(aes(label = paste0(round(Value, 1), "%")), vjust = -0.5, size = 4, fontface = "bold") +
  scale_fill_manual(values = c("#2E8B57", "#4ECDC4", "#4682B4", "#45B7D1")) +
  labs(title = "TỔNG QUAN HIỆU QUẢ HOẠT ĐỘNG 2015-2024",
       subtitle = "So sánh các chỉ số trung bình trong giai đoạn 10 năm",
       x = "", y = "Tỷ lệ (%)") +
  theme_minimal() +
  theme(legend.position = "none",
        axis.text.x = element_text(size = 10, face = "bold"),
        plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))
print(p20)