บทความนี้มาเรียนวิธีการคำนวนระยะทาง i.e. distance ง่ายๆระหว่างสอง data points โดยตัวที่เราจะสอนวันนี้ชื่อว่า Euclidean distance สูตรการวัดระยะยอดนิยมในงาน data science – Enough talk! Let’s do it.
Euclidean Distance
สมมติเรามี data points 2 จุด (20, 75) และ (30, 50)
จงหาระยะห่างของสองจุดนี้ ถ้ายังจำได้สมัยประถม (แอดค่อนข้างมั่นใจว่าเรียนกันตั้งแต่ ป.6 555+) วิธีการหาระยะห่างในรูปด้านล่างใช้หลักพีทาโกรัส (Pythagorean theorem): a2 + b2 = c2
Euclidean distance (d) หรือ c ในรูปขวาด้านบนสามารถคำนวณได้ง่ายๆตามหลัก Pythagoras สาเหตุที่เราต้องถอดราก (square root) เพราะตอนแรกพีทาโกรัสไปยกกำลังสองด้าน a และ b เพื่อหา c มีเหตุผล!

บวกลบคูณหารง่ายๆใน R ความยาวด้าน c หรือ Euclidean distance = 26.92 ทำไมมันง่ายอย่างงี้
## example code in R
v1 <- c(30, 50)
v2 <- c(20, 75)
d <- sqrt(sum((v1 - v2)**2)) ## 26.92
General Formula
สูตรทั่วไปของ Euclidean distance เขียนได้ตามรูปด้านล่าง โดยที่ q คือ vector_1 และ p คือ vector_2 และความยาวของทั้งสองเวคเตอร์เท่ากับ n ตัวอย่างเช่น q = (30, 50, 60, 100), p = (20, 75, 50, 45)

R มีฟังชั่น dist()
เพื่อใช้คำนวณระยะห่างของสอง data points ขั้นตอนแรกให้เรารวมเวคเตอร์ v1 และ v2 เป็น data frame ก่อนด้วยฟังชั่น rbind()
เสร็จแล้วใช้ฟังชั่น dist(df, method = "euclidean")
วิธีนี้จะได้ผลเท่ากับการคำนวณมือด้านบน 100%
## create a data frame
df <- rbind(v1, v2)
## euclidean distance
dist(df, method = "euclidean") ## 26.92
Tip – เวลาเราเขียน algorithm ที่ต้องมีการใช้ Euclidean distance ในการคำนวณ ปกติเรานิยม standardize/ normalize features ก่อน เช่น z-score หรือ min-max scaling ปรับค่าของตัวแปรให้อยู่ในช่วง [0, 1] เพราะถ้าตัวแปรบางตัวมี range ที่กว้างกว่าตัวแปรอื่น จะส่งผลอย่างมากต่อการทำงานของ algorithm โดยรวม
Distance More Than 2 Variables
ตัวอย่างการคำนวณ Euclidean distance ของรถยนต์ 5 คันแรกใน mtcars dataframe โดยใช้ตัวแปร hp, wt และ mpg ถ้าเรามีมากกว่าสอง data points ผลลัพธ์ของฟังชั่น dist()
จะออกมาเป็น distance matrix
## dist() works with more than two variables
dist(mtcars[1:5, c("hp", "wt", "mpg")], method = "euclidean")

เราสามารถสรุปผลได้ว่ารถยนต์คู่ที่มีความใกล้กันมากที่สุดคือ Mazda RX4 และ Mazda RX4 Wag (d = 0.255) ส่วนรถยนต์คู่ที่แตกต่างกันมากที่สุดคือ Datsun 710 และ Hornet Sportabout (d = 82.11)
Case Study – Iris
มาลองดูตัวอย่างการใช้งานจริงกับ iris dataset โดยข้อมูลชุดนี้มี 150 rows x 5 columns ชื่อคอลัมน์มีดังนี้ sepal.length, sepal.width, petal.length, petal.width และ species {setosa, versicolor, virginica}
Algorithms ที่ใช้ Euclidean distance ในการทำงานหลักๆมีสองตัวคือ k-means clustering เอาไว้ทำพวก customer segmentation และ k-nearest neighbors สำหรับทำ prediction (i.e. ทำนาย iris species)

ถัดไปจะเป็นตัวอย่าง R code สำหรับเทรนโมเดล k-means และ k-NN เรา assume ว่าผู้อ่านเข้าใจภาษา R บ้างแล้ว ถ้าใครยังเคยเขียนโปรแกรมมาก่อนเลย เรียนปรับพื้นฐาน Intro to R ฟรีกับเราได้ที่นี่
K-Means Clustering
k-means เป็น unsupervised learning algorithm ที่นิยมใช้ในงานพวก customer segmentation โดยเราจะลองเทรนโมเดลกับ features ของ iris dataset (column 1-4) เพื่อจับกลุ่ม observations ตามสายพันธุ์
วันนี้เราจะยังไม่อธิบายลงลึกมากเกี่ยวกับการทำงานของ k-means แต่หลักการเบื้องต้นของ algorithm นี้ก็ง่ายๆ – observations ที่อยู่ใกล้กันวัดจาก distance ก็ควรจะอยู่ segment เดียวกัน มีเหตุผล! ลองดูรูปด้านล่าง

เราใช้ฟังชั่น kmeans()
เพื่อเทรนโมเดลและกำหนดจำนวน segment (k) ด้วย argument center ความยากของ k-means คือการกำหนดค่า k ที่เหมาะสม ซึ่งต้องอาศัยการทำ EDA และประสบการณ์ของเราเยอะมาก ในตัวอย่างด้านล่าง เรากำหนด k=3 เพราะเรารู้ว่า iris species มีสามพันธุ์ – setosa, versicolor และ virginica
## load dataset
data("iris")
head(iris)
## prepare dataset
actual_class <- iris[, 5]
train_data <- iris[, 1:4]
## train kmeans
set.seed(99)
km_result <- kmeans(train_data, centers = 3)
km_result$cluster
## cluster accuracy
table(km_result$cluster, actual_class)
K-Nearest Neighbors
อีกหนึ่ง algorithm ที่ใช้ Euclidean distance สำหรับทำ prediction คือ k-NN โค้ดด้านล่างเราแบ่งข้อมูล iris ออกเป็นสองส่วนคือ train 80% และ test 20% และเทรนโมเดลด้วยฟังชั่น class::knn()
กำหนด k=5

หลักการทำงานของ k-NN ก็ง่ายมาก เราเลือกจำนวน k หรือเพื่อนบ้านที่อยู่ใกล้กับจุด X มากที่สุดเพื่อใช้ทำนายผล ในรูปด้านบนเรากำหนด k=5 เป็นสีดำ 3/5 = 60% สีเหลือง 2/5 = 40% เราจะทำนายว่า X เป็นสีดำยึดตามเสียงข้างมาก i.e. ภาษาอังกฤษเรียกว่า Majority Vote เสร็จแล้ว ทำไมมันง่ายอย่างนี้!
## split data into train/ test
set.seed(99)
n <- nrow(iris)
id <- sample(1:n, size = 0.8*n)
iris_train <- iris[id, ]
iris_test <- iris[-id, ]
nrow(iris_train); nrow(iris_test)
## prepare data
iris_train_x <- iris_train[, 1:4]
iris_train_y <- iris_train[, 5]
iris_test_x <- iris_test[, 1:4]
iris_test_y <- iris_test[, 5]
## train knn model
library(class)
set.seed(99)
knn_fit <- knn(iris_train_x, iris_test_x, iris_train_y, k = 5)
## prediction accuracy 96.67%
table(knn_fit, iris_test_y)
สรุปว่า k-means และ k-NN เป็น machine learning algorithms ตัวหลักๆที่ใช้การวัดระยะแบบ Euclidean distance เพื่อทำ segment และ prediction ตามลำดับ ฝั่ง data science ยังมี distance metric อีกหลายแบบ เช่น Manhattan, Minkowski, Cosine หรือ Jaccard ขึ้นอยู่กับประเภทของข้อมูลที่เรากำลังวิเคราะห์อยู่
Key Learning
- เลขที่ใช้ใน machine learning หลายๆตัวไม่ยากอย่างที่หลายคนคิด อย่าง Euclidean distance ใช้แค่เลขประถม ไม่ต้องจบ pure math ก็ทำได้ แหม่!!
- k-means ใช้ทำ segment ส่วน knn ใช้ทำ prediction ได้ทั้งปัญหา regression และ classification
- ถ้าไม่หัดเขียนโปรแกรม R หรือ Python แล้วเราจะทำ machine learning คูลๆได้ยังไง 😛