GornNutagorn_R_Market_Basket_Analysis

สวัสดีครับ

ซื้อเหล้าพ่วงโซดา? บทความนี้เป็นคนละเรื่องกับขายเหล้าพ่วงเบียร์นะครับ แค่จั่วหัวให้คิดภาพง่ายๆเฉยๆครับ ว่าเวลาคนซื้อของบางอย่าง มักจะไม่ได้ซื้อแค่อย่างเดียว ด้วยสาเหตุหลายอย่าง เช่น

เป็นสินค้าประกอบกัน (complementary goods) เช่น ที่โกนหนวดกับ ใบมีด
ซื้อเพื่อความหลากหลาย เช่น ซื้อมาม่าทีละหลายๆรส
โดนโปรโมชั่นพ่วง เช่น ซื้อของครบ 100 บาท รับสิทธิ์แลกซื้อชาเขียว 5 บาท เลยซื้อมันหมดเลย
Market Basket Analysis เป็นสิ่งที่จะเข้ามาช่วยวิเคราะห์ตรงนี้ โดยบทความนี้จะเน้นเฉพาะวิธีรันและแปรผล โดยแม้แต่ท่านที่ไม่เคยใช้ R ยังไม่ลง R ไว้ในเครื่อง อ่านแล้วน่าจะสามารถทำตามได้เลย

Market Basket Analysis ที่กำลังจะนำเสนอนี้ จะอยู่ภายใต้ Association Rule โดยใช้ apriori algorithm ซึ่งจะเหมาะกับการวิเคราะห์การซื้อขายของการค้าปลีก เช่นในซุปเปอร์มาร์เก็ต เพราะมันกำลังที่จะตอบคำถามว่า

ถ้าซื้อ สินค้า A1, A2,A3,…. แล้วน่าจะซื้อสินค้า B… อย่างไร

[ตรงนี้ขอแทนเรียก สินค้า A1, A2,A3, …. ว่า LHS และสินค้า B ว่า RHS ]

ถ้าสินค้าเราไม่เยอะ เราขายเอง เราก็พอจะเดาได้ว่าลูกค้าจะซื้ออะไรพร้อมๆกัน จัดโปรสินค้าแบบไหนดี แต่ถ้าสินค้าเราเยอะ และจำนวนบิล (transaction) เยอะมาก คงจะงมเรื่องนี้ด้วยประสบการณ์ไม่ไหวครับ

การรันโมเดลนี้ จะบอกเราประมาณ 3 อย่างนี้คือ

  1. Support : สัดส่วนเหตุการณ์ต่อ Transaction ทั้งหมดว่ามีกี่% //// เช่นมีบิล 0.002% จากบิลทั้งหมด ที่ลูกค้าซื้อ ชาเขียวA และ ผงซักฟอกC ไปด้วยกัน
  2. Confidence : ถ้าซื้อสินค้า A1, A2,A3, … (LHS) แล้วน่าจะซื้อสินค้า B (RHS) กี่%
  3. Lift : ถ้าซื้อสินค้า A1, A2,A3, ….(LHS) แล้วโอกาศที่จะซื้อสินค้า B (RHS) จะเพิ่มขึ้นกี่%

ตัวอย่างที่โด่งดังจากการการวิเคราะห์นี้ เช่น มีการพบว่า การซื้อผ้าอ้อมกับเบียร์จะขายดีในวันพฤหัส โดยมีการอนุมานว่าเป็นเพราะ คู่สามีภรรยาที่มีเด็กอ่อน จะสต้อกของที่จำเป็นไว้ก่อนที่จะเข้าสู่วันหยุด …. (แล้วแต่จะคิดนะครับ) ……แต่เมื่อข้อมูลมันออกมาตามนี้ จึงมีการประยุกต์ใช้ เช่น จัดเชลฟ์วางสินค้าโดยเอาผ้าอ้อมไปวางข้างตู้เบียร์เพื่อเพิ่มยอดขาย

นอกจากนี้ ตัว Association Rule ยังสามารถใช้ประโยชน์ได้หลายอย่างเช่น

  • Product recommendation ใน Amazon ตรงที่ว่า “customers who bought that, also bought this”
  • Music recommendations ใน Last FM ตรง artist recommendation

เอาล่ะครับ เกริ่นมาได้พอสมควรแล้วครับ เข้าเรื่องเลยก็คือ

บทความนี้จะแนะนำวิธีใช้ R รันโมเดลตัวนี้แบบง่ายๆ ง่ายแบบว่าถึงท่านไม่เคยมี R ลงในเครื่อง ใช้ความถึกเล็กน้อย หา R มาลง แปะโค้ด กดรันก็ทำได้เลย (อาจมีการเซตอะไรเล็กน้อย จะพูดถึงทีหลังนะครับ) โดยสิ่งที่ผมจะพูดถึง จะเป็นแค่ วิธีเตรียมข้อมูล รันข้อมูล ตั้งค่าเล็กน้อย และแปรผลเอาไปใช้ เท่านั้นนะครับ

*** อยากขอหมายเหตุตรงนี้ไว้เล็กน้อยครับว่า ผมเองไม่ได้เป็นคนที่เป้ะทฤษฎีมาก วิธีการทำงานของผมจะเป็นแบบทำให้้มันใช้งานได้ก่อน เมื่อมั่นใจว่าเราจะใช้มันต่อไป จึงค่อยลงลึกศึกษาเพิ่มเติมปรับแต่งและพัฒนามัน ดังนั้น ผมอาจละเลยรายละเอียดบางส่วนไป ต้องขออภัยไว้ ณ ที่นี้ด้วยครับ***

ดังนั้นในส่วนการทำงานของมันหรือแนวคิดโดยละเอียด สามารถอ่านได้ตามลิงค์ด้านล่างนี้นะครับ โดยแต่ละท่านอธิบายไว้ค่อนข้างละเอียดแล้วครับ

ภาษาอังกฤษ

  • http://www.listendata.com/2015/12/market-basket-analysis-with-r.html
  • http://www.salemmarafi.com/code/market-basket-analysis-with-r/

ภาษาไทย

  • Eakasit Pacharawongsakda
  • https://wipawanblog.files.wordpress.com/2014/06/chapter-4-association-rule.pdf
  • https://www.facebook.com/pg/is.cite/photos/?tab=album&album_id=391280867886817

ทำไมไม่ใช้ Excel ทำ?

  • ข้อมูลที่ต้องใส่ค่อนข้างมหาศาล (เกิน 1000000 row ง่ายๆครับ)
  • ที่จริงสามารถ run ใน excel ได้เช่นกันโดยใช้ XLMINER ซึ่งเป็น Add-in แต่ไม่น่าจะฟรีครับ (มี trial version)
  • R มันฟรีครับ (แน่นอน)

ทั้งนี้ถ้าข้อมูลไม่เยอะ/ ทำคู่ไม่กี่ product สามารถใช้ Excel ทำแบบ บวกลบคูณหารได้เลย เพราะโดยวิธีคิดแล้ว model นี้ไม่ได้ซับซ้อนมาก สามารถลองดูวิธีทำตามหนังสือเล่มนี้ครับ

Marketing Analytics: Data-Driven Techniques with Microsoft Excel

ขั้นตอนการทำ ผมจะแบ่งเป็นดังนี้นะครับ

  1. เตรียมข้อมูลไฟล์
  2. เอาโค้ดไปแปะแล้วรัน ใน R
  3. แปรผลที่ได้

ขั้นตอนที่ 1 เตรียมข้อมูลไฟล์

โดยตั้งชื่อว่า mba.csv แล้วเอาไปใส่ใน working directory

(คนที่ไม่เคยใช้ R ดูหมายเหตุด้านล่างครับ)

คือเตรียมไฟล์ที่ต้องการวิเคราะห์โดยทำให้อยู่ในรูป .csv และ
ในกรณีที่ท่านจะใช้ข้อมูลของท่านเอง
บรรทัดแรกเป็นชื่อคอลัมน์ให้ใส่ ID และ Products โดย
คอลัมน์ 1 เป็นข้อมูล transaction ID
คอลัมน์ 2 เป็นข้อมูล รายการสินค้าที่อยู่ในบิล
เช่น สมมติ
ถ้าบิลที่ 1001 ซื้อ egg milk meat
ถ้าบิลที่ 1002 ซื้อ egg milk flour tea

ไฟล์ก็จะออกมาหน้าตาแบบนี้ (สมมติเริ่มทำใน excel)

GornNutagorn_R_data_example
รูปที่ 1 : ตัวอย่างการใส่ข้อมูลตัวเอง

อย่างไรก็ตาม ผมมีตัวอย่างไฟล์ซึ่งสามารถโหลดได้ตามด้านล่างนี้
https://gornnutagorn.com/wp-content/uploads/2018/04/GornNutagorn_mba_data.csvGornNutagorn_mba_data
โดยไฟล์ตัวอย่างที่ผมให้ไว้ เป็นตัวอย่างจริงจากร้านค้าปลีก ซึ่งผมได้แปลงเลขบิล (transaction) ให้สั้นลง และแปลงชื่อสินค้าเป็นตัวเลข (เพื่อทำให้ data มีขนาดเล็กที่สุด)
มีจำนวนบิล 10,000 กว่าบิล เป็นข้อมูล 50,000 กว่าบรรทัด
ดังนั้นหน้าตาจะประมาณนี้ครับ

GornNutagorn_R_data_example2
รูปที่ 2 : ตัวอย่างข้อมูลจากตัวอย่างของผม

** สังเกตนะครับว่าโมเดลนี้ไม่สนใจจำนวนสินค้าที่ซื้อต่อรายการ มันแค่สนใจว่าอะไรที่ซื้อพร้อมกันครับ**

ขั้นตอนที่ 2 เอาโค้ดไปแปะแล้วรัน ใน R (สำหรับท่านที่ยังไม่เคยใช้ R ดูหมายเหตุตอนท้ายนะครับ)

โดยโค้ดนี้ส่วนมากผมเอามาจาก
http://www.listendata.com/2015/12/market-basket-analysis-with-r.html
ต้องขอให้เครดิตเต็มๆเลยนะครับ แต่ผมจะมีแก้บางส่วนเพราะโค้ดบางตัวที่รันบนเครื่องผมมัน error ครับ
ผมจะใส่โค้ดก่อนนะครับ แล้วค่อยๆอธิบาย (มีหมายเหตุการแก้ไขโค้ดที่ท้ายบทความ)

----------
# step1 - preparation
mydata = read.csv("./mba.csv") # Read CSV data file
names(mydata) <- c("ID","Products") # Rename Column name (optional)
dt <- split(mydata$Products, mydata$ID)
if(!require(arules)) install.packages("arules")
library(arules)
dt2 = as(dt,"transactions")

# step2 - aggregated data
rules = apriori(dt2, parameter=list(support=0.001, confidence=0.4,minlen = 2))

# step3 - Sort by Lift
rules<-sort(rules, by="lift", decreasing=TRUE)

# step4 - Remove Unnecessary Rules
subset.matrix <- is.subset(rules, rules)
subset.matrix2 <- subset.matrix*1
subset.matrix3 <- subset.matrix2
subset.matrix3[lower.tri(subset.matrix3, diag=T)] <- NA
redundant <- colSums(subset.matrix3, na.rm=T) >= 1
rules.pruned <- rules[!redundant]
rules<-rules.pruned

##step4(Original) - Remove Unnecessary Rules (not included due to technical problem)
#subset.matrix <- is.subset(rules, rules)
#subset.matrix[lower.tri(subset.matrix, diag=T)] <- NA
#redundant <- colSums(subset.matrix, na.rm=T) >= 1
#rules.pruned <- rules[!redundant]
#rules<-rules.pruned

# step5.1 - Convert rules into data frame
rules3 = as(rules, "data.frame")

# step5.2 - Clean Rules
rules3$rules=gsub("\\{", "", rules3$rules)
rules3$rules=gsub("\\}", "", rules3$rules)
rules3$rules=gsub("\"", "", rules3$rules)

# step6 - Split the rule
if(!require(splitstackshape)) install.packages("splitstackshape")
library(splitstackshape)
Rules4=cSplit(rules3, "rules","=>")
names(Rules4)[names(Rules4) == 'rules_1'] <- 'LHS'
Rules5=cSplit(Rules4, "LHS",",")
Rules6=subset(Rules5, select= -c(rules_2))
names(Rules6)[names(Rules6) == 'rules_3'] <- 'RHS'

# step7 - write final result to CSV file
Rules7 = as(Rules6, "data.frame")
write.csv(Rules7, "./rules_final.csv")
----------

 

เมื่อท่านเอาไฟล์ mba.csv ไปวางไว้ใน working directory เรียบร้อยแล้ว
สิ่งที่ท่านต้องทำการปรับค่า จะมีเพียงแค่ค่าตัวเลข parameter ทั้ง 3 ตัวใน step2 ตามด้านล่าง

“rules = apriori(dt2, parameter=list(support=0.001, confidence=0.4,minlen = 2))”

3 ตัวนี้คือตัวที่กำหนดค่า minimum ของแต่ละ parameter ตามนี้ จากตัวอย่างด้านบน

  1. support เช่น support=0.001 คือสัดส่วนของ transaction ที่มีชุดสินค้าดังกล่าวต่อ transaction ทั้งหมด (คือเป็น subset) ตรงนี้ output ที่ออกจะต้องเป็น item set ที่ต้องมี support ขั้นต่ำ 0.1%
  2. confidence เช่น confidence=0.4 คือค่าสัดส่วนเมื่อรูปแบบ LHS (A1,A2,A3,…..) เกิดขึ้นแล้วรูปแบบ RHS (B) จะเกิดขึ้นด้วย ตรงนี้ output ที่ออกจะต้องเป็น item set ที่ต้องมี confidence ขั้นต่ำ 40%
  3. minlen คือ จำนวนชุดรายการสินค้า minimum (รวมทั้งฝั่ง LHS และ RHS) ตรงนี้ output ที่ออกจะต้องเป็น item set ที่ต้องมี จำนวนรายการสินค้าขั้นต่ำ 2 ตัว

**สิ่งที่ต้องระวังคือ หากใส่ค่าเหล่านี้ไม่เหมาะสม บางทีจะไม่มีผลลัพธ์ออกมาเลยนะครับ (ค่า minimum สูงเกินไป) หรือเครื่องจะรันจนแฮงค์ได้เลย (ค่า minimum ต่ำเกินไป) ดังนั้น ผมแนะนำว่าให้เริ่มจากสูงๆเช่น support=0.005, confidence=0.8 แล้วค่อยๆลดไปเรื่อยๆนะครับ

จากนั้น กด run แล้วผลลัพธ์จะออกมาเป็นไฟล์ชื่อ rules_final.csv อยู่ใน folder เดิมที่วางไฟล์ mba.csv ลงไป (ทั้งนี้ผมใช้ R studio แบบโหลดเป็น script ขึ้นมาก่อนแล้วค่อย run)

ผมจะแปะไฟล์ที่รันเสร็จแล้วไว้ด้านล่างนี้นะครับ

https://gornnutagorn.com/wp-content/uploads/2018/04/GornNutagorn_mba_output.xlsxGornNutagorn_mba_output

แต่จะเป็นในรูป Excel โดยจะมี 2 sheet คือ

  • sheet : output คือผลลัพธ์ทีได้เหมือนกับ ไฟล์ rules_final.csv จากตัวอย่างของผม
  • sheet : rename คือผมแปลงรหัสสินค้าบางตัวกลับเป็นชื่อสินค้าภาษาไทย (โดยชื่อที่แปลงกลับจะเป็นชื่อ สมมติ และมีไม่ครบ คือผมนำข้อมูลนี้มาเพื่อการศึกษาและความเข้าใจที่เพิ่มขึ้นเท่านั้น ผมจึงไม่เปิดเผยข้อมูลต้นฉบับ แต่ชื่อสมมติที่ผมใส่ไป มันก็เป็นสินค้าชนิดนั้นๆจริงๆ)

ขั้นตอนที่ 3 แปรผลที่ได้

GornNutagorn_R_data_result1
รูปที่ 3 : ตัวอย่างผลลัพธ์ที่ได้จากไฟล์ตัวอย่าง

จากรูปที่ 3 ผมแค่มาใส่สีกับรวมกันให้อ่านง่ายเฉยๆ (เหมือนในไฟล์ที่แปะไว้ด้านบนครับ)
ฟากซ้ายคือ output จากการรันผลออกมา
ฟากขวา คือผมแค่เอาตัวเลขมา map กับชื่อสินค้า

วิธีการอ่านนั้น

จาก parameter ที่ใส่ไปในขั้นตอนที่ 2 ข้อมูลชุดนี้จะตัดกฎที่

  • support ต่ำกว่า 0.001
  • confidence ต่ำกว่า 0.4
  • จำนวน item ด้าน LHS รวมกับ RHS ต่ำกว่า 2 ออกไป

ผมจะอธิบายเช่น item ที่ 9 ให้ฟังนะครับ

1. ค่า support
พบการซื้อ itemset [ กาแฟ A1 / คอฟฟี่เมต A1 / น้ำผลไม้ B1] เป็นสัดส่วน 0.1% จากจำนวนบิล (transaction) ตัวอย่างทั้งหมด

2. ค่า confidence
เมื่อเกิดการซื้อ [คอฟฟี่เมต A1 / น้ำผลไม้ B1] (LHS) จะเกิดการซื้อ [กาแฟ A1] (RHS) เป็นสัดส่วน 100% จากบิลที่มีรายการ [คอฟฟี่เมต A1 / น้ำผลไม้ B1] ทั้งหมด

3. ค่า lift
ค่า lift สามารถอ่านได้ตามสูตรนี้นะครับ
% increase of chance of buying other product(s) = (Lift – 1) * 100
ดังนั้นค่า lift ตรงนี้คือ (240.67-1) x 100 = 23,967% แปลว่า
เมื่อลูกค้าซื้อ [คอฟฟี่เมต A1 / น้ำผลไม้ B1] (LHS) แล้ว มีโอกาศที่จะซื้อ [กาแฟ A1] (RHS) เพิ่มขึ้นอีก 23,967%

จบครับ ….

————-

จากตรงนี้จะเป็นหมายเหตุเพิ่มเติมสำหรับ

วิธีรัน R โค้ดอันนี้สำหรับคนที่ใช้ Excel เป็นแต่ยังไม่เคยแตะ R และไม่มี R ในเครื่อง
การแก้ไขโค้ดจากต้นฉบับ

1. วิธีรัน R โค้ดอันนี้สำหรับคนที่ใช้ Excel เป็นแต่ยังไม่เคยแตะ R และไม่มี R ในเครื่องถ้าคุณเป็นคนหนึ่งที่อยากลองเริ่มใช้ R จากบทความนี้ ผมจะแนะนำอย่างรวดเร็วนะครับว่าต้องทำอย่างไรบ้าง

  • เข้า google
  • พิม r download เพื่อโหลด r มาลงเครื่อง (https://cran.r-project.org)
  • พิม r studio download เพื่อโหลด r studio มาลงเครื่อง (https://www.rstudio.com/)
  • สร้างแฟ้มที่ต้องการวางข้อมูลสำหรับ R ไว้ที่ desktop เช่นกำหนดชื่อว่า R_temp
  • เปิด R Studio แล้วกำหนดแฟ้มที่ว่าเป็น working directory คุณต้องหา path ของแฟ้มก่อน โดยต้องพิ
  • โค้ดประมาณด้านล่างนี้ อันนี้ผมยกตัวอย่างคอมผมนะครับ แต่คอมคุณ path คงต่างกัน ก็เปลี่ยนตามใน quote เลยครับ พิมลงไปที่หน้าต่าง console ซ้ายล่างแล้ว entersetwd(“C:/Users/g/Desktop/R_Temp”)

**ผมใช้ windows10 ไม่แน่ใจว่า mac จะมีอะไรต่างไปบ้างครับ

  • จากนั้นก็ทำตามทำผมว่าในบทความได้เลยครับ โดยวางข้อมูล /ก้อปโค้ดที่ผมให้ไป ลงในหน้าต่าง script ซ้ายบน กด ctrl+A เพื่อคลุมทั้งหมดและกดปุ่ม ctrl+R เพื่อรันได้เลยครับ

2. การแก้ไขโค้ดจากต้นฉบับ

สำหรับคนที่ใช้ R อยู่แล้ว ลองอ่านตรงนี้นิดนึงนะครับ

  • ผมแก้โค้ดตรงนู่นตรงนี้เล็กน้อยเพื่อให้สามารถ import และ export ไฟล์ ได้สะดวก
  • ส่วนที่ผมแก้ไขจริงจังจะเป็นส่วน step 4 คือส่วนที่ลบ rule ที่ซ้ำซ้อนออกไปนะครับ คือจะสังเกตได้ว่า ตรงหัวข้อ step 4(Original) ผมจะใส่ # ไว้ทั้งหมดคือไม่ให้มันรันนะครับ นั่นคือโค้ดต้นฉบับ และหลายๆที่ก็ใช้โค้ดนี้เป้ะๆเลย คือปีที่แล้วผมก็ใช้โค้ดนี้รันไม่มีปัญหา แต่พอผมจะเขียนบล้อกแล้วมารันใหม่ มันกลับแฮงค์ ไม่ค่อยเข้าใจ แต่ผมก็ลองปรับโค้ดเองจนกลายเป็น step 4 ที่ผมเขียนไปครับ เอาจริงๆ อยากให้ลองเอา step 4 ของผมออกแล้วไปรันโค้ดที่เป็น original ดีกว่าครับ อย่างไรก็ตามผมเทสแล้ว ผลลัพธ์ข้อมูลก็เหมือนกับที่ผมเคยรันไว้เมื่อปีที่แล้วครับ ถ้าท่านอื่นเทสแล้วผิดพลาดอะไร คอมเมนต์มาได้เลยนะครับ

ถึงตรงนี้ผิดพลาดประการใด ต้องขออภัยไว้ตรงนี้ และ คอมเมนต์ได้เลยครับ

ขอบคุณที่อ่านจนจบครับ

(บทความนี้ เขียนเมื่อ 2017-07-30)

Created by : GornNutagorn

 

ช่องทางอื่นๆของ GornNutagorn

Facebook : https://www.facebook.com/GornNutagorn/

Youtube : www.youtube.com/c/GornNutagornChannel

 

Sponsored by :

#####################################

grocerlock_โกรเซอล็อค

 

สนับสนุนโดย : www.grocerlock.com (คลิกเพื่อเข้าเว็บ)

ซุปเปอร์มาร์เก็ตออนไลน์ ขายสินค้าอุปโภคบริโภคทั่วไป

ขายปลีก-ส่ง / ต่อรองได้ / ส่งทั่วประเทศ

FB อินบ้อกได้ที่ : https://www.facebook.com/grocerlock (คลิกเพื่อส่งข้อความทางอินบ็อกซ์)

ซื้อผ่านไลน์ได้ที่ Line ID : @grocerlock (คลิกเพื่อเพิ่มเพื่อน)

#####################################

LEAVE A REPLY

Please enter your comment!
Please enter your name here