รู้สึกว่าตั้งแต่เรื่อง Machine Learning กำลังเป็นที่พูดถึงเรื่อยๆ เรื่องของ Probabilistic Programming Language ก็เป็นที่พูดถึงมากขึ้นไปด้วย แต่บทความที่พูดถึงว่า Probabilistic Programming Language (PPL) คืออะไร มีประโยชน์อย่างไรและเอาไปใช้งานยังไงในบ้านเรานั้นน้อยมาก ผมก็เลยคิดว่าผมน่าจะแชร์อะไรบ้างตามที่ได้ไปรู้ไปเห็นมาครับ
PPL คืออะไร PPL ก็เป็นรูปแบบของภาษาหรือชุดคำสั่งในคอมพิวเตอร์แบบหนึ่งที่จะช่วยให้เราทำสถิติเชิงอนุมาน Inference กับโมเดลความน่าจะเป็นต่างๆ ได้ง่ายขึ้น ซึ่งแน่นอนมันก็จะเกี่ยวข้องกับทฤษฎีของเบย์ด้วย ลองดูตัวอย่างของการทำ Linear regression นี้ดูนะครับ สมมุติว่าเรามีข้อมูลเป็นคู่ และมีโมเดลที่ใช้อธิบายข้อมูลเป็นสมการเส้นตรง
โดยที่
(หรือในบางตำราจะใช้ precision หรือความถูกต้อง
) หรือ
เราสามารถที่จะเขียน probability density function (PDF) สำหรับ likelihood ที่เราจะได้
ได้ว่า
ดังนั้น likelihood สำหรับทุกๆจุดของข้อมูลก็สามารถเขียนได้ว่า (เอาของทุกจุดคูณกัน)
พิจารณาที่เทอมยกกำลังสองนะครับ
โดยที่ และ
ถ้าพิจารณาดูที่ เราสามารถเขียนฟังก์ชั่นของความน่าจะเป็นของ
ได้ว่า
หรือ
นั้นสามารถสุ่มมาจาก Normal distribution ตามนี้เลย
มันมาจากการโยกย้ายฟ้าดิน 🙂 บวกกับอาศัยความสัมพันธ์นี้ครับ ถ้า มี PDF
โดย
เราจะได้ว่า
หรือ ถ้า
เราจะได้ว่า
(พยายามนึกอยู่ว่าไปจำมาจากไหน)
ทำในลักษณะคล้ายๆกันกับ และ
เราจะได้ว่า
นั่นก็หมายความว่าในการที่เราจะหาค่า เราก็เพียงสุ่มจากสูตรที่ได้นี้ได้เลยครับ ซึ่งเราสามารถที่จะใช้ R ช่วยได้เลย ครับ ****(จริงๆแล้วในตัวอย่างนี้ ผมสมมุติให้เราไม่รู้อะไรเลยสำหรับ prior distribution ( i.e.,
) หรือข้อมูลอะไรบางอย่าง เช่นของ
มีรูปแบบการกระจายตัวหรือ distribution เป็นอย่างไร มีช่วงของค่าที่เป็นไปได้อย่างไร ง่ายที่สุดผมให้ prior distribution
หรือ
เหมือนกันสำหรับ
) ครับ
เราเขียนใน R ได้ว่า
alpha<-rnorm(1,mean(y)-beta*mean(x),1/(n*tau))
m<-(sum(x+y)-alpha*n*mean(x))/sum(x**2) s<-1/(tau*sum(x**2)) beta<-rnorm(1,m,s)
w<- y-alpha-beta*x tau<-rgamma(1,((n/2)+1),(sum(w**2)/2))
ทดลองเอาไปใช้จริงอาศัย R code ที่ผมเขียนข้างล่างนี้ดูครับ วิธีการเอาไปใช้ก็ลองสร้างข้อมูลมาสักหนึ่งชุด ในที่นี้ผมมีfunction ชื่อfakedata สำหรับสร้างข้อมูลครับ ก็ใช้สมการเส้นตรงนี่แหละแล้วก็บวกค่า error ที่สุ่มมาบวกเข้าไป โดยในตัวอย่างนี้ผมลองสร้างโดยให้ และก็ให้
จากนั้นก็ลองใช้ คำสั่ง lm ของ R ลอง fit ดูว่าจะได้
เท่าไหร่ ซึ่งค่านี่แหละเอาไว้เปรียบเทียบกับที่เราจะได้จากการสุ่มมาจากสูตรที่เพิ่งคิดไปครับ
#fake data set.seed(12345) fakedata<-function(alpha, beta, t){ err<-rnorm(length(t),mean = 0, sd = 5) fake<-data.frame(time=t,y=alpha + beta*t +err) return(fake) } ob<-fakedata(alpha = 1.5, beta = 0.5, 1:100) plot(ob) # using lm to fit the fake data lmfit<-lm(ob$y ~ ob$time) cat(paste0("alpha = ",format(round(lmfit$coefficients[1],4),nsmall = 4), " beta = ", format(round(lmfit$coefficients[2],4),nsmall = 4))) abline(lmfit, col='red') # # linear regression from the posterior distributions # slphyx LinReg<-function(y,x,size){ #initial values alpha<-0 beta<-1 tau<-1 n<-length(y) output<-matrix(ncol=3,nrow=size) for(i in 1:size) { alpha <- rnorm(1,mean(y)-beta*mean(x),1/(n*tau)) m <- (sum(x*y)-alpha*n*mean(x))/sum(x**2) s <- 1/(tau*sum(x**2)) beta <- rnorm(1,m,s) w <- y-alpha-beta*x tau <- rgamma(1,((n/2)+1),(sum(w**2)/2)) output[i,] <- c(alpha,beta,tau) } data.frame(alpha=output[,1],beta=output[,2],tau=output[,3]) } outLR<-LinReg(y=ob$y,x=ob$time,size=10000) cat(paste0("alpha = ",format(round(mean(outLR$alpha),4),nsmall = 4), " beta = ", format(round(mean(outLR$beta),4),nsmall = 4), " tau = ",format(round(mean(outLR$tau),4),nsmall = 4))) cat(paste0("sigma = ",format(round(sqrt(mean(1/outLR$tau)),4),nsmall = 4) ))