Data Analysis with R #5

ลองมาดูการทำ Data Analysis กันสักหนึ่ง algorithm จากการทำ Data Mining ดูนะครับ

ตอนแรกเราจะทำการอ่าน transactions ก่อนอ่านไฟล์ต้อง set working directory ปัจจุบันโดย setwd ก่อนครับ
ไฟล์ชื่อ Groceries_dataset.csv เขามาเป็น data set ที่จะมาทำ algorithm Apriori ครับ ไฟล์ csv นี้นำมาจาก 
rawdata of Groceries_dataset.csv เป็นข้อมูลของการซื้อของจากมินิมาร์ทหนึ่งๆในช่วงนึงในสินค้าที่พบบ่อยๆและมาเก็บเป็น data frame

หลังจากนั้นทำการ preprocessing โดยการ sort ข้อมูลจาก Member_number ครับ

#read transactions
setwd(“E:/downloads”)
df_groceries <- read.csv(“Groceries_dataset.csv”)
str(df_groceries)
df_sorted <- df_groceries[order(df_groceries$Member_number),]
ข้อมูลโครงสร้าง data frame จากการ run >str(df_groceries)

ข้อมูลเลขตรง column Member_number จะนำมาคำนวณได้ตรงเปลี่ยน class ให้เป็น numeric ก่อนครับ

#convert member number to numeric
df_sorted$Member_number <- as.numeric(df_sorted$Member_number)

เปลี่ยนข้อมูลการซื้อให้เป็นฟอร์แมตทีเช็คตัวซ้ำได้โดยเปลี่ยนเป็น class factor ก็จะนำมาใช้ได้เลย

#convert item description to categorical format
df_sorted$itemDescription <- as.factor(df_sorted$itemDescription)
str(df_sorted)
ข้อมูลโครงสร้าง data frame จากการ run >str(df_sorted)

ทำการเปลี่ยน data frame เป็นฟอร์แมต transaction เพื่อจะทำฟังก์ชัน Apriori
อย่าลืม include package plyr เพื่อใช้ฟังก์ชัน dplyr

#convert dataframe to transaction format using ddply;
library("plyr")
if(sessionInfo()[‘basePkgs’]==”dplyr” | sessionInfo()[‘otherPkgs’]==”dplyr”){
detach(package:dplyr, unload=TRUE)
}

รวมทุกข้อมูลที่ซื้อมาให้ group โดย customer โดยใช้ฟังก์ชัน ddply(จาก package plyr)
หลังจากนั้นลบ column Member_number กับ Date ออก เพราะข้อมูลถูก group แล้วเราจะใช้แค่ item และตั้งชื่อ comlumn ว่า itemList เพื่อให้ data frame สำเร็จรูปที่สุด

#group all the items that were bought together; by the same customer on the same date
df_itemList <- ddply(df_groceries, c(“Member_number”,”Date”), function(df1)paste(df1$itemDescription,collapse = “,”))
#remove member number and date
df_itemList$Member_number <- NULL
df_itemList$Date <- NULL
colnames(df_itemList) <- c("itemList")

เขียนไฟล์ csv ที่ preprocessing เสร็จแล้วลง csv ใหม่ โดยมีชื่อแถวอยู่และไม่มี logical value อยู่

#write to csv format
write.csv(df_itemList,”ItemList.csv”, quote = FALSE, row.names = TRUE)

include package arules เพื่อที่จะใช้ฟังก์ชัน apriori
หลังจากนั้นดึงข้อมูลที่เขียนไว้ก่อนหน้านี้มาใช้ โดยที่ไม่ลบตัวซ้ำ ฟอร์มอตแบบ basket

library(arules)
#convert csv file to basket format
txn = read.transactions(file=”ItemList.csv”, rm.duplicates= FALSE, format=”basket”,sep=”,”,cols=1);

ลบ quote เครื่องหมายที่ยังมีอยู่ออก โดยฟังก์ชัน gsub

#remove quotes from transactions
txn@itemInfo$labels <- gsub(“\””,””,txn@itemInfo$labels)

มาถึงขั้นตอนเข้า algorithm apriori ต้องทำการทดสอบ sup กับ conf ก่อนว่าค่า max (ลองเช็คค่าจาก output) ของมันอยู่ตรงไหนละค่อยๆกำหนดค่าที่เหมาะสมที่เราอยากได้ ผมใช้ min lenght = 3 (3 items ที่สัมพันธ์กันขึ้นไป) / sup = 0.001 / conf = 0.1

#run apriori algorithm
basket_rules <- apriori(txn,parameter = list(minlen=3,sup = 0.001, conf = 0.1, target=”rules”))

ดู output จากการทำ apriori โดยจะเลือกดูแค่ที่มีค่าเยอะๆทางหัว 20 ค่า เซ็จได้จากค่า head

#view rules
inspect(head(basket_rules,20))
output ที่ผ่าน sup และ conf นั้นๆได้ output ออกมา 17 ตัว

ลองเปลี่ยน min length = 4 (4 items ที่สัมพันธ์กันขึ้นไป) / sup = 0.0001 / conf = 0.1 ได้ output ดังนี้

เราจะเห็นได้ถึงความสัมพันธ์ที่เกิดขึ้นได้ชัดเจนเลยว่าเป็นอย่างไร และมีค่า lift บอกมาให้ด้วยถึงความขึ้นอยู่ต่อกันของ lhs กับ rhs
ที่เด่นๆเลยจากค่า head อันที่ 1
- ผลลัพธ์ของ output แรก (3 items) ผู้คนซื้อ { sausage และ yogurt } ก็จะซื้อ { whole milk } ตามเป็นส่วนใหญ่ 
- ส่วน output ที่สอง (4 items) ผู้คนซื้อ { prosecco, sausage และ waffles} ก็จะซื้อ { other vegetables } ตามเป็นส่วนใหญ่

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

itemFrequencyPlot(txn, topN = 7)

เห็นไหมครับการวิเคราะห์ข้อมูลไม่ยากอย่างที่คิดเพียงศึกษาเพิ่มเติมเล็กน้อยก็สามารถทำได้กับข้อมูลชุดอื่นๆได้อีกมากมายจำนวนมาก :D