Metrik Statistik Penting pada Algoritma Clustering K-Means
Tentang Materi
Metrik Statistik Penting pada Algoritma Clustering K-Means
Tentang Materi
Dengan menyelesaikan module ini, kamu akan memahami apa itu centroids, stabilisasi nilai centroid, iterasi yang diperlukan, memahami dan dapat menggunakan metode penentuan nilai K yang sesuai, seperti Elbow method, mengetahui cost function yang digunakan adalah WSSE with euclidian distance.
I. Clustering K-Means
Langkah-Langkah yang Dilakukan Dalam Algoritma K-Means
K-Means clustering merupakan salah satu algoritma clustering yang sederhana dan sering digunakan. Sesuai namanya, algoritma ini membagi data ke dalam k cluster dan setiap data akan menjadi anggota cluster terdekat.
Langkah-langkah yang dilakukan dalam algoritma ini, sebagai berikut:
- Menentukan jumlah *cluster *k.
- Inisialisasi nilai centroid secara random. Centroid merupakan nilai pusat (center) dari sebuah cluster. Apabila kita mengatur k=3, maka akan terbentuk centroid C1, C2, dan C3 secara random.
- Menetapkan setiap data point ke centroid terdekat. Pada bagian ini, terdapat proses menghitung jarak setiap data dengan centroid yang tadi sudah dibuat. Perhitungan jarak dilakukan Senja dengan menggunakan Euclidean distance.
- Menghitung ulang nilai centroid dari cluster yang baru terbentuk. Proses ini Senja lakukan dengan menghitung nilai mean dari setiap data points di dalam cluster tersebut.
- Mengulang langkah ketiga dan keempat untuk mengoptimisasi posisi dari centroid sampai kriteria berhenti terpenuhi.
Poin-poin di bawah ini yang merupakan kriteria berhenti dalam algoritma K-Means clustering:
- Nilai centroid sudah tidak berubah.
- Data point tetap berada pada cluster yang sama.
- Jumlah iterasi maksimum telah tercapai.
Menginisialisasi Centroid
“Senja, mau tanya. Apakah algoritma K-Means clustering ini selalu memberikan hasil yang baik?” tanyaku penasaran setelah penjabaran yang diberikannya tadi.
“Pada kasus tertentu, jika inisialisasi awal posisi centroid tidak sesuai, algoritma K-Means Clustering dapat menghasilkan cluster yang buruk.” jawab Senja.
“Dan jika dalam data terdapat nilai k yang masih tergolong rendah, kita dapat menjalankan algoritma K-Means beberapa kali dengan nilai centroid yang berbeda. Kemudian, memilih hasil yang terbaik. Namun seiring nilai k meningkat, perlu berhati-hati dalam memilih nilai awal centroid.” lanjut Senja.
Pada kasus tertentu, jika inisialisasi awal posisi centroid tidak sesuai, algoritma K-Means Clustering dapat menghasilkan cluster yang buruk. Untuk nilai k yang masih tergolong rendah, kita dapat menjalankan algoritma k-means beberapa kali dengan nilai centroid yang berbeda, kemudian memilih hasil yang terbaik. Namun seiring nilai k meningkat, kita perlu berhati-hati dalam memilih nilai awal centroid.
“By the way, udah pernah menggunakan modul K-Means dari library scikit-learn, belum?” tanya Senja.
Aku menggeleng.
“Jika menggunakan modul KMeans dari library scikit-learn, disana tersedia beberapa cara yang dapat dipilih untuk menginisialisasi centroid. Kita dapat menambahkan metode inisialisasi dengan menggunakan parameter init dan menuliskan metode yang dipilih.” papar Senja.
Senja menunjukan metode yang umumnya digunakan, antara lain:
Apabila kita menggunakan modul KMeans dari library scikit-learn, tersedia beberapa cara yang dapat dipilih untuk menginisialisasi centroid. Kita dapat menambahkan metode inisialisasi dengan menggunakan parameter init dan menuliskan metode yang dipilih. Metode yang umumnya digunakan antara lain:
- Random
Pada pilihan random, posisi awal centroid akan ditentukan secara acak.
- K-means++
Pada pilihan K-means++, centroid umumnya diinisialisasi dengan posisi yang jauh dari satu sama lain (umumnya). Hal ini menyebabkan adanya kemungkinan pilihan ini lebih baik dibandingkan random.
Apabila kita tidak menuliskan parameter ini, maka inisialisasi yang akan digunakan adalah K-means++.
Inisialisasi Menggunakan Metode K-Means — Part 1
Selanjutnya, Senja menunjukkan langkah-langkah inisialisasi centroid menggunakan K-means++, antara lain:
- Memilih satu centroid secara acak.
- Menghitung jarak setiap data point dengan centroid yang baru saja dibuat.
- Memilih data point dengan jarak terjauh dan menjadikannya centroid.
- Mengulangi langkah kedua dan ketiga sampai sejumlah k centroid telah terbentuk.
“Supaya lebih mudah dipahami, coba lihat gambar di bawah ini.” Senja menampilkan menunjukan gambar K-Means++ dari layar laptop.

Aku memperhatikan gambar yang ditampilkan Senja.
“Misalnya terdapat data dengan sebaran seperti gambar di atas. Posisi centroid kemudian akan dipilih dari data yang ada secara acak. Coba sekarang perhatikan gambar di bawah.” kata Senja.

Aku mengikuti arahan Senja dan fokus memperhatikan gambar yang ada dan menemukan perbedaan pada gambar kedua. “Pada gambar di atas, centroid yang baru saja dipilih berwarna hijau.” responsku.
Inisialisasi Menggunakan Metode K-Means — Part 2

“Selanjutnya pada gambar di bawah ini, bisa dilihat setelah satu centroid terpilih, maka dilakukan perhitungan jarak dari centroid ke setiap data yang ada.” sambung Senja.
Gambar selanjutnya pun ditampilkan Senja seperti di bawah ini.

Setelah aku perhatikan, aku melihat sebuah lingkaran berwarna merah yang baru muncul saat ini.
“Lingkaran yang berwarna merah itu apa, ya?” tanyaku. “Itu adalah centroid baru yang terpilih karena merupakan data dengan jarak paling besar.” jawab Senja.
Senja menggeser layar, memunculkan gambar selanjutnya.

“Kemudian, proses kedua dan ketiga diulangi kembali sampai k centroid terbentuk,” kata Senja.
“Senja, pada gambar di bawah ini, centroid ketiga didapatkan darimana, ya?” tanyaku. “Itu didapatkan dari menghitung jarak setiap data kedua centroid yang baru saja dibuat.” jawab Senja.
“Berarti yang ditandai warna biru itu adalah centroid baru, ya?” Aku mencoba memastikan. “Betul!”

II. Menentukan Jumlah Cluster yang Sesuai
Dua Metode Umum Untuk Menentukan Jumlah Cluster
“Tau gak, ada suatu misteri yang harus kita pecahkan setelah ini,” kata Senja dengan nada serius. Seniorku satu itu sengaja menggantung ucapannya sehingga membuatku makin penasaran. Apakah ada teka-teki yang perlu dipecahkan terkait clustering ini? Aku mulai bertanya-tanya.
“Misteri? Kok jadi serem? Ada apa sih?” sahutku ingin tahu.
“Misterinya adalah menentukan jumlah cluster k pada K-Means!” balas Senja.
Senja pun menunjukkan dua metode umum yang digunakan untuk menentukan nilai k, yaitu:
- Elbow Method.
- Silhouette Method.
Elbow Method
Senja kembali memulai penjelasannya, “Metode yang pertama ada elbow method. Metode ini paling dikenal untuk menentukan jumlah cluster yang optimal. Metode ini menghitung nilai Within-Cluster-Sum of Squared Error (WSS) untuk setiap nilai k.”
Senja telah membuat poin-poin yang menjelaskan Elbow method sebagai berikut:
- Menghitung nilai Squared Error. Squared Error merupakan jarak dari suatu point dengan centroid-nya (cluster center).
- Menghitung inertia atau WSS merupakan total dari nilai squared error seluruh data point.
- Membuat plot WSS-vs-k dalam bentuk grafik.
- Memilih k ketika plot menyerupai siku (elbow).
Rumus Within-Cluster-Sum of Squared Error (WSS) di bawah ini tak lupa dituliskan Senja untukku.

Aku membaca semua poin-poin dan rumus dengan saksama.
“Senja, aku mengerti. Jadi WSS adalah jumlah total jarak (d) antara titik x ke centroid-nya yang dikuadratkan dari seluruh cluster,” kataku.
“Betul! Wah, kamu cepat mengerti juga. Kalau begitu, coba lihat gambar di bawah ini yang merupakan contoh plot WSS-vs-k.” balas Senja.
Contoh plot WSS-vs-k yang dimaksud Senja:

“Dapat dilihat nilai WSS berubah-ubah untuk setiap k. Pada kasus ini, plot terlihat seperti siku pada k=3.” jelas Senja. Setelah melihat gambar yang ada sambil mendengarkan Senja, muncul satu pertanyaan di pikiranku.
“Kalau model yang baik biasanya seperti apa, Nja?” tanyaku..
“Model yang baik biasanya memiliki nilai inertia atau WSS yang rendah dan jumlah *cluster k yang rendah. Namun, ini seperti tradeoff karena semakin banyak jumlah cluster-nya, maka nilai inertia* juga akan semakin rendah.” jawab Senja mantap.
Memang enggak salah aku berguru dengan seniorku satu ini. Semua yang diajarkannya mudah dipahami! Aku pun mengangguk.
Silhouette Method
“Elbow method tadi kan metode pertama, metode keduanya apa?” tanyaku.
“Metode kedua adalah silhouette method. Metode ini mengukur tingkat kemiripan suatu point dengan clusternya (kohesi) dibandingkan dengan cluster lain (separasi).” jawab Senja.
Nilai silhouette memiliki rentang dari -1 sampai +1. Senja menjelaskan jika semakin mendekati angka 1 artinya suatu data point berada pada cluster yang benar. Sementara apabila suatu data point memiliki nilai yang negatif, maka dapat dikatakan Senja memiliki terlalu banyak atau terlalu sedikit cluster.
Sambil mendengarkan penjelasan Senja, aku membaca langkah-langkah mencari silhouette score:
- Menghitung a(i) : rata-rata jarak dari suatu point ke poin-poin lainnya di cluster yang sama.
- Menghitung b(i) : rata-rata jarak dari suatu point ke poin poin dari cluster lain yang paling dekat dengan clusternya.
- Menghitung s(i) : silhouette coefficient dari poin i.

Menghitung rata-rata dari s(i) untuk mendapatkan silhouette score.

Setelah memahami rumus dan langkah-langkah di atas, aku mencoba mengerjakan soal yang diberikan Senja untuk mengukur kemampuanku. Dag dig dug! Namun, kuyakin pasti bisa!
III. Pengolahan dan Transformasi Data
Membaca Dataset
Fiuh, syukurlah aku bisa mengerjakan soal ujian dengan baik. Jadi aku bisa lanjut belajar! Setelah mempelajari teori-teori terkait K-Means clustering dibantu Senja, tiba saatnya aku segera melaksanakan proses pengolahan data.
“Gak istirahat dulu?” tanya Senja sambil mengecek jam.
“Aku lanjut deh soalnya sudah janji untuk cepat menyelesaikan proses ini,” jawabku mengingat tanggung jawabku pada Aksara.
Senja pamit untuk istirahat dulu dan tak lupa menyemangatiku sebelum ke luar ruangan. “Semangat memproses pengolahan datanya. Pasti bisa!” Dengan semangat, aku memulai dengan memuat kembali dataset ke program Python serta mengolah datanya sesuai kebutuhan.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
print(data.head(10))
Output
customer_id frequency recency monetary
0 12346 1 48 27904840000
1 12347 2 40 423420000
2 12348 2 41 414092000
3 12350 1 33 119478000
4 12352 3 6 449984000
5 12356 1 48 809968000
6 12359 2 28 842749000
7 12361 1 10 67602000
8 12362 1 18 170512000
9 12365 2 14 226652000
Melihat Dimensi Dataframe
Aku menggunakan syntax **data.shape** untuk melihat dimensi dataframe.
#Melihat dimensi dataframe
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
print(data.shape)
Output
(1625, 4)
Melihat Tipe Data Dari Setiap Kolom
Untuk melihat tipe data dari setiap kolom, aku dapat menggunakan syntax **data.info()**. Aku menuliskan potongan kode berikut:
#Melihat tipe data dari setiap kolom
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
data.info()
Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1625 entries, 0 to 1624
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 customer_id 1625 non-null int64
1 frequency 1625 non-null int64
2 recency 1625 non-null int64
3 monetary 1625 non-null int64
Melihat Statistik Dari Setiap Kolom
Aku menggunakan syntax **data.describe()** untuk melihat statistik untuk setiap kolom, dan menuliskan syntax berikut:
#Melihat statistik dari setiap kolom
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
print(data.describe())
Output
customer_id frequency recency monetary
count 1625.000000 1625.000000 1625.000000 1.625000e+03
mean 15261.415385 1.910769 36.455385 3.321584e+08
std 1745.556403 2.111145 26.934570 1.140958e+09
min 12346.000000 1.000000 1.000000 3.100000e+05
25% 13764.000000 1.000000 13.000000 7.520200e+07
50% 15221.000000 1.000000 32.000000 1.380670e+08
75% 16805.000000 2.000000 54.000000 2.902490e+08
max 18283.000000 34.000000 90.000000 2.790484e+10
Melakukan Pengecekan Data Null
Untuk melakukan pengecekan data null, aku menggunakan syntax data.isnull().any().any(). Aku menuliskan potongan kode berikut:
#Mengecek apakah ada data null
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
print(data.isnull().any().any())
Membuang Kolom customer_id
Aku membuang kolom customer_id karena kolom ini tidak relevan dalam proses clustering nantinya.
Berikut caraku membuang kolom tersebut.
#Menghapus kolom customer_id
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
RFM_km = data.drop(["customer_id"], axis=1)
print(RFM_km.head())
Output
frequency recency monetary
0 1 48 27904840000
1 2 40 423420000
2 2 41 414092000
3 1 33 119478000
4 3 6 449984000
Pengertian RFM
Aku berhasil menampilkan data Recency, Frequency, dan Monetary value (RFM) dari pelanggan pusat perbelanjaan ABC. Nilai ini banyak digunakan pada analisis customer relationship management untuk menganalisis konsumen.
Aku mengecek kembali pengertian RFM untuk mencegah adanya kesalahan melalui catatan yang diberikan Senja berikut ini:
Recency merupakan variabel untuk mengukur waktu terakhir konsumen melakukan transaksi, Frequency merupakan variabel untuk mengukur seberapa sering konsumen melakukan transaksi, Monetary merupakan variabel untuk mengukur jumlah transaksi dari setiap konsumen.
Sekembalinya dari istirahat, Senja memintaku untuk menampilkan data dalam bentuk boxplot.
Melihat Outliers pada Setiap Kolom
Sekembalinya dari istirahat, setelah itu, Senja memintaku untuk menampilkan data dalam bentuk boxplot.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Import library matplotlib.pyplot
import matplotlib.pyplot as plt
#Import library seaborn
import seaborn as sns
#Menampilkan boxplot data frequency, recency, dan monetary
fig, ax = plt.subplots(3, 1, figsize=(8,5))
sns.boxplot(RFM_km["frequency"], ax=ax[0])
sns.boxplot(RFM_km["recency"], ax=ax[1])
sns.boxplot(RFM_km["monetary"], ax=ax[2])
plt.tight_layout()
plt.show()
Output

Menggunakan RobustScaler()
Senja memperhatikan visualisasi data melalui box plot yang telah diperoleh.
“Hmm, berdasarkan hasil plot yang dilakukan, ada cukup banyaknya data outlier atau data pencilan. Aku sarankan untuk coba menggunakan ***RobustScaler()** karena scaler ini cukup baik dalam menghadapi data dengan outlier,”* kata Senja.
Aku pun menggunakan ***RobustScaler() dan menggunakan method `.fit_transform()`* **sesuai saran Senja.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Import library robust scaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library matplotlib.pyplot dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot data frequency, recency, dan monetary
fig, ax = plt.subplots(3, 1, figsize=(8,5))
sns.boxplot(RFM_robust["Frequency"], ax=ax[0])
sns.boxplot(RFM_robust["Recency"], ax=ax[1])
sns.boxplot(RFM_robust["Monetary"], ax=ax[2])
plt.tight_layout()
plt.show()
Output

IV. Penentuan Jumlah Cluster
Implementasi Elbow Method
Untuk mencari nilai k yang optimal, aku mencoba mengimplementasikan elbow method.
Aku membuat variable SSE untuk menampung nilai WSS dari setiap nilai k seperti berikut.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library Kmeans
from sklearn.cluster import KMeans
#Membuat variable SSE untuk menampung nilai WSS dari setiap nilai k
SSE = []
#Melakukan k-means berulang dengan nilai k yang berbeda-beda dari 2 sampai 10
for k in range(2, 10):
k_means = KMeans(n_clusters=k, random_state=0)
model = k_means.fit(RFM_robust)
SSE.append(k_means.inertia_)
#Mengkonversi hasil ke dalam data frame, kemudian menampilkannya dalam bentuk plot
import matplotlib.pyplot as plt
frame = pd.DataFrame({"Cluster":range(2,10), "SSE":SSE})
plt.figure(figsize=(8,5))
plt.plot(frame["Cluster"], frame["SSE"], marker="o")
plt.xlabel("Number of clusters")
plt.ylabel("Inertia")
plt.show()
Output

Analisa Hasil Clustering Elbow Method
Setelah selesai, aku pun melihat kembali visualisasi untuk variasi jumlah kluster berikut

“Kok seperti ini ya hasil plot-nya. Aku jadi kesulitan memahami nilai k yang tepat.” kataku pada Senja.
Mendengar kebingungan pada suaraku, Senja berinisiatif menghampiriku dan mencoba membantu, “Pada dasarnya kandidat pemilihan nilai k yang terbaik biasanya terdapat pada titik “Elbow” ketika nilai SSE mulai melandai membentuk siku tangan (pada kasus ini terlihat dibagian pada k=3). Namu kamu dapat mencoba nilai k=3 atau 4. Lalu, analisa hasil dari clustering-nya.”
Sunyi merasa kesulitan memahami nilai k yang tepat. Senja menyarankan untuk mencoba nilai k = 3 atau 4, kemudian menganalisa hasil dari clustering-nya.
Aku memilih nilai k=3 sesuai arahan Senja.
Clustering K-Means dengan 3 Cluster
Aku mengikuti saran Senja untuk menjalankan K-Means dengan k=3
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Import library robust scaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library Kmeans
from sklearn.cluster import KMeans
#Menjalankan k-means dengan nilai k = 3
k_means = KMeans(n_clusters=3, random_state=0)
k_means.fit(RFM_robust)
#pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan RFM dan hasil label clustering
RFM_labeled = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Menghitung jumlah data dari tiap cluster
print("Jumlah data dari tiap cluster:")
print(RFM_labeled["cluster"].value_counts())
Output
Jumlah data dari tiap cluster:
1 1598
0 23
2 4
Name: cluster, dtype: int64
Visualisasi Box Plot untuk 3 Cluster
Aku kemudian dapat menampilkan hasil clustering dengan k=3 cluster tadi melalui boxplot.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library Kmeans
from sklearn.cluster import KMeans
# menjalankan k-means dengan nilai k = 3
k_means = KMeans(n_clusters=3, random_state=0)
k_means.fit(RFM_robust)
#pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan RFM dan hasil label clustering
RFM_labeled = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Import library matplotlib dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot elbow method
fig, ax = plt.subplots(1, 3, figsize=(8,6))
sns.boxplot(x="cluster", y="frequency", data=RFM_labeled, ax=ax[0])
sns.boxplot(x="cluster", y="recency", data=RFM_labeled, ax=ax[1])
sns.boxplot(x="cluster", y="monetary", data=RFM_labeled, ax=ax[2])
plt.tight_layout()
plt.show()
Output

Visualisasi Box Plot untuk 3 Cluster
Aku kemudian dapat menampilkan hasil clustering dengan k=3 cluster tadi melalui boxplot.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library Kmeans
from sklearn.cluster import KMeans
# menjalankan k-means dengan nilai k = 3
k_means = KMeans(n_clusters=3, random_state=0)
k_means.fit(RFM_robust)
#pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan RFM dan hasil label clustering
RFM_labeled = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Import library matplotlib dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot elbow method
fig, ax = plt.subplots(1, 3, figsize=(8,6))
sns.boxplot(x="cluster", y="frequency", data=RFM_labeled, ax=ax[0])
sns.boxplot(x="cluster", y="recency", data=RFM_labeled, ax=ax[1])
sns.boxplot(x="cluster", y="monetary", data=RFM_labeled, ax=ax[2])
plt.tight_layout()
plt.show()
Output

Analisis Box Plot untuk 3 Cluster
Aku melihat hasil visualisasi yang telah diperoleh. Berdasarkan hasil boxplot di atas, aku menyimpulkan bahwa ketiga cluster ini jelas berbeda pada bagian monetary. Aku menjelaskan data yang ada pada Senja untuk memastikan pengertianku tidak salah.

“Cluster 1 total transaksinya rendah, sementara cluster 2 memiliki rentang monetary yang cukup besar dan nilai total transaksinya paling tinggi dibandingkan kedua cluster lainnya. Pada bagian recency, cluster 1 memiliki rentang yang sangat besar. Ketiga cluster ini sulit dibedakan pada bagian ini. Sementara pada bagian frekuensi transaksi, cluster 0 memiliki frekuensi transaksi lebih besar dibandingkan kedua cluster lainnya. Nilai frekuensi cluster 1 paling kecil, sehingga kita bisa menyimpulkan bahwa konsumen pada cluster 1 lebih jarang melakukan transaksi dibandingkan kedua cluster lainnya. Benar tidak pemahamanku?” tanyaku.
Implementasi Silhouette Method
Aku melanjutkan metode penentuan k dengan menggunakan silhouette method. Setelah mengingat materi tentang metode ini yang sudah dijelaskan Senja, aku mencoba nilai k dari 2 sampai 15.
Aku menuliskan potongan kode sebagai berikut.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import KMeans & silhouette_score
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#Melakukan k-means berkali-kali dengan nilai k yang berbeda-beda dari 2 sampai 15
silhouette = []
for k in range(2, 15):
k_means = KMeans(n_clusters=k, random_state=0)
model = k_means.fit(RFM_robust)
silhouette.append(silhouette_score(RFM_robust, model.labels_))
#Import library matplotlib
import matplotlib.pyplot as plt
#Mengkonversi hasil ke dalam data frame, kemudian menampilkannya dalam bentuk plot
frame = pd.DataFrame({"Cluster":range(2,15), "Silhouette Score":silhouette})
plt.figure(figsize=(8,5))
plt.plot(frame["Cluster"], frame["Silhouette Score"], marker="o")
plt.xlabel("Number of clusters")
plt.ylabel("Silhouette Score")
plt.show()
Output

Clustering K-Means dengan 4 Cluster
Berdasarkan plot yang dihasilkan, aku dapat memilih k dengan score tertinggi yaitu 2, tetapi ketika aku membandingkan dengan hasil dari elbow method, k=2 memiliki inertia yang tinggi. Sebelumnya, aku juga telah mencoba nilai k = 3.
Situasi ini memancing rasa ingin tahuku. Akhirnya, karena aku penasaran dengan hasil k=4, aku memutuskan untuk menggunakan nilai tersebut.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import KMeans & silhouette_score
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#Menjalankan k-means dengan nilai k = 4
k_means = KMeans(n_clusters=4, random_state=0)
k_means.fit(RFM_robust)
#Pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan dataframe data dan hasil label clustering
RFM_labeled = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Menghitung jumlah data dari tiap cluster
print("Jumlah data dari tiap cluster:")
print(RFM_labeled["cluster"].value_counts())
Output
Jumlah data dari tiap cluster:
0 1596
2 22
1 5
3 2
Name: cluster, dtype: int64
Visualisasi Box Plot untuk 4 Cluster
Aku kemudian dapat menampilkan kembali hasil clustering dengan k=4 cluster tadi melalui boxplot.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import KMeans & silhouette_score
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#Menjalankan k-means dengan nilai k = 4
k_means = KMeans(n_clusters=4, random_state=0)
k_means.fit(RFM_robust)
#Pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan dataframe data dan hasil label clustering
RFM_labeled = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Import library matplotlib dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot silhouette method
fig, ax = plt.subplots(1, 3, figsize=(8,6))
sns.boxplot(x="cluster", y="frequency", data=RFM_labeled, ax=ax[0])
sns.boxplot(x="cluster", y="recency", data=RFM_labeled, ax=ax[1])
sns.boxplot(x="cluster", y="monetary", data=RFM_labeled, ax=ax[2])
plt.tight_layout()
plt.show()
Output

Analisis Box Plot untuk 4 Cluster
Aku memperhatikan visualisasi boxplot yang kudapatkan untuk 4 cluster.

Berdasarkan itu, aku melihat perbedaan yang jelas dari setiap cluster pada bagian monetary dari tiap cluster. Cluster 0 nilai monetary-nya sangat rendah, sementara cluster 1 memiliki nilai monetary tertinggi. Cluster 2 merupakan kelompok dengan frekuensi transaksi yang paling banyak dibandingkan dengan cluster lainnya.
V. Mini Project
Mini Project #1
Mini Project yang diberikan Senja untukku adalah mengulang teknik elbow method dengan percobaan rentang k dari 3 sampai 15. Kemudian tampilkan juga hasil plot dari nilai WSS yang ditampung ke dalam variable bernama wss!
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library K-Means
from sklearn.cluster import KMeans
#Deklarasi variable wss
wss = []
#Melakukan k-means berkali-kali dengan nilai k yang berbeda-beda dari 3 sampai 15
for k in range(3, 15):
k_means = KMeans(n_clusters=k, random_state=0)
model = k_means.fit(RFM_robust)
wss.append(k_means.inertia_)
#Import library matplotlib.pyplot
import matplotlib.pyplot as plt
#Mengkonversi hasil ke dalam data frame, kemudian menampilkannya dalam bentuk plot
frame = pd.DataFrame({"Cluster":range(3,15), "WSS":wss})
plt.figure(figsize=(8,5))
plt.plot(frame["Cluster"], frame["WSS"], marker="o")
plt.xlabel("Number of clusters")
plt.ylabel("Inertia")
plt.show()
Berikut contoh visualisasinya:

Mini Project #2
Setelah melihat hasilnya, aku jadi penasaran dengan jumlah cluster k=5 sehingga aku mencoba membuat grafik boxplot untuk cluster k=5. Aku pasti bisa menyelesaikan tantangan ini!
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library K-Means
from sklearn.cluster import KMeans
#Menjalankan k-means dengan nilai k = 5
k_means = KMeans(n_clusters=5, random_state=0)
k_means.fit(RFM_robust)
#Pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan dataframe data dan hasil label clustering
RFM_k5 = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Import library matplotlib.pyplot dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot dari RFM_k5
fig, ax = plt.subplots(1, 3, figsize=(8,6))
sns.boxplot(x="cluster", y="recency", data=RFM_k5, ax=ax[0])
sns.boxplot(x="cluster", y="frequency", data=RFM_k5, ax=ax[1])
sns.boxplot(x="cluster", y="monetary", data=RFM_k5, ax=ax[2])
plt.tight_layout()
plt.show()
Berikut contoh tampilan visualisasinya.

Mini Project #3
Setelah hasil menggunakan k=5, terlihat, aku kembali ingin mencoba untuk k=6.
#Import library pandas
import pandas as pd
data = pd.read_csv("https://storage.googleapis.com/dqlab-dataset/RFM_customer.csv", encoding='utf8')
#Drop kolom customer_id
RFM_km = data.drop(["customer_id"], axis=1)
#Penerapan RobustScaler
from sklearn.preprocessing import RobustScaler
robust_scaler = RobustScaler()
RFM_robust = robust_scaler.fit_transform(RFM_km)
RFM_robust = pd.DataFrame(RFM_robust)
RFM_robust.columns = ["Frequency","Recency","Monetary"]
#Import library K-Means
from sklearn.cluster import KMeans
#Menjalankan k-means dengan nilai k = 6
k_means = KMeans(n_clusters=6, random_state=0)
k_means.fit(RFM_robust)
#Pred menyimpan hasil prediksi label cluster untuk setiap data
pred = k_means.predict(RFM_robust)
#Menggabungkan dataframe data dan hasil label clustering
RFM_k6 = pd.concat([data, pd.Series(pred).rename("cluster")], axis=1)
#Import library matplotlib.pyplot dan seaborn
import matplotlib.pyplot as plt
import seaborn as sns
#Menampilkan boxplot dari RFM_k6
fig, ax = plt.subplots(1, 3, figsize=(10,6))
sns.boxplot(x="cluster", y="recency", data=RFM_k6, ax=ax[0])
sns.boxplot(x="cluster", y="frequency", data=RFM_k6, ax=ax[1])
sns.boxplot(x="cluster", y="monetary", data=RFM_k6, ax=ax[2])
plt.tight_layout()
plt.show()
Berikut contoh tampilan visualisasinya.

Penutup
Aku menyandarkan punggungku ke atas bantalan sofa kerja. Akhirnya selesai juga! Aku tak menyangka bisa lebih cepat dari dugaanku dan bisa mengirim hasilnya ke Senja tepat waktu. Mengingat hari makin sore, aku memutuskan menyeduh kopi dan mengemil biskuit untuk mengisi perut sembari menikmati pemandangan kota dari jendela besar kantor.
Beberapa menit kemudian, aku melihat Senja berjalan menuju meja kerjaku. Tampaknya Senja telah selesai bekerja.
Berkat bantuan dalam mengerjakan latihan tadi, aku bisa selesai lebih cepat!
Aku sedang menikmati pemandangan kota yang indah dari kantor saat Senja selesai mengecek hasil pembagian data konsumen yang kukerjakan.
“Gimana hasilnya?” tanyaku.
“Berdasarkan yang terlihat, data yang diberikan Aksara memang memiliki banyak outlier, sementara algoritma K-Means merupakan algoritma yang lemah terhadap data outlier.” jawab Senja.
“Apakah hasilnya belum bisa diberikan ke Aksara lagi?” tanyaku lagi.
“Sudah bisa dan jangan lupa jelaskan juga ke Aksara setiap cluster yang terbentuk dari hasil data.” jawab Senja. Tersirat nada puas di sana yang membuatku lebih percaya diri.
Aku pun langsung menghubungi Aksara, mengirimkan hasil pembagian data konsumen, dan menjelaskan hasilnya seperti arahan Senja.
Dag, dig, dug!.. Aku gelisah saat menunggu respons dari Aksara. Apakah Aksara akan kecewa dengan hasilnya? Atau ada data yang kurang lengkap? Mungkinkah perhitunganku ada yang keliru nantinya? Ah! Aku harus lebih tenang.
“Hasil datanya memiliki banyak outlier, ya? Tapi hasil pembagian datanya sudah cukup baik. Mengingat jumlah datanya yang begitu banyak, pihak manajer sudah sangat terbantu karena tidak perlu melakukan clustering data secara manual.” balas Aksara. “Kerja bagus untuk hari ini.”
Mendengar tanggapan Aksara, aku begitu lega! Panggilan itu pun diakhiri dengan baik. Rasanya seperti ada batu besar yang berhasil diangkat dari pundakku.
Setelah mengakhiri panggilan, aku merasa sangat lega.
“Walaupun tugas ini sudah selesai, kamu tetap harus belajar algoritma-algoritma clustering lainnya supaya bisa menyelesaikan masalah-masalah serupa.” saran Senja.
“Siap! Tapi sepertinya aku butuh bantuan Senja lagi nih ke depannya.” balasku.
“Hahaha, boleh!”
Senja setuju untuk membantuku belajar kembali. Kalau seperti ini, aku pasti bakal semangat terus. Bisa belajar hal baru sekaligus memberi solusi untuk masalah-masalah kantor. Aku pun bisa pulang ke rumah dengan perasaan lebih nyaman hari itu.
Hasil Belajarku
Wah senangnya! Aku telah berhasil menyelesaikan rangkaian pelajaran Metrik Statistik Penting pada Algoritma Clustering K-Means. Dari materi yang telah aku pelajari dan praktekkan, aku telah:
- memahami apa itu centroids, stabilisasi nilai centroid, iterasi yang diperlukan
- memahami dan dapat menggunakan metode penetuan nilai K yang sesuai, seperti Elbow method.
- Mengetahui cost function yang digunakan adalah WSSE with euclidian distance.
메타데이터
- post_id
- fad72031c066
- slug
- metrik-statistik-penting-pada-algoritma-clustering-k-means-fad72031c066
- url
- https://medium.com/@assatrissiarzl/metrik-statistik-penting-pada-algoritma-clustering-k-means-fad72031c066
- canonical_url
- https://medium.com/@assatrissiarzl/metrik-statistik-penting-pada-algoritma-clustering-k-means-fad72031c066
- author_url
- https://medium.com/@assatrissiarzl
- status
- ok
- fetched_at
- 2026-07-20 00:49:48