Market Basket Analysis (MBA) adalah teknik analisa yang digunakan oleh bisnis di bidang ritel untuk mencari asosiasi produk yang kuat, atau dengan kata lain menemukan paket produk yang bisa berdampak besar pada penjualan.

Algoritma yang bisa digunakan di R untuk melakukan MBA ini adalah apriori dari package arules. Data yang diperlukan hanya dua, yaitu data transaksi dan data produk. Arules adalah singkatan dari association rules - kategori machine learning. Arules digunakan untuk mencari asosiasi antar objek berbeda dalam satu set, mencari pola yang sering terjadi pada data transaksi, relational database dan informasi lainnya. Arules digunakan di Market Basket Analysis, clustering, dan classification.

Strategi marketing yang dapat dilakukan menggunakan arules: - Mengubah layout toko (baik susunan toko offline maupun online) - Analisis perilaku konsumen - Desain katalog - Marketing silang antar toko online - Item populer yang dibeli customer - Customized email dengan tambahan diskon

Beberapa objek pada arules, yaitu: - Item adalah produk tunggal yang terdapat dalam suatu transaksi. Contoh: Kurma, sirup, gula, santan - Itemset adalah kombinasi satu atau lebih item yang terdapat dalam satu transaksi. Contoh: {Kurma}, {Kurma, Sirup}, {Sirup}, dan lain-lain. - Rule adalah pernyataan hubungan antar Itemset. Biasanya dapat diformulasikan menjadi “Jika membeli itemset A, maka akan membeli itemset B”. Contoh: {Kurma} => {Sirup}, {Kurma, Gula} => {Sirup}, dan lain-lain.

Formula arules dapat ditulis sebagai berikut:

Kurma => Sirup[Support = 30%, Confidence = 60%]

Arti dari pernyataan di atas, 30% transaksi menunjukkan pembelian sirup dan kurma dalam satu transaksi dan 60% pelanggan yang membeli kurma juga membeli sirup.

Contoh Kasus

DQLab.id Fashion adalah sebuah toko fashion yang menjual berbagai produk seperti jeans, kemeja, kosmetik, dan lain-lain. Walaupun cukup berkembang, namun dengan semakin banyaknya kompetitor dan banyak produk yang stoknya masih banyak tentunya membuat kuatir. Salah satu solusi adalah membuat paket yang inovatif. Dimana produk yang sebelumnya tidak terlalu laku tapi punya pangsa pasar malah bisa dipaketkan dan laku.

Kita diminta mengidentifikasi paket produk yang menarik untuk dipaketkan sehingga akhirnya bisa meningkatkan keuntungan dan loyalitas para pelanggan DQLab.id Fashion. Dan untuk wewujudkan ini, Anda akan menggunakan R dan algoritma aproriari dari paket arules di sepanjang project ini.

Untuk memulai project ini, diberikan data transaksi 3 bulan kepada Anda dalam bentuk format TSV (Tab Separated Value) dengan nama https://storage.googleapis.com/dqlab-dataset/transaksi_dqlab_retail.tsv dengan jumlah baris 33,669 baris data (3,450 kode transaksi).

Data transaksi ini telah dirapikan untuk Anda dengan hanya mengandung dua variable, yaitu: - Kode Transaksi - Nama Produk

Variable lain seperti harga, tanggal, jumlah pembelian, dan lain-lain tidak dimasukkan dengan alasan dua variable tersebut sudah cukup.

Berikut adalah sekilas tampilan dari data transaksi yang diberikan. Data transaksi dibaca dengan fungsi read.transaction dengan keterangan code:

Pada transaksi dengan ID #1 dilakukan pembelian terhadap beberapa item yaitu Baju Kaos Olahraga, Baju Renang Pria Dewasa, Baju Renang Wanita Dewasa, dan lain-lain.

library(arules)
## Warning: package 'arules' was built under R version 4.0.4
## Loading required package: Matrix
## 
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
## 
##     abbreviate, write
transaksi_tabular <- read.transactions(file="https://storage.googleapis.com/dqlab-dataset/transaksi_dqlab_retail.tsv", format="single", sep="\t", cols=c(1,2), skip=1)
inspect(transaksi_tabular[1:3])
##     items                       transactionID
## [1] {Baju Kaos Olahraga,                     
##      Baju Renang Pria Dewasa,                
##      Baju Renang Wanita Dewasa,              
##      Celana Jogger Casual,                   
##      Dompet Card Holder,                     
##      Kaos,                                   
##      Sepatu Sport merk Z,                    
##      Serum Vitamin,                          
##      Shampo Biasa}                       #1  
## [2] {Baju Batik Wanita,                      
##      Baju Kemeja Putih,                      
##      Celana Jogger Casual,                   
##      Celana Pendek Jeans,                    
##      Dompet Card Holder,                     
##      Dompet STNK Gantungan,                  
##      Flat Shoes Ballerina,                   
##      Hair Dryer,                             
##      Jeans Jumbo,                            
##      Kaos,                                   
##      Wedges Hitam}                       #10 
## [3] {Baju Renang Wanita Dewasa,              
##      Celana Jogger Casual,                   
##      Dompet Card Holder,                     
##      Dompet Flip Cover,                      
##      Hair Dryer,                             
##      Hair Tonic,                             
##      Sepatu Sandal Anak,                     
##      Sepatu Sport merk Y,                    
##      Sepatu Sport merk Z,                    
##      Shampo Biasa,                           
##      Tali Pinggang Anak}                 #100

1. Output Awal: Statistik Top 10

Tahap pertama memberikan info top 10 dari dataset transaksi yang diberikan.

top10_item <- itemFrequency(transaksi_tabular,type="absolute")
top10_item <- sort(top10_item, decreasing=TRUE)[1:10]
top10_item <- data.frame("Nama.Produk" = names(top10_item),"Jumlah" = top10_item, row.names=NULL)
top10_item
##                  Nama.Produk Jumlah
## 1               Shampo Biasa   2075
## 2              Serum Vitamin   1685
## 3          Baju Batik Wanita   1312
## 4          Baju Kemeja Putih   1255
## 5       Celana Jogger Casual   1136
## 6                Cover Koper   1086
## 7         Sepatu Sandal Anak   1062
## 8  Tali Pinggang Gesper Pria   1003
## 9        Sepatu Sport merk Z    888
## 10              Wedges Hitam    849

Dari tabel di atas, produk yang paling laku terjual adalah shampo kemudian vitamin, keduanya merupakan produk perawatan tubuh. Delapan produk lainnya adalah produk fashion.

2. Output Awal: Statistik Bottom 10

Tahap berikutnya diminta informasi bottom 10 dari dataset transaksi yang diberikan.

bottom10_item <- itemFrequency(transaksi_tabular,type="absolute")
bottom10_item <- sort(bottom10_item, decreasing=FALSE)[1:10]
bottom10_item <- data.frame("Nama.Produk" = names(bottom10_item),"Jumlah" = bottom10_item, row.names=NULL)
bottom10_item
##                   Nama.Produk Jumlah
## 1     Celana Jeans Sobek Pria      9
## 2                Tas Kosmetik     11
## 3                Stripe Pants     19
## 4                    Pelembab     24
## 5      Tali Ban Ikat Pinggang     27
## 6  Baju Renang Pria Anak-anak     32
## 7                    Hair Dye     46
## 8          Atasan Baju Belang     56
## 9  Tas Sekolah Anak Perempuan     71
## 10              Dompet Unisex     75

Sepuluh produk yang paling sedikit terjual kategori itemnya bermacam-macam, ada yang fashion, perawatan wajah, dan keperluan anak. Produk-produk ini yang harus ditingkatkan penjualannya agar tidak menumpuk di gudang penyimpanan. Cara untuk meningkatkan penjualan bisa dengan promosi produk secara langsung atau memasangkan bundling dengan produk lain yang lebih digemari. Maka dari itu perlu dicari tahu, kombinasi produk apa yang biasanya dibeli konsumen atau ada di suatu transaksi.

3. Mendapatkan Kombinasi Produk yang menarik

Setelah yakin Anda dapat melakukannya Pak Agus ingin Anda mengirimkan file yang berisi daftar 10 paket kombinasi produk yang paling “menarik”. Definisi menarik adalah sebagai berikut:

Algoritma apriori menyimpan kolom dan parameter sebagai berikut: - lhs: itemset di bagian kiri (left hand side) - rhs: itemset di bagian kanan (right hand side) - support: frekuensi transaksi yg mengandung item/itemset dibanding seluruh transaksi. Range support dari 0 sampai 1. \[Support(A=>B) = \frac{frekuensi(A=>B)}{TotalTransaksi}\] - confidence: support dari semua item yang ada di rule dibanding support item/itemset di left hand side. Range confidence dari 0 sampai 1. Confidence kurang menunjukkan asosiasi produk karena hanya melihat support di left hand side. \[ Confidence(A=>B) = \frac{frekuensi(A=>B)}{frequency(A)}=\frac{P(A \cap B)}{P(A)} \] - lift: support dari item/itemset di rule dibanding support dari lhs dan rhs. Range lift dari 0 sampai \(\infty\) lift tinggi menandakan kuatnya asosiasi kedua itemset di lhs dan rhs. Jika \(lift<=1\) kedua itemset di lhs dan rhs tidak memiliki asosiasi. Jika \(lift>1\) maka itemset di lhs sangat berpengaruh pada penjualan itemset di rhs. \[ Lift(A=>B) = \frac{Support(A)}{Support(A)\times{Support(B)}} \]

kombinasi_menarik <- apriori(transaksi_tabular,parameter = list(supp = 10/length(transaksi_tabular), confidence = 0.5, minlen = 2, maxlen = 3))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime     support minlen
##         0.5    0.1    1 none FALSE            TRUE       5 0.002898551      2
##  maxlen target  ext
##       3  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 10 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[69 item(s), 3450 transaction(s)] done [0.00s].
## sorting and recoding items ... [68 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3
## Warning in apriori(transaksi_tabular, parameter = list(supp = 10/
## length(transaksi_tabular), : Mining stopped (maxlen reached). Only patterns up
## to a length of 3 returned!
##  done [0.00s].
## writing ... [4637 rule(s)] done [0.00s].
## creating S4 object  ... done [0.00s].
top10_menarik <- sort(kombinasi_menarik, by="lift", decreasing=TRUE)[1:10]
inspect(top10_menarik)
##      lhs                             rhs                              support confidence    coverage     lift count
## [1]  {Tas Makeup,                                                                                                  
##       Tas Pinggang Wanita}        => {Baju Renang Anak Perempuan} 0.010434783  0.8780488 0.011884058 24.42958    36
## [2]  {Tas Makeup,                                                                                                  
##       Tas Travel}                 => {Baju Renang Anak Perempuan} 0.010144928  0.8139535 0.012463768 22.64629    35
## [3]  {Tas Makeup,                                                                                                  
##       Tas Ransel Mini}            => {Baju Renang Anak Perempuan} 0.011304348  0.7358491 0.015362319 20.47322    39
## [4]  {Sunblock Cream,                                                                                              
##       Tas Pinggang Wanita}        => {Kuas Makeup }               0.016231884  0.6913580 0.023478261 20.21343    56
## [5]  {Baju Renang Anak Perempuan,                                                                                  
##       Tas Pinggang Wanita}        => {Tas Makeup}                 0.010434783  0.8000000 0.013043478 19.57447    36
## [6]  {Baju Renang Anak Perempuan,                                                                                  
##       Tas Ransel Mini}            => {Tas Makeup}                 0.011304348  0.7959184 0.014202899 19.47460    39
## [7]  {Baju Renang Anak Perempuan,                                                                                  
##       Celana Pendek Green/Hijau}  => {Tas Makeup}                 0.010144928  0.7777778 0.013043478 19.03073    35
## [8]  {Tas Makeup,                                                                                                  
##       Tas Waist Bag}              => {Baju Renang Anak Perempuan} 0.004347826  0.6818182 0.006376812 18.96994    15
## [9]  {Celana Pendek Green/Hijau,                                                                                   
##       Tas Makeup}                 => {Baju Renang Anak Perempuan} 0.010144928  0.6730769 0.015072464 18.72674    35
## [10] {Dompet Flip Cover,                                                                                           
##       Sunblock Cream}             => {Kuas Makeup }               0.016231884  0.6292135 0.025797101 18.39650    56

Dengan melakukan sort, subsetting dan fungsi inspect dapat ditampilkan 10 kombinasi produk yang dianggap menarik. Baris pertama dapat dibaca, bahwa terdapat pelanggan yang membeli Tas MakeUp dan Tas Pinggang Wanita juga membeli Baju Renang Anak Perempuan. Walaupun supportnya kecil, namun kombinasi ini memiliki asosiasi yang paling tinggi atau pembelian Tas MakeUp dan Tas Pinggang Wanita sangat mempengaruhi pembelian Baju Renang Anak Perempuan. Jadi kesepuluh kombinasi ini merupakan kombinasi yang paling tinggi liftnya, atau barang di lhs sangat mempengaruhi penjualan baran di rhs.

4. Mencari Paket Produk yang bisa dipasangkan dengan Item Slow-Moving

Slow-moving item adalah produk yang pergerakan penjualannya lambat atau kurang cepat. Ini akan bermasalah apabila item produk tersebut masih menumpuk. Kadang kala item ini belum tentu tidak laku, hanya saja mungkin harganya tidak bagus dan jarang dibutuhkan jika dijual satuan. Nah, jika tidak dijual satuan kita perlu cari asosiasi kuat dari item produk ini dengan produk lain sehingga jika dipaketkan akan menjadi lebih menarik.

Identifikasi dua item produk yang menurut dia stoknya masih banyak dan perlu dicari pasangan item untuk pemaketannya. Dua item produk tersebut adalah “Tas Makeup” dan “Baju Renang Pria Anak-anak”.

Masing-masing produk tersebut dikeluarkan 3 rules yang asosiasinya paling kuat, sehingga total ada 6 rules. Persyaratan-persyaratan asosiasi kuat ini masih sama dengan yang telah disebutkan Pak Agus sebelumnya, kecuali tingkat confidence dicoba pada tingkat minimal 0.1.

rules <- apriori(transaksi_tabular,parameter = list(supp = 10/length(transaksi_tabular), confidence = 0.1, minlen = 2, maxlen = 3))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime     support minlen
##         0.1    0.1    1 none FALSE            TRUE       5 0.002898551      2
##  maxlen target  ext
##       3  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 10 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[69 item(s), 3450 transaction(s)] done [0.00s].
## sorting and recoding items ... [68 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3
## Warning in apriori(transaksi_tabular, parameter = list(supp = 10/
## length(transaksi_tabular), : Mining stopped (maxlen reached). Only patterns up
## to a length of 3 returned!
##  done [0.00s].
## writing ... [39832 rule(s)] done [0.01s].
## creating S4 object  ... done [0.01s].
rules_tasmakeup <- sort(subset(rules, rhs %in% "Tas Makeup"), by="lift", decreasing = TRUE)[1:3]
rules_bajurenanglk <- sort(subset(rules, rhs %in% "Baju Renang Pria Anak-anak"), by="lift", decreasing = TRUE)[1:3]
rules_itemslowing <- c(rules_tasmakeup, rules_bajurenanglk)
write(rules_itemslowing, file="kombinasi_retail_slow_moving.txt")
inspect(rules_itemslowing)
##     lhs                             rhs                              support confidence   coverage     lift count
## [1] {Baju Renang Anak Perempuan,                                                                                 
##      Tas Pinggang Wanita}        => {Tas Makeup}                 0.010434783  0.8000000 0.01304348 19.57447    36
## [2] {Baju Renang Anak Perempuan,                                                                                 
##      Tas Ransel Mini}            => {Tas Makeup}                 0.011304348  0.7959184 0.01420290 19.47460    39
## [3] {Baju Renang Anak Perempuan,                                                                                 
##      Celana Pendek Green/Hijau}  => {Tas Makeup}                 0.010144928  0.7777778 0.01304348 19.03073    35
## [4] {Gembok Koper,                                                                                               
##      Tas Waist Bag}              => {Baju Renang Pria Anak-anak} 0.004057971  0.2745098 0.01478261 29.59559    14
## [5] {Flat Shoes Ballerina,                                                                                       
##      Gembok Koper}               => {Baju Renang Pria Anak-anak} 0.004057971  0.1866667 0.02173913 20.12500    14
## [6] {Celana Jeans Sobek Wanita,                                                                                  
##      Jeans Jumbo}                => {Baju Renang Pria Anak-anak} 0.005507246  0.1210191 0.04550725 13.04737    19

Untuk meningkatkan penjualan Tas Make Up, ada 3 jenis kombinasi bundling produk yang disarankan yaitu dengan Baju Renang Anak Perempuan dan Tas Pinggang Wanita, Baju Renang Anak Perempuan dan Tas Ransel Mini, serta Baju Renang Anak Perempuan dan Celana Pendek Green/Hijau. Sedangkan untuk meningkatkan penjualan Baju Renang Pria Anak-anak, dapat dilakukan 3 jenis bundling yaitu dengan Gembok Koper dan Tas Waist Bag, Flat Shoes Ballerina dan Gembok Koper, serta Celana Jeans Sobek Wanita dan Jeans Jumbo.

Bundling yang ditawarkan dapat berupa, beli barang di lhs dapat barang di rhs secara cuma-cuma atau dengan memberikan potongan harga jika membeli barang di lhs dan rhs dalam satu transaksi.

Referensi:

  1. Modul DQLab: Project Machine Learning for Retail with R: Product Packaging
  2. DataCamp: Market Basket Analysis using R