1 Giới thiệu.

FPM còn gọi là basket analysis là kĩ thuật phân tích hành vi khách hàng dựa trên lịch sử giao dịch của họ, từ đó giúp cho kinh doanh nắm được nhu cầu sử dụng sản phẩm và thị hiếu của khách hàng từ đó có những chiến dịch Marketing một cách hợp lý.

Ví dụ: Trong siêu thị, thông thường khách hàng mua bàn chải và kem đánh răng môi lần giao dịch, điều này thấy rằng 2 sản phẩm (item) này đã tạo ra một mối quan hệ (association rule) và các mỗi quan hệ như vậy sẽ giúp cho người bán hàng sẽ dự đoán được hành vi mua hàng của khách hàng để từ đó có được những chiến lược kinh doanh hợp lý để giúp tăng doanh thu.

2 Khái niệm cơ bản

Ta xét một ví dụ:

Xét toàn bộ các giao dịch của khách hàng A trong mỗi lần mua hàng, thì xác suất để khách hàng mua bàn chải là 5%, và trong những lần mua bàn chải xác suất khách hàng mua kem đánh răng là 60% thì hành vi mua sắm của khách hàng đã tạo nên mối quan hệ (association rule) của chính khách hàng A, hành vi mua bàn chải và kem đánh răng của khách hàng A được miêu tả như sau:

      {Bàn chải => Kem đánh răng}[suppport = 5%, confidence = 60%]

Ở đây xuất hiện 2 chỉ số là supportconfidence, đây là 2 chỉ số quan trọng để cấu thành lên 1 rule trong basket analysis. Vậy, 2 chỉ số này có ý nghĩa là gì?

Support: Tần xuất để khách hàng mua một hay nhiều sản phẩm trong toàn bộ các giao dịch của mình.

Confidence: Cơ hội để khách hàng mua thêm 1 sản phẩm tiếp theo trong chuỗi hành vi mua sắm của mình.

Xét trong ví dụ trên:

  • Support[bàn chải] = 5% nghĩa là có 100 khách hàng vào của hàng mua sắm thì có 5 khách hàng mua bàn chải.

  • Confidence[bàn chải => kem đánh răng] = 60% nghĩa là trong số 5 khách hàng mua bàn chải ở trên thì có 3 khách hàng mua cả kem đánh răng trong chuỗi giao dịch của mình.

3 Mô tả bằng ví dụ giao dịch của khách hàng.

Xét hành vi mua sắm của tập khách hàng (dạng số liệu data.frame) được mô tả như sau:

ID Break Beer Milk Egg Meal
101 1 0 1 1 0
102 1 1 0 1 0
103 0 1 0 0 1
104 1 0 0 1 0
105 1 0 0 0 0

Biến đổi dữ liệu dạng data.frame sang dạng liệu kê sản phẩm (transaction):

ID item
101 Break,Milk,Egg
102 Break,Beer,Egg
103 Beer,Meal
104 Break,Egg
105 Break

Trong đó:

        1: có sử dụng sản phẩm
        0: không sử dụng sản phẩm

Mức Support:

\(Support[item_{i}] = \frac{Số khách hàng mua item_{i}}{Tổng số khách hàng} = \frac{count(item_{i})}{count(ID)}\)

  • Ví dụ đối với sản phẩm là Break:

    \(Support[Break] = \frac{4}{5} = 0.8\)

    Ý nghĩa: Có 5 khách hàng thì 4 khách hàng mua Break chiếm 80%

  • Ví dụ khách hàng mua cả Break và Beer.

    \(Support[Break,Beer] = \frac{1}{5} = 0.2\)

    Ý nghĩa: Có 5 khách hàng thì 1 khách hàng mua cả Break và Beer chiếm 20%

Mức Confidence:

Trong số những khách hàng mua Break thì bao nhiêu trong số đó là mua bia, rule được hình thành như sau:

\(Confidence[Break => Beer]=\frac{support[Break,Beer]}{support(Bear)}=\frac{0.2}{0.8}=0.25\)

Ý nghĩa: Đối với những khách hàng mua Break thì xác suất để họ mua thêm Beer là 25%.

4 Ứng dụng.

4.1 Các bước thực hiện thuật toán

Để thực hiện thuật toán Basket Analysis tìm mối liên hệ giữa các item, thì chúng ta cần phải cài đặt package: arules và arulesVis.

Các bước thực hiện biến đổi dữ liệu:

  • Bước 1: Chuyển dữ liệu dạng data.frame về dạng liệt kê các transaction

    • sử dụng hàm read.transaction()
  • Bước 2: Sử dụng hàm apriori() để tìm các mối quan hệ giữa các item.

  • Bước 3: Xóa các rule trùng lặp.

  • Bước 4: Trực quan hóa dữ liệu

    • Sử dụng hàm plot() trong package arulesViz.
  • Bước 5: Convert từ rule sang khách hàng.

4.2 Ứng dụng với dữ liệu ngân hàng.

  • Các package sử dụng trong Basket Analysis.
library(arules)
library(arulesViz)
library(reshape2)
library(dplyr)
  • Basket Analysis.

    • Dữ liệu sử dụng sản phẩm khách hàng - Product holding
folder <- "D:/2.R/1.Datamining/1.Basket analysis/"

baset.raw.test <- 
  read.csv(file = paste(folder,"basket.raw.csv",sep = ""))

baset.raw.test %>% 
  head()
##       cif  item value
## 1  192852 banca     1
## 2 3106491 banca     1
## 3 1998832 banca     1
## 4 2251209 banca     1
## 5 2169657 banca     1
## 6   84728 banca     1
  • Sử dụng hàm read.transaction() chuyển dữ liệu từ dạng data.frame sang dạng dữ liệu liệt kê sản phẩm (item)
baset.raw <- 
  read.transactions(file = paste(folder,"basket.raw.csv",sep = ""),
                    format = "single",
                    sep = ",",
                    cols = c("cif","item"))

baset.raw %>% 
  summary()
## transactions as itemMatrix in sparse format with
##  42264 rows (elements/itemsets/transactions) and
##  33 columns (items) and a density of 0.05489449 
## 
## most frequent items:
##      tgkkh        i2b   gd_noibo card_debit   pro_auto    (Other) 
##      40940      10627       5046       4076       3907      11966 
## 
## element (itemset/transaction) length distribution:
## sizes
##     1     2     3     4     5     6     7     8     9    10    11    12 
## 25388  8971  3873  1711   951   551   362   190   136    66    32    20 
##    13    14    15    16 
##     7     4     1     1 
## 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   1.000   1.812   2.000  16.000 
## 
## includes extended item information - examples:
##              labels
## 1             banca
## 2 bao_lanh_bao_hanh
## 3  bao_lanh_du_thau
## 
## includes extended transaction information - examples:
##   transactionID
## 1          1000
## 2       1000019
## 3        100003
  • Sử dụng hàm apriori tìm rule.
rule <- 
  apriori(data = baset.raw, 
                parameter = list(support = 0.01, #Minimum support level to filter the transaction. 
                                 # Nếu mức support nhỏ nhất là (10%) thì có nghĩa là nếu khách hàng mua 1 sản phẩm A 
                                 # mà ít hơn 10% thì sản phẩm đó sẽ không đc coi là 1 rules.
                                 confidence = 0.5, # Minimum confidence level to filter the transaction- 
                                 # Mức độ tin cậy tới thiểu để lọc các giá trị
                                 maxlen = 9,       # Tìm kiếm mối quan hệ tối đa của 2 sản phẩm. (A ==> B)
                                 minlen = 1)
                # ,appearance = list(rhs = c("Pro1"))
)
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport support minlen maxlen
##         0.5    0.1    1 none FALSE            TRUE    0.01      1      9
##  target   ext
##   rules FALSE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 422 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[33 item(s), 42264 transaction(s)] done [0.00s].
## sorting and recoding items ... [17 item(s)] done [0.00s].
## creating transaction tree ... done [0.01s].
## checking subsets of size 1 2 3 4 done [0.00s].
## writing ... [62 rule(s)] done [0.00s].
## creating S4 object  ... done [0.00s].
  • Kiểm tra 6 rule đầu.
# Bước 3: Kiểm tra các rule có chỉ số lift là cao nhất
as(rule,"data.frame") %>% 
  arrange(desc(lift)) %>% 
  head()
##                                   rules    support confidence      lift
## 1             {fx,tgkkh} => {gd_quocte} 0.01258754  0.8404423 61.242164
## 2                   {gd_quocte} => {fx} 0.01258754  0.9172414 61.145567
## 3                   {fx} => {gd_quocte} 0.01258754  0.8391167 61.145567
## 4             {gd_quocte,tgkkh} => {fx} 0.01258754  0.9172414 61.145567
## 5       {card_credit,i2b} => {gd_noibo} 0.01071834  0.6937213  5.810431
## 6 {card_credit,i2b,tgkkh} => {gd_noibo} 0.01071834  0.6937213  5.810431
  • Nhận xét: Ở đâu xuất hiện thêm chỉ số Lift có ý nghĩa:

    \(Lift[A=>B] = \frac{confidence[A=>B]}{support[B]}=\frac{support[A=>B]}{support[A].support[B]} = a\)

    • Nếu: Lift > 1 khi KH mua sản phẩm A sẽ làm tăng khả năng mua thêm sản phẩm B a lần.

    • Nếu: Lift < 1 khi KH mua sản phẩm A sẽ làm giảm khả năng mua thêm sản phẩm B a lần.

    • Nếu: Lift = 1 khi KKH mua sản phẩm A sẽ không làm tăng khả năng mua sản phẩm B (A và B là 2 sản phẩm độc lập với nhau)

  • Tuy nhiên, trong thực tế, tùy mục đích là tìm các rule để tăng khả năng bán được sản phẩm nên chúng ta chỉ quan tâm tới các rule mà có hệ số Lift > 1.

  • Loại bỏ các rule trùng lặp

# Bước 3: Loại bỏ những rule trùng lặp.

subset.matrix <- is.subset(rule,rule) # Tạo matrix đánh giá các rule
#subset.matrix[1:3,1:3] # Kiểm tra matrix vuông con 3x3.
# Là ma trận vuông cấp nxn ( n là số rule được tạo), nên các giá trị bị trùng lặp qua trường chéo chính nhận giá trị (TRUE).
# nên ta đưa các giá trị phía dước đường chéo chính về giá trị NA.
subset.matrix[lower.tri(subset.matrix,diag = T)] <- NA

# Lấy toàn bộ những giao dịch là tập con của giao dịch khác. Tạo là tập redundant.
redundant <- colSums(subset.matrix,na.rm=T) >= 1
# Loại bỏ những rule trùng (loại bỏ khỏi rule ban đầu tập redundant)
rules <- rule[!redundant]

Định nghĩa về rule trùng:

  • Rule A được gọi 1 rule thừa, khi rule A là tập mẹ của 1 rule khác, và rule A có lift bằng hoặc thấp hơn so với rule đó.

  • Tức là: Với 2 rule {A,B,C} → {D} và {A,B} → {D}, thì {A,B,C} → {D} là rule thừa nếu có lift thấp hơn so với rule còn lại.

  • Ví dụ:

    • Rule 1: Milk => bread (12% support , 85% confidence, 1.2 lift)

    • Rule 2: Milk ,beer ,Chocolate => bread (1% support, 84% confidence, 1.15 lift)

    • Trong 2 rule này thì rule 2 là rule trùng

  • Các rule sau khi loại rule trùng

rule.final <- rules
rule.final %>% 
  inspect()
##    lhs              rhs        support    confidence lift     
## 1  {}            => {tgkkh}    0.96867310 0.9686731   1.000000
## 6  {gd_quocte}   => {fx}       0.01258754 0.9172414  61.145567
## 13 {pro_none}    => {i2b}      0.01802953 0.5277008   2.098687
## 15 {card_credit} => {gd_noibo} 0.01925989 0.6237548   5.224410
## 16 {card_credit} => {i2b}      0.01545050 0.5003831   1.990044
## 21 {gd_noibo}    => {i2b}      0.06009843 0.5033690   2.001918
  • Bài toán xác định 3 trường hợp mà người phân tích muốn quan tâm:

  • Bài toán 1: Khách hàng sẽ mua sản phẩm nào tiếp theo khi mua sản phẩm Credit Card.

sub.rule1 <- subset(rule.final,(lhs %in% c("card_credit")))
sub.rule1 %>% 
  inspect()
##    lhs              rhs        support    confidence lift    
## 15 {card_credit} => {gd_noibo} 0.01925989 0.6237548  5.224410
## 16 {card_credit} => {i2b}      0.01545050 0.5003831  1.990044
  • Bài toán 2: Khách hàng sử dụng sản phẩm gì trước khi sử dụng sản phẩm Giao dịch nội bộ.
sub.rule2 <- subset(rule.final,(lhs %in% c("gd_noibo")))
sub.rule2 %>% 
  inspect()
##    lhs           rhs   support    confidence lift    
## 21 {gd_noibo} => {i2b} 0.06009843 0.503369   2.001918
  • Bài toán 3: Những sản phẩm nào mà khách hàng hay mua cùng nhau.
  as(rule.final,"data.frame") %>% 
  arrange(desc(lift)) %>% 
  as.data.frame()
##                         rules    support confidence      lift
## 1         {gd_quocte} => {fx} 0.01258754  0.9172414 61.145567
## 2 {card_credit} => {gd_noibo} 0.01925989  0.6237548  5.224410
## 3         {pro_none} => {i2b} 0.01802953  0.5277008  2.098687
## 4         {gd_noibo} => {i2b} 0.06009843  0.5033690  2.001918
## 5      {card_credit} => {i2b} 0.01545050  0.5003831  1.990044
## 6               {} => {tgkkh} 0.96867310  0.9686731  1.000000
  • Visualization mối quan hệ giữa các rule.
plot(rule.final,method = "graph")

5 Kết luận.

Trong ngân hàng, bài toán basket analysis là bài toán rất hiệu quả trong việc tìm nhóm khách hàng tiềm năng để từ đó có những chính xác Marketing để bán chéo sản phẩm.

Bài toán Basket Analysis được ứng dụng rộng rãi trong nhiều lĩnh vực như: Y dược, nông nghiệp, môi trường,…