DEV Community

Natthaya
Natthaya

Posted on

จัดกลุ่มข้อมูลด้วย K-Means โดยใช้ Python

หากการจัดกลุ่มให้กับชุดข้อมูลที่มีจำนวนมาก และไม่ได้ผ่านการจัดกลุ่มมาก่อนเลย เป็นเพียงข้อมูลดิบที่จัดเรียงกันอย่างไม่มีหลักการ เป็นการจัดกลุ่มที่ยากและต้องใช้เวลาอย่างมาก หนึ่งในวิธีที่เหมาะสมกับการนำมาใช้คือ การจัดกลุ่มด้วย K-Means

ในบทความนี้จะมาศึกษาการใช้ K-means ด้วย Python และจะทำการรันโค้ดใน Google Colab โดย Dataset ที่เราจะใช้คือ Wine Dataset for Clustering ที่นำมาจาก UC Irvine Machine Learning Repository

ข้อมูลเหล่านี้เป็นผลลัพธ์ของการวิเคราะห์ทางเคมีของไวน์ที่ปลูกในภูมิภาคเดียวกันในอิตาลี เป็นปริมาณของส่วนประกอบ 13 ชนิดที่พบในไวน์แต่ละประเภท จากสามประเภท
ข้อมูลประกอบด้วย

  1. Alcohol
  2. Malic acid
  3. Ash
  4. Alcalinity of ash
  5. Magnesium
  6. Total phenols
  7. Flavanoids
  8. Nonflavanoid phenols
  9. Proanthocyanins
  10. Color intensity
  11. Hue
  12. OD280/OD315 of diluted wines
  13. Proline

ขั้นตอนที่ 1 : โหลดชุดข้อมูล และศึกษารายละเอียดของชุดข้อมูล

Import Library ที่จำเป็นต้องใช้

import math
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from sklearn.cluster import KMeans 
from kneed import KneeLocator
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
Enter fullscreen mode Exit fullscreen mode
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
Enter fullscreen mode Exit fullscreen mode

โหลดชุดข้อมูลตัวอย่าง

wine_df = pd.read_csv("/kaggle/input/wine-dataset-for-clustering/wine-clustering.csv", )
wine_df
Enter fullscreen mode Exit fullscreen mode

ชุดข้อมูลที่ได้

Image description

ขั้นตอนที่ 2 : เริ่มต้นการใช้ K-Means

ทำให้ชุดข้อมูลเป็นมาตรฐาน

sc = StandardScaler()
wine_df_sc = sc.fit_transform(wine_df)
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 3 : วิเคราะห์หาจำนวนกลุ่มที่เหมาะสมด้วยหลักการ Elbow

WSS = []

for i in range (1,15):
    kmeans = KMeans(n_clusters=i, n_init=10)
    kmeans.fit(wine_df_sc)
    WSS.append(kmeans.inertia_)

kl = KneeLocator(range(1, 15), WSS, curve="convex", direction="decreasing")
optimal_k = kl.elbow
print("Optimal number of clusters: ", optimal_k)
plt.figure(figsize=(10,6))
plt.title("Elbow Analysis", fontsize=18)
sns.lineplot(x=list(range(1,15)), y=WSS, color="blue", marker="o", markersize=16)
plt.xlabel("Number of clusters")
plt.ylabel("WSS")
plt.vlines(optimal_k, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')
plt.show()
Enter fullscreen mode Exit fullscreen mode

จุดของกราฟที่หักมากที่สุดเหมือนข้อศอก จะเป็นจุดที่บ่งบอกจำนวนของกลุ่มที่เหมาะสม จากภาพจะเป็นจำนวน 3 กลุ่ม

Image description

ขั้นตอนที่ 4 : ตรวจสอบ และยืนยันจำนวนกลุ่มที่เหมาะสมด้วยหลักการ Silhouette

silhouette = []

for i in range(2,15):
    kmeans = KMeans(n_clusters=i, n_init=10)
    cluster_labels = kmeans.fit_predict(wine_df_sc)
    silhouette.append(silhouette_score(wine_df_sc,cluster_labels))   

plt.figure(figsize=(10,6))
plt.title("Silhouette Analysis", fontsize=18)
sns.lineplot(x=list(range(2,15)), y=silhouette, color="green", marker="o", markersize=16)
plt.xlabel("Number of clusters")
plt.ylabel("Silhouette Score")
plt.show()
Enter fullscreen mode Exit fullscreen mode
print("Best Silhouette Clustering is : ", max(silhouette), "with ", silhouette.index(max(silhouette))+2)
Enter fullscreen mode Exit fullscreen mode

จะได้ภาพกราฟ พร้อมกับคำตอบว่าจำนวนกลุ่มที่เหมาะคือ 3

Image description

Image description

ขั้นตอนที่ 5 : ใช้วิธี K-Means

กำหนดจำนวนกลุ่มที่เหมาะสมเป็น 3 กลุ่มที่ได้วิเคราะห์ไว้ จะได้ข้อมูลที่ถูกแบ่งเป็น 3 กลุ่มเรียบร้อยแล้ว

kmeans = KMeans(n_clusters=3, n_init=10, random_state=51)
kmeans.fit(wine_df_sc)
wine_df['Cluster']=kmeans.labels_
Enter fullscreen mode Exit fullscreen mode
wine_df.groupby('Cluster').describe(percentiles=[])
Enter fullscreen mode Exit fullscreen mode

(เนื่องจากภาพยาวเกินไปจึงตัดเป็น 2 ภาพ)

Image description

Image description

ขั้นตอนที่ 6 : แสดงผล

แสดงภาพผลลัพธ์

from sklearn.decomposition import PCA

data=wine_df.drop("Cluster",axis=1).values
data_sc=sc.fit_transform(data)
pca=PCA(n_components=2)
principal_components = pca.fit_transform(data_sc)
df_pca = pd.DataFrame(principal_components, columns=['PC1', 'PC2'])
df_pca['Cluster']=wine_df['Cluster']

plt.figure(figsize=(10, 7))  
plt.title('Clustering Results using PCA', fontsize=18)
sns.scatterplot(data=df_pca, x='PC1', y='PC2', hue="Cluster", palette="magma", s=100)
plt.grid()
plt.show()
Enter fullscreen mode Exit fullscreen mode

Image description

แสดงข้อมูล

cluster_means=wine_df.groupby('Cluster').mean()
cluster_means
Enter fullscreen mode Exit fullscreen mode

(เนื่องจากภาพยาวเกินไปจึงตัดเป็น 2 ภาพ)

Image description

Image description

สรุปผล

จากการนำข้อมูลปริมาณส่วนประกอบของไวน์ต่าง ๆ มาจัดกลุ่มด้วยวิธี K-means จะสามารถแบ่งออกได้เป็น 3 กลุ่ม ดังนี้
กลุ่มที่ 0 เป็นกลุ่มไวน์ที่มี Magnesium และ Proline ในปริมาณที่สูง
กลุ่มที่ 1 เป็นกลุ่มไวน์ที่มีค่า Flavanoid และ Hue ต่ำ แต่มี Color Intensity สูง
กลุ่มที่ 2 เป็นกลุ่มไวน์ที่มี Magnesium และ Color Intensity ต่ำ

🎉

Top comments (0)