Tag: kmeans

  • วิธีจัดกลุ่มข้อมูลด้วย k-means ผ่าน kmeans() function ในภาษา R — ตัวอย่างการจัดกลุ่มหินจาก rock dataset

    วิธีจัดกลุ่มข้อมูลด้วย k-means ผ่าน kmeans() function ในภาษา R — ตัวอย่างการจัดกลุ่มหินจาก rock dataset

    ในบทความนี้ เราจะมาทำความรู้จักกับ k-means และวิธีใช้ kmeans() ในภาษา R กัน


    1. 👉 Introduction to k-Means
      1. 🤔 k-Means คืออะไร?
      2. 🪜 Steps การทำงานของ k-Means
      3. 🏫 Learn More
    2. 💻 k-Means ในภาษา R: kmeans()
    3. 🔢 Dataset
      1. 🪨 rock
      2. 📏 Data Normalisation
      3. 🔎 Finding the Optimal k
    4. ⏹️ k-Means
      1. 🔥 Train the Model
      2. 🤓 Get the Results
    5. 😺 GitHub
    6. 📃 References
    7. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    👉 Introduction to k-Means

    .

    🤔 k-Means คืออะไร?

    k-means เป็น machine learning algorithm ประเภท unsupervised learning และใช้จัดกลุ่ม data (clustering) ที่เราไม่รู้จำนวนกลุ่มล่วงหน้า

    ตัวอย่างการใช้ k-means ในโลกจริง:

    • Customer segmentation: จัดกลุ่มลูกค้าที่เข้ามาซื้อสินค้า/บริการ
    • Anomaly detection: ตรวจจับความผิดปกติในคอมพิวเตอร์ (แบ่งกลุ่มกิจกรรมในคอมพิวเตอร์ เป็น “ปกติ” และ “ไม่ปกติ”)
    • Document clustering: จัดกลุ่มเอกสาร โดยอ้างอิงจากเนื้อหา

    .

    🪜 Steps การทำงานของ k-Means

    k-means มีการทำงานอยู่ 5 ขั้นตอน ได้แก่:

    1. กำหนดจำนวนกลุ่ม หรือ clusters (k)
    2. สุ่มวาง centroid หรือจุดศูนย์กลางของ cluster ลงในข้อมูล
    3. จัดกลุ่มข้อมูล โดยข้อมูลจะอยู่กลุ่มเดียวกับ centroid ที่ใกล้ที่สุด
    4. คำนวณหา centroid ใหม่
    5. ทำขั้นที่ 3 และ 4 ซ้ำ ตามจำนวนครั้งที่กำหนด หรือจนกว่าข้อมูลจะไม่เปลี่ยนกลุ่ม

    ตัวอย่างเช่น เราต้องการจัดกลุ่มข้อมูล 100 ตัวอย่าง:

    ขั้นที่ 1. เรากำหนด k เช่น ให้ k = 3

    ขั้นที่ 2. สุ่มวาง centroid (ดอกจันสีแดง) ลงในข้อมูล:

    ขั้นที่ 3. จัดข้อมูลให้อยู่กลุ่มเดียวกัน โดยอิงจาก centroid ที่อยู่ใกล้ที่สุด:

    ขั้นที่ 4. คำนวณหา centroids ใหม่:

    จะสังเกตเห็นว่า centroids ของเราเปลี่ยนไป

    ขั้นที่ 5. ทำขั้นที่ 3 และ 4 ซ้ำ ๆ ไปเรื่อย ๆ เช่น ทำไป 10 ครั้ง:

    เราก็จะได้การจัดกลุ่มข้อมูลมา

    .

    🏫 Learn More

    เรียนรู้เพิ่มเติมเกี่ยวกับ k-means ได้จากคอร์ส The Nuts and Bolts of Machine Learning จาก Google Career Certificates (เริ่มต้นที่ 1:33:49)


    💻 k-Means ในภาษา R: kmeans()

    ในภาษา R เราสามารถใช้ k-means ได้ผ่าน kmeans() function ซึ่งต้องการ 3 arguments หลัก ดังนี้:

    kmeans(x, centers, nstart)
    • x = dataset ที่ต้องการจัดกลุ่ม
    • centers = จำนวนกลุ่มข้อมูล หรือ k
    • nstart = จำนวนครั้งที่ k-means จะสุ่มวาง centroids ลงใน dataset เพื่อหาการจัดกลุ่มที่ดีที่สุด

    (Note: ศึกษา arguments เพิ่มเติมของ kmeans() ได้ที่ kmeans: K-Means Clustering)

    เราไปดูวิธีใช้งาน kmeans() กัน


    🔢 Dataset

    .

    🪨 rock

    ในบทความนี้ เราจะใช้ rock dataset ซึ่งเป็น built-in dataset ในภาษา R เป็นตัวอย่าง

    rock มีข้อมูลหิน 48 ตัวอย่าง และมีข้อมูลลักษณะ 4 อย่าง:

    ลำดับลักษณะคำอธิบาย
    1areaพื้นที่ผิว
    2periเส้นผ่านศูนย์กลาง
    3shapeขนาด (เส้นผ่านศูนย์กลาง หารด้วย พื้นที่ผิว)
    4permระดับความสามารถที่ให้น้ำซึมผ่านได้

    เป้าหมายของเรา คือ จัดกลุ่มหิน 48 ตัวอย่างตามลักษณะทั้งสี่

    เราสามารถโหลด rock dataset ได้โดยใช้ data() function:

    # Load
    data(rock)
    

    หลังจากโหลดแล้ว เราสามารถ preview ข้อมูลได้ด้วย head():

    # Preview the dataset
    head(rock)
    

    ผลลัพธ์:

      area    peri     shape perm
    1 4990 2791.90 0.0903296  6.3
    2 7002 3892.60 0.1486220  6.3
    3 7558 3930.66 0.1833120  6.3
    4 7352 3869.32 0.1170630  6.3
    5 7943 3948.54 0.1224170 17.1
    6 7979 4010.15 0.1670450 17.1
    

    .

    📏 Data Normalisation

    เนื่องจาก k-means ใช้ระยะห่างระหว่างข้อมูลในการจัดกลุ่ม ข้อมูลที่มีระยะห่างมาก (เช่น ระยะห่าง 500 เมตร กับ 1,000 เมตร) อาจมีผลต่อการจัดกลุ่มมากกว่าข้อมูลที่มีระยะห่างน้อย (เช่น ระยะห่าง 1 ซม. กับ 5 ซม.) และทำให้เกิด bias ในการจัดกลุ่มได้

    เพื่อป้องกัน bias เราควร normalise ข้อมูล หรือการปรับให้ข้อมูลอยู่ใน scale เดียวกัน

    สำหรับ k-means เรามักจะ normalise ข้อมูล ด้วย z-score standardisation ซึ่งมีสูตรการคำนวณดังนี้:

    Z = (X - M(X)) / SD(X)
    • Z = ข้อมูลที่ scaled แล้ว
    • X = ข้อมูลดิบ
    • M(X) = mean ของ X
    • SD(X) = SD ของ X

    ในภาษา R เราสามารถทำ z-score standardisation ได้ด้วย scale():

    # Scale
    rock_scaled <- scale(rock)
    

    Note: เราใส่ rock ไปใน argument และเก็บผลลัพธ์ไว้ใน data frame ใหม่ ชื่อ rock_scaled

    เราสามารถเช็กผลลัพธ์ได้ด้วย:

    • colMeans() เพื่อเช็ก mean
    • apply() และ sd() เพื่อเช็ก SD
    # Check the results
    
    ## Check mean
    round(colMeans(rock_scaled), 2)
    
    # Check SD
    apply(rock_scaled, 2, sd)
    

    ผลลัพธ์:

    > ### Check mean
    > round(colMeans(rock_scaled), 2)
     area  peri shape  perm 
        0     0     0     0 
    > 
    > ### Check SD
    > apply(rock_scaled, 2, sd)
     area  peri shape  perm 
        1     1     1     1 
    

    จากผลลัพธ์ เราจะเห็นได้ว่า ทุกลักษณะมี mean เท่ากับ 0 และ SD เท่ากับ 1 แสดงว่า เราทำ z-score standardisation ได้สำเร็จ และพร้อมไปขั้นตอนถัดไป

    .

    🔎 Finding the Optimal k

    ในการจัดกลุ่มด้วย k-means เราต้องเริ่มด้วยการกำหนด k

    แต่เราจะรู้ได้ยังไงว่า k ควรมีค่าเท่าไร?

    เรามี 3 วิธีในการหาค่า k ที่ดีที่สุด (optimal k):

    1. Elbow method
    2. Silhouette analysis
    3. Gap analysis

    ในบทความนี้ เราจะมาใช้วิธีแรกกัน: elbow method

    (Note: เรียนรู้เกี่ยวทั้งสามวิธีได้ที่ ML | Determine the optimal value of K in K-Means Clustering)

    Elbow method หาค่า k ที่ดีที่สุด โดยสร้างกราฟระหว่างค่า k และ within-cluster sum of squares (WSS) หรือระยะห่างระหว่างข้อมูลในกลุ่ม ค่า k ที่ดีที่สุด คือ ค่า k ที่ WSS เริ่มไม่ลดลง

    ในภาษา R เราสามารถเริ่มสร้างกราฟได้ โดยเริ่มจากใช้ for loop หา WSS สำหรับช่วงค่า k ที่เราต้องการ

    ในตัวอย่าง rock dataset เราจะใช้ช่วงค่า k ระหว่าง 1 ถึง 15:

    # Initialise a vector for within cluster sum of squares (wss)
    wss <- numeric(15)
    
    # For-loop through the wss
    for (k in 1:15) {
      
      ## Try the k
      km <- kmeans(rock_scaled,
                   centers = k,
                   nstart = 20)
      
      ## Get WSS for the k
      wss[k] <- km$tot.withinss
    }
    

    จากนั้น ใช้ plot() สร้างกราฟความสัมพันธ์ระหว่างค่า k และ WSS:

    # Plot the wss
    plot(1:15,
         wss,
         type = "b",
         main = "The Number of Clusters vs WSS",
         xlab = "Number of Clusters",
         ylab = "WSS")
    

    ผลลัพธ์:

    จากกราฟ จะเห็นว่า WSS เริ่มชะลอตัว เมื่อค่า k อยู่ที่ 3 และ 4 ซึ่งเป็นจุดที่เป็นข้อศอก (elbow) ของกราฟ:

    แสดงว่า optimal k มีค่า 3 หรือ 4

    สำหรับบทความนี้ เราจะกำหนด optimal k = 4:

    # Set optiomal k = 4
    opt_k <- 4
    

    ⏹️ k-Means

    🔥 Train the Model

    หลังเตรียมข้อมูลและหา optimal k แล้ว เราก็พร้อมที่จะใช้ kmeans() ในการจัดกลุ่มข้อมูลแล้ว:

    # Set see for reproducibility
    set.seed(100)
    
    # Train the model
    km <- kmeans(rock_scaled,
                 centers = opt_k,
                 nstart = 20)
    

    .

    🤓 Get the Results

    เราสามารถดูผลการจัดกลุ่มได้ 2 วิธี:

    วิธีที่ 1. ดูค่าทางสถิติ:

    # Print the model
    print(km)
    

    ผลลัพธ์:

    K-means clustering with 4 clusters of sizes 10, 18, 6, 14
    
    Cluster means:
            area       peri
    1 -0.4406840 -0.9164442
    2  0.3496197  0.8022501
    3  1.5646450  1.3101981
    4 -0.8052989 -0.9383748
           shape       perm
    1  1.5369800  1.1775435
    2 -0.7319607 -0.8017914
    3  0.2358392 -0.7425075
    4 -0.2578245  0.5079897
    
    Clustering vector:
     [1] 2 2 2 2 2 2 2 2 2 2 2 2 3
    [14] 2 2 2 3 3 3 2 2 3 3 2 1 4
    [27] 4 4 4 1 1 1 4 1 4 1 4 1 4
    [40] 4 1 4 1 1 4 4 4 4
    
    Within cluster sum of squares by cluster:
    [1] 18.917267  8.104718
    [3]  1.471788 22.095636
     (between_SS / total_SS =  73.1 %)
    
    Available components:
    
    [1] "cluster"     
    [2] "centers"     
    [3] "totss"       
    [4] "withinss"    
    [5] "tot.withinss"
    [6] "betweenss"   
    [7] "size"        
    [8] "iter"        
    [9] "ifault"
    

    จากผลลัพธ์ จะเห็นได้ว่า ข้อมูลถูกแบ่งเป็น 4 กลุ่ม และเราสามารถดูค่า mean และ WSS ของแต่ละกลุ่มได้

    .

    วิธีที่ 2. สร้างกราฟ:

    # Create a plot
    plot(rock_scaled[, c("shape", "perm")], 
         col = km$cluster,
         pch = 19,
         main = "K-Means Clustering (Rock Dataset)",
         xlab = "Shape",
         ylab = "Permeability")
    
    # Add cluster centers
    points(km$centers[, c("shape", "perm")], 
           col = 1:5,
           pch = 4,
           cex = 2,
           lwd = 2)
    

    ผลลัพธ์:

    ตอนนี้ เราก็ได้ข้อมูลที่จัดกลุ่มด้วย k-means เรียบร้อยแล้ว 👍


    😺 GitHub

    ดู code ทั้งหมดในบทความนี้ได้ที่ GitHub


    📃 References


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb: