[DA-DS] Thử làm Data Analyst – Topic 1. Phân tích dữ liệu giao dịch Ngân hàng điện tử

Hello anh em! Chào mừng anh em quay lại với series về DA-DS. Hôm nay chúng ta sẽ thử làm một Data Analyst với bài toán số 1 – Phân tích dữ liệu giao dịch Ngân hàng điện tử nhé.

Như vậy sau 02 bài đầu tiên về DA-DS, các bạn đã có một số kiến thức cơ bản ban đầu về món này như: cài đặt và sử dụng Python, các thao tác cơ bản với pandas… . Bạn nào chưa đọc có thể đọc tại đây:

Từ bài số 3 trở đi, chúng ta sẽ cùng học tiếp món này với các topic cụ thể để các bạn đỡ chán và ngấy. Mình rất mong nhận được sự tương tác của các bạn để cùng nghiên cứu, học hỏi nhiều hơn trong mảng này.

Và cụ thể hơn, ngày hôm nay chúng ta sẽ thử trải nghiệm làm một DA với giả định là bạn làm trong một Ngân hàng và được sếp giao phân tích tình hình giao dịch Ngân hàng điện tử trong 6 tháng vừa qua cho sếp xem.

Chúng ta sẽ từng bước giải quyết bài toán đó đồng thời ôn lại các lệnh đã biết, thử một số lệnh mới để vẽ đồ thị visualize cho sếp. Lý do vì chả sếp nào thích nhìn một file excel dày đặc số với má đâu, sếp ít thời gian và sếp thích nhanh gọn cơ.

Qua bài này các bạn cũng sẽ hình dung được khi tiếp cận một bài toán DA thì cần làm những step by step như thế nào. Let’s go!

Phần 1 – Chuẩn bị phân tích dữ liệu

Với món DA-DS thì việc đầu tiên là phải có dữ liệu. Không có dữ liệu thì thôi, book vé đi nghỉ mát luôn chứ mần gì nữa. Trong thực tế với bài này các bạn sẽ sử dụng dữ liệu trong DB của Ngân hàng trực tiếp. Còn hôm nay để minh họa, mình đã chuẩn bị sẵn một file dữ liệu cho các bạn thực hành.

Chú ý rằng:

  • Dữ liệu đã được làm mờ, chỉnh sửa dữ liệu để tránh vi phạm quy định về chống thất thoát dữ liệu.
  • File dữ liệu này chỉ để minh họa, ko ám chỉ hay nói tới bất kỳ ngân hàng cụ thể nào.

File dữ liệu các bạn có thể tải tại đây.

Việc đầu tiên khi chúng ta tiếp cận dữ liệu là chúng ta phải load và display ra xem dữ liệu của chúng ta có những trường gì, giá trị ra sao.

# Load thư viện
import pandas as pd
import numpy as np

# Đọc file csv
df = pd.read_csv("S2_DataFile.csv")

# Hiển thị 5 dòng đầu tiên
df.head(5)Code language: PHP (php)

Và đây là kết quả:

Với bảng dữ liệu này ta có thể thấy Dataframe gồm 5 field và có ý nghĩa là: Mã chi nhánh, kênh giao dịch (qua Mobile Banking, Internet Banking hoặc ATM), số tiền giao dịch, loại giao dịch và ngày giờ giao dịch.

Nói thêm là file dữ liệu có 500 dòng tất cả nhé!

Phần 2 – Tiền xử lý dữ liệu

Dữ liệu collect từ nhiều nguồn khác nhau, từ nhiều người khác nhau nên chắc chắn trước khi sử dụng chúng ta sẽ phải tiền xử lý dữ liệu. Với mỗi dữ liệu khác nhau, cách xử lý lại khác nhau do đó mình không thể cover hết các case được. Ở đây mình sẽ chỉ xin demo một vài bước tiền xử lý mình thử nghiệm với dữ liệu demo này để các bạn hình dung cách thức làm như nào thôi.

Kiểm tra kiểu dữ liệu

Việc đầu tiên mình hay làm là kiểm tra các cột dữ liệu, đặc biệt là cột số và cột ngày tháng, mục đích là nó hay bị nhầm sang kiểu “String”. Ví dụ bây giờ mình kiểm tra thử cột TRAN_TIME xem.

# Kim tra dliu TRAN_TYPE
print(df['TRAN_TYPE'].dtypes)

-> Kết qutrra là objectCode language: CSS (css)

Điều đó có nghĩa là chưa phải là kiểu DateTime. Mình sẽ convert nó về dạng DateTime bằng lệnh:

# Convert về dạng DateTime
df['TRAN_TIME'] = pd.to_datetime(df['TRAN_TIME'],format='%d/%m/%Y %H:%M')

# In kiểu dữ liệu
print(df['TRAN_TIME'].dtype)

-> Kết quả trả ra là datetime64[ns]Code language: PHP (php)

Tương tự với cột AMOUNT, chúng ta cũng kiểm tra và… nó đã là kiểu float64 sẵn rồi, khỏi can thiệp mất công:

print(df['AMOUNT'].dtype)Code language: CSS (css)

Tùy theo bài toán, tùy dữ liệu mà các bạn phải kiểm tra nhiều hay ít cột dữ liệu. Hãy đảm bảo làm chuẩn bước này để tránh các lỗi phát sinh về sau nha!

Kiểm tra tính đúng đắn của dữ liệu

Bây giờ các cột data đã đúng kiểu dữ liệu rồi nhưng chúng có thể sai về mặt ý nghĩa dữ liệu. Lý do thì có thể do nhập sai, do lỗi khi xuất… Phần này các bạn sẽ phải sử dụng kiến thức của mình trong lĩnh vực mà bạn đang làm việc để phán đoán và đưa ra quyết định.

Ta ví dụ với trường dữ liệu AMOUNT đi chẳng hạn. Sử dụng kiến thức chuyên gia ta sẽ biết rằng trường này phải là số > 0 và chúng ta cần loại ra các dòng dữ liệu có vấn đề ( <=0 ).

Để đơn giản mình sẽ drop các dòng có dữ liệu sai đi. Các bạn cũng có thể áp dụng các phương pháp phức tạp hơn như chuyển các giá trị đó về NaN rồi áp dụng df.fillna() như đã thảo luận trong bài trước.

Đầu tiên ta kiểm tra cột AMOUNT cái nào:

# Check tng quan dliu
print(df['AMOUNT'].describe())Code language: CSS (css)

count    5.000000e+02
mean     3.529194e+06
std      1.602360e+07
min     -2.000000e+06
25%      7.883650e+04
50%      1.002200e+06
75%      3.000000e+06
max      3.000000e+08
Name: AMOUNT, dtype: float64Code language: CSS (css)

Như vậy là đã đúng kiểu float64 nhưng các bạn để ý min value = -2.000000e+06. Ố ô ồ…. sai rồi! Bây giờ xử lý cắt đi các row bị lỗi nào:

# Tạo mask để lấy các bản ghi hợp lệ
mask = df['AMOUNT'] > 0

# Lấy các bản ghi không lỗi
df = df[mask]Code language: PHP (php)

Sau 2 câu lệnh trên, có 2 dòng sẽ bị xóa đi và chúng ta sẽ còn lại 498 dòng.

Chú ý: Nãy giờ chúng ta thao tác là hoàn toàn làm trên bộ nhớ RAM của máy tính nhé. Nghĩa là dữ liệu từ csv được load vào Python, chúng ta làm trên đó chứ không hề thay đổi đến file csv. Do đó, nếu muốn lưu lại kết quả xử lý (để lần sau vào không phải làm lại từ đầu) các bạn có thể dùng lệnh df.to_csv(‘tên file.csv’) nhé!

Sang bước tiếp theo thôi!

Tạo ra các cột dữ liệu mới

Thông thường để tiện cho việc tính toán, group hay biểu diễn lên biểu đồ thì chúng ta hay tạo ra các cột dữ liệu mới. Cái này là tùy các bạn nhé, chứ không phải bài nào cũng phải tạo. Với bài này mình cần thống kê số giao dịch theo giờ trong ngày nên để tiện mình sẽ tạo ra 1 cột TRAN_HOUR – giờ giao dịch của khách hàng

# Tạo cột giờ
df['TRAN_HOUR'] = df['TRAN_TIME'].dt.strftime('%H')

# Kiểm tra thử
print(df[['TRAN_HOUR','TRAN_TIME']])Code language: PHP (php)

Và kết quả đây:

    TRAN_HOUR           TRAN_TIME
0          01 2019-01-12 01:11:00
1          11 2019-01-12 11:01:00
2          01 2019-01-12 01:11:00
3          06 2019-01-12 06:50:00
4          01 2019-01-12 01:11:00
..        ...                 ...
495        08 2019-01-12 08:45:00
496        21 2019-04-11 21:13:00
497        10 2019-01-12 10:53:00
498        08 2019-01-12 08:58:00
499        09 2019-01-12 09:13:00Code language: CSS (css)

Đó, như vậy với vài bước cơ bản chúng ta đã tiền xử lý và có được một bảng dữ liệu khá ổn. Bây giờ chúng ta bắt đầu vào bước vẽ vời nào.

Phần 3 – Phân tích dữ liệu và biểu diễn dữ liệu

Phần này thì tùy yêu cầu cụ thể của sếp cũng như tùy ý đồ và kinh nghiệm thực chiến của các bạn mà sáng tạo, vẽ vời.

Mình tạm thời đưa ra 3 biểu đồ mà theo mình thấy là có ích và đoán là sếp mình sẽ muốn xem.

Biểu đồ 1. Biểu đồ Pie về tỷ lệ sô tiền giao dịch trên các kênh

Với biểu đồ này mình muốn thể hiện rằng kênh giao dịch nào khách hàng dùng nhiều, kênh nào dùng ít để từ đó Ngân hàng có các chiến lược kinh doanh khác nhau.

# Thực hiện group by channel và tính tổng số tiền giao dịch
sum_AMT_byChannel = df.groupby(['CHANNEL_ID'])['AMOUNT'].sum().reset_index(name='SUM_AMT_BY_CHN')
print(sum_AMT_byChannel)

df_plot = sum_AMT_byChannel
df_plot = df_plot.set_index('CHANNEL_ID')
print(df_plot)
plot = df_plot.plot.pie(y='SUM_AMT_BY_CHN',subplots=True, figsize=(8, 8))

# TRANG TRÍ VÀ HIEN THI BIEU DO
plt.title("DOANH SỐ GIAO DỊCH THEO KÊNH")
plt.ylabel("")
plt.show()
Code language: PHP (php)

Và kết quả thật Awsome:

phân tích dữ liệu

Như vậy ta có gì nhỉ? Khách hàng ngày nay đã dùng Mobile và Internet nhiều hơn ATM rồi. Đúng trend không dùng tiền mặt ra phết!

Biểu đồ 2. Biểu đồ cột về số lượng và doanh số giao dịch theo kênh

Để làm rõ, ta tiếp tục tìm hiểu Số lượng giao dịch và Doanh số thu được của mỗi kênh để phân tích dữ liệu và tìm hiểu xem kênh nào có hiệu quả hoạt động tốt nhất. Chúng ta sẽ biểu diễn thử vào biểu đồ hình Bar để thấy được độ tương quan giữa Số giao dịch và Doanh số của mỗi kênh.

Chú ý: trong việc biểu diễn các mối tương quan giữa các đại lượng khác nhau ví dụ như số tiền giao dịch thường rất lớn (đơn vị triệu đồng, tỷ đồng,…) và số giao dịch (chục, trăm, nghìn,…) nên ta cần thực hiện quy dữ liệu về một đại lượng chung để biểu diễn trên hình ảnh được phù hợp và chính xác.

Trong bài tập này chúng ta quy Doanh số và Số lượng giao dịch về tỷ lệ % của để so sánh mức độ tương quan.

# 8. VE BIEU DO DANH DOANH SO VA SO LUONG GIAO DICH TREN CAC KENH GIAO DICH
count_byChannel = df.groupby(['CHANNEL_ID']).size().reset_index(name='COUNTS')
print(count_byChannel)
df_plot2 = sum_AMT_byChannel.merge(count_byChannel, on=['CHANNEL_ID'])
print(df_plot2)
df_plot2 = df_plot2.set_index('CHANNEL_ID')
print(df_plot2)

# Quy đổi dữ liệu Doanh số về phần trăm để biểu diễn tính tương quan của dữ liệu
max_amt = df_plot2['SUM_AMT_BY_CHN'].max()
df_plot2['%_DOANHSO'] =df_plot2['SUM_AMT_BY_CHN']*100/max_amt
# Quy đổi dữ liệu Số lượng giao dịch về phần trăm để biểu diễn tính tương quan của dữ liệu
max_count = df_plot2['COUNTS'].max()
df_plot2['%_SOLUONG'] = df_plot2['COUNTS'] * 100 / max_count
print(df_plot2)
 
df_plot2.plot.bar( y=['%_SOLUONG','%_DOANHSO'])
plt.title("Tỷ lệ doanh số và số lượng giao dịch theo các kênh", fontsize=22)
plt.ylabel('tỷ lệ %')
plt.xticks(rotation=0)
 
plt.show()
Code language: PHP (php)
phân tích dữ liệu

Kênh Mobile vẫn là kênh nhiều giao dịch nhất vì ngày nay mobile quá tiện và là vật bất ly thân rồi. Nhưng để ý chút thì ta thấy dù Internet giao dịch ít nhưng volume giao dịch lại cao suy ra các món lớn người ta hay có thói quen dùng IB để chuyển tiền kaka. Còn ông ATM thì miễn bàn =))

Biểu đồ 3. Số liệu giao dịch trung bình trong từng giờ trong ngày

Cuối cùng trong bài tập này chúng ta cùng vận dụng các kiến thức phân tích dữ liệu của bài số 2 để tổng hợp số liệu và biểu diễn dữ liệu thành dạng đồ thị đường  lưu lượng giao dịch trung bình trong ngày theo giờ giao dịch để xem đối với mỗi kênh hành vi giao dịch có gì khác biệt

# 9. VE BIEU DO LUU LUONG GIAO DICH CÁC KENH TRUNG BINH THEO GIO MOI NGAY
# Tính số ngày trong dữ liệu
number_of_days = (df['TRAN_TIME'].max().date() - df['TRAN_TIME'].min().date()).days
print(number_of_days)
 
# Trích ra 2 cột kênh và giờ
df = df[['CHANNEL_ID', 'TRAN_HOUR']]

# Group và tính số lượng từng kênh trong từng giờ
count_by_CNNTime = df.groupby(['CHANNEL_ID','TRAN_HOUR']).size().reset_index(name='COUNTS_CNNTIME')

# Áp dung pivot table để xoay dữ liệu
df_plot3 = pd.pivot_table(count_by_CNNTime, values='COUNTS_CNNTIME', index=['TRAN_HOUR'], columns=['CHANNEL_ID'])

# Xử lý NaN
df_plot3['ATM'] = df_plot3['ATM'].fillna(0)
df_plot3['INTERNET'] = df_plot3['INTERNET'].fillna(0)
df_plot3['MOBILE'] = df_plot3['MOBILE'].fillna(0)

# Tính giá trị trung bình theo ngày
df_plot3['ATM']  = df_plot3['ATM'] / number_of_days
df_plot3['INTERNET'] = df_plot3['INTERNET'] / number_of_days
df_plot3['MOBILE'] = df_plot3['MOBILE'] / number_of_days

# Vẽ biểu đồ
df_plot3.plot(y=['ATM', 'INTERNET', 'MOBILE'], figsize=(12, 6),marker='o')
plt.title('Số lượng giao dịch trung bình trong ngày theo giờ')
plt.ylabel('Số lượng giao dịch trung bình')
plt.xlabel('Giờ giao dịch')
 
plt.show()Code language: PHP (php)
phân tích dữ liệu

Phần 4 – Kết luận

Bằng một số các xử lý dữ liệu và hiển thị đơn giản chúng ta biểu diễn được các kết quả phân tích dữ liệu khá ổn như trên đây.

Cuối cung kết thúc bài tập này, chúng ta có thể đưa ra một số kết luận “vui vẻ” nhưng cũng có vẻ hợp lý đó nhỉ:

  • Dữ liệu nguồn có lỗi, dẫn đến trường hợp phi lý về số tiền giao dịch, cần xem xét lại cách ghi nhận, thu thập dữ liệu nguồn này có tin cậy hay không
  • Kênh giao dịch Internet Banking và Mobile Banking chiếm được ưu thế cao hơn so với kênh giao dịch ATM
  • Số lượng giao dịch tại kênh Mobile so với doanh số thu được là tương đương, trong khi đó số lượng giao dịch tại kênh Internet Banking thì thấp nhưng giá trị giao dịch lại lớn hơn rất nhiều, trong khi đó ngược lại tại ATM thì số lượng giao dịch lại nhiều hơn so với số tiền giao dịch. Tất nhiên còn cần thêm các phân tích khác nhưng có thể tạm đánh giá rằng người ta thường dùng Mobile Banking để làm các giao dịch nhỏ, còn khi có các khoản giao dịch lớn khách hàng sẽ chuộng dùng Internet Banking hơn, tại ATM khách hàng có vẻ cũng chỉ có nhu cầu rút các món tiền giá trị nhỏ.
  • Khách hàng có nhu cầu sử dụng dịch vụ Mobile Banking vào buổi đêm là rất lớn, sau đó là các thời điểm giữa giờ sáng, giữa giờ chiều, tối. Trong khi đó dịch vụ Internet Banking được sử dụng nhiều vào khung giờ hành chính. Và dịch vụ ATM được dùng nhiều hơn vào buổi sáng. Từ các thông tin này ngân hàng cũng có thể dễ ra quyết định cho các thời điểm tắt/ dừng dịch vụ của mình hợp lý hơn

Rồi, mình xin tạm dừng bài này ở đây. Hi vọng đã mang lại cho các bạn những thông tin bổ ích và lý thú! Hẹn gặp lại các bạn trong các bài tiếp theo trong series DA-DS nhé!

Hãy join cùng cộng đồng Mì AI nhé!

Fanpage: http://facebook.com/miaiblog
Group trao đổi, chia sẻ: https://www.facebook.com/groups/miaigroup
Website: https://miai.vn
Youtube: http://bit.ly/miaiyoutube

Related Post

One Reply to “[DA-DS] Thử làm Data Analyst – Topic 1. Phân tích dữ liệu giao dịch Ngân hàng điện tử”

Leave a Reply

Your email address will not be published. Required fields are marked *