Nhóm sinh viên thực hiện: Hồ Trần Hoàng Triều,
Nguyễn Trung Hậu
Giảng viên hướng dẫn: ThS. Trần Mạnh Tường
data <- read.csv(file.choose(), header = TRUE)
Ở dòng lệnh này, tụi em đã chọn file transactions_data.csv để thêm file csv vào RStudio. Sau đó tụi em đã gán data.frame này vào biến data để thuận lợi phân tích.
dim(data)
## [1] 13305915 12
Từ đây cho thấy bộ dữ liệu có 13305915 dòng và 12 cột. Tương ứng với 13305915 quan sát và 12 biến
str(data)
## 'data.frame': 13305915 obs. of 12 variables:
## $ id : int 7475327 7475328 7475329 7475331 7475332 7475333 7475334 7475335 7475336 7475337 ...
## $ date : chr "2010-01-01 00:01:00" "2010-01-01 00:02:00" "2010-01-01 00:02:00" "2010-01-01 00:05:00" ...
## $ client_id : int 1556 561 1129 430 848 1807 1556 1684 335 351 ...
## $ card_id : int 2972 4575 102 2860 3915 165 2972 2140 5131 1112 ...
## $ amount : chr "$-77.00" "$14.57" "$80.00" "$200.00" ...
## $ use_chip : chr "Swipe Transaction" "Swipe Transaction" "Swipe Transaction" "Swipe Transaction" ...
## $ merchant_id : int 59935 67570 27092 27092 13051 20519 59935 39021 50292 3864 ...
## $ merchant_city : chr "Beulah" "Bettendorf" "Vista" "Crown Point" ...
## $ merchant_state: chr "ND" "IA" "CA" "IN" ...
## $ zip : num 58523 52722 92084 46307 20776 ...
## $ mcc : int 5499 5311 4829 4829 5813 5942 5499 4784 7801 5813 ...
## $ errors : chr "" "" "" "" ...
Từ câu lệnh cho thấy bộ dữ liệu có 6 biến định tính và 6 biến định lượng
missing_col <- colSums(is.na(data))
missing_value <- sum(is.na(data))
print(missing_value)
## [1] 1652706
print(missing_col)
## id date client_id card_id amount
## 0 0 0 0 0
## use_chip merchant_id merchant_city merchant_state zip
## 0 0 0 0 1652706
## mcc errors
## 0 0
Ở câu lệnh này chúng em đã xác định các giá trị bị thiếu theo cột và tổng giá trị bị thiếu của bộ dữ liệu. Kết quả cho thấy có 1652706 giá trị bị thiếu và các giá trị này nằm ở cột zip
library(data.table)
setDT(data)
dup_count <- data[, .N, by = names(data)][N > 1, .N]
print(dup_count)
## [1] 0
Ở dòng lệnh này, chúng em sử dụng gói data.table phù hợp xử lý dữ liệu có số quan sát lớn (hơn 13 triệu quan sát). Kết quả thu được: không có quan sát nào bị trùng
dup_id <- length(unique(data$card_id))
print(dup_id)
## [1] 4071
Kết quả phân tích cho thấy trong tổng số hơn 13 triệu giao dịch, chỉ có 4071 thẻ khác nhau được sử dụng.
Bộ dữ liệu bao gồm thông tin chi tiết về các giao dịch thanh toán bằng thẻ trong một khoảng thời gian nhất định. Mỗi dòng trong dữ liệu đại diện cho một giao dịch duy nhất, được mô tả thông qua 12 biến chính.Cụ thể:
Biến id là mã định danh duy nhất cho từng giao dịch, giúp phân biệt các giao dịch với nhau.
Biến date ghi nhận thời điểm giao dịch xảy ra, bao gồm ngày và giờ chính xác.
Biến client_id (mã khách hàng) cho biết thông tin lưu trữ về khách hàng.
Biến card_id (mã thẻ được sử dụng), cho phép theo dõi hành vi tiêu dùng theo từng cá nhân hoặc thiết bị thanh toán.
Biến amount thể hiện số tiền của giao dịch, trong đó giá trị dương tương ứng với số tiền giao dịch thành công và giá trị âm tương ứng với số tiền giao dịch thất bại(hoàn tiền).
Biến use_chip thể hiện phương thức thanh toán giao dịch, bao gồm ba loại: Chip Transaction (giao dịch qua chip EMV), Online Transaction (thanh toán trực tuyến), và Swipe Transaction (quẹt thẻ từ).
Biến merchant_id thể hiện mã nhà bán hàng
Biến merchant_city thể hiện thành phố/ nơi thực hiện giao dịch
Biến merchant_state thể hiện bang/ tiểu bang của nơi thực hiện giao dịch
Biến zip thể hiện mã bưu điện tương ứng với từng thành phố - nơi thực hiện giao dịch
Biến mcc (Merchant Category Code) phân loại ngành nghề kinh doanh của nhà bán hàng
Ví dụ:
Biến errors ghi nhận mã lỗi (nếu có) trong quá trình xử lý giao dịch; giá trị bằng 0 cho thấy giao dịch thành công, trong khi các lỗi chi tiết sẽ được ghi chú ở mục này phản ánh sự cố kỹ thuật hoặc từ chối thanh toán.
library(DT)
data$amount <- as.numeric(gsub("\\$", "", data$amount))
data_duong <- data[data$amount >0,]
data_am <- data[data$amount <0,]
Vì kiểu dữ liệu của cột amount là dạng character (ví dụ $80.00), nên chúng em đã chuyển định dạng cột này thành kiểu numberic (ví dụ 80.00) bằng cách bỏ đi ký tự $.
Ngoài ra do tính chất của biến amount là dương nếu có số tiền giao dịch thành công và âm nếu là số tiền giao dịch bị hoàn lại. Chính vì thế, nhóm em đã chia số tiền giao dịch này thành hai mẫu khác nhau tương ứng với đặc tính giao dịch.
library(DT)
counts <- sort(table(data$merchant_city), decreasing = TRUE)
counts <- as.data.frame(counts)
colnames(counts) <- c("Nơi thực hiện giao dịch","Số giao dịch")
datatable(head(counts,1000))
Kết quả cho thấy số lượng giao dịch trực tuyến (online) chiếm tỷ trọng cao nhất với 1563700 giao dịch
counts_duong <- sort(table(data_duong$client_id), decreasing = TRUE)
counts_duong <- as.data.frame(counts_duong)
colnames(counts_duong) <- c("Client_id","Số lần giao dịch thành công")
datatable(head(counts_duong,1000))
Kết quả cho thấy khách hàng có id 1963 có số lần giao dịch thành công cao nhất với 42137 giao dịch.
data_abs <- data_am
data_abs$amount <- abs(data_am$amount)
counts_am <- sort(table(data_abs$client_id), decreasing = TRUE)
counts_am <- as.data.frame(counts_am)
colnames(counts_am) <- c("Client_id","Số lần giao dịch bị hoàn tiền")
datatable(head(counts_am,1000))
Kết quả cho thấy khách hàng có id 1888 có số lần giao dịch thất bại và bị hoàn tiền nhiều nhất với *10957 giao dịch**.
counts_duong1 <- sort(table(data_duong$use_chip), decreasing = TRUE)
counts_duong1 <- as.data.frame(counts_duong1)
colnames(counts_duong1) <- c("Phương thức thanh toán","Số lần giao dịch thành công")
datatable(counts_duong1)
library(ggplot2)
ggplot(counts_duong1, aes(x = reorder(`Phương thức thanh toán`, `Số lần giao dịch thành công`),
y = `Số lần giao dịch thành công`)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(title = "Số lần giao dịch thành công theo các phương thức",
x = "Phương thức thanh toán", y = "Số lần") +
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Từ kết quả này, chúng em có nhận xét sau: Số lần giao dịch thành công
bằng hình thức quẹt thẻ là 6571735 giao dịch, chiếm ưu thế vượt
trội hơn hai phương thức còn lại do tính tiện lợi và nhanh chóng trong
cách thức giao dịch.
counts_am1 <- sort(table(data_abs$use_chip), decreasing = TRUE)
counts_am1 <- as.data.frame(counts_am1)
colnames(counts_am1) <- c("Phương thức thanh toán","Số lần giao dịch thất bại")
datatable(counts_am1)
ggplot(counts_am1, aes(x = reorder(`Phương thức thanh toán`, `Số lần giao dịch thất bại`),
y = `Số lần giao dịch thất bại`)) +
geom_col(fill = "tomato") +
coord_flip() +
labs(title = "Số lần giao dịch thất bại theo các phương thức",
x = "Phương thức thanh toán", y = "Số lần") +
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Từ kết quả này, chúng em có nhận xét sau: Số lần giao dịch thất bại bằng
hình thức quẹt thẻ là 637314 giao dịch, vượt trội hơn phương
thức còn lại là online.Ngoài ra, ta không thấy phương thức sử
dụng chip trong bảng này. Giải thích cho những điều này gồm hai
lý do chính sau:
Ở phần này, chúng em lựa chọn 2 biến chính để phân tích là use_chip và amount
table(data$use_chip)
##
## Chip Transaction Online Transaction Swipe Transaction
## 4780818 1557912 6967185
Kết quả cho thấy số lượng giao dịch bằng Chip là 4780818, bằng Thẻ là 6967185 và giao dịch trực tuyến là 1557912 . Điều này chứng tỏ, việc giao dịch bằng Thẻ trở nên phổ biến và được ưa chuộng vì sự tiện lợi và nhanh chóng của phương thức này vượt trội hơn so với hai phương thức còn lại.
Vì phương thức thanh toán có ba loại chính là Chip Transaction, Online Transaction Swipe Transaction mà mỗi loại lại có số tiền giao dịch khác nhau, nên chúng em đã lập bảng thống kê mô tả cho từng loại, nhằm mục đích để so sánh hành vi chi tiêu giữa các phương thức thanh toán, từ đó rút ra những nhận định về xu hướng sử dụng, mức độ an toàn và đặc điểm khách hàng tiềm năng.
Thống kê mô tả
library(dplyr)
summary1<- data_duong %>%
group_by(use_chip) %>%
summarise(
mean = mean(amount),
Q1 = quantile(amount, 0.25),
median = median(amount),
Q3 = quantile(amount, 0.75),
var = var(amount),
sd = sd(amount),
min = min(amount),
max = max(amount)
) %>%
mutate(across(where(is.numeric), ~ round(., 2)))
datatable(
summary1, caption = "Thống kê mô tả các giao dịch thành công theo các phương thức")
Biểu đồ Box-plot
library(ggplot2)
ggplot(data_duong, aes(x = use_chip, y = amount, fill = use_chip)) +
geom_boxplot(show.legend = FALSE) +
coord_cartesian(ylim = c(0, 250)) +
labs(
title = "Biểu đồ Box-Plot cho giá trị giao dịch thanh toán thành công theo từng phương thức",
x = "Phương thức thanh toán",
y = "Số tiền (USD)"
) +
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Từ bảng thống kê mô tả trên và biểu đồ Box-plot, chúng
em đưa ra những nhận xét sau:
1. Về Giá trị Giao dịch Trung bình:
2. Về Giá trị trung vị:
3. Về Mức độ Biến động (Độ lệch chuẩn):
Thống kê mô tả
summary2 <- data_abs %>%
group_by(use_chip) %>%
summarise(
mean = mean(amount),
Q1 = quantile(amount, 0.25),
median = median(amount),
Q3 = quantile(amount, 0.75),
var = var(amount),
sd = sd(amount),
min = min(amount),
max = max(amount))%>%
mutate(across(where(is.numeric), ~ round(., 2)))
datatable(summary2,
caption = "Thống kê mô tả các giao dịch hoàn tiền theo các phương thức")
Biểu đồ Box - plox
ggplot(data_abs, aes(x = use_chip, y = amount, fill = use_chip)) +
geom_boxplot(show.legend = FALSE) +
labs(
title = "Biểu đồ Box-Plot cho giá trị hoàn tiền theo từng phương thức",
x = "Phương thức thanh toán",
y = "Số tiền hoàn (USD)"
) +
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Từ kết quả trên, nhóm em rút ra các nhận xét sau:
1. Về Giá trị Hoàn tiền Trung bình:
2. Về Giá trị Hoàn tiền trung vị và tứ phân vị: