Chuyển đến nội dung chính

Phân tích giỏ hàng bằng R

Tìm hiểu về Market Basket Analysis & Thuật toán APRIORI đứng sau nó. Bạn sẽ thấy cách nó giúp nhà bán lẻ thúc đẩy kinh doanh bằng cách dự đoán các mặt hàng khách hàng mua cùng nhau.
· 15 phút đọc

Khám phá cùng AI

Bạn là một nhà khoa học dữ liệu (hoặc đang trở thành một người như vậy!), và bạn nhận được một khách hàng điều hành một cửa hàng bán lẻ. Khách hàng đưa cho bạn dữ liệu tất cả giao dịch gồm các mặt hàng được mua trong cửa hàng bởi nhiều khách hàng trong một khoảng thời gian và yêu cầu bạn sử dụng dữ liệu đó để giúp thúc đẩy kinh doanh. Khách hàng sẽ dùng phát hiện của bạn không chỉ để thay đổi/cập nhật/bổ sung hàng tồn kho mà còn để thay đổi bố cục cửa hàng vật lý hoặc cửa hàng trực tuyến. Để tìm ra kết quả giúp ích cho khách hàng, bạn sẽ dùng Phân tích giỏ hàng (MBA) dựa trên Khai phá luật kết hợp từ dữ liệu giao dịch đã cho.

Trong hướng dẫn này, bạn sẽ học:

  • Khai phá luật kết hợp là gì và các ứng dụng
  • Thuật toán APRIORI là gì?
  • Cách triển khai MBA/Khai phá luật kết hợp bằng R kèm trực quan hóa

Khai phá luật kết hợp

Khai phá luật kết hợp được dùng khi bạn muốn tìm mối liên hệ giữa các đối tượng khác nhau trong một tập, tìm mẫu phổ biến trong cơ sở dữ liệu giao dịch, cơ sở dữ liệu quan hệ hoặc bất kỳ kho thông tin nào khác. Ứng dụng của khai phá luật kết hợp xuất hiện trong Marketing, Phân tích dữ liệu giỏ hàng (hay Market Basket Analysis) trong bán lẻ, phân cụm và phân loại. Phương pháp này có thể cho bạn biết những mặt hàng khách hàng thường mua cùng nhau bằng cách sinh ra một tập luật gọi là Luật kết hợp. Nói đơn giản, nó đưa ra đầu ra là các luật dạng nếu cái này thì cái kia. Khách hàng có thể dùng các luật đó cho nhiều chiến lược marketing:

  • Thay đổi bố cục cửa hàng theo xu hướng
  • Phân tích hành vi khách hàng
  • Thiết kế danh mục sản phẩm
  • Tiếp thị chéo trên cửa hàng trực tuyến
  • Các mặt hàng đang thịnh hành khách hàng mua
  • Email cá nhân hóa với sản phẩm bán kèm

Xem ví dụ sau:

example

Đã cho một tập dữ liệu giao dịch. Bạn thấy các giao dịch được đánh số từ 1 đến 5. Mỗi giao dịch hiển thị các mặt hàng được mua trong giao dịch đó. Bạn có thể thấy Tã đi kèm Bia trong ba giao dịch. Tương tự, Bánh mì đi kèm sữa trong ba giao dịch khiến cả hai trở thành các tập mục phổ biến. Luật kết hợp được cho dưới dạng như sau:

$A=>B[Support,Confidence]$

Phần trước $=>$ được gọi là nếu (Tiền đề) và phần sau $=>$ được gọi là thì (Hậu đề).

Trong đó A và B là các tập mặt hàng trong dữ liệu giao dịch. A và B là các tập rời nhau.

$Computer=>Anti-virus Software[Support=20\%,confidence=60\%]$

Luật trên nói rằng:

  1. 20% giao dịch cho thấy Phần mềm diệt virus được mua cùng với Máy tính
  2. 60% khách hàng mua Phần mềm diệt virus thì mua kèm Máy tính

Trong phần tiếp theo bạn sẽ tìm hiểu các khái niệm cơ bản của Khai phá luật kết hợp:

Các khái niệm cơ bản của Khai phá luật kết hợp

Basic Concepts of Association Rule Mining
  1. Tập mục (Itemset): Tập hợp của một hoặc nhiều mặt hàng. Tập k-mục nghĩa là tập gồm k mặt hàng.

  2. Số đếm hỗ trợ (Support Count): Tần suất xuất hiện của một tập mục

  3. Độ hỗ trợ (s): Tỷ lệ giao dịch chứa tập mục 'X'

    $Support(X)=\frac{frequency(X)}{N}$

Với một luật A=>B, Độ hỗ trợ được tính bởi:

$Support(A=>B)=\frac{frequency(A,B)}{N}$

Lưu ý: P(AUB) là xác suất A và B xảy ra cùng nhau. P ký hiệu xác suất.

Hãy thử tự tính độ hỗ trợ cho Milk=>Diaper như một bài tập.

  1. Độ tin cậy (c): Với một luật A=>B, Độ tin cậy cho biết phần trăm B được mua cùng A.

$Confidence(A=>B)=\frac{P(A\cap B)}{P(A)}=\frac{frequency(A,B)}{frequency(A)}$

Số giao dịch có cả A và B chia cho tổng số giao dịch có A.

$Confidence(Bread=>Milk)=\frac{3}{4}=0.75=75\%$

Bây giờ hãy tìm độ tin cậy cho Milk=>Diaper.

Lưu ý: Độ hỗ trợ và Độ tin cậy đo mức độ thú vị của luật. Chúng được đặt bởi ngưỡng hỗ trợ tối thiểu và ngưỡng tin cậy tối thiểu. Các ngưỡng do khách hàng đặt giúp so sánh sức mạnh luật theo ý bạn hoặc khách hàng. Càng gần ngưỡng thì luật càng hữu ích cho khách hàng.

  1. Tập mục thường xuyên: Các tập mục có độ hỗ trợ lớn hơn hoặc bằng ngưỡng hỗ trợ tối thiểu (min_sup). Trong ví dụ trên min_sup=3. Tham số này do người dùng đặt.

  2. Luật mạnh: Nếu một luật A=>B[Support, Confidence] thỏa mãn min_sup và min_confidence thì đó là luật mạnh.

  3. Lift: Lift cho biết mức tương quan giữa A và B trong luật A=>B. Tương quan cho thấy tập mục A ảnh hưởng đến tập mục B như thế nào.

$Lift(A=>B)=\frac{Support}{Supp(A)Supp(B)}$

Ví dụ, với luật {Bread}=>{Milk}, lift được tính như sau:

$support(Bread)=\frac{4}{5}=0.8$

$support(Milk)=\frac{4}{5}=0.8$

$Lift(Bread=>Milk)=\frac{0.6}{0.8*0.8}=0.9$

  • Nếu luật có lift bằng 1, thì A và B độc lập và không thể rút ra luật từ chúng.

  • Nếu lift > 1, thì A và B phụ thuộc lẫn nhau, mức độ phụ thuộc thể hiện qua giá trị lift.

  • Nếu lift < 1, thì sự hiện diện của A sẽ tác động tiêu cực lên B.

Mục tiêu của Khai phá luật kết hợp

Khi bạn áp dụng Khai phá luật kết hợp lên một tập giao dịch T, mục tiêu là tìm tất cả luật có:

  1. Độ hỗ trợ lớn hơn hoặc bằng min_support
  2. Độ tin cậy lớn hơn hoặc bằng min_confidence

Thuật toán APRIORI

Ở phần này, bạn sẽ tìm hiểu thuật toán chạy phía sau các thư viện R cho Phân tích giỏ hàng. Điều này giúp bạn hiểu khách hàng hơn và phân tích kỹ hơn. Nếu bạn đã biết về thuật toán APRIORI và cách hoạt động, bạn có thể chuyển đến phần mã.

Khai phá luật kết hợp được xem là quy trình hai bước:

  1. Sinh tập mục thường xuyên: Tìm tất cả tập mục thường xuyên với hỗ trợ >= min_support đặt trước

  2. Sinh luật: Liệt kê tất cả Luật kết hợp từ các tập mục thường xuyên. Tính Độ hỗ trợ và Độ tin cậy cho mọi luật. Cắt tỉa các luật không đạt ngưỡng min_support và min_confidence.

Sinh tập mục thường xuyên là bước tốn kém tính toán nhất vì cần quét toàn bộ cơ sở dữ liệu.

Trong các bước trên, sinh tập mục thường xuyên là tốn kém nhất về tính toán.

Ở trên bạn chỉ thấy ví dụ với 5 giao dịch, nhưng trong thực tế dữ liệu giao dịch bán lẻ có thể lên tới GB và TB, cần một thuật toán tối ưu để lược bỏ các tập mục không hữu ích cho các bước sau. Vì thế dùng Thuật toán APRIORI. Thuật toán phát biểu:

Mọi tập con của một tập mục thường xuyên cũng phải là thường xuyên. Nói cách khác, không sinh hay kiểm tra siêu tập của một tập mục không thường xuyên

Điều này được biểu diễn bằng Lưới tập mục (Itemset Lattice), là biểu diễn đồ họa nguyên lý của APRIORI. Nó gồm các nút là tập k-mục và quan hệ tập con của tập k-mục đó.

itemset lattice

Bạn có thể thấy ở hình trên phía đáy là tất cả mặt hàng trong dữ liệu giao dịch và sau đó bạn bắt đầu đi lên tạo các tập con cho đến tập rỗng. Với số lượng mặt hàng là d, kích thước lưới sẽ là $2^d$. Điều này cho thấy việc sinh Tập mục thường xuyên bằng cách tìm hỗ trợ cho mỗi tổ hợp khó đến mức nào. Hình sau cho thấy APRIORI giúp giảm bao nhiêu tập cần sinh:

itemset lattice 2

Nếu tập mục {a,b} không thường xuyên thì không cần xét tất cả siêu tập của nó.

Hãy hiểu điều này bằng một ví dụ. Trong ví dụ sau, bạn sẽ thấy vì sao APRIORI hiệu quả và cũng sẽ sinh các luật kết hợp mạnh từng bước. Cùng theo dõi với vở ghi của bạn nhé!

example

Như bạn thấy, bạn bắt đầu bằng cách tạo Danh sách ứng viên cho 1-tập mục gồm tất cả mặt hàng có trong dữ liệu giao dịch, xét riêng lẻ. Xét dữ liệu giao dịch bán lẻ thực tế, bạn có thể thấy việc sinh ứng viên tốn kém thế nào. Đây là lúc APRIORI phát huy tác dụng và giúp giảm số lượng danh sách ứng viên, và cuối cùng sinh ra các luật hữu ích. Ở các bước sau, bạn sẽ thấy cách chúng ta đi đến cuối giai đoạn Sinh tập mục thường xuyên, tức bước đầu tiên của khai phá luật kết hợp.

example

Bước tiếp theo là liệt kê tất cả tập mục thường xuyên. Bạn sẽ lấy Tập mục thường xuyên cuối cùng không rỗng, trong ví dụ này là L2={I1, I2},{I2, I3}. Sau đó tạo tất cả tập con không rỗng của các tập mục trong Danh sách Tập mục thường xuyên đó. Làm theo như minh họa dưới đây:

example

Bạn có thể thấy có bốn luật mạnh. Ví dụ, ${I2}=>I3$ có độ tin cậy bằng 75% cho biết 75% người mua I2 cũng mua I3.

Bạn đã học trọn vẹn thuật toán APRIORI, một trong những thuật toán được dùng nhiều nhất trong khai phá dữ liệu. Giờ đến phần code thôi, phewww!

Triển khai MBA/Khai phá luật kết hợp bằng R

Trong hướng dẫn này, bạn sẽ dùng một tập dữ liệu từ UCI Machine Learning Repository. Tập dữ liệu có tên Online-Retail, bạn có thể tải về từ đây. Bộ dữ liệu chứa dữ liệu giao dịch từ 01/12/2010 đến 09/12/2011 cho một nhà bán lẻ trực tuyến (không có cửa hàng) tại Vương quốc Anh. Lý do dùng bộ này thay vì bộ dữ liệu R có sẵn là vì bạn nhiều khả năng sẽ nhận dữ liệu bán lẻ ở dạng này và cần tiền xử lý dữ liệu.

Mô tả tập dữ liệu

  • Số dòng:541909
  • Số thuộc tính:08
Thông tin thuộc tính
  • InvoiceNo: Số hóa đơn. Danh nghĩa, số nguyên 6 chữ số gán duy nhất cho mỗi giao dịch. Nếu mã này bắt đầu bằng chữ 'c', đó là giao dịch hủy. +StockCode: Mã sản phẩm (mặt hàng). Danh nghĩa, số nguyên 5 chữ số gán duy nhất cho mỗi sản phẩm khác biệt.
  • Description: Tên sản phẩm (mặt hàng). Danh nghĩa.
  • Quantity: Số lượng mỗi sản phẩm (mặt hàng) theo giao dịch. Số.
  • InvoiceDate: Ngày giờ hóa đơn. Số, ngày và giờ tạo mỗi giao dịch. Ví dụ từ dữ liệu: 12/1/2010 8:26
  • UnitPrice: Đơn giá. Số, giá sản phẩm theo đơn vị bằng bảng Anh.
  • CustomerID: Mã khách hàng. Danh nghĩa, số nguyên 5 chữ số gán duy nhất cho mỗi khách hàng.
  • Country: Tên quốc gia. Danh nghĩa, tên quốc gia nơi khách hàng cư trú.

Nạp thư viện

Đầu tiên, bạn sẽ nạp các thư viện cần thiết. Mô tả ngắn về các thư viện (lấy từ Đây) được cho trong bảng sau để bạn biết mỗi thư viện làm gì:

PackageMô tả
arulesCung cấp hạ tầng để biểu diễn, thao tác và phân tích dữ liệu giao dịch và các mẫu (tập mục thường xuyên và luật kết hợp).
arulesVizMở rộng gói 'arules' với nhiều kỹ thuật trực quan hóa cho luật kết hợp và tập mục. Gói cũng bao gồm một số trực quan hóa tương tác để khám phá luật.
tidyverseTidyverse là bộ sưu tập các gói R có quan điểm thống nhất, được thiết kế cho khoa học dữ liệu
readxlĐọc tệp Excel trong R
plyrCông cụ để Tách, Áp dụng và Kết hợp Dữ liệu
ggplot2Tạo đồ họa và biểu đồ
knitrTạo báo cáo động trong R
lubridateLubridate là gói R giúp làm việc với ngày giờ dễ dàng hơn.
#install and load package arules
#install.packages("arules")
library(arules)
#install and load arulesViz
#install.packages("arulesViz")
library(arulesViz)
#install and load tidyverse
#install.packages("tidyverse")
library(tidyverse)
#install and load readxml
#install.packages("readxml")
library(readxl)
#install and load knitr
#install.packages("knitr")
library(knitr)
#load ggplot2 as it comes in tidyverse
library(ggplot2)
#install and load lubridate
#install.packages("lubridate")
library(lubridate)
#install and load plyr
#install.packages("plyr")
library(plyr)
library(dplyr)

Tiền xử lý dữ liệu

Dùng read_excel(path to file) để đọc bộ dữ liệu từ tệp đã tải vào R. Cung cấp đường dẫn đầy đủ kèm tên tệp trong read_excel(path-to-file-with-filename)

#read excel into R dataframe
retail <- read_excel('D:/Documents/Online_Retail.xlsx')
#complete.cases(data) will return a logical vector indicating which rows have no missing values. Then use the vector to get only rows that are complete using retail[,].
retail <- retail[complete.cases(retail), ]
#mutate function is from dplyr package. It is used to edit or add new columns to dataframe. Here Description column is being converted to factor column. as.factor converts column to factor column. %>% is an operator with which you may pipe values to another function or expression
retail %>% mutate(Description = as.factor(Description))
retail %>% mutate(Country = as.factor(Country))
#Converts character data to date. Store InvoiceDate as date in new variable
retail$Date <- as.Date(retail$InvoiceDate)
#Extract time from InvoiceDate and store in another variable
TransTime<- format(retail$InvoiceDate,"%H:%M:%S")
#Convert and edit InvoiceNo into numeric
InvoiceNo <- as.numeric(as.character(retail$InvoiceNo))
NAs introduced by coercion
#Bind new columns TransTime and InvoiceNo into dataframe retail
cbind(retail,TransTime)
cbind(retail,InvoiceNo)
#get a glimpse of your data
glimpse(retail)

Lưu ý: Trang 1 trên 100.
Observations: 406,829
Variables: 9
$ InvoiceNo   <chr> "536365", "536365", "536365", "536365", "536365", "536365", "53...
$ StockCode   <chr> "85123A", "71053", "84406B", "84029G", "84029E", "22752", "2173...
$ Description <chr> "WHITE HANGING HEART T-LIGHT HOLDER", "WHITE METAL LANTERN", "C...
$ Quantity    <dbl> 6, 6, 8, 6, 6, 2, 6, 6, 6, 32, 6, 6, 8, 6, 6, 3, 2, 3, 3, 4, 4,...
$ InvoiceDate <dttm> 2010-12-01 08:26:00, 2010-12-01 08:26:00, 2010-12-01 08:26:00,...
$ UnitPrice   <dbl> 2.55, 3.39, 2.75, 3.39, 3.39, 7.65, 4.25, 1.85, 1.85, 1.69, 2.1...
$ CustomerID  <dbl> 17850, 17850, 17850, 17850, 17850, 17850, 17850, 17850, 17850, ...
$ Country     <chr> "United Kingdom", "United Kingdom", "United Kingdom", "United K...
$ Date        <date> 2010-12-01, 2010-12-01, 2010-12-01, 2010-12-01, 2010-12-01, 20...

Bây giờ, dataframe retail sẽ có 10 thuộc tính, với hai thuộc tính bổ sung là Date và Time.

Trước khi áp dụng MBA/Khai phá luật kết hợp, chúng ta cần chuyển dataframe thành dữ liệu giao dịch để tất cả mặt hàng được mua cùng nhau trong một hóa đơn nằm trên cùng một dòng. Bạn có thể thấy trong đầu ra glimpse rằng mỗi giao dịch ở dạng nguyên tử, tức mọi sản phẩm thuộc một hóa đơn là các bản ghi riêng lẻ như trong cơ sở dữ liệu quan hệ. Định dạng này còn gọi là định dạng đơn lẻ.

Việc bạn cần làm là nhóm dữ liệu trong dataframe retail theo CustomerID, CustomerID và Date hoặc bạn cũng có thể nhóm theo InvoiceNo và Date. Chúng ta cần nhóm như vậy, áp dụng một hàm lên đó và lưu kết quả vào dataframe khác. Có thể làm việc này bằng ddply.

Các dòng mã sau sẽ gộp tất cả sản phẩm từ một InvoiceNo và date và gộp tất cả sản phẩm từ InvoiceNo và date đó thành một dòng, với mỗi mặt hàng ngăn cách bằng ,

library(plyr)
#ddply(dataframe, variables_to_be_used_to_split_data_frame, function_to_be_applied)
transactionData <- ddply(retail,c("InvoiceNo","Date"),
                       function(df1)paste(df1$Description,
                       collapse = ","))
#The R function paste() concatenates vectors to character and separated results using collapse=[any optional charcater string ]. Here ',' is used
transactionData

Lưu ý: Trang 1 trên 100.

Tiếp theo, vì InvoiceNo và Date sẽ không hữu ích trong quá trình khai phá luật, bạn có thể đặt chúng thành NULL.

#set column InvoiceNo of dataframe transactionData  
transactionData$InvoiceNo <- NULL
#set column Date of dataframe transactionData
transactionData$Date <- NULL
#Rename column to items
colnames(transactionData) <- c("items")
#Show Dataframe transactionData
transactionData

Lưu ý: Trang 1 trên 100.

Định dạng dữ liệu giao dịch này được gọi là định dạng basket. Tiếp theo, bạn cần lưu dữ liệu giao dịch này vào tệp .csv (Comma Separated Values). Dùng write.csv()

write.csv(transactionData,"D:/Documents/market_basket_transactions.csv", quote = FALSE, row.names = FALSE)
#transactionData: Data to be written
#"D:/Documents/market_basket.csv": location of file with file name to be written to
#quote: If TRUE it will surround character or factor column with double quotes. If FALSE nothing will be quoted
#row.names: either a logical value indicating whether the row names of x are to be written along with x, or a character vector of row names to be written.

Kiểm tra xem dữ liệu giao dịch của bạn có đúng dạng không:

transaction data

Tiếp theo, bạn cần nạp dữ liệu giao dịch này vào một đối tượng lớp transaction. Thao tác này dùng hàm R read.transactions của gói arules.

Dòng mã sau sẽ lấy tệp dữ liệu giao dịch D:/Documents/market_basket_transactions.csv ở định dạng basket và chuyển nó thành một đối tượng lớp transaction.

tr <- read.transactions('D:/Documents/market_basket_transactions.csv', format = 'basket', sep=',')
#sep tell how items are separated. In this case you have separated using ','

Khi chạy các dòng mã trên, bạn có thể nhận được nhiều thông báo EOF within quoted string trong đầu ra, đừng lo lắng về điều đó.

Nếu bạn đã có dữ liệu giao dịch trong một dataframe, dùng dòng mã sau để chuyển nó thành đối tượng transaction:

          `trObj<-as(dataframe.dat,"transactions")`

Xem đối tượng giao dịch tr:

tr
transactions in sparse format with
 22191 transactions (rows) and
 30066 items (columns)
 summary(tr)
 
transactions in sparse format with
 22191 transactions (rows) and
 7876 items (columns)
transactions as itemMatrix in sparse format with
 22191 rows (elements/itemsets/transactions) and
 7876 columns (items) and a density of 0.001930725

most frequent items:
WHITE HANGING HEART T-LIGHT HOLDER           REGENCY CAKESTAND 3 TIER
                              1803                               1709
           JUMBO BAG RED RETROSPOT                      PARTY BUNTING
                              1460                               1285
     ASSORTED COLOUR BIRD ORNAMENT                            (Other)
                              1250                             329938

element (itemset/transaction) length distribution:
sizes
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17
3598 1594 1141  908  861  758  696  676  663  593  624  537  516  531  551  522  464
  18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34
 441  483  419  395  315  306  272  238  253  229  213  222  215  170  159  138  142
  35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51
 134  109  111   90  113   94   93   87   88   65   63   67   63   60   59   49   64
  52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68
  40   41   49   43   36   29   39   30   27   28   17   25   25   20   27   24   22
  69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85
  15   20   19   13   16   16   11   15   12    7    9   14   15   12    8    9   11
  86   87   88   89   90   91   92   93   94   95   96   97   98   99  100  101  102
  11   14    8    6    5    6   11    6    4    4    3    6    5    2    4    2    4
 103  104  105  106  107  108  109  110  111  112  113  114  116  117  118  120  121
   4    3    2    2    6    3    4    3    2    1    3    1    3    3    3    1    2
 122  123  125  126  127  131  132  133  134  140  141  142  143  145  146  147  150
   2    1    3    2    2    1    1    2    1    1    2    2    1    1    2    1    1
 154  157  168  171  177  178  180  202  204  228  236  249  250  285  320  400  419
   3    2    2    2    1    1    1    1    1    1    1    1    1    1    1    1    1

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
   1.00    3.00   10.00   15.21   21.00  419.00

includes extended item information - examples:
                      labels
1                   1 HANGER
2     10 COLOUR SPACEBOY PEN
3 12 COLOURED PARTY BALLOONS

summary(tr) là lệnh rất hữu ích cung cấp thông tin về đối tượng giao dịch. Hãy xem đầu ra trên nói gì:

  • Có 22191 giao dịch (hàng) và 7876 mặt hàng (cột). Lưu ý 7876 là số mô tả sản phẩm trong dữ liệu và 22191 giao dịch là tổ hợp của các mặt hàng này.

  • Mật độ (Density) cho biết tỷ lệ ô khác 0 trong ma trận thưa. Bạn có thể hiểu là tổng số mặt hàng được mua chia cho số mặt hàng có thể có trong ma trận đó. Bạn có thể tính số mặt hàng đã được mua bằng mật độ: 22191x7876x0.001930725=337445

Thông tin! Ma trận thưa: Ma trận thưa là ma trận trong đó phần lớn phần tử là 0. Ngược lại, nếu đa số phần tử khác 0, ma trận được coi là dày. Số phần tử bằng 0 chia cho tổng số phần tử gọi là độ thưa của ma trận (bằng 1 trừ đi mật độ của ma trận).

  • Summary cũng có thể cho biết các mặt hàng xuất hiện thường xuyên nhất.

  • Phân phối độ dài phần tử (tập mục/giao dịch): Điều này cho biết có bao nhiêu giao dịch là 1-tập mục, 2-tập mục, v.v. Hàng đầu là số mặt hàng và hàng thứ hai là số giao dịch.

Ví dụ, chỉ có 3598 giao dịch cho một mặt hàng, 1594 giao dịch cho 2 mặt hàng, và có 419 mặt hàng trong một giao dịch là dài nhất.

Bạn có thể tạo itemFrequencyPlot để vẽ Biểu đồ thanh tần suất mặt hàng nhằm xem phân phối đối tượng dựa trên itemMatrix (ví dụ, >transactions hoặc mặt hàng trong >itemsets và >rules) như trường hợp của chúng ta.

# Create an item frequency plot for the top 20 items
if (!require("RColorBrewer")) {
  # install color package of R
install.packages("RColorBrewer")
#include library RColorBrewer
library(RColorBrewer)
}
itemFrequencyPlot(tr,topN=20,type="absolute",col=brewer.pal(8,'Pastel2'), main="Absolute Item Frequency Plot")
absolute item frequency plot

Trong 

itemFrequencyPlot(tr,topN=20,type="absolute")

đối số đầu tiên là đối tượng giao dịch cần vẽ, tức tr. topN cho phép bạn vẽ N mặt hàng có tần suất cao nhất. type có thể là type="absolute" hoặc type="relative". Nếu absolute sẽ vẽ tần suất số của từng mặt hàng độc lập. Nếu relative sẽ vẽ số lần các mặt hàng xuất hiện so với những mặt hàng khác.

relative item frequency plot
itemFrequencyPlot(tr,topN=20,type="relative",col=brewer.pal(8,'Pastel2'),main="Relative Item Frequency Plot")

Biểu đồ này cho thấy 'WHITE HANGING HEART T-LIGHT HOLDER' và 'REGENCY CAKESTAND 3 TIER' có doanh số cao nhất. Vì vậy để tăng doanh số 'SET OF 3 CAKE TINS PANTRY DESIGN' nhà bán lẻ có thể đặt nó gần 'REGENCY CAKESTAND 3 TIER'.

Bạn có thể khám phá các tùy chọn khác cho itemFrequencyPlot tại đây.

Sinh luật!

Bước tiếp theo là khai phá luật bằng thuật toán APRIORI. Hàm apriori() thuộc gói arules.

# Min Support as 0.001, confidence as 0.8.
association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8,maxlen=10))
 Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.11s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 3 4 5 6 7 8 9 10
Mining stopped (maxlen reached). Only patterns up to a length of 10 returned!
 done [0.70s].
writing ... [49122 rule(s)] done [0.06s].
creating S4 object  ... done [0.06s]. 
set of 49122 rules

rule length distribution (lhs + rhs):sizes
    2     3     4     5     6     7     8     9    10
  105  2111  6854 16424 14855  6102  1937   613   121

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  2.000   5.000   5.000   5.499   6.000  10.000

summary of quality measures:
    support           confidence          lift             count       
 Min.   :0.001036   Min.   :0.8000   Min.   :  9.846   Min.   : 23.00  
 1st Qu.:0.001082   1st Qu.:0.8333   1st Qu.: 22.237   1st Qu.: 24.00  
 Median :0.001262   Median :0.8788   Median : 28.760   Median : 28.00  
 Mean   :0.001417   Mean   :0.8849   Mean   : 64.589   Mean   : 31.45  
 3rd Qu.:0.001532   3rd Qu.:0.9259   3rd Qu.: 69.200   3rd Qu.: 34.00  
 Max.   :0.015997   Max.   :1.0000   Max.   :715.839   Max.   :355.00  

mining info:
 data ntransactions support confidence
   tr         22191   0.001        0.8

apriori sẽ nhận tr là đối tượng giao dịch cần khai phá. parameter cho phép bạn đặt min_sup và min_confidence. Giá trị mặc định cho parameter là hỗ trợ tối thiểu 0.1, độ tin cậy tối thiểu 0.8, tối đa 10 mặt hàng (maxlen).

summary(association.rules) cho thấy:

  • Đặc tả tham số: min_sup=0.001 và min_confidence=0.8 với tối đa 10 mặt hàng trong một luật.

  • Tổng số luật: Tập gồm 49122 luật

  • Phân phối độ dài luật: Độ dài 5 mặt hàng có nhiều luật nhất: 16424 và độ dài 2 mặt hàng có ít luật nhất:105

  • Tóm tắt thước đo chất lượng: Giá trị nhỏ nhất và lớn nhất cho Support, Confidence và Lift.

  • Thông tin dùng để tạo luật: Dữ liệu, hỗ trợ và độ tin cậy chúng ta cung cấp cho thuật toán.

Vì có 49122 luật, hãy chỉ in top 10:

inspect(association.rules[1:10])
     lhs                         rhs             support     confidence lift      count
[1]  {WOBBLY CHICKEN}         => {METAL}         0.001261773 1          443.82000 28   
[2]  {WOBBLY CHICKEN}         => {DECORATION}    0.001261773 1          443.82000 28   
[3]  {DECOUPAGE}              => {GREETING CARD} 0.001036456 1          389.31579 23   
[4]  {BILLBOARD FONTS DESIGN} => {WRAP}          0.001306836 1          715.83871 29   
[5]  {WOBBLY RABBIT}          => {METAL}         0.001532153 1          443.82000 34   
[6]  {WOBBLY RABBIT}          => {DECORATION}    0.001532153 1          443.82000 34   
[7]  {FUNK MONKEY}            => {ART LIGHTS}    0.001712406 1          583.97368 38   
[8]  {ART LIGHTS}             => {FUNK MONKEY}   0.001712406 1          583.97368 38   
[9]  {BLACK TEA}              => {SUGAR JARS}    0.002072912 1          238.61290 46   
[10] {BLACK TEA}              => {COFFEE}        0.002072912 1           69.34687 46 

Dựa vào đầu ra trên, bạn có thể đưa ra phân tích như:

  • 100% khách hàng mua 'WOBBLY CHICKEN' cũng mua 'METAL'.

  • 100% khách hàng mua 'BLACK TEA' cũng mua 'SUGAR JARS'.

Giới hạn số lượng và kích thước luật

Làm sao giới hạn kích thước và số lượng luật được sinh? Bạn có thể làm điều này bằng cách đặt parameters trong apriori. Bạn chỉnh các tham số này để điều chỉnh số lượng luật nhận được. Nếu muốn luật mạnh hơn, bạn có thể tăng giá trị conf và để có luật dài hơn hãy tăng maxlen.

shorter.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8,maxlen=3))

Loại bỏ luật dư thừa

Bạn có thể loại bỏ các luật là tập con của những luật lớn hơn. Dùng mã dưới đây để loại các luật như vậy:

subset.rules <- which(colSums(is.subset(association.rules, association.rules)) > 1) # get subset rules in vector
length(subset.rules)  #> 3913
[1] 44014
subset.association.rules. <- association.rules[-subset.rules] # remove subset rules.
  • which() trả về vị trí các phần tử trong vector có giá trị TRUE.

  • colSums() tính tổng theo hàng và cột cho dataframe và mảng số.

  • is.subset() Xác định liệu phần tử của một vector có chứa tất cả phần tử của vector khác hay không

Đôi khi, bạn muốn làm việc trên một sản phẩm cụ thể. Nếu bạn muốn tìm xem điều gì ảnh hưởng đến việc mua mặt hàng X, bạn có thể dùng tùy chọn appearance trong lệnh apriori. appearance cho phép đặt LHS (phần NẾU) và RHS (phần THÌ) của luật.

Ví dụ, để tìm khách hàng thường mua gì trước khi mua 'METAL', chạy dòng mã sau:

metal.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8),appearance = list(default="lhs",rhs="METAL"))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.21s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 3 4 5 6 7 8 9 10
Mining stopped (maxlen reached). Only patterns up to a length of 10 returned!
 done [0.63s].
writing ... [5 rule(s)] done [0.07s].
creating S4 object  ... done [0.02s]. 
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))
    lhs                            rhs     support     confidence lift   count
[1] {WOBBLY CHICKEN}            => {METAL} 0.001261773 1          443.82 28   
[2] {WOBBLY RABBIT}             => {METAL} 0.001532153 1          443.82 34   
[3] {DECORATION}                => {METAL} 0.002253166 1          443.82 50   
[4] {DECORATION,WOBBLY CHICKEN} => {METAL} 0.001261773 1          443.82 28   
[5] {DECORATION,WOBBLY RABBIT}  => {METAL} 0.001532153 1          443.82 34 

Tương tự, để trả lời câu hỏi Khách hàng mua METAL cũng mua.... bạn sẽ để METAL ở lhs:

metal.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8),appearance = list(lhs="METAL",default="rhs"))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.10s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 done [0.01s].
writing ... [1 rule(s)] done [0.00s].
creating S4 object  ... done [0.01s].
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))
    lhs        rhs          support     confidence lift   count
[1] {METAL} => {DECORATION} 0.002253166 1          443.82 50 

Trực quan hóa Luật kết hợp

Vì sẽ có hàng trăm hoặc hàng nghìn luật được sinh ra dựa trên dữ liệu, bạn cần vài cách để trình bày phát hiện của mình. ItemFrequencyPlot đã được nói ở trên và cũng là cách tuyệt vời để tìm các mặt hàng bán chạy.

Dưới đây là các trực quan hóa sẽ được bàn đến:

  • Biểu đồ phân tán
  • Biểu đồ phân tán tương tác
  • Biểu diễn từng luật

Biểu đồ phân tán

Một trực quan hóa đơn giản cho luật kết hợp là dùng biểu đồ phân tán với plot() của gói arulesViz. Nó dùng Support và Confidence trên các trục. Ngoài ra, thước đo thứ ba Lift mặc định dùng để tô màu (mức xám) các điểm.

# Filter rules with confidence greater than 0.4 or 40%
subRules<-association.rules[quality(association.rules)$confidence>0.4]
#Plot SubRules
plot(subRules)
scatter plot

Biểu đồ trên cho thấy các luật có lift cao thường có hỗ trợ thấp. Bạn có thể dùng các tùy chọn sau cho biểu đồ:

plot(rulesObject, measure, shading, method)
  • rulesObject: đối tượng luật cần vẽ

  • measure: Thước đo độ thú vị của luật. Có thể là Support, Confidence, lift hoặc kết hợp các thước đo này tùy theo giá trị method.

  • shading: Thước đo dùng để tô màu điểm (Support, Confidence, lift). Mặc định là Lift.

  • method: Phương thức trực quan hóa dùng (scatterplot, two-key plot, matrix3D).

plot(subRules,method="two-key plot")
two key plot

Two-key plot dùng support và confidence lần lượt trên trục x và y. Nó dùng order để tô màu. Order là số mặt hàng trong luật.

Biểu đồ phân tán tương tác

Một biểu đồ tương tác tuyệt vời có thể dùng để trình bày các luật của bạn với arulesViz và plotly. Bạn có thể di chuột qua từng luật và xem tất cả thước đo chất lượng (support, confidence và lift).

plotly_arules(subRules)
'plotly_arules' is deprecated.
Use 'plot' instead.
See help("Deprecated")plot: Too many rules supplied. Only plotting the best 1000 rules using measure lift (change parameter max if needed)To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.

Trực quan hóa dựa trên đồ thị

Các kỹ thuật dựa trên đồ thị trực quan hóa luật kết hợp bằng các đỉnh và cạnh, trong đó đỉnh được gắn nhãn tên mặt hàng, và các tập mục hoặc luật được biểu diễn như một tập đỉnh thứ hai. Các mặt hàng được nối với tập mục/luật bằng mũi tên có hướng. Mũi tên từ mặt hàng đến đỉnh luật chỉ các mục ở LHS và mũi tên từ luật đến mặt hàng chỉ RHS. Kích thước và màu sắc của đỉnh thường biểu diễn các thước đo độ quan tâm.

Đồ thị là cách tuyệt vời để trực quan hóa luật nhưng dễ trở nên rối khi số lượng luật tăng. Vì vậy tốt hơn nên trực quan hóa ít luật hơn với đồ thị.

Hãy chọn 10 luật từ subRules có độ tin cậy cao nhất.

top10subRules <- head(subRules, n = 10, by = "confidence")

Bây giờ, vẽ một đồ thị tương tác:

Lưu ý: Bạn có thể biến tất cả biểu đồ của mình thành tương tác bằng tham số engine=htmlwidget trong plot

plot(top10subRules, method = "graph",  engine = "htmlwidget")
graph

Từ arulesViz các đồ thị cho tập luật kết hợp có thể được xuất ở định dạng GraphML hoặc tệp Graphviz dot để khám phá trong các công cụ như Gephi. Ví dụ, 1000 luật có lift cao nhất được xuất bằng:

saveAsGraph(head(subRules, n = 1000, by = "lift"), file = "rules.graphml")

Biểu diễn từng luật

Biểu diễn này còn gọi là Parallel Coordinates Plot. Nó hữu ích để trực quan hóa những sản phẩm nào cùng với những mặt hàng nào dẫn đến kiểu doanh số ra sao.

Như đã nói, RHS là Hậu đề hoặc mặt hàng ta dự đoán khách hàng sẽ mua; các vị trí ở LHS trong đó 2 là mặt hàng được thêm gần đây nhất vào giỏ và 1 là mặt hàng đã có trước đó.

# Filter top 20 rules with highest lift
subRules2<-head(subRules, n=20, by="lift")
plot(subRules2, method="paracoord")
parallel coordinates plot

Nhìn vào mũi tên trên cùng. Nó cho thấy khi tôi có 'CHILDS GARDEN SPADE PINK' và 'CHILDS GARDEN RAKE PINK' trong giỏ hàng, tôi có khả năng sẽ mua thêm 'CHILDS GARDEN RAKE BLUE'.

Kết luận

Chúc mừng bạn! Bạn đã học thuật toán APRIORI, một trong những thuật toán được dùng thường xuyên nhất trong khai phá dữ liệu. Bạn đã hiểu về Khai phá luật kết hợp, các ứng dụng của nó, và ứng dụng trong bán lẻ gọi là Phân tích giỏ hàng. Bạn cũng đã có khả năng triển khai Market Basket Analysis trong R và trình bày các luật kết hợp với những biểu đồ tuyệt vời! Chúc học tốt!

Tài liệu tham khảo:

  1. https://datascienceplus.com/a-gentle-introduction-on-market-basket-analysis%E2%80%8A-%E2%80%8Aassociation-rules/

  2. https://en.wikipedia.org/wiki/Sparse_matrix

  3. https://cran.r-project.org/web/packages/arulesViz/vignettes/arulesViz.pdf

Nếu bạn muốn học thêm về R, hãy tham gia khóa Importing and Managing Financial Data in R của DataCamp.

Chủ đề

Liên quan