Dataset yang digunakan dalam project ini adalah Dataset Transaksi Penjualan DQLab.id Fashion. 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 manajer DQLab.id Fashion.
Salah satu solusi adalah membuat paket yang inovatif. Dimana produk yang sebelumnya tidak terlalu laku tapi punya pangsa pasar malah bisa dipaketkan dan laku.
Tujuan dari project ini adalah membuat rekomendasi paket produk yang inovatif dan menarik untuk meningkatkan keuntungan dan loyalitas para pelanggan DQLab.id Fashion.
Dataset DQLab.id Fashion ini merupakan data transaksi 3 bulan dalam bentuk format TSV (Tab Separated Value) dengan jumlah transaksi 33,669 data (3,450 kode transaksi).
#import library
library(arules)
## Warning: package 'arules' was built under R version 4.1.3
## Loading required package: Matrix
## Warning: package 'Matrix' was built under R version 4.1.3
##
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
##
## abbreviate, write
#import data
data_transaksi <- read.transactions(file="https://storage.googleapis.com/dqlab-dataset/transaksi_dqlab_retail.tsv",
format="single", sep="\t", cols=c(1,2), skip=1)
data_transaksi
## transactions in sparse format with
## 3450 transactions (rows) and
## 69 items (columns)
# show all item product
all_item <- itemFrequency(data_transaksi, type = "absolute")
names(all_item)
## [1] "Atasan Baju Belang" "Atasan Kaos Putih"
## [3] "Baju Batik Wanita" "Baju Kaos Anak - Karakter Kartun"
## [5] "Baju Kaos Anak - Superheroes" "Baju Kaos Olahraga"
## [7] "Baju Kemeja Putih" "Baju Renang Anak Perempuan"
## [9] "Baju Renang Pria Anak-anak" "Baju Renang Pria Dewasa"
## [11] "Baju Renang Wanita Dewasa" "Blouse Denim"
## [13] "Celana Jeans Sobek Pria" "Celana Jeans Sobek Wanita"
## [15] "Celana Jogger Casual" "Celana Panjang Format Hitam"
## [17] "Celana Pendek Casual" "Celana Pendek Green/Hijau"
## [19] "Celana Pendek Jeans" "Celana Tactical "
## [21] "Cover Koper" "Cream Whitening"
## [23] "Dompet Card Holder" "Dompet Flip Cover"
## [25] "Dompet Kulit Pria" "Dompet STNK Gantungan"
## [27] "Dompet Unisex" "Flat Shoes Ballerina"
## [29] "Gembok Koper" "Hair and Scalp"
## [31] "Hair Dryer" "Hair Dye"
## [33] "Hair Tonic" "Jeans Jumbo"
## [35] "Kaos" "Koper Fiber"
## [37] "Kuas Makeup " "Mascara"
## [39] "Minyak Rambut" "Obat Penumbuh Rambut"
## [41] "Pelembab" "Sepatu Kulit Casual"
## [43] "Sepatu Sandal Anak" "Sepatu Sekolah Hitam W"
## [45] "Sepatu Sport merk Y" "Sepatu Sport merk Z"
## [47] "Serum Vitamin" "Shampo Anti Dandruff"
## [49] "Shampo Biasa" "Stripe Pants"
## [51] "Sunblock Cream" "Sweater Top Panjang"
## [53] "Tali Ban Ikat Pinggang" "Tali Pinggang Anak"
## [55] "Tali Pinggang Gesper Pria" "Tank Top"
## [57] "Tas Kosmetik" "Tas Kulit Selempang"
## [59] "Tas Makeup" "Tas Multifungsi"
## [61] "Tas Pinggang Wanita" "Tas Ransel Mini"
## [63] "Tas Sekolah Anak Laki-laki" "Tas Sekolah Anak Perempuan"
## [65] "Tas Tangan" "Tas Travel"
## [67] "Tas Waist Bag" "Wedges Hitam"
## [69] "Woman Ripped Jeans "
# statistic top 10 item
item_top <- sort(all_item, decreasing=TRUE)
item_top <- item_top[1:10]
item_top <- data.frame("Nama Produk"=names(item_top), "Jumlah"=item_top, row.names=NULL)
item_top
## 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
# save result top 10 item
write.csv(item_top, file="top10_item_retail.txt")
# statistic bottom 10 item
item_bottom <- sort(all_item, decreasing=FALSE)
item_bottom <- item_bottom[1:10]
item_bottom <- data.frame("Nama Produk"=names(item_bottom), "Jumlah"=item_bottom, row.names=NULL)
item_bottom
## 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
# save result bottom 10 item
write.csv(item_bottom, file="bottom10_item_retail.txt")
Definisi kombinasi produk yang manarik adalah :
apriori_rules <- apriori(data_transaksi, parameter=list(supp=10/length(data_transaksi),conf=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(data_transaksi, parameter = list(supp = 10/
## length(data_transaksi), : 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].
apriori_rules <- head(sort(apriori_rules,by='lift', decreasing=T), n=10)
inspect(apriori_rules)
## 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
Pada kombinasi pertama mengartikan bahwa jika Tas Makeup dan Tas Pinggang Wanita dibeli secara bersamaan, maka kemungkinan Baju Renang Anak Perempuan turut dibeli.
# save combination product
write(apriori_rules, file="kombinasi_retail.txt")
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 perlu mencari asosiasi kuat dari item produk ini dengan produk lain sehingga jika dipaketkan akan menjadi lebih menarik.
Sebagai contoh, 2 item produk yakni “Tas Makeup” dan “Baju Renang Pria Anak-anak” yang stoknya masih banyak dan perlu dicari pasangan item untuk bisa dipaketkan.
Masing-masing produk tersebut dikeluarkan 3 rules yang asosiasinya paling kuat, sehingga total ada 6 rules. Selanjutnya mendapatkan kombinasi produk menggunakan fungsi apriori dengan kriteria Sama seperti kriteria sebelumnya, dan memiliki tingkat confidence minimal 0.1
jumlah_transaksi <- length(data_transaksi)
jumlah_kemunculan_minimal <- 10
apriori_rules <- apriori(data_transaksi, parameter=list(supp=jumlah_kemunculan_minimal/jumlah_transaksi, conf=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(data_transaksi, parameter = list(supp =
## jumlah_kemunculan_minimal/jumlah_transaksi, : 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].
Pada association rules, item “Tas Makeup” dan “Baju Renang Pria Anak-anak” masukkan di rhs (right hand side).
# filter tas makeup
apriori_rules1 <- subset(apriori_rules, lift > 1 & rhs %in% "Tas Makeup")
apriori_rules1 <- sort(apriori_rules1, by='lift', decreasing=T)[1:3]
# filter baju renang pria anak-anak
apriori_rules2 <- subset(apriori_rules, lift > 1 & rhs %in% "Baju Renang Pria Anak-anak")
apriori_rules2 <- sort(apriori_rules2, by='lift', decreasing=T)[1:3]
apriori_rules <- c(apriori_rules1, apriori_rules2)
inspect(apriori_rules)
## 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
# save slow-moving combination product
write(apriori_rules, file="kombinasi_retail_slow_moving.txt")